linux_keyutils/
metadata.rs1use crate::ffi::{self, KeyCtlOperation, KeySerialId};
2use crate::utils::{CStr, String};
3use crate::{KeyError, KeyPermissions, KeyType};
4use alloc::string::ToString;
5use core::str::{self, FromStr};
6
7#[derive(Debug, Clone)]
11pub struct Metadata {
12 ktype: KeyType,
13 uid: u32,
14 gid: u32,
15 perm: KeyPermissions,
16 description: String,
17}
18
19impl FromStr for Metadata {
20 type Err = KeyError;
21
22 fn from_str(s: &str) -> Result<Self, Self::Err> {
32 let mut iter = s.split(';');
34
35 let ktype: KeyType = iter
37 .next()
38 .and_then(|v| v.try_into().ok())
39 .ok_or(KeyError::InvalidDescription)?;
40
41 let uid = iter
43 .next()
44 .and_then(|v| v.parse().ok())
45 .ok_or(KeyError::InvalidDescription)?;
46
47 let gid = iter
49 .next()
50 .and_then(|v| v.parse().ok())
51 .ok_or(KeyError::InvalidDescription)?;
52
53 let perms: u32 = iter
55 .next()
56 .and_then(|v| u32::from_str_radix(v, 16).ok())
57 .ok_or(KeyError::InvalidDescription)?;
58
59 let description = iter.next().ok_or(KeyError::InvalidDescription)?.to_string();
61
62 Ok(Self {
64 ktype,
65 uid,
66 gid,
67 perm: KeyPermissions::from_u32(perms),
68 description,
69 })
70 }
71}
72
73impl Metadata {
74 pub(crate) fn from_id(id: KeySerialId) -> Result<Self, KeyError> {
77 let mut result = alloc::vec![0u8; 512];
78
79 let len = ffi::keyctl!(
81 KeyCtlOperation::Describe,
82 id.as_raw_id() as libc::c_ulong,
83 result.as_mut_ptr() as _,
84 result.len() as _
85 )? as usize;
86
87 let cs = CStr::from_bytes_with_nul(&result[..len]).or(Err(KeyError::InvalidDescription))?;
89
90 let s = cs.to_str().or(Err(KeyError::InvalidDescription))?;
92 Self::from_str(s)
93 }
94
95 pub fn get_type(&self) -> KeyType {
97 self.ktype
98 }
99
100 pub fn get_uid(&self) -> u32 {
102 self.uid
103 }
104
105 pub fn get_gid(&self) -> u32 {
107 self.gid
108 }
109
110 pub fn get_perms(&self) -> KeyPermissions {
112 self.perm
113 }
114
115 pub fn get_description(&self) -> &str {
117 &self.description
118 }
119}