diff --git a/lib/cookies/alg_containers.c b/lib/cookies/alg_containers.c index 1a5767b7a15f84dea5c2a8f0da0a55fd247f5fca..417959ed1a988c1826d37180d0b52ffa4016e803 100644 --- a/lib/cookies/alg_containers.c +++ b/lib/cookies/alg_containers.c @@ -23,52 +23,24 @@ #include "lib/cookies/alg_containers.h" #include "lib/cookies/alg_sha.h" -const struct kr_cc_alg_descr kr_cc_algs[] = { - { "FNV-64", &knot_cc_alg_fnv64 }, - { "HMAC-SHA256-64", &knot_cc_alg_hmac_sha256_64 }, - { NULL, NULL } +const struct knot_cc_alg *const kr_cc_algs[] = { + /* 0 */ &knot_cc_alg_fnv64, + /* 1 */ &knot_cc_alg_hmac_sha256_64 }; -const struct kr_cc_alg_descr *kr_cc_alg(const struct kr_cc_alg_descr cc_algs[], - const char *name) -{ - if (!cc_algs || !name) { - return NULL; - } - - const struct kr_cc_alg_descr *aux_ptr = cc_algs; - while (aux_ptr && aux_ptr->alg && aux_ptr->alg->gen_func) { - assert(aux_ptr->name); - if (strcmp(aux_ptr->name, name) == 0) { - return aux_ptr; - } - ++aux_ptr; - } - - return NULL; -} - -const struct kr_sc_alg_descr kr_sc_algs[] = { - { "FNV-64", &knot_sc_alg_fnv64 }, - { "HMAC-SHA256-64", &knot_sc_alg_hmac_sha256_64 }, - { NULL, NULL } +const knot_lookup_t kr_cc_alg_names[] = { + { 0, "FNV-64" }, + { 1, "HMAC-SHA256-64" }, + { -1, NULL } }; -const struct kr_sc_alg_descr *kr_sc_alg(const struct kr_sc_alg_descr sc_algs[], - const char *name) -{ - if (!sc_algs || !name) { - return NULL; - } - - const struct kr_sc_alg_descr *aux_ptr = sc_algs; - while (aux_ptr && aux_ptr->alg && aux_ptr->alg->hash_func) { - assert(aux_ptr->name); - if (strcmp(aux_ptr->name, name) == 0) { - return aux_ptr; - } - ++aux_ptr; - } +const struct knot_sc_alg *const kr_sc_algs[] = { + /* 0 */ &knot_sc_alg_fnv64, + /* 1 */ &knot_sc_alg_hmac_sha256_64 +}; - return NULL; -} +const knot_lookup_t kr_sc_alg_names[] = { + { 0, "FNV-64" }, + { 1, "HMAC-SHA256-64" }, + { -1, NULL } +}; diff --git a/lib/cookies/alg_containers.h b/lib/cookies/alg_containers.h index 1a5aa003859d7790a193900495f5fe6839a94f05..68a50cb52e212d7ea6bbe6126f5a657db79cc7d6 100644 --- a/lib/cookies/alg_containers.h +++ b/lib/cookies/alg_containers.h @@ -18,56 +18,25 @@ #include <libknot/cookies/client.h> #include <libknot/cookies/server.h> +#include <libknot/lookup.h> #include "lib/defines.h" -/** Maximal size of a cookie option. */ -#define KR_COOKIE_OPT_MAX_LEN (KNOT_EDNS_OPTION_HDRLEN + KNOT_OPT_COOKIE_CLNT + KNOT_OPT_COOKIE_SRVR_MAX) - -/** Holds description of client cookie hashing algorithms. */ -struct kr_cc_alg_descr { - const char *name; /**< Algorithgm name. */ - const struct knot_cc_alg *alg; /**< Algorithm. */ -}; - -/** - * List of available client cookie algorithms. - * - * Last element contains all null entries. - */ +/** Client algorithm identifiers are used as index into this array of pointers. */ KR_EXPORT -extern const struct kr_cc_alg_descr kr_cc_algs[]; +extern const struct knot_cc_alg *const kr_cc_algs[]; -/** - * @brief Return pointer to client cookie algorithm with given name. - * @param cc_algs List of available algorithms. - * @param name Algorithm name. - * @return pointer to algorithm or NULL if not found. - */ +/** Binds client algorithm identifiers onto names. */ KR_EXPORT -const struct kr_cc_alg_descr *kr_cc_alg(const struct kr_cc_alg_descr cc_algs[], - const char *name); +extern const knot_lookup_t kr_cc_alg_names[]; -/** Holds description of server cookie hashing algorithms. */ -struct kr_sc_alg_descr { - const char *name; /**< Algorithm name. */ - const struct knot_sc_alg *alg; /**< Algorithm. */ -}; - -/** - * List of available server cookie algorithms. - * - * Last element contains all null entries. - */ +/** Server algorithm identifiers are used as index into this array of pointers. */ KR_EXPORT -extern const struct kr_sc_alg_descr kr_sc_algs[]; +extern const struct knot_sc_alg *const kr_sc_algs[]; -/** - * @brief Return pointer to server cookie algorithm with given name. - * @param sc_algs List of available algorithms. - * @param name Algorithm name. - * @return pointer to algorithm or NULL if not found. - */ +/** Binds server algorithm identifiers onto names. */ KR_EXPORT -const struct kr_sc_alg_descr *kr_sc_alg(const struct kr_sc_alg_descr sc_algs[], - const char *name); +extern const knot_lookup_t kr_sc_alg_names[]; + +/** Maximal size of a cookie option. */ +#define KR_COOKIE_OPT_MAX_LEN (KNOT_EDNS_OPTION_HDRLEN + KNOT_OPT_COOKIE_CLNT + KNOT_OPT_COOKIE_SRVR_MAX) diff --git a/lib/cookies/control.c b/lib/cookies/control.c index f2ae2fca189580d653f2eb151fff0b5d292edf71..96f0b0cfab7b95a23fb9735624c5c692c7fbcdc4 100644 --- a/lib/cookies/control.c +++ b/lib/cookies/control.c @@ -17,6 +17,6 @@ #include "lib/cookies/control.h" struct kr_cookie_ctx kr_glob_cookie_ctx = { - .clnt = { false, { NULL, NULL }, { NULL, NULL}, DFLT_COOKIE_TTL }, - .srvr = { false, { NULL, NULL }, { NULL, NULL} } + .clnt = { false, { NULL, -1 }, { NULL, -1}, DFLT_COOKIE_TTL }, + .srvr = { false, { NULL, -1 }, { NULL, -1} } }; diff --git a/lib/cookies/control.h b/lib/cookies/control.h index c2842d81c9dbb739aba41eccf4b100674cbd253f..ca546a078575deca495262d88104023495702121 100644 --- a/lib/cookies/control.h +++ b/lib/cookies/control.h @@ -37,7 +37,7 @@ struct kr_cookie_secret { /** Holds settings that have direct influence on client cookie values. */ struct kr_clnt_cookie_settings { struct kr_cookie_secret *csec; /*!< Client secret data. */ - const struct kr_cc_alg_descr *calg; /**< Client cookie algorithm. */ + int calg_id; /*!< Client cookie algorithm identifier. */ }; /** Holds settings that control client behaviour. */ @@ -53,7 +53,7 @@ struct kr_clnt_cookie_ctx { /** Holds settings that have direct influence on server cookie values. */ struct kr_srvr_cookie_settings { struct kr_cookie_secret *ssec; /*!< Server secret data. */ - const struct kr_sc_alg_descr *salg; /**< Server cookie algorithm. */ + int salg_id; /**< Server cookie algorithm identifier. */ }; /** Holds settings that control server behaviour. */ diff --git a/lib/cookies/helper.c b/lib/cookies/helper.c index 5d4c3b869998b7d9e969617b178fe37ebd44b663..e9a3a5ee9a103b9872b18dcca3658aae3b94d819 100644 --- a/lib/cookies/helper.c +++ b/lib/cookies/helper.c @@ -125,8 +125,7 @@ int kr_request_put_cookie(const struct kr_clnt_cookie_settings *clnt_cntrl, return kr_ok(); } - if (!clnt_cntrl->csec || !clnt_cntrl->calg || - !cookie_cache) { + if (!clnt_cntrl->csec || (clnt_cntrl->calg_id < 0) || !cookie_cache) { return kr_error(EINVAL); } @@ -141,9 +140,9 @@ int kr_request_put_cookie(const struct kr_clnt_cookie_settings *clnt_cntrl, }; uint8_t cc[KNOT_OPT_COOKIE_CLNT]; uint16_t cc_len = KNOT_OPT_COOKIE_CLNT; - assert(clnt_cntrl->calg && clnt_cntrl->calg->alg && - clnt_cntrl->calg->alg->gen_func); - int ret = clnt_cntrl->calg->alg->gen_func(&input, cc, &cc_len); + assert((clnt_cntrl->calg_id >= 0) && kr_cc_algs[clnt_cntrl->calg_id] && + kr_cc_algs[clnt_cntrl->calg_id]->gen_func); + int ret = kr_cc_algs[clnt_cntrl->calg_id]->gen_func(&input, cc, &cc_len); if (ret != kr_ok()) { return ret; } diff --git a/lib/layer/cookiemonster.c b/lib/layer/cookiemonster.c index 5f1b98fb9fc085a9dacc172a0a164f68d331dd09..5b408ceb4311894b0442a00fe71b64d707f452e1 100644 --- a/lib/layer/cookiemonster.c +++ b/lib/layer/cookiemonster.c @@ -68,7 +68,7 @@ static const struct sockaddr *passed_server_sockaddr(const struct kr_query *qry) static const struct sockaddr *guess_server_addr(const struct kr_nsrep *nsrep, const uint8_t *cc, uint16_t cc_len, const struct kr_cookie_secret *csecr, - const struct kr_cc_alg_descr *cc_alg) + const struct knot_cc_alg *cc_alg) { assert(nsrep && cc && cc_len && csecr && cc_alg); @@ -88,7 +88,7 @@ static const struct sockaddr *guess_server_addr(const struct kr_nsrep *nsrep, } input.srvr_sockaddr = (struct sockaddr *)&nsrep->addr[i]; - int ret = knot_cc_check(cc, cc_len, &input, cc_alg->alg); + int ret = knot_cc_check(cc, cc_len, &input, cc_alg); if (ret == KNOT_EOK) { sockaddr = (struct sockaddr *)&nsrep->addr[i]; break; @@ -127,14 +127,14 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr, .secret_len = clnt_cntrl->current.csec->size }; int ret = knot_cc_check(cc, cc_len, &input, - clnt_cntrl->current.calg->alg); + kr_cc_algs[clnt_cntrl->current.calg_id]); bool have_current = (ret == KNOT_EOK); if ((ret != KNOT_EOK) && - clnt_cntrl->recent.csec && clnt_cntrl->recent.calg) { + clnt_cntrl->recent.csec && (clnt_cntrl->recent.calg_id >= 0)) { input.secret_data = clnt_cntrl->recent.csec->data; input.secret_len = clnt_cntrl->recent.csec->size; ret = knot_cc_check(cc, cc_len, &input, - clnt_cntrl->recent.calg->alg); + kr_cc_algs[clnt_cntrl->recent.calg_id]); } if (ret == KNOT_EOK) { *sockaddr = tmp_sockaddr; @@ -143,10 +143,6 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr, return (ret == KNOT_EOK) ? kr_ok() : kr_error(EINVAL); } -// if (!cc || !clnt_cntrl) { -// return kr_error(EINVAL); -// } - DEBUG_MSG(NULL, "%s\n", "guessing response address from ns reputation"); @@ -154,14 +150,14 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr, const struct kr_nsrep *ns = &qry->ns; tmp_sockaddr = guess_server_addr(ns, cc, cc_len, clnt_cntrl->current.csec, - clnt_cntrl->current.calg); + kr_cc_algs[clnt_cntrl->current.calg_id]); bool have_current = (tmp_sockaddr != NULL); if (!tmp_sockaddr && - clnt_cntrl->recent.csec && clnt_cntrl->recent.calg) { + clnt_cntrl->recent.csec && (clnt_cntrl->recent.calg_id >= 0)) { /* Try recent client secret to check obtained cookie. */ tmp_sockaddr = guess_server_addr(ns, cc, cc_len, clnt_cntrl->recent.csec, - clnt_cntrl->recent.calg); + kr_cc_algs[clnt_cntrl->recent.calg_id]); } if (tmp_sockaddr) { *sockaddr = tmp_sockaddr; @@ -410,7 +406,7 @@ static int check_request(knot_layer_t *ctx, void *module_param) struct kr_srvr_cookie_ctx *srvr_cntrl = &kr_glob_cookie_ctx.srvr; if (!req->qsource.addr || - !srvr_cntrl->current.ssec || !srvr_cntrl->current.salg) { + !srvr_cntrl->current.ssec || (srvr_cntrl->current.salg_id < 0)) { DEBUG_MSG(NULL, "%s\n", "missing server cookie context"); return KNOT_STATE_FAIL; } @@ -449,9 +445,9 @@ static int check_request(knot_layer_t *ctx, void *module_param) /* Check server cookie obtained in request. */ ret = knot_sc_check(NONCE_LEN, &cookies, &srvr_data, - srvr_cntrl->current.salg->alg); + kr_sc_algs[srvr_cntrl->current.salg_id]); if (ret == KNOT_EINVAL && - srvr_cntrl->recent.ssec && srvr_cntrl->recent.salg->alg) { + srvr_cntrl->recent.ssec && (srvr_cntrl->recent.salg_id >= 0)) { /* Try recent algorithm. */ struct knot_sc_private recent_srvr_data = { .clnt_sockaddr = req->qsource.addr, @@ -459,7 +455,7 @@ static int check_request(knot_layer_t *ctx, void *module_param) .secret_len = srvr_cntrl->recent.ssec->size }; ret = knot_sc_check(NONCE_LEN, &cookies, &recent_srvr_data, - srvr_cntrl->recent.salg->alg); + kr_sc_algs[srvr_cntrl->recent.salg_id]); } if (ret != KNOT_EOK) { /* TODO -- Silently discard? */ @@ -484,7 +480,8 @@ static int check_request(knot_layer_t *ctx, void *module_param) answer_add_cookies: /* Add server cookie into response. */ ret = kr_answer_write_cookie(&srvr_data, cookies.cc, cookies.cc_len, - &nonce, srvr_cntrl->current.salg->alg, + &nonce, + kr_sc_algs[srvr_cntrl->current.salg_id], req->answer); if (ret != kr_ok()) { return_state = KNOT_STATE_FAIL; diff --git a/lib/resolve.c b/lib/resolve.c index cc93f2b2a2e41b5ef8f02d66178f3a208c8dbe62..12eefdd4b145fd29c50a9f01f285a57140190367 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -429,14 +429,14 @@ static int cookie_answer(const void *clnt_sockaddr, /* Add fres cookie into the answer. */ int ret = kr_answer_write_cookie(&srvr_data, cookies->cc, cookies->cc_len, &nonce, - srvr_cntrl->current.salg->alg, answer); + kr_sc_algs[srvr_cntrl->current.salg_id], answer); if (ret != kr_ok()) { return KNOT_STATE_FAIL; } /* Check server cookie only with current settings. */ ret = knot_sc_check(NONCE_LEN, cookies, &srvr_data, - srvr_cntrl->current.salg->alg); + kr_sc_algs[srvr_cntrl->current.salg_id]); if (ret != KNOT_EOK) { kr_pkt_set_ext_rcode(answer, KNOT_RCODE_BADCOOKIE); return KNOT_STATE_FAIL | KNOT_STATE_DONE; diff --git a/modules/cookiectl/cookiectl.c b/modules/cookiectl/cookiectl.c index 55e7cba9212fd806623a1f6a05e76125c05bd527..498ab07b7485fae5340a9efd2701eb215efec0f4 100644 --- a/modules/cookiectl/cookiectl.c +++ b/modules/cookiectl/cookiectl.c @@ -145,12 +145,12 @@ static bool apply_client_hash_func(struct kr_cookie_ctx *cntrl, const JsonNode *node) { if (node->tag == JSON_STRING) { - const struct kr_cc_alg_descr *cc_alg = kr_cc_alg(kr_cc_algs, - node->string_); - if (!cc_alg) { + const knot_lookup_t *lookup = knot_lookup_by_name(kr_cc_alg_names, + node->string_); + if (!lookup) { return false; } - cntrl->clnt.current.calg = cc_alg; + cntrl->clnt.current.calg_id = lookup->id; return true; } @@ -161,12 +161,12 @@ static bool apply_server_hash_func(struct kr_cookie_ctx *cntrl, const JsonNode *node) { if (node->tag == JSON_STRING) { - const struct kr_sc_alg_descr *sc_alg = kr_sc_alg(kr_sc_algs, - node->string_); - if (!sc_alg) { + const knot_lookup_t *lookup = knot_lookup_by_name(kr_sc_alg_names, + node->string_); + if (!lookup) { return false; } - cntrl->srvr.current.salg = sc_alg; + cntrl->srvr.current.salg_id = lookup->id; return true; } @@ -249,9 +249,8 @@ static bool read_available_cc_hashes(JsonNode *root) return false; } - const struct kr_cc_alg_descr *aux_ptr = kr_cc_algs; - while (aux_ptr && aux_ptr->alg && aux_ptr->alg->gen_func) { - assert(aux_ptr->name); + const knot_lookup_t *aux_ptr = kr_cc_alg_names; + while (aux_ptr && (aux_ptr->id >= 0) && aux_ptr->name) { JsonNode *element = json_mkstring(aux_ptr->name); if (!element) { goto fail; @@ -280,9 +279,8 @@ static bool read_available_sc_hashes(JsonNode *root) return false; } - const struct kr_sc_alg_descr *aux_ptr = kr_sc_algs; - while (aux_ptr && aux_ptr->alg && aux_ptr->alg->hash_func) { - assert(aux_ptr->name); + const knot_lookup_t *aux_ptr = kr_sc_alg_names; + while (aux_ptr && (aux_ptr->id >= 0) && aux_ptr->name) { JsonNode *element = json_mkstring(aux_ptr->name); if (!element) { goto fail; @@ -307,7 +305,7 @@ static bool clnt_settings_equal(const struct kr_clnt_cookie_settings *s1, { assert(s1 && s2 && s1->csec && s2->csec); - if (s1->calg != s2->calg || s1->csec->size != s2->csec->size) { + if (s1->calg_id != s2->calg_id || s1->csec->size != s2->csec->size) { return false; } @@ -319,7 +317,7 @@ static bool srvr_settings_equal(const struct kr_srvr_cookie_settings *s1, { assert(s1 && s2 && s1->ssec && s2->ssec); - if (s1->salg != s2->salg || s1->ssec->size != s2->ssec->size) { + if (s1->salg_id != s2->salg_id || s1->ssec->size != s2->ssec->size) { return false; } @@ -401,7 +399,8 @@ char *read_config(struct kr_cookie_ctx *ctx) return NULL; } - char *result = NULL; + const knot_lookup_t *lookup; + char *result; JsonNode *root_node = json_mkobject(); json_append_member(root_node, NAME_CLIENT_ENABLED, @@ -409,9 +408,11 @@ char *read_config(struct kr_cookie_ctx *ctx) read_secret(root_node, NAME_CLIENT_SECRET, ctx->clnt.current.csec); - assert(ctx->clnt.current.calg->name); - json_append_member(root_node, NAME_CLIENT_COOKIE_ALG, - json_mkstring(ctx->clnt.current.calg->name)); + lookup = knot_lookup_by_id(kr_cc_alg_names, ctx->clnt.current.calg_id); + if (lookup) { + json_append_member(root_node, NAME_CLIENT_COOKIE_ALG, + json_mkstring(lookup->name)); + } read_available_cc_hashes(root_node); @@ -423,9 +424,11 @@ char *read_config(struct kr_cookie_ctx *ctx) read_secret(root_node, NAME_SERVER_SECRET, ctx->srvr.current.ssec); - assert(ctx->srvr.current.salg->name); - json_append_member(root_node, NAME_SERVER_COOKIE_ALG, - json_mkstring(ctx->srvr.current.salg->name)); + lookup = knot_lookup_by_id(kr_sc_alg_names, ctx->srvr.current.salg_id); + if (lookup) { + json_append_member(root_node, NAME_SERVER_COOKIE_ALG, + json_mkstring(lookup->name)); + } read_available_sc_hashes(root_node); @@ -470,14 +473,20 @@ int cookiectl_init(struct kr_module *module) return kr_error(ENOMEM); } + const knot_lookup_t *lookup; + kr_glob_cookie_ctx.clnt.enabled = false; kr_glob_cookie_ctx.clnt.current.csec = cs; - kr_glob_cookie_ctx.clnt.current.calg = kr_cc_alg(kr_cc_algs, "FNV-64"); + lookup = knot_lookup_by_name(kr_cc_alg_names, "FNV-64"); + assert(lookup); + kr_glob_cookie_ctx.clnt.current.calg_id = lookup->id; kr_glob_cookie_ctx.clnt.cache_ttl = DFLT_COOKIE_TTL; kr_glob_cookie_ctx.srvr.enabled = false; kr_glob_cookie_ctx.srvr.current.ssec = ss; - kr_glob_cookie_ctx.srvr.current.salg = kr_sc_alg(kr_sc_algs, "FNV-64"); + lookup = knot_lookup_by_name(kr_sc_alg_names, "FNV-64"); + assert(lookup); + kr_glob_cookie_ctx.srvr.current.salg_id = lookup->id; module->data = NULL;