From: Evan Hunt Date: Thu, 2 Jul 2026 01:49:18 +0000 (-0700) Subject: Move the dnssec_findnoqname_mismatch test into dnssec_py X-Git-Tag: v9.21.24~3^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=825750f3f8bbec0ede095e44d49b2c4fd232263e;p=thirdparty%2Fbind9.git Move the dnssec_findnoqname_mismatch test into dnssec_py Instead of adding a new separate test for this, we can add it as a module in the dnssec_py test. --- diff --git a/bin/tests/system/_common/zones.conf.j2 b/bin/tests/system/_common/zones.conf.j2 index 27bcb942be3..bf4a58b698d 100644 --- a/bin/tests/system/_common/zones.conf.j2 +++ b/bin/tests/system/_common/zones.conf.j2 @@ -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 index f4fbd8a617b..00000000000 --- a/bin/tests/system/dnssec_findnoqname_mismatch/ns2/named.conf.j2 +++ /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@"; -}; diff --git a/bin/tests/system/dnssec_py/ans4/ans.py b/bin/tests/system/dnssec_py/ans4/ans.py index af8704370ab..5869641a2ca 100644 --- a/bin/tests/system/dnssec_py/ans4/ans.py +++ b/bin/tests/system/dnssec_py/ans4/ans.py @@ -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()) diff --git a/bin/tests/system/dnssec_findnoqname_mismatch/ans1/ans.py b/bin/tests/system/dnssec_py/ans4/noqname_mismatch.py 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 70f05865799..9c8b270e534 100644 --- a/bin/tests/system/dnssec_findnoqname_mismatch/ans1/ans.py +++ b/bin/tests/system/dnssec_py/ans4/noqname_mismatch.py @@ -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() diff --git a/bin/tests/system/dnssec_py/common.py b/bin/tests/system/dnssec_py/common.py index ebece637dbf..a972242fd53 100644 --- a/bin/tests/system/dnssec_py/common.py +++ b/bin/tests/system/dnssec_py/common.py @@ -11,14 +11,19 @@ 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", + ] + ), +] diff --git a/bin/tests/system/dnssec_findnoqname_mismatch/tests_findnoqname_mismatch.py b/bin/tests/system/dnssec_py/tests_findnoqname_mismatch.py 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 413b8205c47..5a4ff903900 100644 --- a/bin/tests/system/dnssec_findnoqname_mismatch/tests_findnoqname_mismatch.py +++ b/bin/tests/system/dnssec_py/tests_findnoqname_mismatch.py @@ -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):