keyctl.ha (2839B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use bytes; 5 use errors; 6 use rt; 7 use types::c; 8 9 fn errno(errno: rt::errno) error = { 10 switch (errno) { 11 case rt::ENOKEY => 12 return nokey; 13 case => 14 return errors::errno(errno); 15 }; 16 }; 17 18 // Adds a key to the kernel's key management facility. 19 export fn add_key( 20 keytype: str, 21 name: str, 22 payload: []u8, 23 keyring: serial, 24 ) (serial | error) = { 25 const keytype = c::fromstr(keytype); 26 defer free(keytype); 27 const name = c::fromstr(name); 28 defer free(name); 29 match (rt::add_key(keytype: *const u8, name: *const u8, 30 payload: *[*]u8: *opaque, len(payload), keyring)) { 31 case let err: rt::errno => 32 return errno(err); 33 case let n: int => 34 return n: serial; 35 }; 36 }; 37 38 fn keyctl( 39 cmd: command, 40 arg2: u64, 41 arg3: u64, 42 arg4: u64, 43 arg5: u64, 44 ) (int | error) = { 45 match (rt::keyctl(cmd, arg2, arg3, arg4, arg5)) { 46 case let err: rt::errno => 47 return errno(err); 48 case let n: int => 49 return n; 50 }; 51 }; 52 53 // Maps a special key or keyring ID to the serial number of the key actually 54 // representing that feature. If it does not exist and 'create' is true, then 55 // the key or keyring will be created if it is appropriate to do so. 56 export fn get_keyring_id(key: serial, create: bool) (serial | error) = { 57 return keyctl(command::GET_KEYRING_ID, 58 key: u64, if (create) 1 else 0, 0, 0)?: serial; 59 }; 60 61 // Replace the session keyring this process subscribes to with a new session 62 // keyring using the given name, or, given an empty string, "_ses". 63 export fn join_session_keyring(name: str) (serial | error) = { 64 let name = if (name == "") { 65 yield null; 66 } else { 67 yield c::fromstr(name); 68 }; 69 defer free(name); 70 return keyctl(command::JOIN_SESSION_KEYRING, 71 name: uintptr: u64, 0, 0, 0)?: serial; 72 }; 73 74 // Update a key's payload. 75 export fn update(id: serial, payload: []u8) (void | error) = { 76 keyctl(command::UPDATE, id: u64, 77 payload: *[*]u8: uintptr: u64, 78 len(payload): u64, 0)?; 79 }; 80 81 // Revoke the key with the provided ID. 82 export fn revoke(id: serial) (void | error) = { 83 keyctl(command::REVOKE, id: u64, 0, 0, 0)?; 84 }; 85 86 // Reads the payload from a key, returning the size of the key data. The 87 // provided buffer may be empty to probe the key size without reading. 88 export fn read(id: serial, buf: []u8) (size | error) = { 89 const bufln = len(buf); 90 const buf = if (len(buf) == 0) { 91 yield null; 92 } else { 93 yield buf: *[*]u8: *opaque; 94 }; 95 return keyctl(command::READ, id: u64, 96 buf: uintptr: u64, bufln: u64, 0)?: size; 97 }; 98 99 // Changes the user and group ownership of the key. 100 export fn chown(id: serial, uid: uint, gid: uint) (void | error) = { 101 keyctl(command::CHOWN, id: u64, uid: u64, gid: u64, 0)?; 102 }; 103 104 // Changes the permissions mask of the key. 105 export fn setperm(id: serial, perm: perm) (void | error) = { 106 keyctl(command::SETPERM, id: u64, perm, 0, 0)?; 107 };