bunpen: implement capability
struct with parse method
This commit is contained in:
172
pkgs/additional/bunpen/config/capability.ha
Normal file
172
pkgs/additional/bunpen/config/capability.ha
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
// vim: set shiftwidth=2 :
|
||||||
|
|
||||||
|
use ascii;
|
||||||
|
use strings;
|
||||||
|
|
||||||
|
export type capability = enum {
|
||||||
|
AUDIT_CONTROL,
|
||||||
|
AUDIT_READ,
|
||||||
|
AUDIT_WRITE,
|
||||||
|
BLOCK_SUSPEND,
|
||||||
|
BPF,
|
||||||
|
CHECKPOINT_RESTORE,
|
||||||
|
CHOWN,
|
||||||
|
DAC_OVERRIDE,
|
||||||
|
DAC_READ_SEARCH,
|
||||||
|
FOWNER,
|
||||||
|
FSETID,
|
||||||
|
IPC_LOCK,
|
||||||
|
IPC_OWNER,
|
||||||
|
KILL,
|
||||||
|
LEASE,
|
||||||
|
LINUX_IMMUTABLE,
|
||||||
|
MAC_ADMIN,
|
||||||
|
MAC_OVERRIDE,
|
||||||
|
MKNOD,
|
||||||
|
NET_ADMIN,
|
||||||
|
NET_BIND_SERVICE,
|
||||||
|
NET_BROADCAST,
|
||||||
|
NET_RAW,
|
||||||
|
PERFMON,
|
||||||
|
SETFCAP,
|
||||||
|
SETGID,
|
||||||
|
SETPCAP,
|
||||||
|
SETUID,
|
||||||
|
SYS_ADMIN,
|
||||||
|
SYS_BOOT,
|
||||||
|
SYS_CHROOT,
|
||||||
|
SYS_MODULE,
|
||||||
|
SYS_NICE,
|
||||||
|
SYS_PACCT,
|
||||||
|
SYS_PTRACE,
|
||||||
|
SYS_RAWIO,
|
||||||
|
SYS_RESOURCE,
|
||||||
|
SYS_TIME,
|
||||||
|
SYS_TTY_CONFIG,
|
||||||
|
SYSLOG,
|
||||||
|
WAKE_ALARM,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn capability_fromstr(v: str) (capability | error) = {
|
||||||
|
// strip leading CAP_ and allow either form.
|
||||||
|
if (len(v) > 4 && ascii::strcasecmp(strings::sub(v, 0, 4), "CAP_") == 0)
|
||||||
|
v = strings::sub(v, 4);
|
||||||
|
|
||||||
|
if (ascii::strcasecmp(v, "AUDIT_CONTROL") == 0)
|
||||||
|
return capability::AUDIT_CONTROL;
|
||||||
|
if (ascii::strcasecmp(v, "AUDIT_READ") == 0)
|
||||||
|
return capability::AUDIT_READ;
|
||||||
|
if (ascii::strcasecmp(v, "AUDIT_WRITE") == 0)
|
||||||
|
return capability::AUDIT_WRITE;
|
||||||
|
if (ascii::strcasecmp(v, "BLOCK_SUSPEND") == 0)
|
||||||
|
return capability::BLOCK_SUSPEND;
|
||||||
|
if (ascii::strcasecmp(v, "BPF") == 0)
|
||||||
|
return capability::BPF;
|
||||||
|
if (ascii::strcasecmp(v, "CHECKPOINT_RESTORE") == 0)
|
||||||
|
return capability::CHECKPOINT_RESTORE;
|
||||||
|
if (ascii::strcasecmp(v, "CHOWN") == 0)
|
||||||
|
return capability::CHOWN;
|
||||||
|
if (ascii::strcasecmp(v, "DAC_OVERRIDE") == 0)
|
||||||
|
return capability::DAC_OVERRIDE;
|
||||||
|
if (ascii::strcasecmp(v, "DAC_READ_SEARCH") == 0)
|
||||||
|
return capability::DAC_READ_SEARCH;
|
||||||
|
if (ascii::strcasecmp(v, "FOWNER") == 0)
|
||||||
|
return capability::FOWNER;
|
||||||
|
if (ascii::strcasecmp(v, "FSETID") == 0)
|
||||||
|
return capability::FSETID;
|
||||||
|
if (ascii::strcasecmp(v, "IPC_LOCK") == 0)
|
||||||
|
return capability::IPC_LOCK;
|
||||||
|
if (ascii::strcasecmp(v, "IPC_OWNER") == 0)
|
||||||
|
return capability::IPC_OWNER;
|
||||||
|
if (ascii::strcasecmp(v, "KILL") == 0)
|
||||||
|
return capability::KILL;
|
||||||
|
if (ascii::strcasecmp(v, "LEASE") == 0)
|
||||||
|
return capability::LEASE;
|
||||||
|
if (ascii::strcasecmp(v, "LINUX_IMMUTABLE") == 0)
|
||||||
|
return capability::LINUX_IMMUTABLE;
|
||||||
|
if (ascii::strcasecmp(v, "MAC_ADMIN") == 0)
|
||||||
|
return capability::MAC_ADMIN;
|
||||||
|
if (ascii::strcasecmp(v, "MAC_OVERRIDE") == 0)
|
||||||
|
return capability::MAC_OVERRIDE;
|
||||||
|
if (ascii::strcasecmp(v, "MKNOD") == 0)
|
||||||
|
return capability::MKNOD;
|
||||||
|
if (ascii::strcasecmp(v, "NET_ADMIN") == 0)
|
||||||
|
return capability::NET_ADMIN;
|
||||||
|
if (ascii::strcasecmp(v, "NET_BIND_SERVICE") == 0)
|
||||||
|
return capability::NET_BIND_SERVICE;
|
||||||
|
if (ascii::strcasecmp(v, "NET_BROADCAST") == 0)
|
||||||
|
return capability::NET_BROADCAST;
|
||||||
|
if (ascii::strcasecmp(v, "NET_RAW") == 0)
|
||||||
|
return capability::NET_RAW;
|
||||||
|
if (ascii::strcasecmp(v, "PERFMON") == 0)
|
||||||
|
return capability::PERFMON;
|
||||||
|
if (ascii::strcasecmp(v, "SETFCAP") == 0)
|
||||||
|
return capability::SETFCAP;
|
||||||
|
if (ascii::strcasecmp(v, "SETGID") == 0)
|
||||||
|
return capability::SETGID;
|
||||||
|
if (ascii::strcasecmp(v, "SETPCAP") == 0)
|
||||||
|
return capability::SETPCAP;
|
||||||
|
if (ascii::strcasecmp(v, "SETUID") == 0)
|
||||||
|
return capability::SETUID;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_ADMIN") == 0)
|
||||||
|
return capability::SYS_ADMIN;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_BOOT") == 0)
|
||||||
|
return capability::SYS_BOOT;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_CHROOT") == 0)
|
||||||
|
return capability::SYS_CHROOT;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_MODULE") == 0)
|
||||||
|
return capability::SYS_MODULE;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_NICE") == 0)
|
||||||
|
return capability::SYS_NICE;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_PACCT") == 0)
|
||||||
|
return capability::SYS_PACCT;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_PTRACE") == 0)
|
||||||
|
return capability::SYS_PTRACE;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_RAWIO") == 0)
|
||||||
|
return capability::SYS_RAWIO;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_RESOURCE") == 0)
|
||||||
|
return capability::SYS_RESOURCE;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_TIME") == 0)
|
||||||
|
return capability::SYS_TIME;
|
||||||
|
if (ascii::strcasecmp(v, "SYS_TTY_CONFIG") == 0)
|
||||||
|
return capability::SYS_TTY_CONFIG;
|
||||||
|
if (ascii::strcasecmp(v, "SYSLOG") == 0)
|
||||||
|
return capability::SYSLOG;
|
||||||
|
if (ascii::strcasecmp(v, "WAKE_ALARM") == 0)
|
||||||
|
return capability::WAKE_ALARM;
|
||||||
|
|
||||||
|
return error;
|
||||||
|
};
|
||||||
|
|
||||||
|
// return true if `s` parses to `expect`
|
||||||
|
fn _parse_eq(s: str, expect: (capability | error)) bool = {
|
||||||
|
let got = capability_fromstr(s);
|
||||||
|
return match (expect) {
|
||||||
|
case let c: capability => yield match (got) {
|
||||||
|
case let c2: capability => yield c2 == c;
|
||||||
|
case => yield false;
|
||||||
|
};
|
||||||
|
case error => yield match (got) {
|
||||||
|
case error => yield true; // both errors
|
||||||
|
case => yield false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn cap_from_str_good() void = {
|
||||||
|
assert(_parse_eq("SYS_ADMIN", capability::SYS_ADMIN));
|
||||||
|
assert(_parse_eq("CAP_SYS_ADMIN", capability::SYS_ADMIN));
|
||||||
|
|
||||||
|
assert(_parse_eq("sys_admin", capability::SYS_ADMIN));
|
||||||
|
assert(_parse_eq("cap_sys_admin", capability::SYS_ADMIN));
|
||||||
|
|
||||||
|
assert(_parse_eq("CAP_sys_admin", capability::SYS_ADMIN));
|
||||||
|
assert(_parse_eq("cap_SYS_ADMIN", capability::SYS_ADMIN));
|
||||||
|
};
|
||||||
|
|
||||||
|
@test fn cap_from_str_bad() void = {
|
||||||
|
assert(_parse_eq("CAP_SYS_ADMIN_AND_MORE", error));
|
||||||
|
assert(_parse_eq("SYS_ADMIN_CAP", error));
|
||||||
|
assert(_parse_eq("SYS", error));
|
||||||
|
assert(_parse_eq("", error));
|
||||||
|
};
|
Reference in New Issue
Block a user