]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Test dangling CNAMEs come with NXDOMAIN proofs
authorPetr Špaček <pspacek@isc.org>
Thu, 10 Jul 2025 11:13:02 +0000 (13:13 +0200)
committerPetr Špaček <pspacek@isc.org>
Tue, 29 Jul 2025 08:00:46 +0000 (10:00 +0200)
Simplistic test. Ignores the possibility of CNAME chain going through
multiple zones and/or wildcard expansions.

bin/tests/system/nsec3-answer/ns1/root.db.in
bin/tests/system/nsec3-answer/tests_nsec3.py

index 295e28c1d9734ccd6601fcd76e7b6eb3a1cdfb35..2171c44239a3aeb62168b2c263645862f85b3d8d 100644 (file)
@@ -25,7 +25,9 @@ a.                                            A       10.0.0.1
 a.a.a.a.                                       A       10.0.0.3
 b.                                             A       10.0.0.2
 b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.     A       10.0.0.2
-; cname.                                               CNAME   cname.a.a.
+cname.                                         CNAME   does-not-exist.
+cname.cname.                                   CNAME   cname.
+cname.ent.cname.                               CNAME   cname.cname.
 d.                                             A       10.0.0.4
 dname-nowhere.                                 DNAME   does-not-exist.
 insecure.                                      NS      a.root-servers.nil.
index ac3fe44715932b9f72eaf2563cb4feaf9e98a916..f1b0a70154e1ddfbe9679d039c0b1ba69bc00898 100755 (executable)
@@ -47,7 +47,7 @@ ZONE = isctest.name.ZoneAnalyzer.read_path(
 
 def do_test_query(
     qname, qtype, server, named_port
-) -> Tuple[dns.message.Message, "NSEC3Checker"]:
+) -> Tuple[dns.message.QueryMessage, "NSEC3Checker"]:
     query = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True)
     response = isctest.query.tcp(query, server, named_port, timeout=TIMEOUT)
     isctest.check.is_response_to(response, query)
@@ -58,7 +58,11 @@ def do_test_query(
 @pytest.mark.parametrize(
     "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")]
 )
-@given(qname=sampled_from(sorted(ZONE.reachable)))
+@given(
+    qname=sampled_from(
+        sorted(ZONE.reachable - ZONE.get_names_with_type(dns.rdatatype.CNAME))
+    )
+)
 def test_nodata(server, qname: dns.name.Name, named_port: int) -> None:
     """An existing name, no wildcards, but a query type for RRset which does not exist"""
     response, nsec3check = do_test_query(qname, dns.rdatatype.HINFO, server, named_port)
@@ -96,6 +100,22 @@ def test_nxdomain(server, qname: dns.name.Name, named_port: int) -> None:
     check_nxdomain(qname, nsec3check)
 
 
+@pytest.mark.parametrize(
+    "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")]
+)
+@given(qname=sampled_from(sorted(ZONE.get_names_with_type(dns.rdatatype.CNAME))))
+def test_cname_nxdomain(server, qname: dns.name.Name, named_port: int) -> None:
+    """CNAME which terminates by NXDOMAIN, no wildcards involved"""
+    response, nsec3check = do_test_query(qname, dns.rdatatype.A, server, named_port)
+    chain = response.resolve_chaining()
+    assume_nx_and_no_delegation(chain.canonical_name)
+
+    wname = ZONE.source_of_synthesis(chain.canonical_name)
+    assume(wname not in ZONE.reachable_wildcards)
+
+    check_nxdomain(chain.canonical_name, nsec3check)
+
+
 @pytest.mark.parametrize(
     "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")]
 )