From b5f2ab9cd4e7d0fbcdce35e39e8b81f37699b5ad Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Thu, 14 Apr 2022 10:57:11 +1000
Subject: [PATCH] Check that pending negative cache entries for DS can be used
 successfully

Prime the cache with a negative cache DS entry then make a query for
name beneath that entry. This will cause the DS entry to be retieved
as part of the validation process.  Each RRset in the ncache entry
will be validated and the trust level for each will be updated.

(cherry picked from commit d2d9910da23951bf310c7be8ba68e1030eb13caa)
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/b5f2ab9cd4e7d0fbcdce35e39e8b81f37699b5ad
---
 bin/tests/system/dnssec/ns2/example.db.in     |  4 +++
 .../system/dnssec/ns3/insecure2.example.db    | 27 +++++++++++++++++++
 bin/tests/system/dnssec/ns3/named.conf.in     |  6 +++++
 bin/tests/system/dnssec/tests.sh              | 18 +++++++++++++
 4 files changed, 55 insertions(+)
 create mode 100644 bin/tests/system/dnssec/ns3/insecure2.example.db

diff --git a/bin/tests/system/dnssec/ns2/example.db.in b/bin/tests/system/dnssec/ns2/example.db.in
index 5ec88013c9..f711f5823f 100644
--- a/bin/tests/system/dnssec/ns2/example.db.in
+++ b/bin/tests/system/dnssec/ns2/example.db.in
@@ -55,6 +55,10 @@ ns3.secure		A	10.53.0.3
 insecure		NS	ns.insecure
 ns.insecure		A	10.53.0.3
 
+; A second insecure subdomain
+insecure2		NS	ns.insecure2
+ns.insecure2		A	10.53.0.3
+
 ; A secure subdomain we're going to inject bogus data into
 bogus			NS	ns.bogus
 ns.bogus		A	10.53.0.3
diff --git a/bin/tests/system/dnssec/ns3/insecure2.example.db b/bin/tests/system/dnssec/ns3/insecure2.example.db
new file mode 100644
index 0000000000..76e3f47f21
--- /dev/null
+++ b/bin/tests/system/dnssec/ns3/insecure2.example.db
@@ -0,0 +1,27 @@
+; 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 300	; 5 minutes
+@			IN SOA	mname1. . (
+				2000042407 ; serial
+				20         ; refresh (20 seconds)
+				20         ; retry (20 seconds)
+				1814400    ; expire (3 weeks)
+				3600       ; minimum (1 hour)
+				)
+			NS	ns
+ns			A	10.53.0.3
+
+a			A	10.0.0.1
+b			A	10.0.0.2
+d			A	10.0.0.4
+x			DNSKEY	258 3 5 Cg==
+z			A	10.0.0.26
diff --git a/bin/tests/system/dnssec/ns3/named.conf.in b/bin/tests/system/dnssec/ns3/named.conf.in
index 202f6a931d..bd0771dd49 100644
--- a/bin/tests/system/dnssec/ns3/named.conf.in
+++ b/bin/tests/system/dnssec/ns3/named.conf.in
@@ -78,6 +78,12 @@ zone "insecure.example" {
 	allow-update { any; };
 };
 
+zone "insecure2.example" {
+	type primary;
+	file "insecure2.example.db";
+	allow-update { any; };
+};
+
 zone "insecure.nsec3.example" {
 	type primary;
 	file "insecure.nsec3.example.db";
diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh
index c6410ae79e..db3e19533e 100644
--- a/bin/tests/system/dnssec/tests.sh
+++ b/bin/tests/system/dnssec/tests.sh
@@ -4412,5 +4412,23 @@ n=$((n+1))
 test "$ret" -eq 0 || echo_i "failed"
 status=$((status+ret))
 
+# Check that a query against a validating resolver succeeds when there is
+# a negative cache entry with trust level "pending" for the DS.  Prime
+# with a +cd DS query to produce the negative cache entry, then send a
+# query that uses that entry as part of the validation process. [GL #3279]
+echo_i "check that pending negative DS cache entry validates ($n)"
+ret=0
+dig_with_opts @10.53.0.4 +cd insecure2.example. ds > dig.out.prime.ns4.test$n || ret=1
+grep "flags: qr rd ra cd;" dig.out.prime.ns4.test$n >/dev/null || ret=1
+grep "status: NOERROR" dig.out.prime.ns4.test$n >/dev/null || ret=1
+grep "ANSWER: 0, AUTHORITY: 4, " dig.out.prime.ns4.test$n > /dev/null || ret=1
+dig_with_opts @10.53.0.4 a.insecure2.example. a > dig.out.ns4.test$n || ret=1
+grep "ANSWER: 1, AUTHORITY: 1, " dig.out.ns4.test$n > /dev/null || ret=1
+grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1
+grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1
+n=$((n+1))
+if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
 echo_i "exit status: $status"
 [ $status -eq 0 ] || exit 1
-- 
2.23.0

