]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
Added basic support for client secret rotation.
authorKarel Slany <karel.slany@nic.cz>
Tue, 24 May 2016 14:41:13 +0000 (16:41 +0200)
committerOndřej Surý <ondrej@sury.org>
Thu, 11 Aug 2016 12:06:45 +0000 (14:06 +0200)
lib/cookies/control.c
lib/cookies/control.h
modules/cookies/cookies.c

index 2c6c5e0452afddc8828bac31deeaa815facd054a..97e73860c5df3ec158c9d896b4aa06d513a5a9cf 100644 (file)
 
 #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;
        }
index 9703bf535b8b1a26e5eae8b50a3d5cceeb1e869d..7a2bbaabaf791a00d306a00814b9bdd43a412ef3 100644 (file)
 /** 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. */
 };
index 84498b056244110286c1f12b99552165805578cf..1297adbc3a71a2bb7953f211a6f6491edbf7fa89 100644 (file)
@@ -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();
 }