commit eec7d2a4e3e007a7f1276a76d16bac88a2eca93b
parent abfe7b684aa2e46ca308c2ccae3a4f8ea010f64c
Author: Jan Pobrislo <ccx@te2000.cz>
Date: Wed, 9 Oct 2024 11:36:49 +0000
miniroon: refactor into reading and processing phases
Diffstat:
M | src/miniroon.c | | | 131 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
1 file changed, 74 insertions(+), 57 deletions(-)
diff --git a/src/miniroon.c b/src/miniroon.c
@@ -19,6 +19,8 @@
#define input_fd 0
#define payload_size_max 1024*1024
+#define MAX_CAVEATS 256
+#define MAX_ENV_ALLOW 256
typedef struct bytebuffer_s {
char *data;
@@ -44,12 +46,20 @@ typedef struct miniroon_header_s {
} miniroon_header;
+typedef struct miniroon_data_s {
+ miniroon_header hdr;
+ bytebuffer env_allow[MAX_ENV_ALLOW];
+ bytebuffer caveats[MAX_CAVEATS];
+ size_t env_count;
+ size_t caveat_count;
+} miniroon_data;
+
/* declarations */
void dbg_print_bb(const bytebuffer bb);
void dbg_print_bb1(const char *text, const bytebuffer bb);
-void parse_payload(const bytebuffer payload);
-void parse_header(miniroon_header *header, const bytebuffer source);
-void parse_caveat(const bytebuffer source); // TODO
+void process_payload(const bytebuffer payload);
+void process_header(miniroon_header *header, const bytebuffer source);
+void process_caveat(const bytebuffer source); // TODO
void read_secret(const bytebuffer secret); // TODO
void hmac_b2s_256(const bytebuffer key, const bytebuffer msg, const bytebuffer output);
void hmac_sha2_256(const bytebuffer key, const bytebuffer msg, const bytebuffer output);
@@ -104,6 +114,10 @@ void netstring_chunk_init (netstring_chunk *chunk, const bytebuffer source) {
}
bool netstring_chunk_next (netstring_chunk *c) {
+ // bytebuffer dbg_bb = {(void*)c, sizeof(netstring_chunk)};
+ // dbg_print_bb1("netstring chunk", dbg_bb);
+ // dbg_print_bb1("netstring source", c->source);
+
if(!c->source.len) {
return false;
}
@@ -112,18 +126,19 @@ bool netstring_chunk_next (netstring_chunk *c) {
if (c->source.data[c->outer.len] != ':') {
strerr_dief1x(111, "Malformed netstring (expected ':')");
}
- if (c->outer.len + c->inner.len >= c->source.len) {
+ if (c->outer.len + c->inner.len + 2 > c->source.len) {
strerr_dief1x(111, "Malformed netstring (truncated)");
}
if (c->source.data[c->outer.len + c->inner.len + 1] != ',') {
strerr_dief1x(111, "Malformed netstring (expected ',')");
}
+ assert(c->source.len >= c->outer.len);
c->inner.data = &c->source.data[c->outer.len + 1];
c->outer.len += c->inner.len + 2;
c->source.data += c->outer.len;
c->source.len -= c->outer.len;
- // dbg_print_bb1("Chunk > Outer", &c->outer);
- // dbg_print_bb1("Chunk > Inner", &c->inner);
+ // dbg_print_bb1("Chunk > Outer", c->outer);
+ // dbg_print_bb1("Chunk > Inner", c->inner);
return true;
}
@@ -162,7 +177,7 @@ void set_header_action(miniroon_header *header, const bytebuffer source) {
}
}
-void parse_header(miniroon_header *header, const bytebuffer source) {
+void process_header(miniroon_header *header, const bytebuffer source) {
dbg_print_bb1("Got header", source);
netstring_chunk c;
netstring_chunk_init(&c, source);
@@ -205,12 +220,11 @@ void parse_header(miniroon_header *header, const bytebuffer source) {
}
-void handle_payload(size_t payload_size) {
- char payload[payload_size+1];
- char *read_next = payload;
+void read_payload(const bytebuffer bb) {
+ char *read_next = bb.data;
ssize_t read_size;
- while(read_next - payload < payload_size + 1) {
- read_size = read(input_fd, read_next, payload_size + 1 - (read_next - payload));
+ 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");
}
@@ -222,22 +236,17 @@ void handle_payload(size_t payload_size) {
}
read_next += read_size;
}
- if(payload[payload_size] != ',') {
+ if(bb.data[bb.len - 1] != ',') {
strerr_dief1x(111, "Invalid netstring terminator");
}
-
- bytebuffer payload_bb = {payload, payload_size};
- dbg_print_bb1("Got payload", payload_bb);
- parse_payload(payload_bb);
}
-void parse_caveat(const bytebuffer source) {
+void process_caveat(const bytebuffer source) {
// TODO
}
void read_secret(const bytebuffer secret){
assert(secret.len == MINIROON_HMAC_SIZE);
- // memset(secret.data, 0, secret.len);
size_t bytes_read = 0;
int secret_fd = open("secret", O_RDONLY);
if (secret_fd < 0) {
@@ -262,15 +271,15 @@ void read_secret(const bytebuffer secret){
}
}
-void parse_payload(const bytebuffer payload) {
+void process_payload(const bytebuffer payload) {
+ miniroon_data m;
netstring_chunk c;
netstring_chunk_init(&c, payload);
if(!netstring_chunk_next(&c)) {
strerr_dief1x(111, "Mising miniroon header");
}
- miniroon_header hdr;
- parse_header(&hdr, c.inner);
+ process_header(&m.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};
@@ -287,7 +296,7 @@ void parse_payload(const bytebuffer payload) {
while(netstring_chunk_next(&body)) {
dbg_print_bb1("Got caveat", body.inner);
- parse_caveat(body.inner);
+ process_caveat(body.inner);
MINIROON_HMAC_FUNC(hmac_bb, body.inner, hmac_bb);
// dbg_print_bb1("Signature update", hmac_bb);
}
@@ -403,49 +412,20 @@ void hmac_sha2_256(const bytebuffer key, const bytebuffer msg, bytebuffer output
dbg_print_bb1("HMAC output", output);
}
-/*
-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)]
-```
-*/
-
-int main (int argc, char const *const *argv)
-{
+size_t read_payload_size(int fd) {
char read_char;
size_t payload_size = 0;
- if (argc != 2) {
- strerr_dieusage(100, USAGE);
- }
-
- if (chdir(argv[1]) != 0) {
- strerr_dief1sys(111, "chdir()");
- }
-
- fd_block(input_fd);
+ fd_block(fd);
while(payload_size < payload_size_max) {
- switch(read(input_fd, &read_char, 1)) {
+ switch(read(fd, &read_char, 1)) {
case 0:
strerr_dief1x(111, "EOF before netstring size was read");
break;
case 1:
if(read_char == ':') {
- handle_payload(payload_size);
- strerr_dief1x(110, "Internal logic error, should not get here");
- return 1;
+ return payload_size;
} else if(read_char >= '0' && read_char <= '9') {
payload_size *= 10;
payload_size += read_char - '0';
@@ -465,8 +445,45 @@ int main (int argc, char const *const *argv)
}
strerr_dief1x(111, "Input netstring too big");
- return 111;
}
+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);
+ 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
*/