]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Move the dnssec_findnoqname_mismatch test into dnssec_py
authorEvan Hunt <each@isc.org>
Thu, 2 Jul 2026 01:49:18 +0000 (18:49 -0700)
committerMichał Kępień <michal@isc.org>
Fri, 10 Jul 2026 07:26:46 +0000 (09:26 +0200)
Instead of adding a new separate test for this, we can add it
as a module in the dnssec_py test.

bin/tests/system/_common/zones.conf.j2
bin/tests/system/dnssec_findnoqname_mismatch/ns2/named.conf.j2 [deleted file]
bin/tests/system/dnssec_py/ans4/ans.py
bin/tests/system/dnssec_py/ans4/noqname_mismatch.py [moved from bin/tests/system/dnssec_findnoqname_mismatch/ans1/ans.py with 86% similarity]
bin/tests/system/dnssec_py/common.py
bin/tests/system/dnssec_py/tests_findnoqname_mismatch.py [moved from bin/tests/system/dnssec_findnoqname_mismatch/tests_findnoqname_mismatch.py with 82% similarity]

index 27bcb942be3020e7c3485021b8af4b2dcea1e24b..bf4a58b698deb36a22cbcffb3e0097e6b87d6e26 100644 (file)
@@ -3,7 +3,11 @@
 {% if zone.ns.name == ns.name %}
 zone "@zone.name@" {
        type @zone.type@;
+{% if zone.type == "static-stub" %}
+        server-addresses { @zone.ns.ip@; };
+{% else %}
        file "@zone.filepath@";
+{% endif %}
 };
 {% endif %}
 {% endfor %}
diff --git a/bin/tests/system/dnssec_findnoqname_mismatch/ns2/named.conf.j2 b/bin/tests/system/dnssec_findnoqname_mismatch/ns2/named.conf.j2
deleted file mode 100644 (file)
index f4fbd8a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// validating resolver
-
-options {
-       query-source address 10.53.0.2;
-       notify-source 10.53.0.2;
-       transfer-source 10.53.0.2;
-       port @PORT@;
-       pid-file "named.pid";
-       listen-on { 10.53.0.2; };
-       listen-on-v6 { none; };
-       recursion yes;
-       dnssec-validation yes;
-};
-
-controls {
-       inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
-};
-
-include "../../_common/rndc.key";
-
-zone "." {
-       type hint;
-       file "../../_common/root.hint";
-};
-
-zone "f217.test" {
-       type static-stub;
-       server-addresses { 10.53.0.1; };
-};
-
-trust-anchors {
-       f217.test. static-key 257 3 13 "@ZONE_DNSKEY@";
-};
index af8704370abcfe10735f4d3347ce3e192db4bc01..5869641a2ca5fe438ad4d40cf80b11a7a2d451b1 100644 (file)
@@ -17,7 +17,7 @@ AsyncDnsServer.  Keeping each domain's crafted-response logic in its own
 file bounds its scope as the server accrues unrelated domains.
 """
 
-from dnssec_py.ans4 import rrsig_labels_signer_ans, sibling_ds_ans
+from dnssec_py.ans4 import noqname_mismatch, rrsig_labels_signer_ans, sibling_ds_ans
 from isctest.asyncserver import AsyncDnsServer
 
 
@@ -25,6 +25,8 @@ def main() -> None:
     server = AsyncDnsServer()
 
     server.install_response_handler(sibling_ds_ans.SiblingDsInjectionHandler())
+    if noqname_mismatch.PEM_PATH.exists():
+        server.install_response_handlers(noqname_mismatch.RuntimeCheckHandler())
     if rrsig_labels_signer_ans.PEM_PATH.exists():
         server.install_response_handler(rrsig_labels_signer_ans.AttackerZoneHandler())
 
similarity index 86%
rename from bin/tests/system/dnssec_findnoqname_mismatch/ans1/ans.py
rename to bin/tests/system/dnssec_py/ans4/noqname_mismatch.py
index 70f05865799a8a00c48683b9054f6829c29f56aa..9c8b270e5349f8141447c3f063ef6d697f43492a 100644 (file)
@@ -10,29 +10,25 @@ from datetime import datetime, timedelta, timezone
 from pathlib import Path
 
 import base64
-import json
 
 from cryptography.hazmat.primitives import serialization
+from dns.rdtypes.dnskeybase import Flag
 
 import dns.dnssec
 import dns.flags
 import dns.message
 import dns.name
+import dns.rcode
 import dns.rdata
 import dns.rdataclass
-import dns.rcode
 import dns.rdatatype
 import dns.rrset
 
-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
 
 TTL = 300
 ZONE = "f217.test."
+PEM_PATH = Path(f"{ZONE}.pem")
 CHILD = f"evil.{ZONE}"
 ATTACK = f"www.{CHILD}"
 NSEC_OWNER = f"00000000.{CHILD}"
@@ -52,23 +48,20 @@ def name(text: str) -> dns.name.Name:
 
 
 def load_key() -> Key:
-    path = Path(__file__).resolve().parent / "keys.json"
-    with path.open(encoding="utf-8") as keys_file:
-        raw_key = json.load(keys_file)[ZONE]
-
     private_key = serialization.load_pem_private_key(
-        raw_key["private_pem"].encode("ascii"),
-        password=None,
+        PEM_PATH.read_bytes(), password=None
     )
-    dnskey = dns.rdata.from_text(
-        dns.rdataclass.IN, dns.rdatatype.DNSKEY, raw_key["dnskey"]
+
+    dnskey = dns.dnssec.make_dnskey(
+        private_key.public_key(),
+        dns.dnssec.Algorithm.ECDSAP256SHA256,
+        flags=Flag.ZONE | Flag.SEP,
     )
+
     return Key(name(ZONE), private_key, dnskey)
 
 
-def rrset(
-    owner: str, rdtype: dns.rdatatype.RdataType, *rdatas: str
-) -> dns.rrset.RRset:
+def rrset(owner: str, rdtype: dns.rdatatype.RdataType, *rdatas: str) -> dns.rrset.RRset:
     return dns.rrset.from_text(owner, TTL, dns.rdataclass.IN, rdtype, *rdatas)
 
 
@@ -162,9 +155,14 @@ def add_attack_answer(response: dns.message.Message) -> None:
     response.authority.append(nsec3)
 
 
-class RuntimeCheckHandler(ResponseHandler):
-    def __init__(self, key: Key) -> None:
-        self.key = key
+class RuntimeCheckHandler(DomainHandler):
+    """Serve attacker.rrsig-labels-signer. with crafted wildcard RRSIG."""
+
+    domains = [ZONE]
+
+    def __init__(self) -> None:
+        super().__init__()
+        self.key = load_key()
         self.zone = name(ZONE)
         self.child = name(CHILD)
         self.attack = name(ATTACK)
@@ -197,13 +195,3 @@ class RuntimeCheckHandler(ResponseHandler):
             add_signed(qctx.response.authority, soa_rrset(ZONE), self.key)
 
         yield DnsResponseSend(qctx.response, authoritative=True)
-
-
-def main() -> None:
-    server = AsyncDnsServer(default_aa=True)
-    server.install_response_handlers(RuntimeCheckHandler(load_key()))
-    server.run()
-
-
-if __name__ == "__main__":
-    main()
index ebece637dbf741baea84b87bad1a0248109ed5b0..a972242fd53e269e1b0a20bc04d78f4085ae85ed 100644 (file)
 
 import pytest
 
-DNSSEC_PY_MARK = pytest.mark.extra_artifacts(
-    [
-        "ans*/*.db",
-        "ans*/*.run",
-        "ans*/*.pem",
-        "ns*/dsset-*",
-        "ns*/trusted.conf",
-        "ns*/zones/*.db",
-        "ns*/zones/*.db.signed",
-    ]
-)
+import isctest
+
+DNSSEC_PY_MARK = [
+    isctest.mark.with_ecdsa_deterministic,
+    pytest.mark.extra_artifacts(
+        [
+            "ans*/*.db",
+            "ans*/*.run",
+            "ans*/*.pem",
+            "ns*/dsset-*",
+            "ns*/trusted.conf",
+            "ns*/zones/*.db",
+            "ns*/zones/*.db.signed",
+        ]
+    ),
+]
similarity index 82%
rename from bin/tests/system/dnssec_findnoqname_mismatch/tests_findnoqname_mismatch.py
rename to bin/tests/system/dnssec_py/tests_findnoqname_mismatch.py
index 413b8205c4713f416e3a816c2c545ee770e51485..5a4ff9039007f0c26ea274ff4140a6a85aa1ec46 100644 (file)
@@ -4,9 +4,6 @@
 #
 # SPDX-License-Identifier: MPL-2.0
 
-from pathlib import Path
-
-import json
 
 from cryptography.hazmat.primitives import serialization
 from cryptography.hazmat.primitives.asymmetric import ec
@@ -15,7 +12,10 @@ import dns.dnssec
 import dns.name
 import dns.rdataclass
 import dns.rdatatype
-import pytest
+
+from dnssec_py.common import DNSSEC_PY_MARK
+from isctest.template import NS4, NS9, Nameserver, zones
+from isctest.zone import PythonZoneKey, Zone
 
 import isctest
 
@@ -24,15 +24,10 @@ CHILD = f"evil.{ZONE}"
 ATTACK = f"www.{CHILD}"
 NSEC_OWNER = f"00000000.{CHILD}"
 FORGED_A = "192.0.2.217"
-AUTH = "10.53.0.1"
-RESOLVER = "10.53.0.2"
+AUTH = "10.53.0.4"
+RESOLVER = "10.53.0.9"
 
-pytestmark = pytest.mark.extra_artifacts(
-    [
-        "ans1/ans.run",
-        "ans1/keys.json",
-    ]
-)
+pytestmark = DNSSEC_PY_MARK
 
 
 def _make_key():
@@ -54,10 +49,20 @@ def _make_key():
 
 
 def bootstrap():
-    keys = {ZONE: _make_key()}
-    Path("ans1/keys.json").write_text(json.dumps(keys, indent=2), encoding="ascii")
-    zone_dnskey = "".join(keys[ZONE]["dnskey"].split()[3:])
-    return {"ZONE_DNSKEY": zone_dnskey}
+    # for a static stub zones, NS name is the stub and NS IP is the target
+    ans = Nameserver(NS9.name, NS9.num, NS4.ip, NS4.ip6)
+
+    zone = Zone(ZONE, ans, signed=False, zone_type="static-stub")
+    zonekey = PythonZoneKey.generate(zone)
+    zonekey.write_private_key_pem(f"ans4/{ZONE}.pem")
+    zone.keys = [zonekey]
+
+    ta = zonekey.into_ta("static-key")
+
+    return {
+        "zones": zones([zone]),
+        "trust_anchors": [ta],
+    }
 
 
 def _query(server, qname, qtype):