hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };