]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add test for SIG in prequisites of dynamic update
authorMatthijs Mekking <matthijs@isc.org>
Thu, 16 Apr 2026 14:17:34 +0000 (16:17 +0200)
committerOndřej Surý <ondrej@isc.org>
Fri, 17 Apr 2026 17:24:13 +0000 (19:24 +0200)
Make sure the nameserver correctly handles SIG records in the
prerequisites of the dynamic update. The first check is to ensure that
the prerequisites are not examined prior to checking the credentials.

The second test case checks that the SIG present prerequisite is
examined and therefore refuses the update. Also this should not trigger
an assertion failure in dns__db_findrdataset() (due to the REQUIRE()
only accepted dns_rdatatype_rrsig when the covers parameter was set).

(cherry picked from commit 51f27fda46870acea69835f82835ca857c000bd0)

bin/tests/system/nsupdate/tests_sh_nsupdate.py
bin/tests/system/nsupdate/tests_update_sig.py [moved from bin/tests/system/nsupdate/tests_tcp_self_sig.py with 84% similarity]

index bd41ac64c51535be419972d19197982844bd488a..51e22c9985e69bd39e61e30a711d3fed16ffe499 100644 (file)
@@ -58,6 +58,7 @@ pytestmark = pytest.mark.extra_artifacts(
         "ns5/local.db",
         "ns6/2.0.0.2.ip6.addr.db",
         "ns6/in-addr.db",
+        "ns6/sigaxfr.bk",
         "ns7/_default.tsigkeys",
         "ns7/example.com.db",
         "ns7/in-addr.db",
similarity index 84%
rename from bin/tests/system/nsupdate/tests_tcp_self_sig.py
rename to bin/tests/system/nsupdate/tests_update_sig.py
index 6e83aded29110aa20bac065c69f67ffd07fe15a5..42f60a2b56695fdf3d308cb450b043c6d384e258 100644 (file)
@@ -39,9 +39,29 @@ import dns.rdataclass
 import dns.rdataset
 import dns.rdatatype
 import dns.update
+import pytest
 
 import isctest
 
+pytestmark = pytest.mark.extra_artifacts(
+    [
+        "ans*/ans.run",
+        "ns*/*.bk",
+        "ns*/*.conf",
+        "ns*/*.db",
+        "ns*/*.db.jnl",
+        "ns*/*.db.signed",
+        "ns*/*.jnl",
+        "ns*/*.key",
+        "ns*/K*.key",
+        "ns*/K*.private",
+        "ns*/K*.state",
+        "ns*/dsset-*.",
+        "ns6/sigaxfr.bk",
+        "verylarge",
+    ]
+)
+
 
 def _make_sig_rdata(text):
     """Create a SIG rdata from text.
@@ -79,9 +99,9 @@ def test_tcp_self_sig_record(ns6):
     crash-reproducing precondition.
     """
     ptr_update = dns.update.UpdateMessage("in-addr.arpa.")
-    ptr_update.add("1.0.0.127.in-addr.arpa.", 600, "PTR", "localhost.")
+    ptr_update.add("1.0.53.10.in-addr.arpa.", 600, "PTR", "localhost.")
     response = isctest.query.tcp(
-        ptr_update, ns6.ip, port=ns6.ports.dns, source="127.0.0.1"
+        ptr_update, ns6.ip, port=ns6.ports.dns, source="10.53.0.1"
     )
     assert response.rcode() == dns.rcode.NOERROR
 
@@ -92,18 +112,58 @@ def test_tcp_self_sig_record(ns6):
     sig_update = dns.update.UpdateMessage("in-addr.arpa.")
     sig_update.add("1.0.0.127.in-addr.arpa.", rds)
 
-    response = isctest.query.tcp(
-        sig_update, ns6.ip, port=ns6.ports.dns, source="127.0.0.1"
-    )
-    assert response.rcode() == dns.rcode.REFUSED
+    with ns6.watch_log_from_here() as watcher:
+        response = isctest.query.tcp(
+            sig_update, ns6.ip, port=ns6.ports.dns, source="10.53.0.1"
+        )
+        assert response.rcode() == dns.rcode.REFUSED
+
+        watcher.wait_for_line(
+            "updating zone 'in-addr.arpa/IN': update failed: SIG updates are not allowed (REFUSED)"
+        )
 
     # Confirm nothing of type SIG was stored.
-    msg = isctest.query.create("1.0.0.127.in-addr.arpa.", "SIG")
+    msg = isctest.query.create("1.0.53.10.in-addr.arpa.", "SIG")
     res = isctest.query.tcp(msg, ns6.ip, port=ns6.ports.dns)
     stored = any(rrset.rdtype == dns.rdatatype.SIG for rrset in res.answer)
     assert not stored, "SIG record was stored despite REFUSED response"
 
 
+def test_tcp_self_nxt_record(ns6):
+    """NXT (type 30) updates must be refused at the front door.
+
+    NXT is the legacy DNSSEC denial-of-existence type, obsolete since
+    RFC 3755 replaced it with NSEC.  Accepting it via dynamic update
+    would let an authorised updater inject records that the signing
+    and cut-point logic has no provision for.
+    """
+    # A second owner under a source that also matches tcp-self.
+    source = "10.53.0.2"
+    owner = "2.0.53.10.in-addr.arpa."
+
+    ptr_update = dns.update.UpdateMessage("in-addr.arpa.")
+    ptr_update.add(owner, 600, "PTR", "localhost.")
+    response = isctest.query.tcp(ptr_update, ns6.ip, port=ns6.ports.dns, source=source)
+    assert response.rcode() == dns.rcode.NOERROR
+
+    nxt = _make_nxt_rdata()
+    rds = dns.rdataset.Rdataset(dns.rdataclass.IN, dns.rdatatype.NXT)
+    rds.update_ttl(600)
+    rds.add(nxt)
+    nxt_update = dns.update.UpdateMessage("in-addr.arpa.")
+    nxt_update.add(owner, rds)
+
+    with ns6.watch_log_from_here() as watcher:
+        response = isctest.query.tcp(
+            nxt_update, ns6.ip, port=ns6.ports.dns, source="10.53.0.1"
+        )
+        assert response.rcode() == dns.rcode.REFUSED
+
+        watcher.wait_for_line(
+            "updating zone 'in-addr.arpa/IN': update failed: NXT updates are not allowed (REFUSED)"
+        )
+
+
 def test_sig_covers_preserved_via_axfr(ns6):
     """Regression test for GL#5818 Finding 1, reached via AXFR.
 
@@ -170,31 +230,3 @@ def test_sig_covers_preserved_via_axfr(ns6):
         "the Finding 1 bug both records are filed under typepair (SIG, 0) "
         "and share the first-seen TTL (600)."
     )
-
-
-def test_tcp_self_nxt_record(ns6):
-    """NXT (type 30) updates must be refused at the front door.
-
-    NXT is the legacy DNSSEC denial-of-existence type, obsolete since
-    RFC 3755 replaced it with NSEC.  Accepting it via dynamic update
-    would let an authorised updater inject records that the signing
-    and cut-point logic has no provision for.
-    """
-    # A second owner under a source that also matches tcp-self.
-    source = "127.0.0.2"
-    owner = "2.0.0.127.in-addr.arpa."
-
-    ptr_update = dns.update.UpdateMessage("in-addr.arpa.")
-    ptr_update.add(owner, 600, "PTR", "localhost.")
-    response = isctest.query.tcp(ptr_update, ns6.ip, port=ns6.ports.dns, source=source)
-    assert response.rcode() == dns.rcode.NOERROR
-
-    nxt = _make_nxt_rdata()
-    rds = dns.rdataset.Rdataset(dns.rdataclass.IN, dns.rdatatype.NXT)
-    rds.update_ttl(600)
-    rds.add(nxt)
-    nxt_update = dns.update.UpdateMessage("in-addr.arpa.")
-    nxt_update.add(owner, rds)
-
-    response = isctest.query.tcp(nxt_update, ns6.ip, port=ns6.ports.dns, source=source)
-    assert response.rcode() == dns.rcode.REFUSED