Commit 3bd46b05 authored by Karel Slaný's avatar Karel Slaný Committed by Ondřej Surý
Browse files

Using libknot lookup table to store and access cookie algorithms.

parent c0779701
......@@ -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 }
};
......@@ -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)
......@@ -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} }
};
......@@ -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. */
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment