@@ -3,9 +3,7 @@ use crate::{KeyError, KeyPermissions};
3
3
use alloc:: string:: String ;
4
4
use core:: fmt;
5
5
6
- /// Rust Interface for KeyCtl operations using the kernel
7
- /// provided keyrings. Each method is implemented to leverage
8
- /// Rust strict typing.
6
+ /// A key corresponding to a specific real ID.
9
7
#[ derive( Debug , Copy , Clone ) ]
10
8
pub struct Key ( KeySerialId ) ;
11
9
@@ -17,7 +15,7 @@ impl fmt::Display for Key {
17
15
}
18
16
19
17
impl Key {
20
- /// Initialize a new `KeyCtl` object from the provided ID
18
+ /// Initialize a new [Key] object from the provided ID
21
19
pub fn from_id ( id : KeySerialId ) -> Self {
22
20
Self ( id)
23
21
}
@@ -31,8 +29,8 @@ impl Key {
31
29
///
32
30
/// The key must grant the caller view permission.
33
31
///
34
- /// The returned string is null-terminated and contains the following
35
- /// information about the key:
32
+ /// The returned string contains the following information about
33
+ /// the key:
36
34
///
37
35
/// `type;uid;gid;perm;description`
38
36
///
@@ -58,14 +56,15 @@ impl Key {
58
56
/// The key must either grant the caller read permission, or grant
59
57
/// the caller search permission when searched for from the process
60
58
/// keyrings (i.e., the key is possessed).
61
- ///
62
- /// The returned data will be processed for presentation according to
63
- /// the key type. For example, a keyring will return an array of
64
- /// key_serial_t entries representing the IDs of all the keys that
65
- /// are linked to it. The user key type will return its data as is.
66
- /// If a key type does not implement this function, the operation
67
- /// fails with the error EOPNOTSUPP.
68
59
pub fn read < T : AsMut < [ u8 ] > > ( & self , buffer : & mut T ) -> Result < usize , KeyError > {
60
+ // TODO: alternate key types? Currenlty we only support KeyType::User
61
+ //
62
+ // The returned data will be processed for presentation according to
63
+ // the key type. For example, a keyring will return an array of
64
+ // key_serial_t entries representing the IDs of all the keys that
65
+ // are linked to it. The user key type will return its data as is.
66
+ // If a key type does not implement this function, the operation
67
+ // fails with the error EOPNOTSUPP.
69
68
let len = ffi:: keyctl!(
70
69
KeyCtlOperation :: Read ,
71
70
self . 0 . as_raw_id( ) as libc:: c_ulong,
@@ -80,7 +79,7 @@ impl Key {
80
79
/// The caller must have write permission on the key specified and the key
81
80
/// type must support updating.
82
81
///
83
- /// A negatively instantiated key (see the description of `KeyCtl ::reject` )
82
+ /// A negatively instantiated key (see the description of [Key ::reject] )
84
83
/// can be positively instantiated with this operation.
85
84
pub fn update < T : AsRef < [ u8 ] > > ( & self , update : & T ) -> Result < ( ) , KeyError > {
86
85
_ = ffi:: keyctl!(
@@ -127,23 +126,72 @@ impl Key {
127
126
Ok ( ( ) )
128
127
}
129
128
130
- pub fn set_timeout ( ) {
131
- todo ! ( )
129
+ /// Set a timeout on a key.
130
+ ///
131
+ /// Specifying the timeout value as 0 clears any existing timeout on the key.
132
+ ///
133
+ /// The `/proc/keys` file displays the remaining time until each key will expire.
134
+ /// (This is the only method of discovering the timeout on a key.)
135
+ ///
136
+ /// The caller must either have the setattr permission on the key or hold an
137
+ /// instantiation authorization token for the key.
138
+ ///
139
+ /// The key and any links to the key will be automatically garbage collected
140
+ /// after the timeout expires. Subsequent attempts to access the key will
141
+ /// then fail with the error EKEYEXPIRED.
142
+ ///
143
+ /// This operation cannot be used to set timeouts on revoked, expired, or
144
+ /// negatively instantiated keys.
145
+ pub fn set_timeout ( & self , seconds : usize ) -> Result < ( ) , KeyError > {
146
+ _ = ffi:: keyctl!(
147
+ KeyCtlOperation :: SetTimeout ,
148
+ self . 0 . as_raw_id( ) as libc:: c_ulong,
149
+ seconds as _
150
+ ) ?;
151
+ Ok ( ( ) )
152
+ }
153
+
154
+ /// Revoke this key. Similar to [Key::reject] just without the timeout.
155
+ ///
156
+ /// The key is scheduled for garbage collection; it will no longer be findable,
157
+ /// and will be unavailable for further operations. Further attempts to use the
158
+ /// key will fail with the error EKEYREVOKED.
159
+ ///
160
+ /// The caller must have write or setattr permission on the key.
161
+ pub fn revoke ( & self ) -> Result < ( ) , KeyError > {
162
+ _ = ffi:: keyctl!( KeyCtlOperation :: Revoke , self . 0 . as_raw_id( ) as libc:: c_ulong) ?;
163
+ Ok ( ( ) )
164
+ }
165
+
166
+ /// Mark a key as negatively instantiated and set an expiration timer on the key.
167
+ ///
168
+ /// This will prevent others from retrieving the key in further searches. And they
169
+ /// will receive a `EKEYREJECTED` error when performing the search.
170
+ ///
171
+ /// Similar to [Key::revoke] but with a timeout.
172
+ pub fn reject ( & self , seconds : usize ) -> Result < ( ) , KeyError > {
173
+ _ = ffi:: keyctl!(
174
+ KeyCtlOperation :: Reject ,
175
+ self . 0 . as_raw_id( ) as libc:: c_ulong,
176
+ seconds as _,
177
+ libc:: EKEYREJECTED as _
178
+ ) ?;
179
+ Ok ( ( ) )
132
180
}
133
181
134
182
/// Mark a key as invalid.
135
183
///
136
184
/// To invalidate a key, the caller must have search permission on the
137
185
/// key.
138
186
///
139
- /// This operation marks the key as invalid and schedules immediate
140
- /// garbage collection. The garbage collector removes the invali‐
187
+ /// This operation marks the key as invalid and schedules immediate
188
+ /// garbage collection. The garbage collector removes the invali‐
141
189
/// dated key from all keyrings and deletes the key when its refer‐
142
- /// ence count reaches zero. After this operation, the key will be
190
+ /// ence count reaches zero. After this operation, the key will be
143
191
/// ignored by all searches, even if it is not yet deleted.
144
192
///
145
193
/// Keys that are marked invalid become invisible to normal key oper‐
146
- /// ations immediately, though they are still visible in /proc/keys
194
+ /// ations immediately, though they are still visible in ` /proc/keys`
147
195
/// (marked with an 'i' flag) until they are actually removed.
148
196
pub fn invalidate ( & self ) -> Result < ( ) , KeyError > {
149
197
ffi:: keyctl!(
@@ -195,25 +243,4 @@ mod tests {
195
243
assert_eq ! ( "wow" . as_bytes( ) , & buf[ ..len] ) ;
196
244
key. invalidate ( ) . unwrap ( )
197
245
}
198
- /*
199
- #[test]
200
- fn test_user_keyring_chmod() {
201
- let secret = "Test Data";
202
- let id = ffi::add_key(
203
- KeyType::User,
204
- KeyringIdentifier::User,
205
- "my-super-secret-test-key2",
206
- secret.as_bytes(),
207
- )
208
- .unwrap();
209
- let mut buf = [0u8; 4096];
210
-
211
- let euid = unsafe { libc::geteuid() };
212
-
213
- let keyctl = KeyCtl::from_id(id);
214
- keyctl.chown(Some(euid), Some(0)).unwrap();
215
- let len = keyctl.read(&mut buf).unwrap();
216
- assert_eq!(secret.as_bytes(), &buf[..len]);
217
- keyctl.invalidate().unwrap()
218
- }*/
219
246
}
0 commit comments