]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add system test for SIG record handling in update-policy tcp-self
authorOndřej Surý <ondrej@isc.org>
Tue, 7 Apr 2026 14:40:36 +0000 (16:40 +0200)
committerOndřej Surý <ondrej@isc.org>
Fri, 17 Apr 2026 14:09:39 +0000 (16:09 +0200)
Verify that a SIG record sent via TCP dynamic update is accepted
by the tcp-self update-policy and correctly stored in the zone.

bin/tests/system/nsupdate/tests_tcp_self_sig.py [new file with mode: 0644]

diff --git a/bin/tests/system/nsupdate/tests_tcp_self_sig.py b/bin/tests/system/nsupdate/tests_tcp_self_sig.py
new file mode 100644 (file)
index 0000000..3378097
--- /dev/null
@@ -0,0 +1,88 @@
+# 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.
+
+"""
+Regression test for GL#5818: update-policy tcp-self must handle SIG records.
+
+The dns_db_findrdataset() REQUIRE check only accepted dns_rdatatype_rrsig
+for the covers parameter, causing named to abort when processing a SIG
+record (type 24) via dynamic update with tcp-self policy.
+"""
+
+import dns.rcode
+import dns.rdata
+import dns.rdataclass
+import dns.rdataset
+import dns.rdatatype
+import dns.update
+
+import isctest
+
+
+def _make_sig_rdata(text):
+    """Create a SIG rdata from text.
+
+    dnspython has no native text parser for the legacy SIG type (24),
+    but the wire format is identical to RRSIG (46).  Parse as RRSIG,
+    then re-wrap as SIG via the wire representation.
+    """
+    rrsig = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.RRSIG, text)
+    wire = rrsig.to_digestable()
+    return dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.SIG, wire, 0, len(wire))
+
+
+def test_tcp_self_sig_record(ns6):
+    """Verify that update-policy tcp-self accepts a SIG record via TCP.
+
+    The node must already exist (have at least one RR) so that
+    dns_db_findrdataset() is called during the update — that is the
+    function whose REQUIRE was too strict.  We therefore add a PTR
+    record first.
+    """
+    # First, create the node by adding a PTR record (allowed by tcp-self).
+    ptr_update = dns.update.UpdateMessage("in-addr.arpa.")
+    ptr_update.add("1.0.0.127.in-addr.arpa.", 600, "PTR", "localhost.")
+    response = isctest.query.tcp(
+        ptr_update, ns6.ip, port=ns6.ports.dns, source="127.0.0.1"
+    )
+    assert response.rcode() == dns.rcode.NOERROR
+
+    # Now add a SIG record at the same node — this triggers the
+    # dns_db_findrdataset() call with type=SIG and covers=A.
+    sig = _make_sig_rdata("A 6 0 86400 20260331170000 20260318160000 21831 . 0000")
+    rds = dns.rdataset.Rdataset(dns.rdataclass.IN, dns.rdatatype.SIG)
+    rds.update_ttl(600)
+    rds.add(sig)
+
+    sig_update = dns.update.UpdateMessage("in-addr.arpa.")
+    sig_update.add("1.0.0.127.in-addr.arpa.", rds)
+
+    with ns6.watch_log_from_here() as watcher:
+        response = isctest.query.tcp(
+            sig_update, ns6.ip, port=ns6.ports.dns, source="127.0.0.1"
+        )
+        assert response.rcode() == dns.rcode.NOERROR
+
+        watcher.wait_for_sequence(
+            [
+                "update-policy: using: signer= name=1.0.0.127.in-addr.arpa"
+                " addr=127.0.0.1 tcp=1 type=SIG target=",
+                "update-policy: trying: grant * tcp-self . PTR(1) ANY(2) A",
+                "update-policy: tcp-self=1.0.0.127.IN-ADDR.ARPA",
+                "update-policy: matched: grant * tcp-self . PTR(1) ANY(2) A",
+            ]
+        )
+
+    # Verify the SIG record was actually stored
+    msg = isctest.query.create("1.0.0.127.in-addr.arpa.", "SIG")
+    res = isctest.query.tcp(msg, ns6.ip, port=ns6.ports.dns)
+    found = any(rrset.rdtype == dns.rdatatype.SIG for rrset in res.answer)
+    assert found, "SIG record not found in answer section"