summaryrefslogtreecommitdiffstats
path: root/bin/tests/system/cookie
diff options
context:
space:
mode:
Diffstat (limited to 'bin/tests/system/cookie')
-rw-r--r--bin/tests/system/cookie/ans9/ans.py300
-rw-r--r--bin/tests/system/cookie/bad-cookie-badaes.conf17
-rw-r--r--bin/tests/system/cookie/bad-cookie-badhex.conf16
-rw-r--r--bin/tests/system/cookie/bad-cookie-badsiphash24.conf17
-rw-r--r--bin/tests/system/cookie/bad-cookie-toolong.conf16
-rw-r--r--bin/tests/system/cookie/clean.sh24
-rw-r--r--bin/tests/system/cookie/good-cookie-aes.conf17
-rw-r--r--bin/tests/system/cookie/good-cookie-siphash24.conf17
-rw-r--r--bin/tests/system/cookie/ns1/example.db24
-rw-r--r--bin/tests/system/cookie/ns1/named.conf.in60
-rw-r--r--bin/tests/system/cookie/ns1/root.hint14
-rw-r--r--bin/tests/system/cookie/ns2/named.conf.in31
-rw-r--r--bin/tests/system/cookie/ns2/root.db28
-rw-r--r--bin/tests/system/cookie/ns3/named.conf.in52
-rw-r--r--bin/tests/system/cookie/ns3/root.hint14
-rw-r--r--bin/tests/system/cookie/ns4/named.conf.in41
-rw-r--r--bin/tests/system/cookie/ns4/root.hint14
-rw-r--r--bin/tests/system/cookie/ns5/named.conf.in42
-rw-r--r--bin/tests/system/cookie/ns5/root.hint14
-rw-r--r--bin/tests/system/cookie/ns6/named.conf.in41
-rw-r--r--bin/tests/system/cookie/ns6/root.hint14
-rw-r--r--bin/tests/system/cookie/ns7/named.conf.in31
-rw-r--r--bin/tests/system/cookie/ns7/root.db24
-rw-r--r--bin/tests/system/cookie/ns8/example.db13
-rw-r--r--bin/tests/system/cookie/ns8/named.conf.in39
-rw-r--r--bin/tests/system/cookie/prereq.sh33
-rw-r--r--bin/tests/system/cookie/setup.sh24
-rwxr-xr-xbin/tests/system/cookie/tests.sh515
28 files changed, 1492 insertions, 0 deletions
diff --git a/bin/tests/system/cookie/ans9/ans.py b/bin/tests/system/cookie/ans9/ans.py
new file mode 100644
index 0000000..1266b7e
--- /dev/null
+++ b/bin/tests/system/cookie/ans9/ans.py
@@ -0,0 +1,300 @@
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# 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 https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+from __future__ import print_function
+import os
+import sys
+import signal
+import socket
+import select
+from datetime import datetime, timedelta
+import time
+import functools
+
+import dns
+import dns.edns
+import dns.flags
+import dns.message
+import dns.query
+import dns.tsig
+import dns.tsigkeyring
+import dns.version
+
+from dns.edns import *
+from dns.name import *
+from dns.rcode import *
+from dns.rdataclass import *
+from dns.rdatatype import *
+from dns.tsig import *
+
+
+# Log query to file
+def logquery(type, qname):
+ with open("qlog", "a") as f:
+ f.write("%s %s\n", type, qname)
+
+
+# DNS 2.0 keyring specifies the algorithm
+try:
+ keyring = dns.tsigkeyring.from_text(
+ {
+ "foo": {"hmac-sha256", "aaaaaaaaaaaa"},
+ "fake": {"hmac-sha256", "aaaaaaaaaaaa"},
+ }
+ )
+except:
+ keyring = dns.tsigkeyring.from_text({"foo": "aaaaaaaaaaaa", "fake": "aaaaaaaaaaaa"})
+
+dopass2 = False
+
+
+############################################################################
+#
+# This server will serve valid and spoofed answers. A spoofed answer will
+# have the address 10.53.0.10 included.
+#
+# When receiving a query over UDP:
+#
+# A query to "nocookie"/A will result in a spoofed answer with no cookie set.
+# A query to "tcponly"/A will result in a spoofed answer with no cookie set.
+# A query to "withtsig"/A will result in two responses, the first is a spoofed
+# answer that is TSIG signed, the second is a valid answer with a cookie set.
+# A query to anything else will result in a valid answer with a cookie set.
+#
+# When receiving a query over TCP:
+#
+# A query to "nocookie"/A will result in a valid answer with no cookie set.
+# A query to anything else will result in a valid answer with a cookie set.
+#
+############################################################################
+def create_response(msg, tcp, first, ns10):
+ global dopass2
+ m = dns.message.from_wire(msg, keyring=keyring)
+ qname = m.question[0].name.to_text()
+ lqname = qname.lower()
+ labels = lqname.split(".")
+ rrtype = m.question[0].rdtype
+ typename = dns.rdatatype.to_text(rrtype)
+
+ with open("query.log", "a") as f:
+ f.write("%s %s\n" % (typename, qname))
+ print("%s %s" % (typename, qname), end=" ")
+
+ r = dns.message.make_response(m)
+ r.set_rcode(NOERROR)
+ if rrtype == A:
+ # exempt potential nameserver A records.
+ if labels[0] == "ns" and ns10:
+ r.answer.append(dns.rrset.from_text(qname, 1, IN, A, "10.53.0.10"))
+ else:
+ r.answer.append(dns.rrset.from_text(qname, 1, IN, A, "10.53.0.9"))
+ if not tcp and labels[0] == "nocookie":
+ r.answer.append(dns.rrset.from_text(qname, 1, IN, A, "10.53.0.10"))
+ if not tcp and labels[0] == "tcponly":
+ r.answer.append(dns.rrset.from_text(qname, 1, IN, A, "10.53.0.10"))
+ if first and not tcp and labels[0] == "withtsig":
+ r.answer.append(dns.rrset.from_text(qname, 1, IN, A, "10.53.0.10"))
+ dopass2 = True
+ elif rrtype == NS:
+ r.answer.append(dns.rrset.from_text(qname, 1, IN, NS, "."))
+ elif rrtype == SOA:
+ r.answer.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
+ else:
+ r.authority.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
+ # Add a server cookie to the response
+ if labels[0] != "nocookie":
+ for o in m.options:
+ if o.otype == 10: # Use 10 instead of COOKIE
+ if first and labels[0] == "withtsig" and not tcp:
+ r.use_tsig(
+ keyring=keyring,
+ keyname=dns.name.from_text("fake"),
+ algorithm=HMAC_SHA256,
+ )
+ elif labels[0] != "tcponly" or tcp:
+ cookie = o
+ if len(o.data) == 8:
+ cookie.data = o.data + o.data
+ else:
+ cookie.data = o.data
+ r.use_edns(options=[cookie])
+ r.flags |= dns.flags.AA
+ return r
+
+
+def sigterm(signum, frame):
+ print("Shutting down now...")
+ os.remove("ans.pid")
+ running = False
+ sys.exit(0)
+
+
+############################################################################
+# Main
+#
+# Set up responder and control channel, open the pid file, and start
+# the main loop, listening for queries on the query channel or commands
+# on the control channel and acting on them.
+############################################################################
+ip4_addr1 = "10.53.0.9"
+ip4_addr2 = "10.53.0.10"
+ip6_addr1 = "fd92:7065:b8e:ffff::9"
+ip6_addr2 = "fd92:7065:b8e:ffff::10"
+
+try:
+ port = int(os.environ["PORT"])
+except:
+ port = 5300
+
+query4_udp1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+query4_udp1.bind((ip4_addr1, port))
+query4_tcp1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+query4_tcp1.bind((ip4_addr1, port))
+query4_tcp1.listen(1)
+query4_tcp1.settimeout(1)
+
+query4_udp2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+query4_udp2.bind((ip4_addr2, port))
+query4_tcp2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+query4_tcp2.bind((ip4_addr2, port))
+query4_tcp2.listen(1)
+query4_tcp2.settimeout(1)
+
+havev6 = True
+query6_udp1 = None
+query6_udp2 = None
+query6_tcp1 = None
+query6_tcp2 = None
+try:
+ query6_udp1 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
+ query6_udp1.bind((ip6_addr1, port))
+ query6_tcp1 = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+ query6_tcp1.bind((ip6_addr1, port))
+ query6_tcp1.listen(1)
+ query6_tcp1.settimeout(1)
+
+ query6_udp2 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
+ query6_udp2.bind((ip6_addr2, port))
+ query6_tcp2 = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+ query6_tcp2.bind((ip6_addr2, port))
+ query6_tcp2.listen(1)
+ query6_tcp2.settimeout(1)
+except:
+ if query6_udp1 != None:
+ query6_udp1.close()
+ if query6_tcp1 != None:
+ query6_tcp1.close()
+ if query6_udp2 != None:
+ query6_udp2.close()
+ if query6_tcp2 != None:
+ query6_tcp2.close()
+ havev6 = False
+
+signal.signal(signal.SIGTERM, sigterm)
+
+f = open("ans.pid", "w")
+pid = os.getpid()
+print(pid, file=f)
+f.close()
+
+running = True
+
+print("Using DNS version %s" % dns.version.version)
+print("Listening on %s port %d" % (ip4_addr1, port))
+print("Listening on %s port %d" % (ip4_addr2, port))
+if havev6:
+ print("Listening on %s port %d" % (ip6_addr1, port))
+ print("Listening on %s port %d" % (ip6_addr2, port))
+print("Ctrl-c to quit")
+
+if havev6:
+ input = [
+ query4_udp1,
+ query6_udp1,
+ query4_tcp1,
+ query6_tcp1,
+ query4_udp2,
+ query6_udp2,
+ query4_tcp2,
+ query6_tcp2,
+ ]
+else:
+ input = [query4_udp1, query4_tcp1, query4_udp2, query4_tcp2]
+
+while running:
+ try:
+ inputready, outputready, exceptready = select.select(input, [], [])
+ except select.error as e:
+ break
+ except socket.error as e:
+ break
+ except KeyboardInterrupt:
+ break
+
+ for s in inputready:
+ ns10 = False
+ if s == query4_udp1 or s == query6_udp1 or s == query4_udp2 or s == query6_udp2:
+ if s == query4_udp1 or s == query6_udp1:
+ print(
+ "UDP Query received on %s"
+ % (ip4_addr1 if s == query4_udp1 else ip6_addr1),
+ end=" ",
+ )
+ if s == query4_udp2 or s == query6_udp2:
+ print(
+ "UDP Query received on %s"
+ % (ip4_addr2 if s == query4_udp2 else ip6_addr2),
+ end=" ",
+ )
+ ns10 = True
+ # Handle incoming queries
+ msg = s.recvfrom(65535)
+ dopass2 = False
+ rsp = create_response(msg[0], False, True, ns10)
+ print(dns.rcode.to_text(rsp.rcode()))
+ s.sendto(rsp.to_wire(), msg[1])
+ if dopass2:
+ print("Sending second UDP response without TSIG", end=" ")
+ rsp = create_response(msg[0], False, False, ns10)
+ s.sendto(rsp.to_wire(), msg[1])
+ print(dns.rcode.to_text(rsp.rcode()))
+
+ if s == query4_tcp1 or s == query6_tcp1 or s == query4_tcp2 or s == query6_tcp2:
+ try:
+ (cs, _) = s.accept()
+ if s == query4_tcp1 or s == query6_tcp1:
+ print(
+ "TCP Query received on %s"
+ % (ip4_addr1 if s == query4_tcp1 else ip6_addr1),
+ end=" ",
+ )
+ if s == query4_tcp2 or s == query6_tcp2:
+ print(
+ "TCP Query received on %s"
+ % (ip4_addr2 if s == query4_tcp2 else ip6_addr2),
+ end=" ",
+ )
+ ns10 = True
+ # get TCP message length
+ buf = cs.recv(2)
+ length = struct.unpack(">H", buf[:2])[0]
+ # grep DNS message
+ msg = cs.recv(length)
+ rsp = create_response(msg, True, True, ns10)
+ print(dns.rcode.to_text(rsp.rcode()))
+ wire = rsp.to_wire()
+ cs.send(struct.pack(">H", len(wire)))
+ cs.send(wire)
+ cs.close()
+ except s.timeout:
+ pass
+ if not running:
+ break
diff --git a/bin/tests/system/cookie/bad-cookie-badaes.conf b/bin/tests/system/cookie/bad-cookie-badaes.conf
new file mode 100644
index 0000000..7d8cfe3
--- /dev/null
+++ b/bin/tests/system/cookie/bad-cookie-badaes.conf
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ cookie-algorithm aes;
+ cookie-secret "ebc7701beabb4a40c57d140eeb6733faaa"; // 136 bits
+};
diff --git a/bin/tests/system/cookie/bad-cookie-badhex.conf b/bin/tests/system/cookie/bad-cookie-badhex.conf
new file mode 100644
index 0000000..43c11ad
--- /dev/null
+++ b/bin/tests/system/cookie/bad-cookie-badhex.conf
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ cookie-secret "012345678901234567890123456789012345678901234567890123456789012";
+};
diff --git a/bin/tests/system/cookie/bad-cookie-badsiphash24.conf b/bin/tests/system/cookie/bad-cookie-badsiphash24.conf
new file mode 100644
index 0000000..25ff78f
--- /dev/null
+++ b/bin/tests/system/cookie/bad-cookie-badsiphash24.conf
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ cookie-algorithm siphash24;
+ cookie-secret "ebc7701beabb4a40c57d140eeb6733faaabbccdd"; // 160 bits
+};
diff --git a/bin/tests/system/cookie/bad-cookie-toolong.conf b/bin/tests/system/cookie/bad-cookie-toolong.conf
new file mode 100644
index 0000000..5ea67b9
--- /dev/null
+++ b/bin/tests/system/cookie/bad-cookie-toolong.conf
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ cookie-secret "01234567890123456789012345678901234567890123456789012345678901234567890";
+};
diff --git a/bin/tests/system/cookie/clean.sh b/bin/tests/system/cookie/clean.sh
new file mode 100644
index 0000000..2c10757
--- /dev/null
+++ b/bin/tests/system/cookie/clean.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# 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 https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+rm -f ns*/named.conf
+rm -f dig.out.*
+rm -f named.run.*
+rm -f rndc.out.*
+rm -f ns1/named_dump.db*
+rm -f ns*/named.memstats
+rm -f ns*/named.run
+rm -f ns*/named.lock
+rm -f ns*/managed-keys.bind*
+rm -f ns*/named.run.prev
+rm -f ans*/ans.run ans*/ans.log ans*/query.log
diff --git a/bin/tests/system/cookie/good-cookie-aes.conf b/bin/tests/system/cookie/good-cookie-aes.conf
new file mode 100644
index 0000000..97a6f67
--- /dev/null
+++ b/bin/tests/system/cookie/good-cookie-aes.conf
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ cookie-algorithm aes;
+ cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits
+};
diff --git a/bin/tests/system/cookie/good-cookie-siphash24.conf b/bin/tests/system/cookie/good-cookie-siphash24.conf
new file mode 100644
index 0000000..c937d71
--- /dev/null
+++ b/bin/tests/system/cookie/good-cookie-siphash24.conf
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ cookie-algorithm siphash24;
+ cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits
+};
diff --git a/bin/tests/system/cookie/ns1/example.db b/bin/tests/system/cookie/ns1/example.db
new file mode 100644
index 0000000..75a6d3c
--- /dev/null
+++ b/bin/tests/system/cookie/ns1/example.db
@@ -0,0 +1,24 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; 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 https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+@ SOA ns1 hostmaster.isc.org. 1 600 600 1200 600
+@ NS ns1
+ns1 A 10.53.0.1
+large TXT ( large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large )
diff --git a/bin/tests/system/cookie/ns1/named.conf.in b/bin/tests/system/cookie/ns1/named.conf.in
new file mode 100644
index 0000000..129a9b1
--- /dev/null
+++ b/bin/tests/system/cookie/ns1/named.conf.in
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://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;
+};
+
+key foo {
+ secret "aaaaaaaaaaaa";
+ algorithm hmac-sha256;
+};
+
+server 10.53.0.10 {
+ keys foo;
+};
+
+controls {
+ inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+ query-source address 10.53.0.1 dscp 1;
+ notify-source 10.53.0.1 dscp 2;
+ transfer-source 10.53.0.1 dscp 3;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.1; };
+ listen-on-v6 { none; };
+ recursion yes;
+ dnssec-validation yes;
+ deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; }
+ except-from { "example.org"; };
+ deny-answer-aliases { "example.org"; }
+ except-from { "goodcname.example.net";
+ "gooddname.example.net"; };
+ allow-query {!10.53.0.8; any; };
+ send-cookie yes;
+ nocookie-udp-size 512;
+};
+
+zone "." {
+ type hint;
+ file "root.hint";
+};
+
+zone "example" {
+ type primary;
+ file "example.db";
+};
diff --git a/bin/tests/system/cookie/ns1/root.hint b/bin/tests/system/cookie/ns1/root.hint
new file mode 100644
index 0000000..993227d
--- /dev/null
+++ b/bin/tests/system/cookie/ns1/root.hint
@@ -0,0 +1,14 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; 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 https://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/ns2/named.conf.in b/bin/tests/system/cookie/ns2/named.conf.in
new file mode 100644
index 0000000..ef08125
--- /dev/null
+++ b/bin/tests/system/cookie/ns2/named.conf.in
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ query-source address 10.53.0.2 dscp 1;
+ notify-source 10.53.0.2 dscp 2;
+ transfer-source 10.53.0.2 dscp 3;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.2; };
+ listen-on-v6 { none; };
+ recursion no;
+ dnssec-validation no;
+ send-cookie yes;
+ nocookie-udp-size 512;
+};
+
+zone "." {
+ type primary;
+ file "root.db";
+};
diff --git a/bin/tests/system/cookie/ns2/root.db b/bin/tests/system/cookie/ns2/root.db
new file mode 100644
index 0000000..533ab88
--- /dev/null
+++ b/bin/tests/system/cookie/ns2/root.db
@@ -0,0 +1,28 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; 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 https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+@ SOA a.root-servers.nil. hostmaster.isc.org. 1 600 600 1200 600
+@ NS a.root-servers.nil.
+a.root-servers.nil. A 10.53.0.2
+large.xxx TXT ( large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large )
+tld. NS ns.tld.
+ns.tld A 10.53.0.9
+tsig. NS ns.tsig.
+ns.tsig A 10.53.0.10
diff --git a/bin/tests/system/cookie/ns3/named.conf.in b/bin/tests/system/cookie/ns3/named.conf.in
new file mode 100644
index 0000000..8b2ad79
--- /dev/null
+++ b/bin/tests/system/cookie/ns3/named.conf.in
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://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.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+ query-source address 10.53.0.3 dscp 1;
+ notify-source 10.53.0.3 dscp 2;
+ transfer-source 10.53.0.3 dscp 3;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.3; };
+ listen-on-v6 { none; };
+ recursion yes;
+ dnssec-validation yes;
+ deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; }
+ except-from { "example.org"; };
+ deny-answer-aliases { "example.org"; }
+ except-from { "goodcname.example.net";
+ "gooddname.example.net"; };
+ allow-query {!10.53.0.8; any; };
+ send-cookie yes;
+ nocookie-udp-size 512;
+ require-server-cookie yes;
+};
+
+zone "." {
+ type hint;
+ file "root.hint";
+};
+
+zone "example" {
+ type primary;
+ file "example.db";
+};
diff --git a/bin/tests/system/cookie/ns3/root.hint b/bin/tests/system/cookie/ns3/root.hint
new file mode 100644
index 0000000..993227d
--- /dev/null
+++ b/bin/tests/system/cookie/ns3/root.hint
@@ -0,0 +1,14 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; 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 https://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/ns4/named.conf.in b/bin/tests/system/cookie/ns4/named.conf.in
new file mode 100644
index 0000000..0b14272
--- /dev/null
+++ b/bin/tests/system/cookie/ns4/named.conf.in
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://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;
+ dnssec-validation yes;
+ cookie-algorithm siphash24;
+ cookie-secret "569d36a6cc27d6bf55502183302ba352";
+ 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
index 0000000..993227d
--- /dev/null
+++ b/bin/tests/system/cookie/ns4/root.hint
@@ -0,0 +1,14 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; 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 https://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
index 0000000..2aabc5a
--- /dev/null
+++ b/bin/tests/system/cookie/ns5/named.conf.in
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://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;
+ dnssec-validation yes;
+ cookie-algorithm siphash24;
+ cookie-secret "569d36a6cc27d6bf55502183302ba352";
+ cookie-secret "6b300e27a0db46d4b046e4189790fa7d";
+ 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
index 0000000..993227d
--- /dev/null
+++ b/bin/tests/system/cookie/ns5/root.hint
@@ -0,0 +1,14 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; 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 https://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
index 0000000..2bf3793
--- /dev/null
+++ b/bin/tests/system/cookie/ns6/named.conf.in
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://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;
+ dnssec-validation yes;
+ cookie-algorithm siphash24;
+ cookie-secret "6b300e27a0db46d4b046e4189790fa7d";
+ 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
index 0000000..993227d
--- /dev/null
+++ b/bin/tests/system/cookie/ns6/root.hint
@@ -0,0 +1,14 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; 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 https://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/ns7/named.conf.in b/bin/tests/system/cookie/ns7/named.conf.in
new file mode 100644
index 0000000..c9518ae
--- /dev/null
+++ b/bin/tests/system/cookie/ns7/named.conf.in
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ query-source address 10.53.0.7 dscp 1;
+ notify-source 10.53.0.7 dscp 2;
+ transfer-source 10.53.0.7 dscp 3;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.7; };
+ listen-on-v6 { none; };
+ recursion no;
+ answer-cookie no;
+ send-cookie yes;
+ nocookie-udp-size 512;
+};
+
+zone "." {
+ type primary;
+ file "root.db";
+};
diff --git a/bin/tests/system/cookie/ns7/root.db b/bin/tests/system/cookie/ns7/root.db
new file mode 100644
index 0000000..39a63da
--- /dev/null
+++ b/bin/tests/system/cookie/ns7/root.db
@@ -0,0 +1,24 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; 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 https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+@ SOA a.root-servers.nil. hostmaster.isc.org. 1 600 600 1200 600
+@ NS a.root-servers.nil.
+a.root-servers.nil. A 10.53.0.2
+large.xxx TXT ( large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large )
diff --git a/bin/tests/system/cookie/ns8/example.db b/bin/tests/system/cookie/ns8/example.db
new file mode 100644
index 0000000..7fa64d6
--- /dev/null
+++ b/bin/tests/system/cookie/ns8/example.db
@@ -0,0 +1,13 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; 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 https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+@ 3600 SOA . . 0 0 0 0 0
+@ 3600 NS .
diff --git a/bin/tests/system/cookie/ns8/named.conf.in b/bin/tests/system/cookie/ns8/named.conf.in
new file mode 100644
index 0000000..1a9697b
--- /dev/null
+++ b/bin/tests/system/cookie/ns8/named.conf.in
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://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.8 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+ query-source address 10.53.0.8;
+ notify-source 10.53.0.8;
+ transfer-source 10.53.0.8;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.8; };
+ listen-on-v6 { none; };
+ dnssec-validation yes;
+ rate-limit {};
+ require-server-cookie yes;
+};
+
+zone "example" {
+ type primary;
+ file "example.db";
+};
diff --git a/bin/tests/system/cookie/prereq.sh b/bin/tests/system/cookie/prereq.sh
new file mode 100644
index 0000000..ad8bbe3
--- /dev/null
+++ b/bin/tests/system/cookie/prereq.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# 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 https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+# shellcheck source=conf.sh
+. "$SYSTEMTESTTOP/conf.sh"
+
+set -e
+
+if test -n "$PYTHON"
+then
+ if $PYTHON -c "import dns" 2> /dev/null
+ then
+ :
+ else
+ echo_i "This test requires the dnspython module." >&2
+ exit 1
+ fi
+else
+ echo_i "This test requires Python and the dnspython module." >&2
+ exit 1
+fi
+
+exit 0
diff --git a/bin/tests/system/cookie/setup.sh b/bin/tests/system/cookie/setup.sh
new file mode 100644
index 0000000..c679d03
--- /dev/null
+++ b/bin/tests/system/cookie/setup.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# 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 https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.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
+copy_setports ns7/named.conf.in ns7/named.conf
+copy_setports ns8/named.conf.in ns8/named.conf
diff --git a/bin/tests/system/cookie/tests.sh b/bin/tests/system/cookie/tests.sh
new file mode 100755
index 0000000..29ace6f
--- /dev/null
+++ b/bin/tests/system/cookie/tests.sh
@@ -0,0 +1,515 @@
+#!/bin/sh
+
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# 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 https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+DIGOPTS="-p ${PORT}"
+RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
+
+status=0
+n=0
+
+getcookie() {
+ awk '$2 == "COOKIE:" {
+ print $3;
+ }' < $1 | tr -d '\r'
+}
+
+fullcookie() {
+ awk 'BEGIN { n = 0 }
+ // { v[n++] = length(); }
+ END { print (v[1] == v[2]); }'
+}
+
+havetc() {
+ grep 'flags:.* tc[^;]*;' $1 > /dev/null
+}
+
+for bad in bad*.conf
+do
+ n=`expr $n + 1`
+ echo_i "checking that named-checkconf detects error in $bad ($n)"
+ ret=0
+ $CHECKCONF $bad > /dev/null 2>&1 && ret=1
+ if [ $ret != 0 ]; then echo_i "failed"; fi
+ status=`expr $status + $ret`
+done
+
+for good in good*.conf
+do
+ n=`expr $n + 1`
+ echo_i "checking that named-checkconf detects accepts $good ($n)"
+ ret=0
+ $CHECKCONF $good > /dev/null 2>&1 || ret=1
+ if [ $ret != 0 ]; then echo_i "failed"; fi
+ status=`expr $status + $ret`
+done
+
+n=`expr $n + 1`
+echo_i "checking RCODE=FORMERR to query without question section and without COOKIE option ($n)"
+ret=0
+$DIG $DIGOPTS +qr +header-only +nocookie version.bind txt ch @10.53.0.1 > dig.out.test$n
+grep COOKIE: dig.out.test$n > /dev/null && ret=1
+grep "status: FORMERR" 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 "checking RCODE=NOERROR to query without question section and with COOKIE option ($n)"
+ret=0
+$DIG $DIGOPTS +qr +header-only +cookie version.bind txt ch @10.53.0.1 > dig.out.test$n
+grep COOKIE: 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 "checking COOKIE token is returned to empty COOKIE option ($n)"
+ret=0
+$DIG $DIGOPTS +cookie version.bind txt ch @10.53.0.1 > dig.out.test$n
+grep COOKIE: 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 "checking COOKIE is not returned when answer-cookie is false ($n)"
+ret=0
+$DIG $DIGOPTS +cookie version.bind txt ch @10.53.0.7 > dig.out.test$n
+grep COOKIE: 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 "checking response size without COOKIE ($n)"
+ret=0
+$DIG $DIGOPTS large.example txt @10.53.0.1 +ignore > dig.out.test$n
+havetc dig.out.test$n || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "checking response size without valid COOKIE ($n)"
+ret=0
+$DIG $DIGOPTS +cookie large.example txt @10.53.0.1 +ignore > dig.out.test$n
+havetc dig.out.test$n || ret=1
+grep "; COOKIE:.*(good)" 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 "checking response size with COOKIE ($n)"
+ret=0
+$DIG $DIGOPTS +cookie large.example txt @10.53.0.1 > dig.out.test$n.l
+cookie=`getcookie dig.out.test$n.l`
+$DIG $DIGOPTS +qr +cookie=$cookie large.example txt @10.53.0.1 +ignore > dig.out.test$n
+havetc dig.out.test$n && ret=1
+grep "; COOKIE:.*(good)" 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 "checking response size with COOKIE recursive ($n)"
+ret=0
+$DIG $DIGOPTS +qr +cookie=$cookie large.xxx txt @10.53.0.1 +ignore > dig.out.test$n
+havetc dig.out.test$n && ret=1
+grep "; COOKIE:.*(good)" 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 "checking COOKIE is learnt for TCP retry ($n)"
+ret=0
+$DIG $DIGOPTS +qr +cookie large.example txt @10.53.0.1 > dig.out.test$n
+linecount=`getcookie dig.out.test$n | wc -l`
+if [ $linecount != 3 ]; then ret=1; fi
+checkfull=`getcookie dig.out.test$n | fullcookie`
+if [ $checkfull != 1 ]; then ret=1; fi
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "checking for COOKIE value in adb ($n)"
+ret=0
+rndc_dumpdb ns1
+grep "10.53.0.2.*\[cookie=" ns1/named_dump.db.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "checking require-server-cookie default (no) ($n)"
+ret=0
+$DIG $DIGOPTS +qr +cookie +nobadcookie soa @10.53.0.1 > dig.out.test$n
+grep BADCOOKIE dig.out.test$n > /dev/null && ret=1
+linecount=`getcookie dig.out.test$n | wc -l`
+if [ $linecount != 2 ]; then ret=1; fi
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "checking require-server-cookie yes ($n)"
+ret=0
+$DIG $DIGOPTS +qr +cookie +nobadcookie soa @10.53.0.3 > dig.out.test$n
+grep "flags: qr[^;]* aa[ ;]" dig.out.test$n > /dev/null && ret=1
+grep "flags: qr[^;]* ad[ ;]" dig.out.test$n > /dev/null && ret=1
+grep BADCOOKIE dig.out.test$n > /dev/null || ret=1
+linecount=`getcookie dig.out.test$n | wc -l`
+if [ $linecount != 2 ]; then ret=1; fi
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "checking require-server-cookie yes with rate-limit ($n)"
+ret=0
+$DIG $DIGOPTS +qr +cookie +nobadcookie soa example @10.53.0.8 > dig.out.test$n
+grep "flags: qr[^;]* ad[ ;]" dig.out.test$n > /dev/null && ret=1
+grep BADCOOKIE dig.out.test$n > /dev/null || ret=1
+linecount=`getcookie dig.out.test$n | wc -l`
+if [ $linecount != 2 ]; then ret=1; fi
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "send undersized cookie ($n)"
+ret=0
+$DIG $DIGOPTS +qr +cookie=000000 soa @10.53.0.1 > dig.out.test$n || ret=1
+grep "status: FORMERR" 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 "send oversized for named cookie ($n)"
+ret=0
+$DIG $DIGOPTS +qr +cookie=${cookie}00 soa @10.53.0.1 > dig.out.test$n || ret=1
+grep "COOKIE: [a-f0-9]* (good)" dig.out.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "send oversized for named cookie with server requiring a good cookie ($n)"
+ret=0
+$DIG $DIGOPTS +qr +cookie=${cookie}00 soa @10.53.0.3 > dig.out.test$n || ret=1
+grep "COOKIE: [a-f0-9]* (good)" dig.out.test$n > /dev/null 2>&1 || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+#
+# Test shared cookie-secret support.
+#
+# NS4 has cookie-secret "569d36a6cc27d6bf55502183302ba352";
+#
+# NS5 has cookie-secret "569d36a6cc27d6bf55502183302ba352";
+# NS5 has cookie-secret "6b300e27a0db46d4b046e4189790fa7d"; (alternate)
+#
+# NS6 has cookie-secret "6b300e27a0db46d4b046e4189790fa7d";
+#
+# 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`
+
+n=`expr $n + 1`
+echo_i "check that test server is correctly configured ($n)"
+ret=0
+pat="; COOKIE: ................................ (good)"
+#UDP
+$DIG $DIGOPTS @10.53.0.9 +notcp tld > dig.out.test$n.1
+grep "status: NOERROR" dig.out.test$n.1 > /dev/null || ret=1
+grep "$pat" dig.out.test$n.1 > /dev/null || ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.1 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.1 > /dev/null && ret=1
+grep ";; TSIG PSEUDOSECTION:" dig.out.test$n.1 > /dev/null && ret=1
+
+$DIG $DIGOPTS @10.53.0.9 +notcp tcponly.tld > dig.out.test$n.2
+grep "status: NOERROR" dig.out.test$n.2 > /dev/null || ret=1
+grep "; COOKIE:" dig.out.test$n.2 > /dev/null && ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.2 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.2 > /dev/null || ret=1
+grep ";; TSIG PSEUDOSECTION:" dig.out.test$n.1 > /dev/null && ret=1
+
+$DIG $DIGOPTS @10.53.0.9 +notcp nocookie.tld > dig.out.test$n.3
+grep "status: NOERROR" dig.out.test$n.3 > /dev/null || ret=1
+grep "; COOKIE:" dig.out.test$n.3 > /dev/null && ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.3 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.3 > /dev/null || ret=1
+grep ";; TSIG PSEUDOSECTION:" dig.out.test$n.1 > /dev/null && ret=1
+
+$DIG $DIGOPTS @10.53.0.9 +notcp withtsig.tld > dig.out.test$n.4
+grep "status: NOERROR" dig.out.test$n.4 > /dev/null || ret=1
+grep "; COOKIE:" dig.out.test$n.4 > /dev/null && ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.4 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.4 > /dev/null || ret=1
+grep ";; TSIG PSEUDOSECTION:" dig.out.test$n.4 > /dev/null || ret=1
+
+#TCP
+$DIG $DIGOPTS @10.53.0.9 +tcp tld > dig.out.test$n.5
+grep "status: NOERROR" dig.out.test$n.5 > /dev/null || ret=1
+grep "$pat" dig.out.test$n.5 > /dev/null || ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.5 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.5 > /dev/null && ret=1
+grep ";; TSIG PSEUDOSECTION:" dig.out.test$n.1 > /dev/null && ret=1
+
+$DIG $DIGOPTS @10.53.0.9 +tcp tcponly.tld > dig.out.test$n.6
+grep "status: NOERROR" dig.out.test$n.6 > /dev/null || ret=1
+grep "$pat" dig.out.test$n.6 > /dev/null || ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.6 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.6 > /dev/null && ret=1
+grep ";; TSIG PSEUDOSECTION:" dig.out.test$n.1 > /dev/null && ret=1
+
+$DIG $DIGOPTS @10.53.0.9 +tcp nocookie.tld > dig.out.test$n.7
+grep "status: NOERROR" dig.out.test$n.7 > /dev/null || ret=1
+grep "; COOKIE:" dig.out.test$n.7 > /dev/null && ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.7 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.7 > /dev/null && ret=1
+grep ";; TSIG PSEUDOSECTION:" dig.out.test$n.1 > /dev/null && ret=1
+
+$DIG $DIGOPTS @10.53.0.9 +tcp withtsig.tld > dig.out.test$n.8
+grep "status: NOERROR" dig.out.test$n.8 > /dev/null || ret=1
+grep "$pat" dig.out.test$n.8 > /dev/null || ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.8 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.8 > /dev/null && ret=1
+grep ";; TSIG PSEUDOSECTION:" dig.out.test$n.8 > /dev/null && ret=1
+
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "check that spoofed response is dropped when we have a server cookie ($n)"
+ret=0
+msg="missing expected cookie from"
+pat='10\.53\.0\.9 .*\[cookie=................................\] \[ttl'
+# prime EDNS COOKIE state
+$DIG $DIGOPTS @10.53.0.1 tld > dig.out.test$n.1
+grep "status: NOERROR" dig.out.test$n.1 > /dev/null || ret=1
+rndc_dumpdb ns1
+grep "$pat" ns1/named_dump.db.test$n > /dev/null || ret=1
+# spoofed response contains 10.53.0.10
+nextpart ns1/named.run >/dev/null
+$DIG $DIGOPTS @10.53.0.1 tcponly.tld > dig.out.test$n.2
+wait_for_log 5 "$msg" ns1/named.run || ret=1
+grep "status: NOERROR" dig.out.test$n.2 > /dev/null || ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.2 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.2 > /dev/null && ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "check that gracefully handle server disabling DNS COOKIE we have a server cookie ($n)"
+ret=0
+msg="missing expected cookie from"
+pat='10\.53\.0\.9 .*\[cookie=................................\] \[ttl'
+# prime EDNS COOKIE state
+$DIG $DIGOPTS @10.53.0.1 tld > dig.out.test$n.1
+grep "status: NOERROR" dig.out.test$n.1 > /dev/null || ret=1
+rndc_dumpdb ns1
+grep "$pat" ns1/named_dump.db.test$n > /dev/null || ret=1
+# check the disabled server response
+nextpart ns1/named.run >/dev/null
+$DIG $DIGOPTS @10.53.0.1 nocookie.tld > dig.out.test$n.2
+wait_for_log 5 "$msg" ns1/named.run || ret=1
+grep "status: NOERROR" dig.out.test$n.2 > /dev/null || ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.2 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.2 > /dev/null && ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "check that spoofed response with a TSIG is dropped when we have a server cookie ($n)"
+ret=0
+pat='10\.53\.0\.9 .*\[cookie=................................\] \[ttl'
+# prime EDNS COOKIE state
+$DIG $DIGOPTS @10.53.0.1 tld > dig.out.test$n.1
+grep "status: NOERROR" dig.out.test$n.1 > /dev/null || ret=1
+rndc_dumpdb ns1
+grep "$pat" ns1/named_dump.db.test$n > /dev/null || ret=1
+# spoofed response contains 10.53.0.10
+nextpart ns1/named.run >/dev/null
+$DIG $DIGOPTS @10.53.0.1 withtsig.tld > dig.out.test$n.2
+grep "status: NOERROR" dig.out.test$n.2 > /dev/null || ret=1
+grep 'A.10\.53\.0\.9' dig.out.test$n.2 > /dev/null || ret=1
+grep 'A.10\.53\.0\.10' dig.out.test$n.2 > /dev/null && ret=1
+nextpart ns1/named.run > named.run.test$n
+count=$(grep -c ') [0-9][0-9]* NOERROR 0' named.run.test$n)
+test $count -eq 1 || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+if $PYTHON -c '
+import dns.version, sys;
+if dns.version.MAJOR > 1: sys.exit(0);
+if dns.version.MAJOR == 1 and dns.version.MINOR >= 16: sys.exit(0);
+sys.exit(1)'
+then
+ n=`expr $n + 1`
+ echo_i "check that TSIG test server is correctly configured ($n)"
+ ret=0
+ pat="; COOKIE: ................................ (good)"
+ key=hmac-sha256:foo:aaaaaaaaaaaa
+ #UDP
+ $DIG $DIGOPTS @10.53.0.10 -y $key +notcp tsig. > dig.out.test$n.1
+ grep "status: NOERROR" dig.out.test$n.1 > /dev/null || ret=1
+ grep "$pat" dig.out.test$n.1 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.9' dig.out.test$n.1 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.10' dig.out.test$n.1 > /dev/null && ret=1
+ grep 'TSIG.*NOERROR' dig.out.test$n.1 > /dev/null || ret=1
+
+ $DIG $DIGOPTS @10.53.0.10 -y $key +notcp tcponly.tsig > dig.out.test$n.2
+ grep "status: NOERROR" dig.out.test$n.2 > /dev/null || ret=1
+ grep "; COOKIE:" dig.out.test$n.2 > /dev/null && ret=1
+ grep 'A.10\.53\.0\.9' dig.out.test$n.2 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.10' dig.out.test$n.2 > /dev/null || ret=1
+ grep 'TSIG.*NOERROR' dig.out.test$n.1 > /dev/null || ret=1
+
+ $DIG $DIGOPTS @10.53.0.10 -y $key +notcp nocookie.tsig > dig.out.test$n.3
+ grep "status: NOERROR" dig.out.test$n.3 > /dev/null || ret=1
+ grep "; COOKIE:" dig.out.test$n.3 > /dev/null && ret=1
+ grep 'A.10\.53\.0\.9' dig.out.test$n.3 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.10' dig.out.test$n.3 > /dev/null || ret=1
+ grep 'TSIG.*NOERROR' dig.out.test$n.1 > /dev/null || ret=1
+
+ #TCP
+ $DIG $DIGOPTS @10.53.0.10 -y $key +tcp tsig. > dig.out.test$n.5
+ grep "status: NOERROR" dig.out.test$n.5 > /dev/null || ret=1
+ grep "$pat" dig.out.test$n.5 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.9' dig.out.test$n.5 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.10' dig.out.test$n.5 > /dev/null && ret=1
+ grep 'TSIG.*NOERROR' dig.out.test$n.1 > /dev/null || ret=1
+
+ $DIG $DIGOPTS @10.53.0.10 -y $key +tcp tcponly.tsig > dig.out.test$n.6
+ grep "status: NOERROR" dig.out.test$n.6 > /dev/null || ret=1
+ grep "$pat" dig.out.test$n.6 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.9' dig.out.test$n.6 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.10' dig.out.test$n.6 > /dev/null && ret=1
+ grep 'TSIG.*NOERROR' dig.out.test$n.1 > /dev/null || ret=1
+
+ $DIG $DIGOPTS @10.53.0.10 -y $key +tcp nocookie.tsig > dig.out.test$n.7
+ grep "status: NOERROR" dig.out.test$n.7 > /dev/null || ret=1
+ grep "; COOKIE:" dig.out.test$n.7 > /dev/null && ret=1
+ grep 'A.10\.53\.0\.9' dig.out.test$n.7 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.10' dig.out.test$n.7 > /dev/null && ret=1
+ grep 'TSIG.*NOERROR' dig.out.test$n.1 > /dev/null || ret=1
+
+ if [ $ret != 0 ]; then echo_i "failed"; fi
+ status=`expr $status + $ret`
+
+ n=`expr $n + 1`
+ echo_i "check that missing COOKIE with a valid TSIG signed response does not trigger TCP fallback ($n)"
+ ret=0
+ pat='10\.53\.0\.10 .*\[cookie=................................\] \[ttl'
+ # prime EDNS COOKIE state
+ $DIG $DIGOPTS @10.53.0.1 tsig. > dig.out.test$n.1
+ grep "status: NOERROR" dig.out.test$n.1 > /dev/null || ret=1
+ rndc_dumpdb ns1
+ grep "$pat" ns1/named_dump.db.test$n > /dev/null || ret=1
+ # check the disabled server response
+ nextpart ns1/named.run >/dev/null
+ $DIG $DIGOPTS @10.53.0.1 nocookie.tsig > dig.out.test$n.2
+ grep "status: NOERROR" dig.out.test$n.2 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.9' dig.out.test$n.2 > /dev/null || ret=1
+ grep 'A.10\.53\.0\.10' dig.out.test$n.2 > /dev/null || ret=1
+ nextpart ns1/named.run > named.run.test$n
+ count=$(grep -c ') [0-9][0-9]* NOERROR 0' named.run.test$n)
+ test $count -eq 2 || ret=1
+ if [ $ret != 0 ]; then echo_i "failed"; fi
+ status=`expr $status + $ret`
+fi
+
+echo_i "exit status: $status"
+[ $status -eq 0 ] || exit 1