commit c9239415b7aa969f1ac5bcd8e46636718d997118
parent d24673d64ec2257dc8362ab75ccd9b0c9f0f6353
Author: Jan Pobrislo <ccx@te2000.cz>
Date: Fri, 6 Dec 2024 00:36:04 +0000
Make source filenames more consistent
Diffstat:
8 files changed, 488 insertions(+), 488 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -7,10 +7,10 @@ build/miniroon-$(1): $$(patsubst %,build/%,$$(obj_$(1))) ../link
../link -o '$$@' $$(patsubst %,build/%,$$(obj_$(1)))
endef
-obj_read:=miniroon-read.o bytebuffer.o netstring.o miniroon-header.o
+obj_read:=cmd_read.o bytebuffer.o netstring.o header.o
$(eval $(call miniroon_link,read))
-obj_verify:=miniroon-verify.o bytebuffer.o netstring.o hmac_sha2_256.o miniroon-header.o envmap.o caveats.o miniroon_caveat_name_perfhash.o caveat_env_is.o caveat_env_absent.o caveat_env_fnmatch.o
+obj_verify:=cmd_verify.o bytebuffer.o netstring.o hmac_sha2_256.o header.o envmap.o caveats.o miniroon_caveat_name_perfhash.o caveat_env_is.o caveat_env_absent.o caveat_env_fnmatch.o
$(eval $(call miniroon_link,verify))
tools:=$(patsubst %,build/miniroon-%,$(miniroon_tool_names))
diff --git a/src/cmd_read.c b/src/cmd_read.c
@@ -0,0 +1,201 @@
+#include <errno.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <skalibs/types.h>
+#include <skalibs/strerr.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+#include <skalibs/netstring.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/env.h>
+
+#include "netstring.h"
+#include "header.h"
+
+#define USAGE "miniroon-read directory"
+#define PROG "miniroon-read"
+
+#define input_fd 0
+#define payload_size_max 1024*1024
+#define MAX_CAVEATS 256
+#define MAX_ENV_ALLOW 256
+
+
+void fd_block(int fd) {
+ int flags = fcntl(fd, F_GETFL);
+ if(flags == -1) {
+ strerr_dief1sys(111, "fcntl() getfd");
+ }
+ if(fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
+ strerr_dief1sys(111, "fcntl() setfd");
+ }
+}
+
+size_t read_payload_size(int fd) {
+ char read_char;
+ size_t payload_size = 0;
+
+ fd_block(fd);
+
+ while(payload_size < payload_size_max) {
+ switch(read(fd, &read_char, 1)) {
+ case 0:
+ strerr_dief1x(111, "EOF before netstring size was read");
+ break;
+ case 1:
+ if(read_char == ':') {
+ return payload_size;
+ } else if(read_char >= '0' && read_char <= '9') {
+ payload_size *= 10;
+ payload_size += read_char - '0';
+ } else {
+ strerr_dief1x(111, "Malformed netstring on input");
+ }
+ break;
+ case -1:
+ if(errno != EINTR) {
+ strerr_dief1sys(111, "read() length");
+ }
+ break;
+ default:
+ strerr_dief1x(110, "Unexpected return value from read()");
+ break;
+ }
+ }
+
+ strerr_dief1x(111, "Input netstring too big");
+}
+
+void read_payload(const bytebuffer bb) {
+ char *read_next = bb.data;
+ ssize_t read_size;
+ while(read_next - bb.data < bb.len) {
+ read_size = read(input_fd, read_next, bb.len - (read_next - bb.data));
+ if(read_size == 0) {
+ strerr_dief1x(111, "EOF before full netstring payload was read");
+ }
+ if(read_size == -1) {
+ if(errno != EINTR) {
+ strerr_dief1sys(111, "read() payload");
+ }
+ continue;
+ }
+ read_next += read_size;
+ }
+ if(bb.data[bb.len - 1] != ',') {
+ strerr_dief1x(111, "Invalid netstring terminator");
+ }
+}
+
+void process_header(miniroon_header *header, const bytebuffer source) {
+ parse_header(header, source);
+
+ char id[header->id.len + 1];
+ for(size_t i=0; i<header->id.len; i++) {
+ id[i] = header->id.data[i];
+ if(id[i] == '-') { continue; }
+ if(id[i] >= '0' && id[i] <= '9') { continue; }
+ if(id[i] >= 'a' && id[i] <= 'z') { continue; }
+ strerr_dief1x(111, "Invalid character in miniroon ID");
+ }
+ id[header->id.len] = 0;
+
+ if (chdir(id) != 0) {
+ strerr_dief1sys(111, "chdir(id)");
+ }
+}
+
+void exec_verify_and_write_payload (const bytebuffer payload);
+void process_payload(const bytebuffer payload) {
+ miniroon_header header;
+ netstring_chunk c;
+ netstring_chunk_init(&c, payload);
+
+ if(!netstring_chunk_next(&c)) {
+ strerr_dief1x(111, "Mising miniroon header");
+ }
+ process_header(&header, c.inner);
+ exec_verify_and_write_payload(payload);
+}
+
+void exec_verify_and_write_payload (const bytebuffer payload) {
+ pid_t pid1=0, pid2=0;
+ int wstat ;
+ int p[2] ;
+
+ if(pipe(p) == -1) {
+ strerr_diefu1sys(111, "create pipe");
+ }
+
+ pid1 = fork();
+ switch(pid1) {
+ case -1:
+ strerr_diefu1sys(111, "first fork()");
+ break;
+ case 0: /* child */
+ fd_close(p[0]);
+ pid2 = fork();
+ switch(pid2) {
+ case -1:
+ strerr_diefu1sys(111, "second fork()");
+ break;
+ case 0: /* child */
+ ssize_t payload_write = fd_write(p[1], payload.data, payload.len);
+ if(payload_write < 0 ) {
+ strerr_dief1sys(111, "write(payload)");
+ }
+ if(payload_write != payload.len) {
+ strerr_dief1x(111, "could not write whole payload");
+ }
+ exit(0);
+ break;
+ default: /* parent */
+ exit(0);
+ break;
+ }
+ break;
+ default: /* parent */
+ waitpid_nointr(pid1, &wstat, 0);
+ if(!WIFEXITED(wstat) || WEXITSTATUS(wstat) != 0) {
+ strerr_dief1x(111, "child terminated abnormally");
+ }
+
+ char cmd[] = "./verify";
+ char fmt_fd[UINT64_FMT], fmt_len[UINT64_FMT];
+ fmt_fd[uint64_fmt(fmt_fd, (uint64_t)p[0])] = 0;
+ fmt_len[uint64_fmt(fmt_len, (uint64_t)payload.len)] = 0;
+ const char *cmd_argv[4] = {cmd, fmt_fd, fmt_len, 0};
+
+ fd_close(p[1]);
+ xexec(cmd_argv);
+ break;
+ }
+}
+
+int main (int argc, char const *const *argv)
+{
+
+ if (argc != 2) {
+ strerr_dieusage(100, USAGE);
+ }
+
+ if (chdir(argv[1]) != 0) {
+ strerr_dief1sys(111, "chdir()");
+ }
+ size_t payload_size = read_payload_size(input_fd);
+ char payload_data[payload_size + 1];
+ bytebuffer payload = {payload_data, payload_size + 1};
+ read_payload(payload);
+ payload.len -= 1; /* strip final netstring terminator */
+ dbg_print_bb1("Got payload", payload);
+ process_payload(payload);
+ assert(0);
+ strerr_dief1x(110, "Internal logic error, should not get here");
+ return 110;
+}
+
+/* vim: sts=2 sw=2 et
+*/
diff --git a/src/cmd_verify.c b/src/cmd_verify.c
@@ -0,0 +1,229 @@
+#include <errno.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/select.h>
+
+// for debug prints
+#include <stdio.h>
+
+#include <skalibs/types.h>
+#include <skalibs/strerr.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+#include <skalibs/netstring.h>
+#include <skalibs/uint64.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/env.h>
+
+#include "verify_common.h"
+#include "bytebuffer.h"
+#include "netstring.h"
+#include "hmac_sha2_256.h"
+#include "header.h"
+#include "caveats.h"
+
+typedef struct miniroon_data_s {
+ miniroon_header hdr;
+ bytebuffer caveats[MAX_CAVEATS];
+ size_t caveat_count;
+} miniroon_data;
+
+/* declarations */
+void miniroon_data_init(miniroon_data *data);
+void process_payload(const bytebuffer payload);
+void validate_and_exec(miniroon_data *data);
+void read_secret(const bytebuffer secret);
+
+#define MINIROON_HMAC_SIZE 32
+//#define MINIROON_HMAC_FUNC(key, msg, out) hmac_b2s_256(key, msg, out)
+#define MINIROON_HMAC_FUNC(key, msg, out) hmac_sha2_256(key, msg, out)
+
+/* definitions */
+
+
+void miniroon_data_init(miniroon_data *data) {
+ memset(data, 0, sizeof(miniroon_data));
+ // data->env_modif = STRALLOC_ZERO ;
+}
+
+void read_secret(const bytebuffer secret){
+ assert(secret.len == MINIROON_HMAC_SIZE);
+ size_t bytes_read = 0;
+ int secret_fd = openc_readb("secret");
+ if (secret_fd < 0) {
+ strerr_dief1sys(111, "open(secret)");
+ }
+ while(bytes_read < secret.len) {
+ ssize_t r = read(secret_fd, &secret.data[bytes_read], secret.len - bytes_read);
+ switch(r) {
+ case 0:
+ strerr_dief1x(111, "EOF before full secret was read");
+ break;
+ case -1:
+ if(errno != EINTR) {
+ strerr_dief1sys(111, "read() length");
+ }
+ break;
+ }
+ bytes_read += r;
+ }
+ if(close(secret_fd) != 0) {
+ strerr_dief1sys(111, "close(secret_fd)");
+ }
+}
+
+
+void validate_and_exec(miniroon_data *md) {
+ miniroon_caveats_state state;
+ miniroon_caveats_state_init(&state);
+ // stralloc env_modif;
+
+ for(size_t i=0; i < md->caveat_count; i++) {
+ dbg_print_bb1("Validate caveat", md->caveats[i]);
+ miniroon_caveat_prepare(md->caveats[i], &state);
+ }
+ for(size_t i=0; i < md->caveat_count; i++) {
+ dbg_print_bb1("Validate caveat", md->caveats[i]);
+ miniroon_caveat_validate(md->caveats[i], &state);
+ }
+
+ /* iff everything validated correctly */
+ // TODO: pass unused argv from main() ?
+ char cmd[] = "./run";
+ const char *cmd_argv[2] = {cmd, 0};
+ miniroon_caveats_state_exec(&state, cmd_argv);
+}
+
+void process_payload(const bytebuffer payload) {
+ miniroon_data md;
+ miniroon_data_init(&md);
+ netstring_chunk c;
+ netstring_chunk_init(&c, payload);
+
+ if(!netstring_chunk_next(&c)) {
+ strerr_dief1x(111, "Mising miniroon header");
+ }
+ parse_header(&md.hdr, c.inner);
+ // header should be verified by now, we can start hashing
+ uint8_t hmac_data[MINIROON_HMAC_SIZE];
+ bytebuffer hmac_bb = {hmac_data, MINIROON_HMAC_SIZE};
+ read_secret(hmac_bb);
+ // dbg_print_bb1("Secret", hmac_bb);
+ MINIROON_HMAC_FUNC(hmac_bb, c.inner, hmac_bb);
+ // dbg_print_bb1("Signature update", hmac_bb);
+
+ if(!netstring_chunk_next(&c)) {
+ strerr_dief1x(111, "Mising miniroon body");
+ }
+ netstring_chunk body;
+ netstring_chunk_init(&body, c.inner);
+
+ while(netstring_chunk_next(&body)) {
+ dbg_print_bb1("Got caveat", body.inner);
+ if(md.caveat_count >= MAX_CAVEATS) {
+ strerr_dief1x(111, "Too many caveats");
+ }
+ md.caveats[md.caveat_count++] = body.inner;
+ MINIROON_HMAC_FUNC(hmac_bb, body.inner, hmac_bb);
+ // dbg_print_bb1("Signature update", hmac_bb);
+ }
+
+ if(!netstring_chunk_next(&c)) {
+ strerr_dief1x(111, "Mising miniroon signature");
+ }
+ dbg_print_bb1("Got signature", c.inner);
+ if(c.inner.len != MINIROON_HMAC_SIZE) {
+ strerr_dief1x(111, "Invalid miniroon signature length");
+ }
+ /* constant time hash compare */
+ uint8_t bitdiff = 0;
+ for(size_t i=0; i<MINIROON_HMAC_SIZE; i++) {
+ bitdiff |= hmac_data[i] ^ c.inner.data[i];
+ }
+ if(netstring_chunk_next(&c)) {
+ strerr_dief1x(111, "Extraneous data in miniroon");
+ }
+ if(bitdiff) {
+ strerr_dief1x(111, "Invalid miniroon signature");
+ }
+
+ validate_and_exec(&md);
+ strerr_dief1x(110, "Internal logic error, should not get here");
+}
+
+void read_payload(int payload_fd, const bytebuffer bb) {
+ int flags = fcntl(payload_fd, F_GETFL);
+ if(flags == -1) {
+ strerr_dief1sys(111, "fcntl(payload_fd) getfd");
+ }
+ if(fcntl(payload_fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
+ strerr_dief1sys(111, "fcntl(payload_fd) setfd");
+ }
+
+ ssize_t payload_read = fd_read(payload_fd, bb.data, bb.len);
+ if(payload_read < 0 ) {
+ strerr_dief1sys(111, "read(payload)");
+ }
+ if(payload_read != bb.len) {
+ strerr_dief1x(111, "could not read whole payload");
+ }
+}
+
+bool parse_fd(char const *arg, int *fd) {
+ size_t arg_size = strlen(arg);
+ return int_scan(arg, fd) == arg_size;
+}
+
+bool parse_size(char const *arg, size_t *size) {
+ size_t arg_size = strlen(arg);
+ return size_scan(arg, size) == arg_size;
+}
+
+int main (int argc, char const *const *argv)
+{
+ if (argc != 3) {
+ strerr_dieusage(100, USAGE);
+ }
+
+ int payload_fd;
+ size_t payload_size;
+
+ if(!parse_fd(argv[1], &payload_fd)) {
+ strerr_dief1x(100, "could not parse payload fd");
+ }
+
+ if(!parse_size(argv[2], &payload_size)) {
+ strerr_dief1x(100, "could not parse payload length");
+ }
+
+ char payload_data[payload_size];
+ bytebuffer payload = {payload_data, payload_size};
+ read_payload(payload_fd, payload);
+ fd_close(payload_fd);
+
+ dbg_print_bb1("Got payload", payload);
+ process_payload(payload);
+ strerr_dief1x(110, "Internal logic error, should not get here");
+ return 110;
+}
+/*
+capability ```
+container/bzr.ccx/123456
+login/tty1/7890
+```
+- secret
+- execline command
+- env allowlist (re?)
+- max execution count/id (uuidv7?)
+
+```
+caphdr = [capv0;name;invoke-once]
+c1 = [caphdr;;h1=hmac(secret, caphdr)]
+c2 = [caphdr;[att1];h2=hmac(h1, att1)]
+c3 = [caphdr;[att1;att2];h3=hmac(h2, att2)]
+```
+*/
+
+/* vim: sts=2 sw=2 et
+*/
diff --git a/src/header.c b/src/header.c
@@ -0,0 +1,56 @@
+#include <skalibs/strerr.h>
+
+#include "netstring.h"
+#include "header.h"
+
+void set_header_version(miniroon_header *header, const bytebuffer source) {
+ if(strbbcmp(source, "capv0") == 0) {
+ header->version = V0;
+ } else {
+ strerr_dief1x(111, "Unhandled miniroon version");
+ }
+}
+
+void set_header_action(miniroon_header *header, const bytebuffer source) {
+ if(strbbcmp(source, "revoke") == 0) {
+ header->action = REVOKE;
+ } else if(strbbcmp(source, "invoke") == 0) {
+ header->action = INVOKE;
+ } else if(strbbcmp(source, "invoke-once") == 0) {
+ header->action = INVOKE_ONCE;
+ } else {
+ strerr_dief1x(111, "Unhandled miniroon action");
+ }
+}
+
+void parse_header(miniroon_header *header, const bytebuffer source) {
+ dbg_print_bb1("Got header", source);
+ netstring_chunk c;
+ netstring_chunk_init(&c, source);
+
+ if(!netstring_chunk_next(&c)) {
+ strerr_dief1x(111, "Mising version in miniroon header");
+ }
+ dbg_print_bb1("Header > Version", c.inner);
+ set_header_version(header, c.inner);
+
+ if(!netstring_chunk_next(&c)) {
+ strerr_dief1x(111, "Mising ID in miniroon header");
+ }
+ dbg_print_bb1("Header > ID", c.inner);
+ header->id = c.inner;
+
+ if(!netstring_chunk_next(&c)) {
+ strerr_dief1x(111, "Mising action in miniroon header");
+ }
+ dbg_print_bb1("Header > Action", c.inner);
+ set_header_action(header, c.inner);
+
+ if(netstring_chunk_next(&c)) {
+ strerr_dief1x(111, "Extraneous data in miniroon header");
+ }
+
+}
+
+/* vim: sts=2 sw=2 et
+*/
diff --git a/src/miniroon-header.h b/src/header.h
diff --git a/src/miniroon-header.c b/src/miniroon-header.c
@@ -1,56 +0,0 @@
-#include <skalibs/strerr.h>
-
-#include "netstring.h"
-#include "miniroon-header.h"
-
-void set_header_version(miniroon_header *header, const bytebuffer source) {
- if(strbbcmp(source, "capv0") == 0) {
- header->version = V0;
- } else {
- strerr_dief1x(111, "Unhandled miniroon version");
- }
-}
-
-void set_header_action(miniroon_header *header, const bytebuffer source) {
- if(strbbcmp(source, "revoke") == 0) {
- header->action = REVOKE;
- } else if(strbbcmp(source, "invoke") == 0) {
- header->action = INVOKE;
- } else if(strbbcmp(source, "invoke-once") == 0) {
- header->action = INVOKE_ONCE;
- } else {
- strerr_dief1x(111, "Unhandled miniroon action");
- }
-}
-
-void parse_header(miniroon_header *header, const bytebuffer source) {
- dbg_print_bb1("Got header", source);
- netstring_chunk c;
- netstring_chunk_init(&c, source);
-
- if(!netstring_chunk_next(&c)) {
- strerr_dief1x(111, "Mising version in miniroon header");
- }
- dbg_print_bb1("Header > Version", c.inner);
- set_header_version(header, c.inner);
-
- if(!netstring_chunk_next(&c)) {
- strerr_dief1x(111, "Mising ID in miniroon header");
- }
- dbg_print_bb1("Header > ID", c.inner);
- header->id = c.inner;
-
- if(!netstring_chunk_next(&c)) {
- strerr_dief1x(111, "Mising action in miniroon header");
- }
- dbg_print_bb1("Header > Action", c.inner);
- set_header_action(header, c.inner);
-
- if(netstring_chunk_next(&c)) {
- strerr_dief1x(111, "Extraneous data in miniroon header");
- }
-
-}
-
-/* vim: sts=2 sw=2 et
-*/
diff --git a/src/miniroon-read.c b/src/miniroon-read.c
@@ -1,201 +0,0 @@
-#include <errno.h>
-#include <unistd.h>
-#include <sys/select.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include <skalibs/types.h>
-#include <skalibs/strerr.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/exec.h>
-#include <skalibs/netstring.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/env.h>
-
-#include "netstring.h"
-#include "miniroon-header.h"
-
-#define USAGE "miniroon-read directory"
-#define PROG "miniroon-read"
-
-#define input_fd 0
-#define payload_size_max 1024*1024
-#define MAX_CAVEATS 256
-#define MAX_ENV_ALLOW 256
-
-
-void fd_block(int fd) {
- int flags = fcntl(fd, F_GETFL);
- if(flags == -1) {
- strerr_dief1sys(111, "fcntl() getfd");
- }
- if(fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
- strerr_dief1sys(111, "fcntl() setfd");
- }
-}
-
-size_t read_payload_size(int fd) {
- char read_char;
- size_t payload_size = 0;
-
- fd_block(fd);
-
- while(payload_size < payload_size_max) {
- switch(read(fd, &read_char, 1)) {
- case 0:
- strerr_dief1x(111, "EOF before netstring size was read");
- break;
- case 1:
- if(read_char == ':') {
- return payload_size;
- } else if(read_char >= '0' && read_char <= '9') {
- payload_size *= 10;
- payload_size += read_char - '0';
- } else {
- strerr_dief1x(111, "Malformed netstring on input");
- }
- break;
- case -1:
- if(errno != EINTR) {
- strerr_dief1sys(111, "read() length");
- }
- break;
- default:
- strerr_dief1x(110, "Unexpected return value from read()");
- break;
- }
- }
-
- strerr_dief1x(111, "Input netstring too big");
-}
-
-void read_payload(const bytebuffer bb) {
- char *read_next = bb.data;
- ssize_t read_size;
- while(read_next - bb.data < bb.len) {
- read_size = read(input_fd, read_next, bb.len - (read_next - bb.data));
- if(read_size == 0) {
- strerr_dief1x(111, "EOF before full netstring payload was read");
- }
- if(read_size == -1) {
- if(errno != EINTR) {
- strerr_dief1sys(111, "read() payload");
- }
- continue;
- }
- read_next += read_size;
- }
- if(bb.data[bb.len - 1] != ',') {
- strerr_dief1x(111, "Invalid netstring terminator");
- }
-}
-
-void process_header(miniroon_header *header, const bytebuffer source) {
- parse_header(header, source);
-
- char id[header->id.len + 1];
- for(size_t i=0; i<header->id.len; i++) {
- id[i] = header->id.data[i];
- if(id[i] == '-') { continue; }
- if(id[i] >= '0' && id[i] <= '9') { continue; }
- if(id[i] >= 'a' && id[i] <= 'z') { continue; }
- strerr_dief1x(111, "Invalid character in miniroon ID");
- }
- id[header->id.len] = 0;
-
- if (chdir(id) != 0) {
- strerr_dief1sys(111, "chdir(id)");
- }
-}
-
-void exec_verify_and_write_payload (const bytebuffer payload);
-void process_payload(const bytebuffer payload) {
- miniroon_header header;
- netstring_chunk c;
- netstring_chunk_init(&c, payload);
-
- if(!netstring_chunk_next(&c)) {
- strerr_dief1x(111, "Mising miniroon header");
- }
- process_header(&header, c.inner);
- exec_verify_and_write_payload(payload);
-}
-
-void exec_verify_and_write_payload (const bytebuffer payload) {
- pid_t pid1=0, pid2=0;
- int wstat ;
- int p[2] ;
-
- if(pipe(p) == -1) {
- strerr_diefu1sys(111, "create pipe");
- }
-
- pid1 = fork();
- switch(pid1) {
- case -1:
- strerr_diefu1sys(111, "first fork()");
- break;
- case 0: /* child */
- fd_close(p[0]);
- pid2 = fork();
- switch(pid2) {
- case -1:
- strerr_diefu1sys(111, "second fork()");
- break;
- case 0: /* child */
- ssize_t payload_write = fd_write(p[1], payload.data, payload.len);
- if(payload_write < 0 ) {
- strerr_dief1sys(111, "write(payload)");
- }
- if(payload_write != payload.len) {
- strerr_dief1x(111, "could not write whole payload");
- }
- exit(0);
- break;
- default: /* parent */
- exit(0);
- break;
- }
- break;
- default: /* parent */
- waitpid_nointr(pid1, &wstat, 0);
- if(!WIFEXITED(wstat) || WEXITSTATUS(wstat) != 0) {
- strerr_dief1x(111, "child terminated abnormally");
- }
-
- char cmd[] = "./verify";
- char fmt_fd[UINT64_FMT], fmt_len[UINT64_FMT];
- fmt_fd[uint64_fmt(fmt_fd, (uint64_t)p[0])] = 0;
- fmt_len[uint64_fmt(fmt_len, (uint64_t)payload.len)] = 0;
- const char *cmd_argv[4] = {cmd, fmt_fd, fmt_len, 0};
-
- fd_close(p[1]);
- xexec(cmd_argv);
- break;
- }
-}
-
-int main (int argc, char const *const *argv)
-{
-
- if (argc != 2) {
- strerr_dieusage(100, USAGE);
- }
-
- if (chdir(argv[1]) != 0) {
- strerr_dief1sys(111, "chdir()");
- }
- size_t payload_size = read_payload_size(input_fd);
- char payload_data[payload_size + 1];
- bytebuffer payload = {payload_data, payload_size + 1};
- read_payload(payload);
- payload.len -= 1; /* strip final netstring terminator */
- dbg_print_bb1("Got payload", payload);
- process_payload(payload);
- assert(0);
- strerr_dief1x(110, "Internal logic error, should not get here");
- return 110;
-}
-
-/* vim: sts=2 sw=2 et
-*/
diff --git a/src/miniroon-verify.c b/src/miniroon-verify.c
@@ -1,229 +0,0 @@
-#include <errno.h>
-#include <assert.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/select.h>
-
-// for debug prints
-#include <stdio.h>
-
-#include <skalibs/types.h>
-#include <skalibs/strerr.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/exec.h>
-#include <skalibs/netstring.h>
-#include <skalibs/uint64.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/env.h>
-
-#include "verify_common.h"
-#include "bytebuffer.h"
-#include "netstring.h"
-#include "hmac_sha2_256.h"
-#include "miniroon-header.h"
-#include "caveats.h"
-
-typedef struct miniroon_data_s {
- miniroon_header hdr;
- bytebuffer caveats[MAX_CAVEATS];
- size_t caveat_count;
-} miniroon_data;
-
-/* declarations */
-void miniroon_data_init(miniroon_data *data);
-void process_payload(const bytebuffer payload);
-void validate_and_exec(miniroon_data *data);
-void read_secret(const bytebuffer secret);
-
-#define MINIROON_HMAC_SIZE 32
-//#define MINIROON_HMAC_FUNC(key, msg, out) hmac_b2s_256(key, msg, out)
-#define MINIROON_HMAC_FUNC(key, msg, out) hmac_sha2_256(key, msg, out)
-
-/* definitions */
-
-
-void miniroon_data_init(miniroon_data *data) {
- memset(data, 0, sizeof(miniroon_data));
- // data->env_modif = STRALLOC_ZERO ;
-}
-
-void read_secret(const bytebuffer secret){
- assert(secret.len == MINIROON_HMAC_SIZE);
- size_t bytes_read = 0;
- int secret_fd = openc_readb("secret");
- if (secret_fd < 0) {
- strerr_dief1sys(111, "open(secret)");
- }
- while(bytes_read < secret.len) {
- ssize_t r = read(secret_fd, &secret.data[bytes_read], secret.len - bytes_read);
- switch(r) {
- case 0:
- strerr_dief1x(111, "EOF before full secret was read");
- break;
- case -1:
- if(errno != EINTR) {
- strerr_dief1sys(111, "read() length");
- }
- break;
- }
- bytes_read += r;
- }
- if(close(secret_fd) != 0) {
- strerr_dief1sys(111, "close(secret_fd)");
- }
-}
-
-
-void validate_and_exec(miniroon_data *md) {
- miniroon_caveats_state state;
- miniroon_caveats_state_init(&state);
- // stralloc env_modif;
-
- for(size_t i=0; i < md->caveat_count; i++) {
- dbg_print_bb1("Validate caveat", md->caveats[i]);
- miniroon_caveat_prepare(md->caveats[i], &state);
- }
- for(size_t i=0; i < md->caveat_count; i++) {
- dbg_print_bb1("Validate caveat", md->caveats[i]);
- miniroon_caveat_validate(md->caveats[i], &state);
- }
-
- /* iff everything validated correctly */
- // TODO: pass unused argv from main() ?
- char cmd[] = "./run";
- const char *cmd_argv[2] = {cmd, 0};
- miniroon_caveats_state_exec(&state, cmd_argv);
-}
-
-void process_payload(const bytebuffer payload) {
- miniroon_data md;
- miniroon_data_init(&md);
- netstring_chunk c;
- netstring_chunk_init(&c, payload);
-
- if(!netstring_chunk_next(&c)) {
- strerr_dief1x(111, "Mising miniroon header");
- }
- parse_header(&md.hdr, c.inner);
- // header should be verified by now, we can start hashing
- uint8_t hmac_data[MINIROON_HMAC_SIZE];
- bytebuffer hmac_bb = {hmac_data, MINIROON_HMAC_SIZE};
- read_secret(hmac_bb);
- // dbg_print_bb1("Secret", hmac_bb);
- MINIROON_HMAC_FUNC(hmac_bb, c.inner, hmac_bb);
- // dbg_print_bb1("Signature update", hmac_bb);
-
- if(!netstring_chunk_next(&c)) {
- strerr_dief1x(111, "Mising miniroon body");
- }
- netstring_chunk body;
- netstring_chunk_init(&body, c.inner);
-
- while(netstring_chunk_next(&body)) {
- dbg_print_bb1("Got caveat", body.inner);
- if(md.caveat_count >= MAX_CAVEATS) {
- strerr_dief1x(111, "Too many caveats");
- }
- md.caveats[md.caveat_count++] = body.inner;
- MINIROON_HMAC_FUNC(hmac_bb, body.inner, hmac_bb);
- // dbg_print_bb1("Signature update", hmac_bb);
- }
-
- if(!netstring_chunk_next(&c)) {
- strerr_dief1x(111, "Mising miniroon signature");
- }
- dbg_print_bb1("Got signature", c.inner);
- if(c.inner.len != MINIROON_HMAC_SIZE) {
- strerr_dief1x(111, "Invalid miniroon signature length");
- }
- /* constant time hash compare */
- uint8_t bitdiff = 0;
- for(size_t i=0; i<MINIROON_HMAC_SIZE; i++) {
- bitdiff |= hmac_data[i] ^ c.inner.data[i];
- }
- if(netstring_chunk_next(&c)) {
- strerr_dief1x(111, "Extraneous data in miniroon");
- }
- if(bitdiff) {
- strerr_dief1x(111, "Invalid miniroon signature");
- }
-
- validate_and_exec(&md);
- strerr_dief1x(110, "Internal logic error, should not get here");
-}
-
-void read_payload(int payload_fd, const bytebuffer bb) {
- int flags = fcntl(payload_fd, F_GETFL);
- if(flags == -1) {
- strerr_dief1sys(111, "fcntl(payload_fd) getfd");
- }
- if(fcntl(payload_fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
- strerr_dief1sys(111, "fcntl(payload_fd) setfd");
- }
-
- ssize_t payload_read = fd_read(payload_fd, bb.data, bb.len);
- if(payload_read < 0 ) {
- strerr_dief1sys(111, "read(payload)");
- }
- if(payload_read != bb.len) {
- strerr_dief1x(111, "could not read whole payload");
- }
-}
-
-bool parse_fd(char const *arg, int *fd) {
- size_t arg_size = strlen(arg);
- return int_scan(arg, fd) == arg_size;
-}
-
-bool parse_size(char const *arg, size_t *size) {
- size_t arg_size = strlen(arg);
- return size_scan(arg, size) == arg_size;
-}
-
-int main (int argc, char const *const *argv)
-{
- if (argc != 3) {
- strerr_dieusage(100, USAGE);
- }
-
- int payload_fd;
- size_t payload_size;
-
- if(!parse_fd(argv[1], &payload_fd)) {
- strerr_dief1x(100, "could not parse payload fd");
- }
-
- if(!parse_size(argv[2], &payload_size)) {
- strerr_dief1x(100, "could not parse payload length");
- }
-
- char payload_data[payload_size];
- bytebuffer payload = {payload_data, payload_size};
- read_payload(payload_fd, payload);
- fd_close(payload_fd);
-
- dbg_print_bb1("Got payload", payload);
- process_payload(payload);
- strerr_dief1x(110, "Internal logic error, should not get here");
- return 110;
-}
-/*
-capability ```
-container/bzr.ccx/123456
-login/tty1/7890
-```
-- secret
-- execline command
-- env allowlist (re?)
-- max execution count/id (uuidv7?)
-
-```
-caphdr = [capv0;name;invoke-once]
-c1 = [caphdr;;h1=hmac(secret, caphdr)]
-c2 = [caphdr;[att1];h2=hmac(h1, att1)]
-c3 = [caphdr;[att1;att2];h3=hmac(h2, att2)]
-```
-*/
-
-/* vim: sts=2 sw=2 et
-*/