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