diff --git a/bin/tests/system/wildcard/ns1/named.conf.in b/bin/tests/system/wildcard/ns1/named.conf.in index ac02abf8dc..7ae63ac1b9 100644 --- a/bin/tests/system/wildcard/ns1/named.conf.in +++ b/bin/tests/system/wildcard/ns1/named.conf.in @@ -34,6 +34,12 @@ zone "example" { type primary; file "example.db"; }; zone "nsec" { type primary; file "nsec.db.signed"; }; zone "private.nsec" { type primary; file "private.nsec.db.signed"; }; +zone "nestedwild.test" { + type primary; + file "nestedwild.db"; + check-names ignore; +}; + /* * The contents of nsec3 and private.nsec3 are specially chosen to * have separate NSEC3 records for the "no qname proof" and the diff --git a/bin/tests/system/wildcard/ns1/nestedwild.db.in b/bin/tests/system/wildcard/ns1/nestedwild.db.in new file mode 100644 index 0000000000..02278a8e52 --- /dev/null +++ b/bin/tests/system/wildcard/ns1/nestedwild.db.in @@ -0,0 +1,16 @@ +; 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. + +$ORIGIN nestedwild.test. +nestedwild.test. 3600 IN SOA . . 0 0 0 0 0 +nestedwild.test. 3600 NS ns.example.test. +*.nestedwild.test. 3600 A 192.0.2.1 +*.*.*.nestedwild.test. 3600 A 192.0.2.1 \ No newline at end of file diff --git a/bin/tests/system/wildcard/ns1/sign.sh b/bin/tests/system/wildcard/ns1/sign.sh index d1d86260f7..3aaa1229cd 100755 --- a/bin/tests/system/wildcard/ns1/sign.sh +++ b/bin/tests/system/wildcard/ns1/sign.sh @@ -20,6 +20,7 @@ dssets= # RFC 4592 example zone. cp allwild.db.in allwild.db cp example.db.in example.db +cp nestedwild.db.in nestedwild.db zone=nsec infile=nsec.db.in diff --git a/bin/tests/system/wildcard/tests_wildcard.py b/bin/tests/system/wildcard/tests_wildcard.py index e5ea5c1b91..cd5b278d28 100755 --- a/bin/tests/system/wildcard/tests_wildcard.py +++ b/bin/tests/system/wildcard/tests_wildcard.py @@ -132,3 +132,62 @@ def test_wildcard_with_star_not_synthesized( isctest.check.is_response_to(response_msg, query_msg) isctest.check.nxdomain(response_msg) isctest.check.empty_answer(query_msg) + + +NESTED_SUFFIX = dns.name.from_text("*.*.nestedwild.test.") + + +# Force `*.*.*.nestedwild.test.` to be checked. +@example(name=isctest.name.prepend_label("*", NESTED_SUFFIX)) +@given(name=dns_names(suffix=NESTED_SUFFIX, min_labels=len(NESTED_SUFFIX) + 1)) +def test_name_in_between_wildcards(name: dns.name.Name, named_port: int) -> None: + """Check nested wildcard cases. + + There are `*.nestedwild.test. A` and `*.*.*.nestedwild.test. A` records present in their zone. + This means that `foo.*.nestedwild.test. A` must not be synthetized (see test above) + but `foo.*.*.nestedwild.test A` must. + """ + + # `*.*.*.nestedwild.test.` and `*.foo.*.*.nestedwild.test.` must be NOERROR + # `foo.*.*.*.nestedwild.test` must be NXDOMAIN (see test below). + assume( + len(name) == len(NESTED_SUFFIX) + 1 + or name.labels[-len(NESTED_SUFFIX) - 1] != b"*" + ) + + query_msg = dns.message.make_query(name, WILDCARD_RDTYPE) + response_msg = isctest.query.tcp(query_msg, IP_ADDR, named_port, timeout=TIMEOUT) + + isctest.check.is_response_to(response_msg, query_msg) + isctest.check.noerror(response_msg) + expected_answer = [ + dns.rrset.from_text( + query_msg.question[0].name, + 300, # TTL, ignored by dnspython comparison + dns.rdataclass.IN, + WILDCARD_RDTYPE, + WILDCARD_RDATA, + ) + ] + assert response_msg.answer == expected_answer, str(response_msg) + + +@given( + name=dns_names( + suffix=isctest.name.prepend_label("*", NESTED_SUFFIX), + min_labels=len(NESTED_SUFFIX) + 2, + ) +) +def test_name_nested_wildcard_subdomains_not_synthesized( + name: dns.name.Name, named_port: int +): + """Check nested wildcard cases. + + `foo.*.*.*.nestedwild.test. A` must not be synthesized. + """ + query_msg = dns.message.make_query(name, WILDCARD_RDTYPE) + response_msg = isctest.query.tcp(query_msg, IP_ADDR, named_port, timeout=TIMEOUT) + + isctest.check.is_response_to(response_msg, query_msg) + isctest.check.nxdomain(response_msg) + isctest.check.empty_answer(query_msg)