Blame SOURCES/bind-9.16-CVE-2021-25220-test.patch

dc3c8a
From bd8fdeb2d1ece6db6dfe9fdc024f3a81440c1c0c Mon Sep 17 00:00:00 2001
dc3c8a
From: Mark Andrews <marka@isc.org>
dc3c8a
Date: Tue, 18 Jan 2022 00:19:47 +1100
dc3c8a
Subject: [PATCH] Add tests for forwarder cache poisoning scenarios
dc3c8a
dc3c8a
- Check that an NS in an authority section returned from a forwarder
dc3c8a
  which is above the name in a configured "forward first" or "forward
dc3c8a
  only" zone (i.e., net/NS in a response from a forwarder configured for
dc3c8a
  local.net) is not cached.
dc3c8a
- Test that a DNAME for a parent domain will not be cached when sent
dc3c8a
  in a response from a forwarder configured to answer for a child.
dc3c8a
- Check that glue is rejected if its name falls below that of zone
dc3c8a
  configured locally.
dc3c8a
- Check that an extra out-of-bailiwick data in the answer section is
dc3c8a
  not cached (this was already working correctly, but was not explicitly
dc3c8a
  tested before).
dc3c8a
dc3c8a
(cherry picked from commit bf3fffff67e1de78e9387a93674d471bf4291604)
dc3c8a
(cherry picked from commit 59d1eb3ff810145c8098a0a4fbf93ef4380ad739)
dc3c8a
---
dc3c8a
 bin/tests/system/forward/ans11/ans.py         | 136 ++++++++++++++++++
dc3c8a
 bin/tests/system/forward/clean.sh             |   2 +
dc3c8a
 bin/tests/system/forward/ns1/diditwork.net.db |  22 +++
dc3c8a
 bin/tests/system/forward/ns1/named.conf.in    |  20 +++
dc3c8a
 bin/tests/system/forward/ns1/net.example.lll  |  15 ++
dc3c8a
 bin/tests/system/forward/ns1/spoofed.net.db   |  22 +++
dc3c8a
 bin/tests/system/forward/ns1/sub.local.net.db |  22 +++
dc3c8a
 bin/tests/system/forward/ns10/fakenet.zone    |  17 +++
dc3c8a
 bin/tests/system/forward/ns10/fakenet2.zone   |  15 ++
dc3c8a
 .../system/forward/ns10/fakesublocalnet.zone  |  15 ++
dc3c8a
 .../system/forward/ns10/fakesublocaltld.zone  |  15 ++
dc3c8a
 bin/tests/system/forward/ns10/named.conf.in   |  53 +++++++
dc3c8a
 bin/tests/system/forward/ns10/net.example.lll |  15 ++
dc3c8a
 bin/tests/system/forward/ns10/spoofednet.zone |  16 +++
dc3c8a
 bin/tests/system/forward/ns2/tld.db           |   6 +
dc3c8a
 bin/tests/system/forward/ns4/named.conf.in    |   5 +
dc3c8a
 bin/tests/system/forward/ns4/sibling.tld.db   |  22 +++
dc3c8a
 bin/tests/system/forward/ns8/named.conf.in    |   5 +
dc3c8a
 bin/tests/system/forward/ns8/sub.local.tld.db |  15 ++
dc3c8a
 bin/tests/system/forward/ns9/local.net.db     |  16 +++
dc3c8a
 bin/tests/system/forward/ns9/local.tld.db     |  15 ++
dc3c8a
 bin/tests/system/forward/ns9/named1.conf.in   |  67 +++++++++
dc3c8a
 bin/tests/system/forward/ns9/named2.conf.in   |  70 +++++++++
dc3c8a
 bin/tests/system/forward/ns9/named3.conf.in   |  50 +++++++
dc3c8a
 bin/tests/system/forward/ns9/named4.conf.in   |  47 ++++++
dc3c8a
 bin/tests/system/forward/ns9/root.db          |  13 ++
dc3c8a
 bin/tests/system/forward/setup.sh             |   2 +
dc3c8a
 bin/tests/system/forward/tests.sh             | 122 ++++++++++++++++
dc3c8a
 bin/tests/system/ifconfig.sh                  |   8 +-
dc3c8a
 29 files changed, 844 insertions(+), 4 deletions(-)
dc3c8a
 create mode 100644 bin/tests/system/forward/ans11/ans.py
dc3c8a
 create mode 100644 bin/tests/system/forward/ns1/diditwork.net.db
dc3c8a
 create mode 100644 bin/tests/system/forward/ns1/net.example.lll
dc3c8a
 create mode 100644 bin/tests/system/forward/ns1/spoofed.net.db
dc3c8a
 create mode 100644 bin/tests/system/forward/ns1/sub.local.net.db
dc3c8a
 create mode 100644 bin/tests/system/forward/ns10/fakenet.zone
dc3c8a
 create mode 100644 bin/tests/system/forward/ns10/fakenet2.zone
dc3c8a
 create mode 100644 bin/tests/system/forward/ns10/fakesublocalnet.zone
dc3c8a
 create mode 100644 bin/tests/system/forward/ns10/fakesublocaltld.zone
dc3c8a
 create mode 100644 bin/tests/system/forward/ns10/named.conf.in
dc3c8a
 create mode 100644 bin/tests/system/forward/ns10/net.example.lll
dc3c8a
 create mode 100644 bin/tests/system/forward/ns10/spoofednet.zone
dc3c8a
 create mode 100644 bin/tests/system/forward/ns4/sibling.tld.db
dc3c8a
 create mode 100644 bin/tests/system/forward/ns8/sub.local.tld.db
dc3c8a
 create mode 100644 bin/tests/system/forward/ns9/local.net.db
dc3c8a
 create mode 100644 bin/tests/system/forward/ns9/local.tld.db
dc3c8a
 create mode 100644 bin/tests/system/forward/ns9/named1.conf.in
dc3c8a
 create mode 100644 bin/tests/system/forward/ns9/named2.conf.in
dc3c8a
 create mode 100644 bin/tests/system/forward/ns9/named3.conf.in
dc3c8a
 create mode 100644 bin/tests/system/forward/ns9/named4.conf.in
dc3c8a
 create mode 100644 bin/tests/system/forward/ns9/root.db
dc3c8a
dc3c8a
diff --git a/bin/tests/system/forward/ans11/ans.py b/bin/tests/system/forward/ans11/ans.py
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..1d35b3d3f1
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ans11/ans.py
dc3c8a
@@ -0,0 +1,136 @@
dc3c8a
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+#
dc3c8a
+# SPDX-License-Identifier: MPL-2.0
dc3c8a
+#
dc3c8a
+# This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+# License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+#
dc3c8a
+# See the COPYRIGHT file distributed with this work for additional
dc3c8a
+# information regarding copyright ownership.
dc3c8a
+
dc3c8a
+from __future__ import print_function
dc3c8a
+import os
dc3c8a
+import sys
dc3c8a
+import signal
dc3c8a
+import socket
dc3c8a
+import select
dc3c8a
+from datetime import datetime, timedelta
dc3c8a
+import time
dc3c8a
+import functools
dc3c8a
+
dc3c8a
+import dns, dns.message, dns.query, dns.flags
dc3c8a
+from dns.rdatatype import *
dc3c8a
+from dns.rdataclass import *
dc3c8a
+from dns.rcode import *
dc3c8a
+from dns.name import *
dc3c8a
+
dc3c8a
+# Log query to file
dc3c8a
+def logquery(type, qname):
dc3c8a
+    with open("qlog", "a") as f:
dc3c8a
+        f.write("%s %s\n", type, qname)
dc3c8a
+
dc3c8a
+############################################################################
dc3c8a
+# Respond to a DNS query.
dc3c8a
+############################################################################
dc3c8a
+def create_response(msg):
dc3c8a
+    m = dns.message.from_wire(msg)
dc3c8a
+    qname = m.question[0].name.to_text()
dc3c8a
+    rrtype = m.question[0].rdtype
dc3c8a
+    typename = dns.rdatatype.to_text(rrtype)
dc3c8a
+
dc3c8a
+    with open("query.log", "a") as f:
dc3c8a
+        f.write("%s %s\n" % (typename, qname))
dc3c8a
+        print("%s %s" % (typename, qname), end=" ")
dc3c8a
+
dc3c8a
+    r = dns.message.make_response(m)
dc3c8a
+    r.set_rcode(NOERROR)
dc3c8a
+    if rrtype == A:
dc3c8a
+        tld=qname.split('.')[-2] + '.'
dc3c8a
+        ns="local." + tld
dc3c8a
+        r.answer.append(dns.rrset.from_text(qname, 300, IN, A, "10.53.0.11"))
dc3c8a
+        r.answer.append(dns.rrset.from_text(tld, 300, IN, NS, "local." + tld))
dc3c8a
+        r.additional.append(dns.rrset.from_text(ns, 300, IN, A, "10.53.0.11"))
dc3c8a
+    elif rrtype == NS:
dc3c8a
+        r.answer.append(dns.rrset.from_text(qname, 300, IN, NS, "."))
dc3c8a
+    elif rrtype == SOA:
dc3c8a
+        r.answer.append(dns.rrset.from_text(qname, 300, IN, SOA, ". . 0 0 0 0 0"))
dc3c8a
+    else:
dc3c8a
+        r.authority.append(dns.rrset.from_text(qname, 300, IN, SOA, ". . 0 0 0 0 0"))
dc3c8a
+    r.flags |= dns.flags.AA
dc3c8a
+    return r
dc3c8a
+
dc3c8a
+def sigterm(signum, frame):
dc3c8a
+    print ("Shutting down now...")
dc3c8a
+    os.remove('ans.pid')
dc3c8a
+    running = False
dc3c8a
+    sys.exit(0)
dc3c8a
+
dc3c8a
+############################################################################
dc3c8a
+# Main
dc3c8a
+#
dc3c8a
+# Set up responder and control channel, open the pid file, and start
dc3c8a
+# the main loop, listening for queries on the query channel or commands
dc3c8a
+# on the control channel and acting on them.
dc3c8a
+############################################################################
dc3c8a
+ip4 = "10.53.0.11"
dc3c8a
+ip6 = "fd92:7065:b8e:ffff::11"
dc3c8a
+
dc3c8a
+try: port=int(os.environ['PORT'])
dc3c8a
+except: port=5300
dc3c8a
+
dc3c8a
+query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dc3c8a
+query4_socket.bind((ip4, port))
dc3c8a
+havev6 = True
dc3c8a
+try:
dc3c8a
+    query6_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
dc3c8a
+    try:
dc3c8a
+        query6_socket.bind((ip6, port))
dc3c8a
+    except:
dc3c8a
+        query6_socket.close()
dc3c8a
+        havev6 = False
dc3c8a
+except:
dc3c8a
+    havev6 = False
dc3c8a
+signal.signal(signal.SIGTERM, sigterm)
dc3c8a
+
dc3c8a
+f = open('ans.pid', 'w')
dc3c8a
+pid = os.getpid()
dc3c8a
+print (pid, file=f)
dc3c8a
+f.close()
dc3c8a
+
dc3c8a
+running = True
dc3c8a
+
dc3c8a
+print ("Listening on %s port %d" % (ip4, port))
dc3c8a
+if havev6:
dc3c8a
+    print ("Listening on %s port %d" % (ip6, port))
dc3c8a
+print ("Ctrl-c to quit")
dc3c8a
+
dc3c8a
+if havev6:
dc3c8a
+    input = [query4_socket, query6_socket]
dc3c8a
+else:
dc3c8a
+    input = [query4_socket]
dc3c8a
+
dc3c8a
+while running:
dc3c8a
+    try:
dc3c8a
+        inputready, outputready, exceptready = select.select(input, [], [])
dc3c8a
+    except select.error as e:
dc3c8a
+        break
dc3c8a
+    except socket.error as e:
dc3c8a
+        break
dc3c8a
+    except KeyboardInterrupt:
dc3c8a
+        break
dc3c8a
+
dc3c8a
+    for s in inputready:
dc3c8a
+        if s == query4_socket or s == query6_socket:
dc3c8a
+            print ("Query received on %s" %
dc3c8a
+                    (ip4 if s == query4_socket else ip6), end=" ")
dc3c8a
+            # Handle incoming queries
dc3c8a
+            msg = s.recvfrom(65535)
dc3c8a
+            rsp = create_response(msg[0])
dc3c8a
+            if rsp:
dc3c8a
+                print(dns.rcode.to_text(rsp.rcode()))
dc3c8a
+                s.sendto(rsp.to_wire(), msg[1])
dc3c8a
+            else:
dc3c8a
+                print("NO RESPONSE")
dc3c8a
+    if not running:
dc3c8a
+        break
dc3c8a
diff --git a/bin/tests/system/forward/clean.sh b/bin/tests/system/forward/clean.sh
dc3c8a
index bc04eadb2c..b65b092680 100644
dc3c8a
--- a/bin/tests/system/forward/clean.sh
dc3c8a
+++ b/bin/tests/system/forward/clean.sh
dc3c8a
@@ -10,10 +10,12 @@
dc3c8a
 #
dc3c8a
 # Clean up after forward tests.
dc3c8a
 #
dc3c8a
+rm -f ./ans11/query.log
dc3c8a
 rm -f ./dig.out.*
dc3c8a
 rm -f ./*/named.conf
dc3c8a
 rm -f ./*/named.memstats
dc3c8a
 rm -f ./*/named.run ./*/named.run.prev
dc3c8a
+rm -f ./*/named_dump.db
dc3c8a
 rm -f ./ns*/named.lock
dc3c8a
 rm -f ./ns*/managed-keys.bind*
dc3c8a
 rm -f ./ns1/root.db ./ns1/root.db.signed
dc3c8a
diff --git a/bin/tests/system/forward/ns1/diditwork.net.db b/bin/tests/system/forward/ns1/diditwork.net.db
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..fd9a46eb0c
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns1/diditwork.net.db
dc3c8a
@@ -0,0 +1,22 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL 300	; 5 minutes
dc3c8a
+@			IN SOA	ns root (
dc3c8a
+				2000082401 ; serial
dc3c8a
+				1800       ; refresh (30 minutes)
dc3c8a
+				1800       ; retry (30 minutes)
dc3c8a
+				1814400    ; expire (3 weeks)
dc3c8a
+				3600       ; minimum (1 hour)
dc3c8a
+				)
dc3c8a
+			NS	ns
dc3c8a
+			TXT	"recursed"
dc3c8a
+ns			A	10.53.0.1
dc3c8a
diff --git a/bin/tests/system/forward/ns1/named.conf.in b/bin/tests/system/forward/ns1/named.conf.in
dc3c8a
index 4aef4e55e5..c5fb2eb172 100644
dc3c8a
--- a/bin/tests/system/forward/ns1/named.conf.in
dc3c8a
+++ b/bin/tests/system/forward/ns1/named.conf.in
dc3c8a
@@ -63,3 +63,23 @@ zone "sld.tld" {
dc3c8a
 zone "example6" {
dc3c8a
 	type forward;
dc3c8a
 };
dc3c8a
+
dc3c8a
+zone "diditwork.net" {
dc3c8a
+	type primary;
dc3c8a
+	file "diditwork.net.db";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "spoofed.net" {
dc3c8a
+	type primary;
dc3c8a
+	file "spoofed.net.db";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "sub.local.net" {
dc3c8a
+	type primary;
dc3c8a
+	file "sub.local.net.db";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "net.example.lll" {
dc3c8a
+	type master;
dc3c8a
+	file "net.example.lll";
dc3c8a
+};
dc3c8a
diff --git a/bin/tests/system/forward/ns1/net.example.lll b/bin/tests/system/forward/ns1/net.example.lll
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..ba0804fd75
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns1/net.example.lll
dc3c8a
@@ -0,0 +1,15 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL 86400
dc3c8a
+net.example.lll.		SOA	. . 0 0 0 0 0
dc3c8a
+net.example.lll.		NS	attackSecureDomain.net.
dc3c8a
+didItWork.net.example.lll.	TXT	"if you can see this record the attack worked"
dc3c8a
diff --git a/bin/tests/system/forward/ns1/spoofed.net.db b/bin/tests/system/forward/ns1/spoofed.net.db
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..eedc46f5c0
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns1/spoofed.net.db
dc3c8a
@@ -0,0 +1,22 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL 300	; 5 minutes
dc3c8a
+@			IN SOA	ns root (
dc3c8a
+				2000082401 ; serial
dc3c8a
+				1800       ; refresh (30 minutes)
dc3c8a
+				1800       ; retry (30 minutes)
dc3c8a
+				1814400    ; expire (3 weeks)
dc3c8a
+				3600       ; minimum (1 hour)
dc3c8a
+				)
dc3c8a
+			NS	ns
dc3c8a
+ns			A	10.53.0.1
dc3c8a
+sub			TXT	"recursed"
dc3c8a
diff --git a/bin/tests/system/forward/ns1/sub.local.net.db b/bin/tests/system/forward/ns1/sub.local.net.db
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..fd9a46eb0c
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns1/sub.local.net.db
dc3c8a
@@ -0,0 +1,22 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL 300	; 5 minutes
dc3c8a
+@			IN SOA	ns root (
dc3c8a
+				2000082401 ; serial
dc3c8a
+				1800       ; refresh (30 minutes)
dc3c8a
+				1800       ; retry (30 minutes)
dc3c8a
+				1814400    ; expire (3 weeks)
dc3c8a
+				3600       ; minimum (1 hour)
dc3c8a
+				)
dc3c8a
+			NS	ns
dc3c8a
+			TXT	"recursed"
dc3c8a
+ns			A	10.53.0.1
dc3c8a
diff --git a/bin/tests/system/forward/ns10/fakenet.zone b/bin/tests/system/forward/ns10/fakenet.zone
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..b655a32459
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns10/fakenet.zone
dc3c8a
@@ -0,0 +1,17 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL 86400
dc3c8a
+net.			SOA	. . 0 0 0 0 0
dc3c8a
+net.			NS	attackSecureDomain.net.
dc3c8a
+attackSecureDomain.net.	A	10.53.0.10
dc3c8a
+didItWork.net.		TXT	"if you can see this record the attack worked"
dc3c8a
+ns.spoofed.net.		A	10.53.0.10
dc3c8a
diff --git a/bin/tests/system/forward/ns10/fakenet2.zone b/bin/tests/system/forward/ns10/fakenet2.zone
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..cd1e6e9944
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns10/fakenet2.zone
dc3c8a
@@ -0,0 +1,15 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL 86400
dc3c8a
+net2.			SOA	. . 0 0 0 0 0
dc3c8a
+net2.			NS	attackSecureDomain.net.
dc3c8a
+net2.			DNAME	net.example.lll.
dc3c8a
diff --git a/bin/tests/system/forward/ns10/fakesublocalnet.zone b/bin/tests/system/forward/ns10/fakesublocalnet.zone
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..160b5332b2
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns10/fakesublocalnet.zone
dc3c8a
@@ -0,0 +1,15 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL 86400
dc3c8a
+sub.local.net.		SOA	. . 0 0 0 0 0
dc3c8a
+sub.local.net.		NS	ns.spoofed.net.
dc3c8a
+sub.local.net.		TXT	"if you see this attacker overrode local delegation"
dc3c8a
diff --git a/bin/tests/system/forward/ns10/fakesublocaltld.zone b/bin/tests/system/forward/ns10/fakesublocaltld.zone
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..f78cbc77f6
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns10/fakesublocaltld.zone
dc3c8a
@@ -0,0 +1,15 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+sub.local.tld.		3600	IN	SOA	. . 0 0 0 0 0
dc3c8a
+sub.local.tld.		3600	IN	NS	ns.sub.local.tld.
dc3c8a
+sub.local.tld.		3600	IN	TXT	bad
dc3c8a
+ns.sub.local.tld.	3600	IN	A	10.53.0.8
dc3c8a
diff --git a/bin/tests/system/forward/ns10/named.conf.in b/bin/tests/system/forward/ns10/named.conf.in
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..1f318dd867
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns10/named.conf.in
dc3c8a
@@ -0,0 +1,53 @@
dc3c8a
+/*
dc3c8a
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+ *
dc3c8a
+ * SPDX-License-Identifier: MPL-2.0
dc3c8a
+ *
dc3c8a
+ * This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+ *
dc3c8a
+ * See the COPYRIGHT file distributed with this work for additional
dc3c8a
+ * information regarding copyright ownership.
dc3c8a
+ */
dc3c8a
+
dc3c8a
+options {
dc3c8a
+	query-source address 10.53.0.10;
dc3c8a
+	notify-source 10.53.0.10;
dc3c8a
+	transfer-source 10.53.0.10;
dc3c8a
+	port @PORT@;
dc3c8a
+	pid-file "named.pid";
dc3c8a
+	listen-on { 10.53.0.10; };
dc3c8a
+	listen-on-v6 { none; };
dc3c8a
+	minimal-responses no;
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "net." {
dc3c8a
+	type master;
dc3c8a
+	file "fakenet.zone";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "spoofed.net." {
dc3c8a
+	type master;
dc3c8a
+	file "spoofednet.zone";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "sub.local.net." {
dc3c8a
+	type master;
dc3c8a
+	file "fakesublocalnet.zone";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "net2" {
dc3c8a
+	type master;
dc3c8a
+	file "fakenet2.zone";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "net.example.lll" {
dc3c8a
+	type master;
dc3c8a
+	file "net.example.lll";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "sub.local.tld." {
dc3c8a
+	type master;
dc3c8a
+	file "fakesublocaltld.zone";
dc3c8a
+};
dc3c8a
diff --git a/bin/tests/system/forward/ns10/net.example.lll b/bin/tests/system/forward/ns10/net.example.lll
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..ba0804fd75
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns10/net.example.lll
dc3c8a
@@ -0,0 +1,15 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL 86400
dc3c8a
+net.example.lll.		SOA	. . 0 0 0 0 0
dc3c8a
+net.example.lll.		NS	attackSecureDomain.net.
dc3c8a
+didItWork.net.example.lll.	TXT	"if you can see this record the attack worked"
dc3c8a
diff --git a/bin/tests/system/forward/ns10/spoofednet.zone b/bin/tests/system/forward/ns10/spoofednet.zone
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..fb70a4372b
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns10/spoofednet.zone
dc3c8a
@@ -0,0 +1,16 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL 86400
dc3c8a
+spoofed.net.		SOA	. . 0 0 0 0 0
dc3c8a
+spoofed.net.		NS	ns.spoofed.net.
dc3c8a
+ns.spoofed.net.		A	10.53.0.10
dc3c8a
+spoofed.net.		TXT	"this record is clearly spoofed"
dc3c8a
diff --git a/bin/tests/system/forward/ns2/tld.db b/bin/tests/system/forward/ns2/tld.db
dc3c8a
index 61b6569b07..819210dc05 100644
dc3c8a
--- a/bin/tests/system/forward/ns2/tld.db
dc3c8a
+++ b/bin/tests/system/forward/ns2/tld.db
dc3c8a
@@ -10,3 +10,9 @@ $TTL 300	; 5 minutes
dc3c8a
 ns			A	10.53.0.2
dc3c8a
 sld			NS	ns.sld
dc3c8a
 ns.sld			A	10.53.0.1
dc3c8a
+local			NS	ns.local
dc3c8a
+ns.local		A	10.53.0.9
dc3c8a
+sibling			NS	ns.sibling
dc3c8a
+ns.sibling		A	10.53.0.4
dc3c8a
+sibling			NS	ns.sub.local
dc3c8a
+ns.sub.local		A	10.53.0.10
dc3c8a
diff --git a/bin/tests/system/forward/ns4/named.conf.in b/bin/tests/system/forward/ns4/named.conf.in
dc3c8a
index 855b4bfb82..85349aa97e 100644
dc3c8a
--- a/bin/tests/system/forward/ns4/named.conf.in
dc3c8a
+++ b/bin/tests/system/forward/ns4/named.conf.in
dc3c8a
@@ -60,3 +60,8 @@ zone "malicious." {
dc3c8a
 	type primary;
dc3c8a
 	file "malicious.db";
dc3c8a
 };
dc3c8a
+
dc3c8a
+zone "sibling.tld" {
dc3c8a
+	type primary;
dc3c8a
+	file "sibling.tld.db";
dc3c8a
+};
dc3c8a
diff --git a/bin/tests/system/forward/ns4/sibling.tld.db b/bin/tests/system/forward/ns4/sibling.tld.db
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..fe080ae974
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns4/sibling.tld.db
dc3c8a
@@ -0,0 +1,22 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+$TTL    86400
dc3c8a
+@       IN      SOA     malicious. admin.malicious. (
dc3c8a
+                              1         ; Serial
dc3c8a
+                         604800         ; Refresh
dc3c8a
+                          86400         ; Retry
dc3c8a
+                        2419200         ; Expire
dc3c8a
+                          86400 )       ; Negative Cache TTL
dc3c8a
+
dc3c8a
+@           IN    NS      ns
dc3c8a
+
dc3c8a
+ns          IN    A       10.53.0.4
dc3c8a
diff --git a/bin/tests/system/forward/ns8/named.conf.in b/bin/tests/system/forward/ns8/named.conf.in
dc3c8a
index 531ff59ece..f752eae885 100644
dc3c8a
--- a/bin/tests/system/forward/ns8/named.conf.in
dc3c8a
+++ b/bin/tests/system/forward/ns8/named.conf.in
dc3c8a
@@ -26,3 +26,8 @@ zone "." {
dc3c8a
 	type hint;
dc3c8a
 	file "root.db";
dc3c8a
 };
dc3c8a
+
dc3c8a
+zone "sub.local.tld" {
dc3c8a
+	type primary;
dc3c8a
+	file "sub.local.tld.db";
dc3c8a
+};
dc3c8a
diff --git a/bin/tests/system/forward/ns8/sub.local.tld.db b/bin/tests/system/forward/ns8/sub.local.tld.db
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..f2234c754e
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns8/sub.local.tld.db
dc3c8a
@@ -0,0 +1,15 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+sub.local.tld.		3600	IN	SOA	. . 0 0 0 0 0
dc3c8a
+sub.local.tld.		3600	IN	NS	ns.sub.local.tld.
dc3c8a
+sub.local.tld.		3600	IN	TXT	good
dc3c8a
+ns.sub.local.tld.	3600	IN	A	10.53.0.8
dc3c8a
diff --git a/bin/tests/system/forward/ns9/local.net.db b/bin/tests/system/forward/ns9/local.net.db
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..af0d2a5a67
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns9/local.net.db
dc3c8a
@@ -0,0 +1,16 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+local.net.		3600	IN	SOA	. . 0 0 0 0 0
dc3c8a
+local.net.		3600	IN	NS	localhost.
dc3c8a
+ns.local.net.		3600	IN	A	10.53.0.9
dc3c8a
+txt.local.net.		3600	IN	TXT	"something in the local auth zone"
dc3c8a
+sub.local.net.		3600	IN	NS	ns.spoofed.net.  ; attacker will try to override this
dc3c8a
diff --git a/bin/tests/system/forward/ns9/local.tld.db b/bin/tests/system/forward/ns9/local.tld.db
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..876a9139da
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns9/local.tld.db
dc3c8a
@@ -0,0 +1,15 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+local.tld.		3600	IN	SOA	. . 0 0 0 0 0
dc3c8a
+local.tld.		3600	IN	NS	localhost.
dc3c8a
+sub.local.tld.		3600	IN	NS	ns.sub.local.tld.
dc3c8a
+ns.sub.local.tld.	3600	IN	A	10.53.0.8
dc3c8a
diff --git a/bin/tests/system/forward/ns9/named1.conf.in b/bin/tests/system/forward/ns9/named1.conf.in
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..be9a43842f
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns9/named1.conf.in
dc3c8a
@@ -0,0 +1,67 @@
dc3c8a
+/*
dc3c8a
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+ *
dc3c8a
+ * SPDX-License-Identifier: MPL-2.0
dc3c8a
+ *
dc3c8a
+ * This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+ *
dc3c8a
+ * See the COPYRIGHT file distributed with this work for additional
dc3c8a
+ * information regarding copyright ownership.
dc3c8a
+ */
dc3c8a
+
dc3c8a
+options {
dc3c8a
+	query-source address 10.53.0.9;
dc3c8a
+	notify-source 10.53.0.9;
dc3c8a
+	transfer-source 10.53.0.9;
dc3c8a
+	port @PORT@;
dc3c8a
+	pid-file "named.pid";
dc3c8a
+	listen-on { 10.53.0.9; };
dc3c8a
+	listen-on-v6 { none; };
dc3c8a
+	dnssec-validation no;
dc3c8a
+	edns-udp-size 1232;
dc3c8a
+};
dc3c8a
+
dc3c8a
+key rndc_key {
dc3c8a
+	secret "1234abcd8765";
dc3c8a
+	algorithm hmac-sha256;
dc3c8a
+};
dc3c8a
+
dc3c8a
+controls {
dc3c8a
+	inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+server 10.53.0.10 {
dc3c8a
+	edns no;
dc3c8a
+};
dc3c8a
+
dc3c8a
+server 10.53.0.11 {
dc3c8a
+	edns no;
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "." {
dc3c8a
+	type hint;
dc3c8a
+	file "root.db";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "attacksecuredomain.net." {
dc3c8a
+	type forward;
dc3c8a
+	forwarders { 10.53.0.10; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "attacksecuredomain.net2." {
dc3c8a
+	type forward;
dc3c8a
+	forwarders { 10.53.0.10; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "attacksecuredomain.net3." {
dc3c8a
+	type forward;
dc3c8a
+	forwarders { 10.53.0.11; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "local.net." {
dc3c8a
+	type primary;
dc3c8a
+	file "local.net.db";
dc3c8a
+	forwarders {};
dc3c8a
+};
dc3c8a
diff --git a/bin/tests/system/forward/ns9/named2.conf.in b/bin/tests/system/forward/ns9/named2.conf.in
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..2c40b42a0c
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns9/named2.conf.in
dc3c8a
@@ -0,0 +1,70 @@
dc3c8a
+/*
dc3c8a
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+ *
dc3c8a
+ * SPDX-License-Identifier: MPL-2.0
dc3c8a
+ *
dc3c8a
+ * This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+ *
dc3c8a
+ * See the COPYRIGHT file distributed with this work for additional
dc3c8a
+ * information regarding copyright ownership.
dc3c8a
+ */
dc3c8a
+
dc3c8a
+options {
dc3c8a
+	query-source address 10.53.0.9;
dc3c8a
+	notify-source 10.53.0.9;
dc3c8a
+	transfer-source 10.53.0.9;
dc3c8a
+	port @PORT@;
dc3c8a
+	pid-file "named.pid";
dc3c8a
+	listen-on { 10.53.0.9; };
dc3c8a
+	listen-on-v6 { none; };
dc3c8a
+	dnssec-validation no;
dc3c8a
+	edns-udp-size 1232;
dc3c8a
+};
dc3c8a
+
dc3c8a
+key rndc_key {
dc3c8a
+	secret "1234abcd8765";
dc3c8a
+	algorithm hmac-sha256;
dc3c8a
+};
dc3c8a
+
dc3c8a
+controls {
dc3c8a
+	inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+server 10.53.0.10 {
dc3c8a
+	edns no;
dc3c8a
+};
dc3c8a
+
dc3c8a
+server 10.53.0.11 {
dc3c8a
+	edns no;
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "." {
dc3c8a
+	type hint;
dc3c8a
+	file "root.db";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "attacksecuredomain.net." {
dc3c8a
+	type forward;
dc3c8a
+	forward only;
dc3c8a
+	forwarders { 10.53.0.10; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "attacksecuredomain.net2." {
dc3c8a
+	type forward;
dc3c8a
+	forward only;
dc3c8a
+	forwarders { 10.53.0.10; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "attacksecuredomain.net3." {
dc3c8a
+	type forward;
dc3c8a
+	forward only;
dc3c8a
+	forwarders { 10.53.0.11; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "local.net." {
dc3c8a
+	type primary;
dc3c8a
+	file "local.net.db";
dc3c8a
+	forwarders {};
dc3c8a
+};
dc3c8a
diff --git a/bin/tests/system/forward/ns9/named3.conf.in b/bin/tests/system/forward/ns9/named3.conf.in
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..576f57c10b
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns9/named3.conf.in
dc3c8a
@@ -0,0 +1,50 @@
dc3c8a
+/*
dc3c8a
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+ *
dc3c8a
+ * SPDX-License-Identifier: MPL-2.0
dc3c8a
+ *
dc3c8a
+ * This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+ *
dc3c8a
+ * See the COPYRIGHT file distributed with this work for additional
dc3c8a
+ * information regarding copyright ownership.
dc3c8a
+ */
dc3c8a
+
dc3c8a
+options {
dc3c8a
+	query-source address 10.53.0.9;
dc3c8a
+	notify-source 10.53.0.9;
dc3c8a
+	transfer-source 10.53.0.9;
dc3c8a
+	port @PORT@;
dc3c8a
+	pid-file "named.pid";
dc3c8a
+	listen-on { 10.53.0.9; };
dc3c8a
+	listen-on-v6 { none; };
dc3c8a
+	dnssec-validation no;
dc3c8a
+	edns-udp-size 1232;
dc3c8a
+	forward only;
dc3c8a
+	forwarders { 10.53.0.10; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+key rndc_key {
dc3c8a
+	secret "1234abcd8765";
dc3c8a
+	algorithm hmac-sha256;
dc3c8a
+};
dc3c8a
+
dc3c8a
+controls {
dc3c8a
+	inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+server 10.53.0.10 {
dc3c8a
+	edns no;
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "." {
dc3c8a
+	type hint;
dc3c8a
+	file "root.db";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "local.net." {
dc3c8a
+	type primary;
dc3c8a
+	file "local.net.db";
dc3c8a
+	forwarders {};
dc3c8a
+};
dc3c8a
diff --git a/bin/tests/system/forward/ns9/named4.conf.in b/bin/tests/system/forward/ns9/named4.conf.in
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..5cd7d84109
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns9/named4.conf.in
dc3c8a
@@ -0,0 +1,47 @@
dc3c8a
+/*
dc3c8a
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+ *
dc3c8a
+ * SPDX-License-Identifier: MPL-2.0
dc3c8a
+ *
dc3c8a
+ * This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+ *
dc3c8a
+ * See the COPYRIGHT file distributed with this work for additional
dc3c8a
+ * information regarding copyright ownership.
dc3c8a
+ */
dc3c8a
+
dc3c8a
+options {
dc3c8a
+	query-source address 10.53.0.9;
dc3c8a
+	notify-source 10.53.0.9;
dc3c8a
+	transfer-source 10.53.0.9;
dc3c8a
+	port @PORT@;
dc3c8a
+	pid-file "named.pid";
dc3c8a
+	listen-on { 10.53.0.9; };
dc3c8a
+	listen-on-v6 { none; };
dc3c8a
+	dnssec-validation no;
dc3c8a
+	edns-udp-size 1232;
dc3c8a
+};
dc3c8a
+
dc3c8a
+key rndc_key {
dc3c8a
+	secret "1234abcd8765";
dc3c8a
+	algorithm hmac-sha256;
dc3c8a
+};
dc3c8a
+
dc3c8a
+controls {
dc3c8a
+	inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
dc3c8a
+};
dc3c8a
+
dc3c8a
+server 10.53.0.10 {
dc3c8a
+	edns no;
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "." {
dc3c8a
+	type hint;
dc3c8a
+	file "root.db";
dc3c8a
+};
dc3c8a
+
dc3c8a
+zone "local.tld." {
dc3c8a
+	type primary;
dc3c8a
+	file "local.tld.db";
dc3c8a
+};
dc3c8a
diff --git a/bin/tests/system/forward/ns9/root.db b/bin/tests/system/forward/ns9/root.db
dc3c8a
new file mode 100644
dc3c8a
index 0000000000..2cbdff5977
dc3c8a
--- /dev/null
dc3c8a
+++ b/bin/tests/system/forward/ns9/root.db
dc3c8a
@@ -0,0 +1,13 @@
dc3c8a
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
dc3c8a
+;
dc3c8a
+; SPDX-License-Identifier: MPL-2.0
dc3c8a
+;
dc3c8a
+; This Source Code Form is subject to the terms of the Mozilla Public
dc3c8a
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
dc3c8a
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
dc3c8a
+;
dc3c8a
+; See the COPYRIGHT file distributed with this work for additional
dc3c8a
+; information regarding copyright ownership.
dc3c8a
+
dc3c8a
+.			NS	a.root-servers.nil.
dc3c8a
+a.root-servers.nil.	A	10.53.0.1
dc3c8a
diff --git a/bin/tests/system/forward/setup.sh b/bin/tests/system/forward/setup.sh
dc3c8a
index 21cf67b782..a56dd3c03f 100644
dc3c8a
--- a/bin/tests/system/forward/setup.sh
dc3c8a
+++ b/bin/tests/system/forward/setup.sh
dc3c8a
@@ -19,6 +19,8 @@ copy_setports ns4/named.conf.in ns4/named.conf
dc3c8a
 copy_setports ns5/named.conf.in ns5/named.conf
dc3c8a
 copy_setports ns7/named.conf.in ns7/named.conf
dc3c8a
 copy_setports ns8/named.conf.in ns8/named.conf
dc3c8a
+copy_setports ns9/named1.conf.in ns9/named.conf
dc3c8a
+copy_setports ns10/named.conf.in ns10/named.conf
dc3c8a
 
dc3c8a
 (
dc3c8a
     cd ns1
dc3c8a
diff --git a/bin/tests/system/forward/tests.sh b/bin/tests/system/forward/tests.sh
dc3c8a
index 6096b06ca7..dfbaf887f7 100644
dc3c8a
--- a/bin/tests/system/forward/tests.sh
dc3c8a
+++ b/bin/tests/system/forward/tests.sh
dc3c8a
@@ -253,5 +253,127 @@ grep "status: SERVFAIL" dig.out.$n.f1 > /dev/null || ret=1
dc3c8a
 if [ $ret != 0 ]; then echo_i "failed"; fi
dc3c8a
 status=$((status+ret))
dc3c8a
 
dc3c8a
+#
dc3c8a
+# Check various spoofed response scenarios. The same tests will be
dc3c8a
+# run twice, with "forward first" and "forward only" configurations.
dc3c8a
+#
dc3c8a
+run_spooftests () {
dc3c8a
+    n=$((n+1))
dc3c8a
+    echo_i "checking spoofed response scenario 1 - out of bailiwick NS ($n)"
dc3c8a
+    ret=0
dc3c8a
+    # prime
dc3c8a
+    dig_with_opts @10.53.0.9 attackSecureDomain.net > dig.out.$n.prime || ret=1
dc3c8a
+    # check 'net' is not poisoned.
dc3c8a
+    dig_with_opts @10.53.0.9 diditwork.net. TXT > dig.out.$n.net || ret=1
dc3c8a
+    grep '^diditwork\.net\..*TXT.*"recursed"' dig.out.$n.net > /dev/null || ret=1
dc3c8a
+    # check 'sub.local.net' is not poisoned.
dc3c8a
+    dig_with_opts @10.53.0.9 sub.local.net TXT > dig.out.$n.sub || ret=1
dc3c8a
+    grep '^sub\.local\.net\..*TXT.*"recursed"' dig.out.$n.sub > /dev/null || ret=1
dc3c8a
+    if [ $ret != 0 ]; then echo_i "failed"; fi
dc3c8a
+    status=$((status+ret))
dc3c8a
+
dc3c8a
+    n=$((n+1))
dc3c8a
+    echo_i "checking spoofed response scenario 2 - inject DNAME/net2. ($n)"
dc3c8a
+    ret=0
dc3c8a
+    # prime
dc3c8a
+    dig_with_opts @10.53.0.9 attackSecureDomain.net2 > dig.out.$n.prime || ret=1
dc3c8a
+    # check that net2/DNAME is not cached
dc3c8a
+    dig_with_opts @10.53.0.9 net2. DNAME > dig.out.$n.net2 || ret=1
dc3c8a
+    grep "ANSWER: 0," dig.out.$n.net2 > /dev/null || ret=1
dc3c8a
+    grep "status: NXDOMAIN" dig.out.$n.net2 > /dev/null || ret=1
dc3c8a
+    if [ $ret != 0 ]; then echo_i "failed"; fi
dc3c8a
+    status=$((status+ret))
dc3c8a
+
dc3c8a
+    n=$((n+1))
dc3c8a
+    echo_i "checking spoofed response scenario 3 - extra answer ($n)"
dc3c8a
+    ret=0
dc3c8a
+    # prime
dc3c8a
+    dig_with_opts @10.53.0.9 attackSecureDomain.net3 > dig.out.$n.prime || ret=1
dc3c8a
+    # check extra net3 records are not cached
dc3c8a
+    rndccmd 10.53.0.9 dumpdb -cache 2>&1 | sed 's/^/ns9 /' | cat_i
dc3c8a
+    for try in 1 2 3 4 5; do
dc3c8a
+        lines=$(grep "net3" ns9/named_dump.db | wc -l)
dc3c8a
+        if [ ${lines} -eq 0 ]; then
dc3c8a
+                sleep 1
dc3c8a
+                continue
dc3c8a
+        fi
dc3c8a
+        [ ${lines} -eq 1 ] || ret=1
dc3c8a
+        grep -q '^attackSecureDomain.net3' ns9/named_dump.db || ret=1
dc3c8a
+        grep -q '^local.net3' ns9/named_dump.db && ret=1
dc3c8a
+    done
dc3c8a
+    if [ $ret != 0 ]; then echo_i "failed"; fi
dc3c8a
+    status=$((status+ret))
dc3c8a
+}
dc3c8a
+
dc3c8a
+echo_i "checking spoofed response scenarios with forward first zones"
dc3c8a
+run_spooftests
dc3c8a
+
dc3c8a
+copy_setports ns9/named2.conf.in ns9/named.conf
dc3c8a
+rndccmd 10.53.0.9 reconfig 2>&1 | sed 's/^/ns3 /' | cat_i
dc3c8a
+rndccmd 10.53.0.9 flush 2>&1 | sed 's/^/ns3 /' | cat_i
dc3c8a
+sleep 1
dc3c8a
+
dc3c8a
+echo_i "rechecking spoofed response scenarios with forward only zones"
dc3c8a
+run_spooftests
dc3c8a
+
dc3c8a
+#
dc3c8a
+# This scenario expects the spoofed response to succeed. The tests are
dc3c8a
+# similar to the ones above, but not identical.
dc3c8a
+#
dc3c8a
+echo_i "rechecking spoofed response scenarios with 'forward only' set globally"
dc3c8a
+copy_setports ns9/named3.conf.in ns9/named.conf
dc3c8a
+rndccmd 10.53.0.9 reconfig 2>&1 | sed 's/^/ns3 /' | cat_i
dc3c8a
+rndccmd 10.53.0.9 flush 2>&1 | sed 's/^/ns3 /' | cat_i
dc3c8a
+sleep 1
dc3c8a
+
dc3c8a
+n=$((n+1))
dc3c8a
+echo_i "checking spoofed response scenario 1 - out of bailiwick NS ($n)"
dc3c8a
+ret=0
dc3c8a
+# prime
dc3c8a
+dig_with_opts @10.53.0.9 attackSecureDomain.net > dig.out.$n.prime || ret=1
dc3c8a
+# check 'net' is poisoned.
dc3c8a
+dig_with_opts @10.53.0.9 diditwork.net. TXT > dig.out.$n.net || ret=1
dc3c8a
+grep '^didItWork\.net\..*TXT.*"if you can see this record the attack worked"' dig.out.$n.net > /dev/null || ret=1
dc3c8a
+# check 'sub.local.net' is poisoned.
dc3c8a
+dig_with_opts @10.53.0.9 sub.local.net TXT > dig.out.$n.sub || ret=1
dc3c8a
+grep '^sub\.local\.net\..*TXT.*"if you see this attacker overrode local delegation"' dig.out.$n.sub > /dev/null || ret=1
dc3c8a
+if [ $ret != 0 ]; then echo_i "failed"; fi
dc3c8a
+status=$((status+ret))
dc3c8a
+
dc3c8a
+n=$((n+1))
dc3c8a
+echo_i "checking spoofed response scenario 2 - inject DNAME/net2. ($n)"
dc3c8a
+ret=0
dc3c8a
+# prime
dc3c8a
+dig_with_opts @10.53.0.9 attackSecureDomain.net2 > dig.out.$n.prime || ret=1
dc3c8a
+# check that net2/DNAME is cached
dc3c8a
+dig_with_opts @10.53.0.9 net2. DNAME > dig.out.$n.net2 || ret=1
dc3c8a
+grep "ANSWER: 1," dig.out.$n.net2 > /dev/null || ret=1
dc3c8a
+grep "net2\..*IN.DNAME.net\.example\.lll\." dig.out.$n.net2 > /dev/null || ret=1
dc3c8a
+if [ $ret != 0 ]; then echo_i "failed"; fi
dc3c8a
+status=$((status+ret))
dc3c8a
+
dc3c8a
+#
dc3c8a
+# This test doesn't use any forwarder clauses but is here because it
dc3c8a
+# is similar to forwarders, as the set of servers that can populate
dc3c8a
+# the namespace is defined by the zone content.
dc3c8a
+#
dc3c8a
+echo_i "rechecking spoofed response scenarios glue below local zone"
dc3c8a
+copy_setports ns9/named4.conf.in ns9/named.conf
dc3c8a
+rndccmd 10.53.0.9 reconfig 2>&1 | sed 's/^/ns3 /' | cat_i
dc3c8a
+rndccmd 10.53.0.9 flush 2>&1 | sed 's/^/ns3 /' | cat_i
dc3c8a
+sleep 1
dc3c8a
+
dc3c8a
+n=$((n+1))
dc3c8a
+echo_i "checking sibling glue below zone ($n)"
dc3c8a
+ret=0
dc3c8a
+# prime
dc3c8a
+dig_with_opts @10.53.0.9 sibling.tld > dig.out.$n.prime || ret=1
dc3c8a
+# check for glue A record for sub.local.tld is not used
dc3c8a
+dig_with_opts @10.53.0.9 sub.local.tld TXT > dig.out.$n.sub || ret=1
dc3c8a
+grep "ANSWER: 1," dig.out.$n.sub > /dev/null || ret=1
dc3c8a
+grep 'sub\.local\.tld\..*IN.TXT."good"$' dig.out.$n.sub > /dev/null || ret=1
dc3c8a
+if [ $ret != 0 ]; then echo_i "failed"; fi
dc3c8a
+status=$((status+ret))
dc3c8a
+
dc3c8a
 echo_i "exit status: $status"
dc3c8a
 [ $status -eq 0 ] || exit 1
dc3c8a
diff --git a/bin/tests/system/ifconfig.sh b/bin/tests/system/ifconfig.sh
dc3c8a
index e078f3313b..2a4d955caf 100755
dc3c8a
--- a/bin/tests/system/ifconfig.sh
dc3c8a
+++ b/bin/tests/system/ifconfig.sh
dc3c8a
@@ -12,10 +12,10 @@
dc3c8a
 #
dc3c8a
 # Set up interface aliases for bind9 system tests.
dc3c8a
 #
dc3c8a
-# IPv4: 10.53.0.{1..10}				RFC 1918
dc3c8a
+# IPv4: 10.53.0.{1..11}				RFC 1918
dc3c8a
 #       10.53.1.{1..2}
dc3c8a
 #       10.53.2.{1..2}
dc3c8a
-# IPv6: fd92:7065:b8e:ffff::{1..10}		ULA
dc3c8a
+# IPv6: fd92:7065:b8e:ffff::{1..11}		ULA
dc3c8a
 #       fd92:7065:b8e:99ff::{1..2}
dc3c8a
 #       fd92:7065:b8e:ff::{1..2}
dc3c8a
 #
dc3c8a
@@ -55,7 +55,7 @@ case "$1" in
dc3c8a
 		  2) ipv6="00" ;;
dc3c8a
 		  *) ipv6="" ;;
dc3c8a
 		esac
dc3c8a
-		for ns in 1 2 3 4 5 6 7 8 9 10
dc3c8a
+		for ns in 1 2 3 4 5 6 7 8 9 10 11
dc3c8a
 		do
dc3c8a
 			[ $i -gt 0 -a $ns -gt 2 ] && break
dc3c8a
 			int=`expr $i \* 10 + $ns`
dc3c8a
@@ -160,7 +160,7 @@ case "$1" in
dc3c8a
 		  2) ipv6="00" ;;
dc3c8a
 		  *) ipv6="" ;;
dc3c8a
 		esac
dc3c8a
-		for ns in 10 9 8 7 6 5 4 3 2 1
dc3c8a
+		for ns in 11 10 9 8 7 6 5 4 3 2 1
dc3c8a
 		do
dc3c8a
 			[ $i -gt 0 -a $ns -gt 2 ] && continue
dc3c8a
 			int=`expr $i \* 10 + $ns - 1`
dc3c8a
-- 
dc3c8a
2.34.1
dc3c8a