File: keyctl.ha

package info (click to toggle)
hare 0.25.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,948 kB
  • sloc: asm: 1,264; makefile: 123; sh: 114; lisp: 101
file content (145 lines) | stat: -rw-r--r-- 3,727 bytes parent folder | download
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)?;
};