From: Karel Slany Date: Tue, 24 May 2016 14:41:13 +0000 (+0200) Subject: Added basic support for client secret rotation. X-Git-Tag: v1.1.0~2^2~126 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d360c2b4c3532c6ea665ec1f65ced4e846e23b5f;p=thirdparty%2Fknot-resolver.git Added basic support for client secret rotation. --- diff --git a/lib/cookies/control.c b/lib/cookies/control.c index 2c6c5e045..97e73860c 100644 --- a/lib/cookies/control.c +++ b/lib/cookies/control.c @@ -30,16 +30,15 @@ #define DEBUG_MSG(qry, fmt...) QRDEBUG(qry, "cookies_control", fmt) -static uint8_t cc[KNOT_OPT_COOKIE_CLNT] = { 1, 2, 3, 4, 5, 6, 7, 8}; - -static struct secret_quantity client_secret = { +/* Default client secret. */ +struct secret_quantity dflt_cs = { .size = KNOT_OPT_COOKIE_CLNT, - .data = cc + .data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; struct cookies_control kr_cookies_control = { - .enabled = true, - .secret = &client_secret + .enabled = false, + .current_cs = &dflt_cs }; static int opt_rr_add_cookies(knot_rrset_t *opt_rr, @@ -213,7 +212,7 @@ int kr_request_put_cookie(struct cookies_control *cntrl, void *clnt_sockaddr, return kr_ok(); } - if (!cntrl->secret) { + if (!cntrl->current_cs) { return kr_error(EINVAL); } @@ -222,7 +221,7 @@ int kr_request_put_cookie(struct cookies_control *cntrl, void *clnt_sockaddr, * and secret quantity. */ uint8_t cc[KNOT_OPT_COOKIE_CLNT]; int ret = kr_client_cokie_fnv64(cc, clnt_sockaddr, srvr_sockaddr, - cntrl->secret); + cntrl->current_cs); if (ret != kr_ok()) { return ret; } diff --git a/lib/cookies/control.h b/lib/cookies/control.h index 9703bf535..7a2bbaaba 100644 --- a/lib/cookies/control.h +++ b/lib/cookies/control.h @@ -28,13 +28,19 @@ /** Holds secret quantity. */ struct secret_quantity { size_t size; /*!< Secret quantity size. */ - const uint8_t *data; /*!< Secret quantity data. */ + uint8_t data[]; /*!< Secret quantity data. */ }; +/* Default client secret. */ +KR_EXPORT +extern struct secret_quantity dflt_cs; + /** DNSSEC cookies controlling structure. */ struct cookies_control { bool enabled; /*!< Enabled/disables DNS cookies functionality. */ - struct secret_quantity *secret; /*!< Client secret quantity. */ + + struct secret_quantity *current_cs; /*!< current client secret */ + struct secret_quantity *recent_cs; /*!< recent client secret */ struct kr_cache cache; /*!< Server cookies cache. */ }; diff --git a/modules/cookies/cookies.c b/modules/cookies/cookies.c index 84498b056..1297adbc3 100644 --- a/modules/cookies/cookies.c +++ b/modules/cookies/cookies.c @@ -182,7 +182,14 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt) const struct sockaddr *srvr_sockaddr = NULL; /* Abusing name server reputation mechanism to obtain IP addresses. */ - srvr_sockaddr = guess_server_addr(cc, ns, kr_cookies_control.secret); + srvr_sockaddr = guess_server_addr(cc, ns, + kr_cookies_control.current_cs); + bool returned_current = (srvr_sockaddr != NULL); + if (!srvr_sockaddr && kr_cookies_control.recent_cs) { + /* Try recent client secret to check obtained cookie. */ + srvr_sockaddr = guess_server_addr(cc, ns, + kr_cookies_control.recent_cs); + } if (!srvr_sockaddr) { DEBUG_MSG(NULL, "%s\n", "could not match received cookie"); DEBUG_MSG(NULL, "%s\n", "falling back to TCP"); @@ -190,7 +197,9 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt) return KNOT_STATE_PRODUCE; } - if (!is_cookie_cached(&kr_cookies_control.cache, srvr_sockaddr, + /* Don't cache received cookies that don't match the current secret. */ + if (returned_current && + !is_cookie_cached(&kr_cookies_control.cache, srvr_sockaddr, cookie_opt)) { DEBUG_MSG(NULL, "%s\n", "caching server cookie"); @@ -256,7 +265,12 @@ int cookies_init(struct kr_module *module) struct engine *engine = module->data; DEBUG_MSG(NULL, "initialising with engine %p\n", (void *) engine); - kr_cookies_control.enabled = true; /* Leave enabled by default. */ + memset(&kr_cookies_control, 0, sizeof(kr_cookies_control)); + + kr_cookies_control.enabled = false; + + kr_cookies_control.current_cs = &dflt_cs; + memset(&kr_cookies_control.cache, 0, sizeof(kr_cookies_control.cache)); struct storage_api *lmdb_storage_api = find_storage_api(&engine->storage_registry, @@ -284,6 +298,22 @@ int cookies_init(struct kr_module *module) KR_EXPORT int cookies_deinit(struct kr_module *module) { + kr_cookies_control.enabled = false; + + if (kr_cookies_control.recent_cs && + kr_cookies_control.recent_cs != &dflt_cs) { + free(kr_cookies_control.recent_cs); + } + kr_cookies_control.recent_cs = NULL; + + if (kr_cookies_control.current_cs && + kr_cookies_control.current_cs != &dflt_cs) { + free(kr_cookies_control.current_cs); + } + kr_cookies_control.current_cs = &dflt_cs; + + kr_cache_close(&kr_cookies_control.cache); + return kr_ok(); }