Commit 29c5fa02 authored by Karel Slaný's avatar Karel Slaný Committed by Ondřej Surý

Added checks when accessing algorithm structures in array.

parent e674c06d
......@@ -23,10 +23,23 @@
#include "lib/cookies/alg_containers.h"
#include "lib/cookies/alg_sha.h"
const struct knot_cc_alg *const kr_cc_algs[] = {
/* 0 */ &knot_cc_alg_fnv64,
/* 1 */ &knot_cc_alg_hmac_sha256_64
};
const struct knot_cc_alg *kr_cc_alg_get(int id)
{
/*
* Client algorithm identifiers are used to index this array of
* pointers.
*/
static const struct knot_cc_alg *const cc_algs[] = {
/* 0 */ &knot_cc_alg_fnv64,
/* 1 */ &knot_cc_alg_hmac_sha256_64
};
if (id >= 0 && id < 2) {
return cc_algs[id];
}
return NULL;
}
const knot_lookup_t kr_cc_alg_names[] = {
{ 0, "FNV-64" },
......@@ -34,10 +47,23 @@ const knot_lookup_t kr_cc_alg_names[] = {
{ -1, NULL }
};
const struct knot_sc_alg *const kr_sc_algs[] = {
/* 0 */ &knot_sc_alg_fnv64,
/* 1 */ &knot_sc_alg_hmac_sha256_64
};
const struct knot_sc_alg *kr_sc_alg_get(int id)
{
/*
* Server algorithm identifiers are used to index this array of
* pointers.
*/
static const struct knot_sc_alg *const sc_algs[] = {
/* 0 */ &knot_sc_alg_fnv64,
/* 1 */ &knot_sc_alg_hmac_sha256_64
};
if (id >= 0 && id < 2) {
return sc_algs[id];
}
return NULL;
}
const knot_lookup_t kr_sc_alg_names[] = {
{ 0, "FNV-64" },
......
......@@ -22,17 +22,27 @@
#include "lib/defines.h"
/** Client algorithm identifiers are used to index this array of pointers. */
/**
* @brief Returns pointer to client cookie algorithm.
*
* @param id algorithm identifier as defined by lookup table
* @return pointer to algorithm structure with given id or NULL on error
*/
KR_EXPORT
extern const struct knot_cc_alg *const kr_cc_algs[];
const struct knot_cc_alg *kr_cc_alg_get(int id);
/** Binds client algorithm identifiers onto names. */
KR_EXPORT
extern const knot_lookup_t kr_cc_alg_names[];
/** Server algorithm identifiers are used to index this array of pointers. */
/**
* @brief Returns pointer to server cookie algorithm.
*
* @param id algorithm identifier as defined by lookup table
* @return pointer to algorithm structure with given id or NULL on error
*/
KR_EXPORT
extern const struct knot_sc_alg *const kr_sc_algs[];
const struct knot_sc_alg *kr_sc_alg_get(int id);
/** Binds server algorithm identifiers onto names. */
KR_EXPORT
......
......@@ -135,9 +135,12 @@ int kr_request_put_cookie(const struct kr_cookie_comp *clnt_comp,
};
uint8_t cc[KNOT_OPT_COOKIE_CLNT];
uint16_t cc_len = KNOT_OPT_COOKIE_CLNT;
assert((clnt_comp->alg_id >= 0) && kr_cc_algs[clnt_comp->alg_id] &&
kr_cc_algs[clnt_comp->alg_id]->gen_func);
cc_len = kr_cc_algs[clnt_comp->alg_id]->gen_func(&input, cc, cc_len);
const struct knot_cc_alg *cc_alg = kr_cc_alg_get(clnt_comp->alg_id);
if (!cc_alg) {
return kr_error(EINVAL);
}
assert(cc_alg->gen_func);
cc_len = cc_alg->gen_func(&input, cc, cc_len);
if (cc_len != KNOT_OPT_COOKIE_CLNT) {
return kr_error(EINVAL);
}
......
......@@ -116,6 +116,8 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr,
const struct sockaddr *tmp_sockaddr = passed_server_sockaddr(req);
const struct knot_cc_alg *cc_alg = NULL;
/* The address must correspond with the client cookie. */
if (tmp_sockaddr) {
assert(clnt_sett->current.secr);
......@@ -126,15 +128,17 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr,
.secret_data = clnt_sett->current.secr->data,
.secret_len = clnt_sett->current.secr->size
};
int ret = knot_cc_check(cc, cc_len, &input,
kr_cc_algs[clnt_sett->current.alg_id]);
cc_alg = kr_cc_alg_get(clnt_sett->current.alg_id);
if (!cc_alg) {
kr_error(EINVAL);
}
int ret = knot_cc_check(cc, cc_len, &input, cc_alg);
bool have_current = (ret == KNOT_EOK);
if ((ret != KNOT_EOK) &&
clnt_sett->recent.secr && (clnt_sett->recent.alg_id >= 0)) {
cc_alg = kr_cc_alg_get(clnt_sett->recent.alg_id);
if ((ret != KNOT_EOK) && clnt_sett->recent.secr && cc_alg) {
input.secret_data = clnt_sett->recent.secr->data;
input.secret_len = clnt_sett->recent.secr->size;
ret = knot_cc_check(cc, cc_len, &input,
kr_cc_algs[clnt_sett->recent.alg_id]);
ret = knot_cc_check(cc, cc_len, &input, cc_alg);
}
if (ret == KNOT_EOK) {
*sockaddr = tmp_sockaddr;
......@@ -147,17 +151,20 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr,
"guessing response address from ns reputation");
/* Abusing name server reputation mechanism to guess IP addresses. */
cc_alg = kr_cc_alg_get(clnt_sett->current.alg_id);
if (!cc_alg) {
kr_error(EINVAL);
}
const struct kr_nsrep *ns = &qry->ns;
tmp_sockaddr = guess_server_addr(ns, cc, cc_len,
clnt_sett->current.secr,
kr_cc_algs[clnt_sett->current.alg_id]);
clnt_sett->current.secr, cc_alg);
bool have_current = (tmp_sockaddr != NULL);
if (!tmp_sockaddr &&
clnt_sett->recent.secr && (clnt_sett->recent.alg_id >= 0)) {
cc_alg = kr_cc_alg_get(clnt_sett->recent.alg_id);
if (!tmp_sockaddr && clnt_sett->recent.secr && cc_alg) {
/* Try recent client secret to check obtained cookie. */
tmp_sockaddr = guess_server_addr(ns, cc, cc_len,
clnt_sett->recent.secr,
kr_cc_algs[clnt_sett->recent.alg_id]);
cc_alg);
}
if (tmp_sockaddr) {
*sockaddr = tmp_sockaddr;
......@@ -385,9 +392,10 @@ int check_request(knot_layer_t *ctx, void *module_param)
bool ignore_badcookie = true; /* TODO -- Occasionally ignore? */
if (!req->qsource.addr ||
!srvr_sett->current.secr || (srvr_sett->current.alg_id < 0)) {
DEBUG_MSG(NULL, "%s\n", "missing server cookie context");
const struct knot_sc_alg *current_sc_alg = kr_sc_alg_get(srvr_sett->current.alg_id);
if (!req->qsource.addr || !srvr_sett->current.secr || !current_sc_alg) {
DEBUG_MSG(NULL, "%s\n", "missing valid server cookie context");
return KNOT_STATE_FAIL;
}
......@@ -428,18 +436,19 @@ int check_request(knot_layer_t *ctx, void *module_param)
/* Check server cookie obtained in request. */
ret = knot_sc_check(KR_NONCE_LEN, &cookies, &srvr_data,
kr_sc_algs[srvr_sett->current.alg_id]);
if (ret == KNOT_EINVAL &&
srvr_sett->recent.secr && (srvr_sett->recent.alg_id >= 0)) {
/* Try recent algorithm. */
struct knot_sc_private recent_srvr_data = {
.clnt_sockaddr = req->qsource.addr,
.secret_data = srvr_sett->recent.secr->data,
.secret_len = srvr_sett->recent.secr->size
};
ret = knot_sc_check(KR_NONCE_LEN, &cookies, &recent_srvr_data,
kr_sc_algs[srvr_sett->recent.alg_id]);
ret = knot_sc_check(KR_NONCE_LEN, &cookies, &srvr_data, current_sc_alg);
if (ret == KNOT_EINVAL && srvr_sett->recent.secr) {
const struct knot_sc_alg *recent_sc_alg = kr_sc_alg_get(srvr_sett->recent.alg_id);
if (recent_sc_alg) {
/* Try recent algorithm. */
struct knot_sc_private recent_srvr_data = {
.clnt_sockaddr = req->qsource.addr,
.secret_data = srvr_sett->recent.secr->data,
.secret_len = srvr_sett->recent.secr->size
};
ret = knot_sc_check(KR_NONCE_LEN, &cookies,
&recent_srvr_data, recent_sc_alg);
}
}
if (ret != KNOT_EOK) {
/* Invalid server cookie. */
......@@ -467,9 +476,7 @@ 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,
kr_sc_algs[srvr_sett->current.alg_id],
answer);
&nonce, current_sc_alg, answer);
if (ret != kr_ok()) {
return_state = KNOT_STATE_FAIL;
}
......
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