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