hare

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

keyctl.ha (2828B)


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