]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4699. [func] Multiple cookie-secret clauses can now be specified.
authorMark Andrews <marka@isc.org>
Mon, 4 Sep 2017 23:19:45 +0000 (09:19 +1000)
committerEvan Hunt <each@isc.org>
Mon, 4 Jun 2018 20:16:28 +0000 (13:16 -0700)
                        The first one specified is used to generate new
                        server cookies.  [RT #45672]

18 files changed:
CHANGES
bin/named/client.c
bin/named/include/named/server.h
bin/named/include/named/types.h
bin/named/server.c
bin/tests/system/cookie/ns4/named.conf.in [new file with mode: 0644]
bin/tests/system/cookie/ns4/root.hint [new file with mode: 0644]
bin/tests/system/cookie/ns5/named.conf.in [new file with mode: 0644]
bin/tests/system/cookie/ns5/root.hint [new file with mode: 0644]
bin/tests/system/cookie/ns6/named.conf.in [new file with mode: 0644]
bin/tests/system/cookie/ns6/root.hint [new file with mode: 0644]
bin/tests/system/cookie/setup.sh
bin/tests/system/cookie/tests.sh
doc/arm/Bv9ARM-book.xml
doc/arm/notes.xml
lib/bind9/check.c
lib/isccfg/namedconf.c
util/copyrights

diff --git a/CHANGES b/CHANGES
index 6fedd0067ca6a6f29a6e35ddb3562f5afd419496..0ec8c60a1dc59d9f38a0bd5bfe1943566c1c5a73 100644 (file)
--- a/CHANGES
+++ b/CHANGES
                        before all zone loading actions triggered by a previous
                        "rndc reload" command were completed. [RT #47076]
 
+4699.  [func]          Multiple cookie-secret clauses can now be specified.
+                       The first one specified is used to generate new
+                       server cookies.  [RT #45672]
+
        --- 9.11.3 released ---
        --- 9.11.3rc2 released ---
 
index 1d666e529cd7943e231facfaf1fe799544782410..bd410784c68fbcc6dec652fa439eeba245a20ab2 100644 (file)
@@ -248,7 +248,8 @@ static inline isc_boolean_t
 allowed(isc_netaddr_t *addr, dns_name_t *signer, isc_netaddr_t *ecs_addr,
        isc_uint8_t ecs_addrlen, isc_uint8_t *ecs_scope, dns_acl_t *acl);
 static void compute_cookie(ns_client_t *client, isc_uint32_t when,
-                          isc_uint32_t nonce, isc_buffer_t *buf);
+                          isc_uint32_t nonce, const unsigned char *secret,
+                          isc_buffer_t *buf);
 
 void
 ns_client_recursing(ns_client_t *client) {
@@ -1606,7 +1607,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
                isc_stdtime_get(&now);
                isc_random_get(&nonce);
 
-               compute_cookie(client, now, nonce, &buf);
+               compute_cookie(client, now, nonce, ns_g_server->secret, &buf);
 
                INSIST(count < DNS_EDNSOPTIONS);
                ednsopts[count].code = DNS_OPT_COOKIE;
@@ -1776,7 +1777,7 @@ ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
 
 static void
 compute_cookie(ns_client_t *client, isc_uint32_t when, isc_uint32_t nonce,
-              isc_buffer_t *buf)
+              const unsigned char *secret, isc_buffer_t *buf)
 {
        switch (ns_g_server->cookiealg) {
 #if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES)
@@ -1793,7 +1794,7 @@ compute_cookie(ns_client_t *client, isc_uint32_t when, isc_uint32_t nonce,
                isc_buffer_putuint32(buf, nonce);
                isc_buffer_putuint32(buf, when);
                memmove(input, cp, 16);
-               isc_aes128_crypt(ns_g_server->secret, input, digest);
+               isc_aes128_crypt(secret, input, digest);
                for (i = 0; i < 8; i++)
                        input[i] = digest[i] ^ digest[i + 8];
                isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
@@ -1802,12 +1803,12 @@ compute_cookie(ns_client_t *client, isc_uint32_t when, isc_uint32_t nonce,
                        cp = (unsigned char *)&netaddr.type.in;
                        memmove(input + 8, cp, 4);
                        memset(input + 12, 0, 4);
-                       isc_aes128_crypt(ns_g_server->secret, input, digest);
+                       isc_aes128_crypt(secret, input, digest);
                        break;
                case AF_INET6:
                        cp = (unsigned char *)&netaddr.type.in6;
                        memmove(input + 8, cp, 16);
-                       isc_aes128_crypt(ns_g_server->secret, input, digest);
+                       isc_aes128_crypt(secret, input, digest);
                        for (i = 0; i < 8; i++)
                                input[i + 8] = digest[i] ^ digest[i + 8];
                        isc_aes128_crypt(ns_g_server->secret, input + 8,
@@ -1833,9 +1834,7 @@ compute_cookie(ns_client_t *client, isc_uint32_t when, isc_uint32_t nonce,
                isc_buffer_putuint32(buf, nonce);
                isc_buffer_putuint32(buf, when);
 
-               isc_hmacsha1_init(&hmacsha1,
-                                 ns_g_server->secret,
-                                 ISC_SHA1_DIGESTLENGTH);
+               isc_hmacsha1_init(&hmacsha1, secret, ISC_SHA1_DIGESTLENGTH);
                isc_hmacsha1_update(&hmacsha1, cp, 16);
                isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
                switch (netaddr.family) {
@@ -1871,8 +1870,7 @@ compute_cookie(ns_client_t *client, isc_uint32_t when, isc_uint32_t nonce,
                isc_buffer_putuint32(buf, nonce);
                isc_buffer_putuint32(buf, when);
 
-               isc_hmacsha256_init(&hmacsha256,
-                                   ns_g_server->secret,
+               isc_hmacsha256_init(&hmacsha256, secret,
                                    ISC_SHA256_DIGESTLENGTH);
                isc_hmacsha256_update(&hmacsha256, cp, 16);
                isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
@@ -1903,6 +1901,7 @@ compute_cookie(ns_client_t *client, isc_uint32_t when, isc_uint32_t nonce,
 
 static void
 process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
+       ns_altsecret_t *altsecret;
        unsigned char dbuf[COOKIE_SIZE];
        unsigned char *old;
        isc_stdtime_t now;
@@ -1962,17 +1961,31 @@ process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
        }
 
        isc_buffer_init(&db, dbuf, sizeof(dbuf));
-       compute_cookie(client, when, nonce, &db);
+       compute_cookie(client, when, nonce, ns_g_server->secret, &db);
 
-       if (!isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
+       if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
                isc_stats_increment(ns_g_server->nsstats,
-                                   dns_nsstatscounter_cookienomatch);
+                                   dns_nsstatscounter_cookiematch);
+               client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
                return;
        }
 
+       for (altsecret = ISC_LIST_HEAD(ns_g_server->altsecrets);
+            altsecret != NULL;
+            altsecret = ISC_LIST_NEXT(altsecret, link))
+       {
+               isc_buffer_init(&db, dbuf, sizeof(dbuf));
+               compute_cookie(client, when, nonce, altsecret->secret, &db);
+               if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
+                       isc_stats_increment(ns_g_server->nsstats,
+                                           dns_nsstatscounter_cookiematch);
+                       client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
+                       return;
+               }
+       }
+
        isc_stats_increment(ns_g_server->nsstats,
-                           dns_nsstatscounter_cookiematch);
-       client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
+                           dns_nsstatscounter_cookienomatch);
 }
 
 static isc_result_t
index 4dd2882916112c4c7ca9cf0193dc0c50287f1aea..e60e96fe4b6e067c1f32707e0b473493a17284ae 100644 (file)
@@ -122,6 +122,7 @@ struct ns_server {
        isc_uint16_t            session_keybits;
        isc_boolean_t           interface_auto;
        unsigned char           secret[32];     /*%< Server Cookie Secret */
+       ns_altsecretlist_t      altsecrets;
        ns_cookiealg_t          cookiealg;
 
        dns_dtenv_t             *dtenv;         /*%< Dnstap environment */
@@ -131,6 +132,11 @@ struct ns_server {
        isc_uint16_t            transfer_tcp_message_size;
 };
 
+struct ns_altsecret {
+       ISC_LINK(ns_altsecret_t) link;
+       unsigned char           secret[32];
+};
+
 #define NS_SERVER_MAGIC                        ISC_MAGIC('S','V','E','R')
 #define NS_SERVER_VALID(s)             ISC_MAGIC_VALID(s, NS_SERVER_MAGIC)
 
index 711853eaa8719f948e9caf57914f6ec1ea2dd255..486ec31777931e14d27339a5c985f076f7eb3055 100644 (file)
@@ -9,8 +9,6 @@
  * information regarding copyright ownership.
  */
 
-/* $Id: types.h,v 1.31 2009/01/09 23:47:45 tbox Exp $ */
-
 #ifndef NAMED_TYPES_H
 #define NAMED_TYPES_H 1
 
@@ -39,6 +37,8 @@ typedef struct ns_dispatch            ns_dispatch_t;
 typedef ISC_LIST(ns_dispatch_t)                ns_dispatchlist_t;
 typedef struct ns_statschannel         ns_statschannel_t;
 typedef ISC_LIST(ns_statschannel_t)    ns_statschannellist_t;
+typedef struct ns_altsecret            ns_altsecret_t;
+typedef ISC_LIST(ns_altsecret_t)       ns_altsecretlist_t;
 
 typedef enum {
        ns_cookiealg_aes,
index cca4e531a0a5d77b7225cc9025eda83e129cb22e..03566eb16f4c51c03b7fcfd17310e22ae7c21152 100644 (file)
@@ -7293,12 +7293,15 @@ load_configuration(const char *filename, ns_server_t *server,
        isc_uint32_t transfer_message_size;
        ns_cache_t *nsc;
        ns_cachelist_t cachelist, tmpcachelist;
+       ns_altsecret_t *altsecret;
+       ns_altsecretlist_t altsecrets, tmpaltsecrets;
        unsigned int maxsocks;
        isc_uint32_t softquota = 0;
 
        ISC_LIST_INIT(viewlist);
        ISC_LIST_INIT(builtin_viewlist);
        ISC_LIST_INIT(cachelist);
+       ISC_LIST_INIT(altsecrets);
 
        /* Create the ACL configuration context */
        if (ns_g_aclconfctx != NULL) {
@@ -8235,7 +8238,6 @@ load_configuration(const char *filename, ns_server_t *server,
                }
        }
 
-
        obj = NULL;
        if (options != NULL &&
            cfg_map_get(options, "memstatistics", &obj) == ISC_R_SUCCESS) {
@@ -8340,36 +8342,72 @@ load_configuration(const char *filename, ns_server_t *server,
        obj = NULL;
        result = ns_config_get(maps, "cookie-secret", &obj);
        if (result == ISC_R_SUCCESS) {
+               const char *str;
+               isc_boolean_t first = ISC_TRUE;
                isc_buffer_t b;
                unsigned int usedlength;
 
-               memset(server->secret, 0, sizeof(server->secret));
-               isc_buffer_init(&b, server->secret, sizeof(server->secret));
-               result = isc_hex_decodestring(cfg_obj_asstring(obj), &b);
-               if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) {
-                       goto cleanup;
-               }
+               for (element = cfg_list_first(obj);
+                    element != NULL;
+                    element = cfg_list_next(element))
+               {
+                       obj = cfg_listelt_value(element);
+                       str = cfg_obj_asstring(obj);
 
-               usedlength = isc_buffer_usedlength(&b);
-               switch (server->cookiealg) {
-               case ns_cookiealg_aes:
-                       if (usedlength != ISC_AES128_KEYLENGTH) {
-                               CHECKM(ISC_R_RANGE,
-                                      "AES cookie-secret must be 128 bits");
-                       }
-                       break;
-               case ns_cookiealg_sha1:
-                       if (usedlength != ISC_SHA1_DIGESTLENGTH) {
-                               CHECKM(ISC_R_RANGE,
-                                      "SHA1 cookie-secret must be 160 bits");
+                       if (first) {
+                               memset(server->secret, 0,
+                                      sizeof(server->secret));
+                               isc_buffer_init(&b, server->secret,
+                                               sizeof(server->secret));
+                               result = isc_hex_decodestring(str, &b);
+                               if (result != ISC_R_SUCCESS &&
+                                   result != ISC_R_NOSPACE)
+                                       goto cleanup;
+                               first = ISC_FALSE;
+                       } else {
+                               altsecret = isc_mem_get(server->mctx,
+                                                       sizeof(*altsecret));
+                               if (altsecret == NULL) {
+                                       result = ISC_R_NOMEMORY;
+                                       goto cleanup;
+                               }
+                               isc_buffer_init(&b, altsecret->secret,
+                                               sizeof(altsecret->secret));
+                               result = isc_hex_decodestring(str, &b);
+                               if (result != ISC_R_SUCCESS &&
+                                   result != ISC_R_NOSPACE) {
+                                       isc_mem_put(server->mctx, altsecret,
+                                                   sizeof(*altsecret));
+                                       goto cleanup;
+                               }
+                               ISC_LIST_INITANDAPPEND(altsecrets,
+                                                      altsecret, link);
                        }
-                       break;
-               case ns_cookiealg_sha256:
-                       if (usedlength != ISC_SHA256_DIGESTLENGTH) {
-                               CHECKM(ISC_R_RANGE,
-                                      "SHA256 cookie-secret must be 256 bits");
+
+                       usedlength = isc_buffer_usedlength(&b);
+                       switch (server->cookiealg) {
+                       case ns_cookiealg_aes:
+                               if (usedlength != ISC_AES128_KEYLENGTH) {
+                                       CHECKM(ISC_R_RANGE,
+                                              "AES cookie-secret must be "
+                                              "128 bits");
+                               }
+                               break;
+                       case ns_cookiealg_sha1:
+                               if (usedlength != ISC_SHA1_DIGESTLENGTH) {
+                                       CHECKM(ISC_R_RANGE,
+                                              "SHA1 cookie-secret must be "
+                                              "160 bits");
+                               }
+                               break;
+                       case ns_cookiealg_sha256:
+                               if (usedlength != ISC_SHA256_DIGESTLENGTH) {
+                                       CHECKM(ISC_R_RANGE,
+                                              "SHA256 cookie-secret must be "
+                                              "256 bits");
+                               }
+                               break;
                        }
-                       break;
                }
        } else {
                result = isc_entropy_getdata(ns_g_entropy,
@@ -8382,6 +8420,13 @@ load_configuration(const char *filename, ns_server_t *server,
                }
        }
 
+       /*
+        * Swap altsecrets lists.
+        */
+       tmpaltsecrets = server->altsecrets;
+       server->altsecrets = altsecrets;
+       altsecrets = tmpaltsecrets;
+
        (void) ns_server_loadnta(server);
 
        result = ISC_R_SUCCESS;
@@ -8446,6 +8491,12 @@ load_configuration(const char *filename, ns_server_t *server,
                isc_mem_put(server->mctx, nsc, sizeof(*nsc));
        }
 
+       /* Same cleanup for altsecrets list. */
+       while ((altsecret = ISC_LIST_HEAD(altsecrets)) != NULL) {
+               ISC_LIST_UNLINK(altsecrets, altsecret, link);
+               isc_mem_put(server->mctx, altsecret, sizeof(*altsecret));
+       }
+
        /*
         * Adjust the listening interfaces in accordance with the source
         * addresses specified in views and zones.
@@ -8672,6 +8723,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
        ns_server_t *server = (ns_server_t *)event->ev_arg;
        isc_boolean_t flush = server->flushonshutdown;
        ns_cache_t *nsc;
+       ns_altsecret_t *altsecret;
 
        UNUSED(task);
        INSIST(task == server->task);
@@ -8716,6 +8768,11 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
                isc_mem_put(server->mctx, nsc, sizeof(*nsc));
        }
 
+       while ((altsecret = ISC_LIST_HEAD(server->altsecrets)) != NULL) {
+               ISC_LIST_UNLINK(server->altsecrets, altsecret, link);
+               isc_mem_put(server->mctx, altsecret, sizeof(*altsecret));
+       }
+
        isc_timer_detach(&server->interface_timer);
        isc_timer_detach(&server->heartbeat_timer);
        isc_timer_detach(&server->pps_timer);
@@ -8960,6 +9017,8 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
 
        ISC_LIST_INIT(server->cachelist);
 
+       ISC_LIST_INIT(server->altsecrets);
+
        server->sessionkey = NULL;
        server->session_keyfile = NULL;
        server->session_keyname = NULL;
diff --git a/bin/tests/system/cookie/ns4/named.conf.in b/bin/tests/system/cookie/ns4/named.conf.in
new file mode 100644 (file)
index 0000000..cd7c07f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       query-source address 10.53.0.4;
+       notify-source 10.53.0.4;
+       transfer-source 10.53.0.4;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.4; };
+       listen-on-v6 { none; };
+       recursion yes;
+       cookie-algorithm sha1;
+       cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2";
+       require-server-cookie yes;
+};
+
+zone "." {
+       type hint;
+       file "root.hint";
+};
diff --git a/bin/tests/system/cookie/ns4/root.hint b/bin/tests/system/cookie/ns4/root.hint
new file mode 100644 (file)
index 0000000..64769b9
--- /dev/null
@@ -0,0 +1,12 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 999999
+.                       IN NS  a.root-servers.nil.
+a.root-servers.nil.     IN A   10.53.0.2
diff --git a/bin/tests/system/cookie/ns5/named.conf.in b/bin/tests/system/cookie/ns5/named.conf.in
new file mode 100644 (file)
index 0000000..0d050a6
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.5 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       query-source address 10.53.0.5;
+       notify-source 10.53.0.5;
+       transfer-source 10.53.0.5;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.5; };
+       listen-on-v6 { none; };
+       recursion yes;
+       cookie-algorithm sha1;
+       cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2";
+       cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3";
+       require-server-cookie yes;
+};
+
+zone "." {
+       type hint;
+       file "root.hint";
+};
diff --git a/bin/tests/system/cookie/ns5/root.hint b/bin/tests/system/cookie/ns5/root.hint
new file mode 100644 (file)
index 0000000..64769b9
--- /dev/null
@@ -0,0 +1,12 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 999999
+.                       IN NS  a.root-servers.nil.
+a.root-servers.nil.     IN A   10.53.0.2
diff --git a/bin/tests/system/cookie/ns6/named.conf.in b/bin/tests/system/cookie/ns6/named.conf.in
new file mode 100644 (file)
index 0000000..634a939
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       query-source address 10.53.0.6;
+       notify-source 10.53.0.6;
+       transfer-source 10.53.0.6;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.6; };
+       listen-on-v6 { none; };
+       recursion yes;
+       cookie-algorithm sha1;
+       cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3";
+       require-server-cookie yes;
+};
+
+zone "." {
+       type hint;
+       file "root.hint";
+};
diff --git a/bin/tests/system/cookie/ns6/root.hint b/bin/tests/system/cookie/ns6/root.hint
new file mode 100644 (file)
index 0000000..64769b9
--- /dev/null
@@ -0,0 +1,12 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 999999
+.                       IN NS  a.root-servers.nil.
+a.root-servers.nil.     IN A   10.53.0.2
index c9f645b29ea4057f0a206c4ddedb5e076a3253ca..2e90ba22c33ca1a348b7efe516a9105c31606639 100644 (file)
@@ -16,3 +16,6 @@ $SHELL clean.sh
 copy_setports ns1/named.conf.in ns1/named.conf
 copy_setports ns2/named.conf.in ns2/named.conf
 copy_setports ns3/named.conf.in ns3/named.conf
+copy_setports ns4/named.conf.in ns4/named.conf
+copy_setports ns5/named.conf.in ns5/named.conf
+copy_setports ns6/named.conf.in ns6/named.conf
index ca846855d3b8892a501956d3645debc7b7ed4576..bb96cbde0196a624c3e08ba3ae78a82ef995a4c1 100755 (executable)
@@ -142,6 +142,105 @@ if [ $linecount != 2 ]; then ret=1; fi
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
+#
+# Test shared cookie-secret support.
+#
+# NS4 has cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2";
+#
+# NS5 has cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2";
+# NS5 has cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3"; (alternate)
+#
+# NS6 has cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3";
+#
+# Server cookies from NS4 are accepted by NS5 and not NS6
+# Server cookies from NS5 are accepted by NS4 and not NS6
+# Server cookies from NS6 are accepted by NS5 and not NS4
+#
+# Force local address so that the client's address is the same to all servers.
+#
+
+n=`expr $n + 1`
+echo_i "get NS4 cookie for cross server checking ($n)"
+ret=0
+$DIG $DIGOPTS +cookie -b 10.53.0.4 soa . @10.53.0.4 > dig.out.test$n
+grep "; COOKIE:.*(good)" dig.out.test$n > /dev/null || ret=1
+ns4cookie=`getcookie dig.out.test$n`
+test -n "$ns4cookie" || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "get NS5 cookie for cross server checking ($n)"
+ret=0
+$DIG $DIGOPTS +cookie -b 10.53.0.4 soa . @10.53.0.5 > dig.out.test$n
+grep "; COOKIE:.*(good)" dig.out.test$n > /dev/null || ret=1
+ns5cookie=`getcookie dig.out.test$n`
+test -n "$ns5cookie" || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "get NS6 cookie for cross server checking ($n)"
+ret=0
+$DIG $DIGOPTS +cookie -b 10.53.0.4 soa . @10.53.0.6 > dig.out.test$n
+grep "; COOKIE:.*(good)" dig.out.test$n > /dev/null || ret=1
+ns6cookie=`getcookie dig.out.test$n`
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "test NS4 cookie on NS5 (expect success) ($n)"
+ret=0
+$DIG $DIGOPTS +cookie=$ns4cookie -b 10.53.0.4 +nobadcookie soa . @10.53.0.5 > dig.out.test$n
+grep "; COOKIE:.*(good)" dig.out.test$n > /dev/null || ret=1
+grep "status: NOERROR," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "test NS4 cookie on NS6 (expect badcookie) ($n)"
+ret=0
+$DIG $DIGOPTS +cookie=$ns4cookie -b 10.53.0.4 +nobadcookie soa . @10.53.0.6 > dig.out.test$n
+grep "; COOKIE:.*(good)" dig.out.test$n > /dev/null || ret=1
+grep "status: BADCOOKIE," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "test NS5 cookie on NS4 (expect success) ($n)"
+ret=0
+$DIG $DIGOPTS +cookie=$ns5cookie -b 10.53.0.4 +nobadcookie soa . @10.53.0.4 > dig.out.test$n
+grep "; COOKIE:.*(good)" dig.out.test$n > /dev/null || ret=1
+grep "status: NOERROR," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "test NS5 cookie on NS6 (expect badcookie) ($n)"
+ret=0
+$DIG $DIGOPTS +cookie=$ns5cookie -b 10.53.0.4 +nobadcookie soa . @10.53.0.6 > dig.out.test$n
+grep "; COOKIE:.*(good)" dig.out.test$n > /dev/null || ret=1
+grep "status: BADCOOKIE," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "test NS6 cookie on NS4 (expect badcookie) ($n)"
+ret=0
+$DIG $DIGOPTS +cookie=$ns6cookie -b 10.53.0.4 +nobadcookie soa . @10.53.0.4 > dig.out.test$n
+grep "; COOKIE:.*(good)" dig.out.test$n > /dev/null || ret=1
+grep "status: BADCOOKIE," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "test NS6 cookie on NS5 (expect success) ($n)"
+ret=0
+$DIG $DIGOPTS +cookie=$ns6cookie -b 10.53.0.4 +nobadcookie soa . @10.53.0.5 > dig.out.test$n
+grep "; COOKIE:.*(good)" dig.out.test$n > /dev/null || ret=1
+grep "status: NOERROR," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
 
 echo_i "exit status: $status"
 [ $status -eq 0 ] || exit 1
index 32ad6425561e3670bb328ac05c0faeb4e79114d0..98024a07cbedfae8c1a6df266ac5cd8edb4d675c 100644 (file)
@@ -6229,6 +6229,12 @@ options {
                  to be 128 bits for AES128, 160 bits for SHA1 and
                  256 bits for SHA256.
                </para>
+               <para>
+                 If there are multiple secrets specified, the first
+                 one listed in <filename>named.conf</filename> is
+                 used to generate new server cookies.  The others
+                 will only be used to verify returned cookies.
+               </para>
              </listitem>
            </varlistentry>
 
index ee745a0e6eb4d44df9c31e3ef9ce05b1b19c8c7e..e03aa80ea0ec2eb18f4d7b0e5df787235db17870 100644 (file)
          with IDN support.
        </para>
       </listitem>
+      <listitem>
+       <para>
+         Multiple <command>cookie-secret</command> clause are now
+         supported.  The first <command>cookie-secret</command> in
+         <filename>named.conf</filename> is used to generate new
+         server cookies.  Any others are used to accept old server
+         cookies or those generated by other servers using the
+         matching <command>cookie-secret</command>.
+       </para>
+      </listitem>
     </itemizedlist>
   </section>
 
index e12e5a079805812d9a39b1d296f2f24ce0b5142e..a8ddc2bee5e57804e1af72a61d8adc46e9d01af7 100644 (file)
@@ -1385,39 +1385,56 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
        if (obj != NULL) {
                unsigned char secret[32];
 
-               memset(secret, 0, sizeof(secret));
-               isc_buffer_init(&b, secret, sizeof(secret));
-               tresult = isc_hex_decodestring(cfg_obj_asstring(obj), &b);
-               if (tresult == ISC_R_NOSPACE) {
-                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
-                                   "cookie-secret: too long");
-               } else if (tresult != ISC_R_SUCCESS) {
-                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
-                                   "cookie-secret: invalid hex string");
-               }
-               if (tresult != ISC_R_SUCCESS)
-                       result = tresult;
+               for (element = cfg_list_first(obj);
+                    element != NULL;
+                    element = cfg_list_next(element)) {
+                       unsigned int usedlength;
 
-               if (tresult == ISC_R_SUCCESS &&
-                   strcasecmp(ccalg, "aes") == 0 &&
-                   isc_buffer_usedlength(&b) != ISC_AES128_KEYLENGTH) {
-                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
-                                   "AES cookie-secret must be 128 bits");
-                       result = ISC_R_RANGE;
-               }
-               if (tresult == ISC_R_SUCCESS &&
-                   strcasecmp(ccalg, "sha1") == 0 &&
-                   isc_buffer_usedlength(&b) != ISC_SHA1_DIGESTLENGTH) {
-                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
-                                   "SHA1 cookie-secret must be 160 bits");
-                       result = ISC_R_RANGE;
-               }
-               if (tresult == ISC_R_SUCCESS &&
-                   strcasecmp(ccalg, "sha256") == 0 &&
-                   isc_buffer_usedlength(&b) != ISC_SHA256_DIGESTLENGTH) {
-                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
-                                   "SHA256 cookie-secret must be 256 bits");
-                       result = ISC_R_RANGE;
+                       obj = cfg_listelt_value(element);
+                       str = cfg_obj_asstring(obj);
+
+                       memset(secret, 0, sizeof(secret));
+                       isc_buffer_init(&b, secret, sizeof(secret));
+                       tresult = isc_hex_decodestring(str, &b);
+                       if (tresult == ISC_R_NOSPACE) {
+                               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                           "cookie-secret: too long");
+                       } else if (tresult != ISC_R_SUCCESS) {
+                               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                           "cookie-secret: invalid hex "
+                                           "string");
+                       }
+                       if (tresult != ISC_R_SUCCESS) {
+                               if (result == ISC_R_SUCCESS)
+                                       result = tresult;
+                               continue;
+                       }
+
+                       usedlength = isc_buffer_usedlength(&b);
+                       if (strcasecmp(ccalg, "aes") == 0 &&
+                           usedlength != ISC_AES128_KEYLENGTH) {
+                               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                           "AES cookie-secret must be "
+                                           "128 bits");
+                               if (result == ISC_R_SUCCESS)
+                                       result = ISC_R_RANGE;
+                       }
+                       if (strcasecmp(ccalg, "sha1") == 0 &&
+                           usedlength != ISC_SHA1_DIGESTLENGTH) {
+                               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                           "SHA1 cookie-secret must be "
+                                           "160 bits");
+                               if (result == ISC_R_SUCCESS)
+                                       result = ISC_R_RANGE;
+                       }
+                       if (strcasecmp(ccalg, "sha256") == 0 &&
+                           usedlength != ISC_SHA256_DIGESTLENGTH) {
+                               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                           "SHA256 cookie-secret must be "
+                                           "256 bits");
+                               if (result == ISC_R_SUCCESS)
+                                       result = ISC_R_RANGE;
+                       }
                }
        }
 
index bfd63734fcc5db9b911a56a928e898ff5774c95c..9a2dbd3be044daf8d3a488ff636b08deb4b330e8 100644 (file)
@@ -1030,7 +1030,7 @@ options_clauses[] = {
        { "bindkeys-file", &cfg_type_qstring, 0 },
        { "blackhole", &cfg_type_bracketed_aml, 0 },
        { "cookie-algorithm", &cfg_type_cookiealg, 0 },
-       { "cookie-secret", &cfg_type_sstring, 0 },
+       { "cookie-secret", &cfg_type_sstring, CFG_CLAUSEFLAG_MULTI },
        { "coresize", &cfg_type_size, 0 },
        { "datasize", &cfg_type_size, 0 },
        { "deallocate-on-exit", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
index 396518d58406aea0f1976c173cbcf99da78e949f..741bdfe2e5f4c3516cf960e04630955b84f203d8 100644 (file)
 ./bin/tests/system/cookie/ns2/root.db          ZONE    2014,2015,2016,2018
 ./bin/tests/system/cookie/ns3/named.conf.in    CONF-C  2018
 ./bin/tests/system/cookie/ns3/root.hint                ZONE    2015,2016,2018
+./bin/tests/system/cookie/ns4/named.conf.in    CONF-C  2018
+./bin/tests/system/cookie/ns4/root.hint                ZONE    2018
+./bin/tests/system/cookie/ns5/named.conf.in    CONF-C  2018
+./bin/tests/system/cookie/ns5/root.hint                ZONE    2018
+./bin/tests/system/cookie/ns6/named.conf.in    CONF-C  2018
+./bin/tests/system/cookie/ns6/root.hint                ZONE    2018
 ./bin/tests/system/cookie/setup.sh             SH      2018
 ./bin/tests/system/cookie/tests.sh             SH      2014,2015,2016,2017,2018
 ./bin/tests/system/coverage/01-ksk-inactive/README     X       2013,2018