miniroon

Simplistic macaroon-based authorization for Unix systems
git clone https://ccx.te2000.cz/git/miniroon
Log | Files | Refs

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:
Msrc/Makefile | 2+-
Msrc/miniroon.c | 131++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
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 +*/