miniroon

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

commit 1b85ee6d654a539fd065968aebe65f555aac3c95
parent 841211df9d93da06981c0c7f26b8d83cffaeb227
Author: Jan Pobrislo <ccx@te2000.cz>
Date:   Fri, 14 Feb 2025 01:05:59 +0000

Add error returncodes to caveat handling

Diffstat:
Msrc/caveat_env_absent.c | 14++++++++------
Msrc/caveat_env_fnmatch.c | 31+++++++++++++++----------------
Msrc/caveat_env_is.c | 22++++++++++------------
Msrc/caveats.c | 36+++++++++++++-----------------------
Msrc/caveats.h | 5+++--
Msrc/caveats_impl.h | 25+++++++++++++++----------
Msrc/cmd_verify.c | 4++--
Msrc/errors.h | 5+++++
8 files changed, 71 insertions(+), 71 deletions(-)

diff --git a/src/caveat_env_absent.c b/src/caveat_env_absent.c @@ -6,16 +6,16 @@ #include "caveats_impl.h" -void miniroon_caveat_prepare_env_absent(netstring_chunk *c, miniroon_caveats_state *state) { +miniroon_error miniroon_caveat_prepare_env_absent(netstring_chunk *c, miniroon_caveats_state *state) { bytebuffer name; if(!netstring_chunk_next(c)) { - caveat_die1("missing variable name"); + return caveat_inv1("missing variable name"); } name = c->inner; if(netstring_chunk_next(c)) { - caveat_die1("unexpected argument"); + return caveat_inv1("unexpected argument"); } char name_0[name.len + 1]; @@ -24,7 +24,7 @@ void miniroon_caveat_prepare_env_absent(netstring_chunk *c, miniroon_caveats_sta miniroon_env_entry *entry = miniroon_env_map_find(&state->emap, name); if(entry == NULL) { - caveat_die3("variable '", name_0, "' not in allowlist"); + return caveat_fail3("variable '", name_0, "' not in allowlist"); } switch(entry->state) { case ENV_NO_CHANGE: @@ -33,12 +33,14 @@ void miniroon_caveat_prepare_env_absent(netstring_chunk *c, miniroon_caveats_sta case ENV_REMOVE: break; default: - caveat_die2("conflicting state for variable: ", name_0); + return caveat_fail2("conflicting state for variable: ", name_0); break; } + return MINIROON_OK; } -void miniroon_caveat_validate_env_absent(netstring_chunk *c, miniroon_caveats_state *state) { +miniroon_error miniroon_caveat_validate_env_absent(netstring_chunk *c, miniroon_caveats_state *state) { + return MINIROON_OK; } /* vim: sts=2 sw=2 et diff --git a/src/caveat_env_fnmatch.c b/src/caveat_env_fnmatch.c @@ -7,21 +7,21 @@ #include "caveats_impl.h" -void miniroon_caveat_prepare_env_fnmatch(netstring_chunk *c, miniroon_caveats_state *state) { +miniroon_error miniroon_caveat_prepare_env_fnmatch(netstring_chunk *c, miniroon_caveats_state *state) { bytebuffer name, pattern; if(!netstring_chunk_next(c)) { - caveat_die1("missing variable name"); + return caveat_inv1("missing variable name"); } name = c->inner; if(!netstring_chunk_next(c)) { - caveat_die1("missing variable pattern"); + return caveat_inv1("missing variable pattern"); } pattern = c->inner; if(netstring_chunk_next(c)) { - caveat_die1("unexpected argument"); + return caveat_inv1("unexpected argument"); } char name_0[name.len + 1]; @@ -30,25 +30,26 @@ void miniroon_caveat_prepare_env_fnmatch(netstring_chunk *c, miniroon_caveats_st miniroon_env_entry *entry = miniroon_env_map_find(&state->emap, name); if(entry == NULL) { - caveat_die3("variable '", name_0, "' not in allowlist"); + return caveat_fail3("variable '", name_0, "' not in allowlist"); } + return MINIROON_OK; } -void miniroon_caveat_validate_env_fnmatch(netstring_chunk *c, miniroon_caveats_state *state) { +miniroon_error miniroon_caveat_validate_env_fnmatch(netstring_chunk *c, miniroon_caveats_state *state) { bytebuffer name, pattern; if(!netstring_chunk_next(c)) { - caveat_die1("missing variable name"); + return caveat_inv1("missing variable name"); } name = c->inner; if(!netstring_chunk_next(c)) { - caveat_die1("missing variable pattern"); + return caveat_inv1("missing variable pattern"); } pattern = c->inner; if(netstring_chunk_next(c)) { - caveat_die1("unexpected argument"); + return caveat_inv1("unexpected argument"); } char name_0[name.len + 1]; @@ -57,11 +58,11 @@ void miniroon_caveat_validate_env_fnmatch(netstring_chunk *c, miniroon_caveats_s miniroon_env_entry *entry = miniroon_env_map_find(&state->emap, name); if(entry == NULL) { - caveat_die3("variable '", name_0, "' not in allowlist"); + return caveat_fail3("variable '", name_0, "' not in allowlist"); } if(entry->state != ENV_SET) { - caveat_die3("required variable '", name_0, "' not provided: "); + return caveat_fail3("required variable '", name_0, "' not provided: "); } assert(entry->value.len); assert(entry->value.data); @@ -72,13 +73,11 @@ void miniroon_caveat_validate_env_fnmatch(netstring_chunk *c, miniroon_caveats_s switch(fnmatch(pattern_0, entry->value.data, 0)) { case 0: - return; /* OK */ + return MINIROON_OK; case FNM_NOMATCH: - caveat_die3("variable '", name_0, "' does not match required pattern"); - break; + return caveat_fail3("variable '", name_0, "' does not match required pattern"); default: - caveat_die2("failure matching required pattern: ", name_0); - break; + return caveat_fail2("failure matching required pattern: ", name_0); } } diff --git a/src/caveat_env_is.c b/src/caveat_env_is.c @@ -5,21 +5,21 @@ #define caveat_name "env-is" #include "caveats_impl.h" -void miniroon_caveat_prepare_env_is(netstring_chunk *c, miniroon_caveats_state *state){ +miniroon_error miniroon_caveat_prepare_env_is(netstring_chunk *c, miniroon_caveats_state *state){ bytebuffer name, value; if(!netstring_chunk_next(c)) { - caveat_die1("missing variable name"); + return caveat_inv1("missing variable name"); } name = c->inner; if(!netstring_chunk_next(c)) { - caveat_die1("missing variable value"); + return caveat_inv1("missing variable value"); } value = c->inner; if(netstring_chunk_next(c)) { - caveat_die1("unexpected argument"); + return caveat_inv1("unexpected argument"); } char name_0[name.len + 1]; @@ -28,30 +28,28 @@ void miniroon_caveat_prepare_env_is(netstring_chunk *c, miniroon_caveats_state * miniroon_env_entry *entry = miniroon_env_map_find(&state->emap, name); if(entry == NULL) { - caveat_die3("variable '", name_0, "'not in allowlist"); + return caveat_fail3("variable '", name_0, "'not in allowlist"); } switch(entry->state) { case ENV_NO_CHANGE: for(size_t i=0; i<value.len; i++) { if(value.data[i] == '\0') { - caveat_die2("invalid value - null bytes not allowed in environment variable: ", name_0); + return caveat_inv2("invalid value - null bytes not allowed in environment variable: ", name_0); } } entry->state = ENV_SET; entry->value = value; - break; + return MINIROON_OK; case ENV_SET: if(bbcmp(entry->value, value) != 0) { - caveat_die2("conflicting values for variable", name_0); + return caveat_fail2("conflicting values for variable", name_0); } - break; default: - caveat_die2("conflicting state for variable: ", name_0); - break; + return caveat_fail2("conflicting state for variable: ", name_0); } } -void miniroon_caveat_validate_env_is(netstring_chunk *c, miniroon_caveats_state *state) { +miniroon_error miniroon_caveat_validate_env_is(netstring_chunk *c, miniroon_caveats_state *state) { } /* vim: sts=2 sw=2 et diff --git a/src/caveats.c b/src/caveats.c @@ -20,51 +20,41 @@ void miniroon_caveats_state_exec(miniroon_caveats_state *state, char const *cons miniroon_caveat_type caveat_get_type(netstring_chunk *c, const bytebuffer caveat) { netstring_chunk_init(c, caveat); if(!netstring_chunk_next(c)) { - strerr_dief1x(111, "Mising caveat name"); + return miniroon_err1(MINIROON_ECAVEAT_MALFORMED, "Mising caveat name"); } dbg_print_bb1("Caveat ID", c->inner); return miniroon_caveat_name_perfhash_hash(c->inner.data, c->inner.len); } -void miniroon_caveat_prepare(const bytebuffer caveat, miniroon_caveats_state *state) { +miniroon_error miniroon_caveat_prepare(const bytebuffer caveat, miniroon_caveats_state *state) { netstring_chunk c; switch(caveat_get_type(&c, caveat)) { case MINIROON_CAVEAT_UNDEFINED: - strerr_dief1x(111, "Unrecognized caveat type"); - break; + return miniroon_err1(MINIROON_ECAVEAT_NOT_RECOGNIZED, "Unrecognized caveat type"); case MINIROON_CAVEAT_ENV_IS: - miniroon_caveat_prepare_env_is(&c, state); - break; + return miniroon_caveat_prepare_env_is(&c, state); case MINIROON_CAVEAT_ENV_ABSENT: - miniroon_caveat_prepare_env_absent(&c, state); - break; + return miniroon_caveat_prepare_env_absent(&c, state); case MINIROON_CAVEAT_ENV_FNMATCH: - miniroon_caveat_prepare_env_fnmatch(&c, state); - break; + return miniroon_caveat_prepare_env_fnmatch(&c, state); default: - strerr_dief1x(111, "Unimplemented caveat type"); - break; + return miniroon_err1(MINIROON_ECAVEAT_NOT_RECOGNIZED, "Unimplemented caveat type"); } } -void miniroon_caveat_validate(const bytebuffer caveat, miniroon_caveats_state *state) { +miniroon_error miniroon_caveat_validate(const bytebuffer caveat, miniroon_caveats_state *state) { netstring_chunk c; switch(caveat_get_type(&c, caveat)) { case MINIROON_CAVEAT_UNDEFINED: - strerr_dief1x(111, "Unrecognized caveat type"); - break; + return miniroon_err1(MINIROON_ECAVEAT_NOT_RECOGNIZED, "Unrecognized caveat type"); case MINIROON_CAVEAT_ENV_IS: - miniroon_caveat_validate_env_is(&c, state); - break; + return miniroon_caveat_validate_env_is(&c, state); case MINIROON_CAVEAT_ENV_ABSENT: - miniroon_caveat_validate_env_absent(&c, state); - break; + return miniroon_caveat_validate_env_absent(&c, state); case MINIROON_CAVEAT_ENV_FNMATCH: - miniroon_caveat_validate_env_fnmatch(&c, state); - break; + return miniroon_caveat_validate_env_fnmatch(&c, state); default: - strerr_dief1x(111, "Unimplemented caveat type"); - break; + return miniroon_err1(MINIROON_ECAVEAT_NOT_RECOGNIZED, "Unimplemented caveat type"); } } diff --git a/src/caveats.h b/src/caveats.h @@ -5,6 +5,7 @@ // {IMP} caveats.c #include "envmap.h" +#include "errors.h" typedef struct miniroon_caveats_state_s { miniroon_env_map emap; @@ -12,7 +13,7 @@ typedef struct miniroon_caveats_state_s { void miniroon_caveats_state_init(miniroon_caveats_state *state); void miniroon_caveats_state_exec(miniroon_caveats_state *state, char const *const *argv); -void miniroon_caveat_prepare(const bytebuffer caveat, miniroon_caveats_state *state); -void miniroon_caveat_validate(const bytebuffer caveat, miniroon_caveats_state *state); +miniroon_error miniroon_caveat_prepare(const bytebuffer caveat, miniroon_caveats_state *state); +miniroon_error miniroon_caveat_validate(const bytebuffer caveat, miniroon_caveats_state *state); #endif diff --git a/src/caveats_impl.h b/src/caveats_impl.h @@ -5,24 +5,29 @@ #include "netstring.h" // {IMP} caveat_env_is.c -void miniroon_caveat_prepare_env_is(netstring_chunk *c, miniroon_caveats_state *state); -void miniroon_caveat_validate_env_is(netstring_chunk *c, miniroon_caveats_state *state); +miniroon_error miniroon_caveat_prepare_env_is(netstring_chunk *c, miniroon_caveats_state *state); +miniroon_error miniroon_caveat_validate_env_is(netstring_chunk *c, miniroon_caveats_state *state); // {IMP} caveat_env_absent.c -void miniroon_caveat_prepare_env_absent(netstring_chunk *c, miniroon_caveats_state *state); -void miniroon_caveat_validate_env_absent(netstring_chunk *c, miniroon_caveats_state *state); +miniroon_error miniroon_caveat_prepare_env_absent(netstring_chunk *c, miniroon_caveats_state *state); +miniroon_error miniroon_caveat_validate_env_absent(netstring_chunk *c, miniroon_caveats_state *state); // {IMP} caveat_env_fnmatch.c -void miniroon_caveat_prepare_env_fnmatch(netstring_chunk *c, miniroon_caveats_state *state); -void miniroon_caveat_validate_env_fnmatch(netstring_chunk *c, miniroon_caveats_state *state); +miniroon_error miniroon_caveat_prepare_env_fnmatch(netstring_chunk *c, miniroon_caveats_state *state); +miniroon_error miniroon_caveat_validate_env_fnmatch(netstring_chunk *c, miniroon_caveats_state *state); #ifndef caveat_name #define caveat_name "(undefined)" #endif -#define caveat_die1(a) strerr_dief4x(111, "caveat `", caveat_name, "`: ", a); -#define caveat_die2(a,b) strerr_dief5x(111, "caveat `", caveat_name, "`: ", a, b); -#define caveat_die3(a,b,c) strerr_dief6x(111, "caveat `", caveat_name, "`: ", a, b, c); -#define caveat_die4(a,b,c,d) strerr_dief7x(111, "caveat `", caveat_name, "`: ", a, b, c, d); +#define caveat_fail1(a) miniroon_err4(MINIROON_ECAVEAT_FAILED, "caveat `", caveat_name, "`: ", a); +#define caveat_fail2(a,b) miniroon_err5(MINIROON_ECAVEAT_FAILED, "caveat `", caveat_name, "`: ", a, b); +#define caveat_fail3(a,b,c) miniroon_err6(MINIROON_ECAVEAT_FAILED, "caveat `", caveat_name, "`: ", a, b, c); +#define caveat_fail4(a,b,c,d) miniroon_err7(MINIROON_ECAVEAT_FAILED, "caveat `", caveat_name, "`: ", a, b, c, d); + +#define caveat_inv1(a) miniroon_err4(MINIROON_ECAVEAT_MALFORMED, "caveat `", caveat_name, "`: ", a); +#define caveat_inv2(a,b) miniroon_err5(MINIROON_ECAVEAT_MALFORMED, "caveat `", caveat_name, "`: ", a, b); +#define caveat_inv3(a,b,c) miniroon_err6(MINIROON_ECAVEAT_MALFORMED, "caveat `", caveat_name, "`: ", a, b, c); +#define caveat_inv4(a,b,c,d) miniroon_err7(MINIROON_ECAVEAT_MALFORMED, "caveat `", caveat_name, "`: ", a, b, c, d); #endif diff --git a/src/cmd_verify.c b/src/cmd_verify.c @@ -41,11 +41,11 @@ void validate_and_exec(miniroon_data *md) { for(size_t i=0; i < md->caveat_count; i++) { dbg_print_bb1("Validate[1] caveat", md->caveats[i]); - miniroon_caveat_prepare(md->caveats[i], &state); + die_on_error(miniroon_caveat_prepare(md->caveats[i], &state)); } for(size_t i=0; i < md->caveat_count; i++) { dbg_print_bb1("Validate[2] caveat", md->caveats[i]); - miniroon_caveat_validate(md->caveats[i], &state); + die_on_error(miniroon_caveat_validate(md->caveats[i], &state)); } /* iff everything validated correctly */ diff --git a/src/errors.h b/src/errors.h @@ -30,6 +30,11 @@ typedef enum miniroon_error_e { MINIROON_EDEC_EXTRA, MINIROON_EDEC_BAD_SIGNATURE, + MINIROON_ECAVEAT_NOT_RECOGNIZED, + MINIROON_ECAVEAT_MALFORMED, + MINIROON_ECAVEAT_FAILED, + + // end MINIROON_EMAX } miniroon_error;