commit 6a91f5a9d2af86320aef98b04ce1915c718b7da0
parent c7890bbe0a836b61dd6052cd6d468080d850d58e
Author: Jan Pobrislo <ccx@te2000.cz>
Date: Sun, 6 Oct 2024 14:19:47 +0000
miniroon can be compiled now
Diffstat:
2 files changed, 101 insertions(+), 32 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -1,5 +1,5 @@
-tools_simple:=argv0exec nosuid pidns_run safelink spawn-pty fdsend fdrecv fdrecvto socketpair ptsname mtime_to_uuidv7 ucspi-socksserver ucspi-socksserver-connected
+tools_simple:=argv0exec nosuid pidns_run safelink spawn-pty fdsend fdrecv fdrecvto socketpair ptsname mtime_to_uuidv7 ucspi-socksserver ucspi-socksserver-connected miniroon
tools_libcap:=applyuidgid-caps
diff --git a/src/miniroon.c b/src/miniroon.c
@@ -1,5 +1,7 @@
#include <errno.h>
+#include <assert.h>
#include <unistd.h>
+#include <stdbool.h>
#include <sys/select.h>
#include <skalibs/types.h>
@@ -8,6 +10,7 @@
#include <skalibs/exec.h>
#include <skalibs/netstring.h>
#include <skalibs/uint64.h>
+#include <skalibs/blake2s.h>
#define USAGE "macrun directory"
#define PROG "macrun"
@@ -20,7 +23,13 @@ typedef struct bytebuffer_s {
size_t len;
} bytebuffer;
-typedef struct miniroon_header_b {
+typedef struct netstring_chunk_b {
+ bytebuffer source;
+ bytebuffer outer;
+ bytebuffer inner;
+} netstring_chunk;
+
+typedef struct miniroon_header_s {
bytebuffer *id;
enum miniroon_version {
@@ -33,6 +42,33 @@ typedef struct miniroon_header_b {
} miniroon_header;
+
+void netstring_chunk_init (netstring_chunk *chunk, const bytebuffer source) {
+ memset(chunk, 0, sizeof(netstring_chunk));
+ chunk->source = source;
+}
+
+bool netstring_chunk_next (netstring_chunk *c) {
+ if(!c->source.len) {
+ return false;
+ }
+ c->outer.data = c->source.data;
+ c->outer.len /* size of numerical prefix */ = uint64_scan(c->source.data, &c->inner.len);
+ if (c->source.data[c->outer.len] != ':') {
+ strerr_dief1x(111, "Malformed netstring (expected ':')");
+ }
+ if (c->outer.len + c->inner.len >= c->source.len) {
+ strerr_dief1x(111, "Malformed netstring (truncated)");
+ }
+ if (c->source.data[c->outer.len + c->inner.len] != ',') {
+ strerr_dief1x(111, "Malformed netstring (expected ',')");
+ }
+ 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;
+}
+
int netstring_get_chunk (const bytebuffer *input, bytebuffer *chunk, bytebuffer *rest)
{
uint64_t nlen; /* size of payload */
@@ -40,15 +76,15 @@ int netstring_get_chunk (const bytebuffer *input, bytebuffer *chunk, bytebuffer
if (!input->len) {
return 0;
}
- pos = uint64_scan(input->start, &nlen) ;
+ pos = uint64_scan(input->data, &nlen) ;
if (pos >= input->len) {
return 0;
}
- if (input->start[pos] != ':') {
+ if (input->data[pos] != ':') {
return 0;
}
- char const *s = input->start + pos + 1; /* start of payload */
- if (len <= nlen + pos + 1) {
+ char *s = input->data + pos + 1; /* start of payload */
+ if (input->len <= nlen + pos + 1) {
return 0;
}
if (s[nlen] != ',') {
@@ -114,8 +150,8 @@ int handle_payload(size_t payload_size) {
if(!netstring_get_chunk(&input, &chunk, &next)) {
strerr_dief1x(111, "Malformed netstring");
}
- macaroon_info_t macaroon_info;
- handle_header(&macaroon_info, &chunk);
+ miniroon_header hdr;
+ parse_header(&hdr, &chunk);
while(next.len) {
input = next;
@@ -126,6 +162,35 @@ int handle_payload(size_t payload_size) {
}
}
+void hmac_b2s_256(const bytebuffer *key, const bytebuffer *msg, bytebuffer *output) {
+ static const size_t block_size = 32;
+ assert(key->len == block_size);
+ assert(output->len == block_size);
+ assert(msg);
+
+ blake2s_ctx hash_ctx;
+ uint8_t pad[block_size], ihash[block_size];
+
+ blake2s_init(&hash_ctx, block_size);
+ // i_key_pad := block_sized_key xor [0x36 blockSize] // Inner padded key
+ for(size_t i=0; i<block_size; i++) {
+ pad[i] = key->data[i] ^ 0x36;
+ }
+ // ihash = hash(i_key_pad || message)
+ blake2s_update(&hash_ctx, pad, block_size);
+ blake2s_update(&hash_ctx, msg->data, msg->len);
+ blake2s_final(&hash_ctx, ihash);
+
+ blake2s_init(&hash_ctx, block_size);
+ // o_key_pad := block_sized_key xor [0x5c blockSize] // Outer padded key
+ for(size_t i=0; i<block_size; i++) {
+ pad[i] = key->data[i] ^ 0x5c;
+ }
+ // ohash = hash(o_key_pad || ihash)
+ blake2s_update(&hash_ctx, pad, block_size);
+ blake2s_update(&hash_ctx, ihash, block_size);
+ blake2s_final(&hash_ctx, output->data);
+}
/*
capability ```
@@ -138,9 +203,10 @@ login/tty1/7890
- max execution count/id (uuidv7?)
```
-h1 = hmac(secret, [capv0;name;invoke-once])
-c1 = [capv0;name;invoke-once;h1]
-c2 = [capv0;name;invoke-once;att1;hmac(h1, [att1])]
+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)]
```
*/
@@ -161,30 +227,33 @@ int main (int argc, char const *const *argv)
while(payload_size < payload_size_max) {
switch(read(input_fd, &read_char, 1)) {
- case 0:
- strerr_dief1x(111, "EOF before netstring size was read");
- break;
- case 1:
- if(read_char == ':') {
- return handle_payload(payload_size);
- } else if(size_next >= '0' && size_next <= '9') {
- payload_size *= 10;
- payload_size += read_char - '0';
- } else {
- strerr_dief1x(111, "Malformed netstring on input");
- }
- break;
+ case 0:
+ strerr_dief1x(111, "EOF before netstring size was read");
+ break;
+ case 1:
+ if(read_char == ':') {
+ return handle_payload(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()");
+ }
+ break;
+ default:
+ strerr_dief1x(110, "Unexpected return value from read()");
+ break;
}
- case -1:
- if(errno != EINTR) {
- strerr_dief1sys(111, "read()");
- }
- break;
- default:
- strerr_dief1x(110, "Unexpected return value from read()");
- break;
}
strerr_dief1x(111, "Input netstring too big");
return 111;
}
+
+/* vim: sts=2 sw=2 et
+*/