hare

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

keyctl.ha (2414B)


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