From: Yorgos Thessalonikefs Date: Mon, 12 May 2025 12:26:47 +0000 (+0200) Subject: Fix auth nsec3 code (#1280) X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=4e23523d1a56ad3a16b9f2437bc8cb2e3feb7015;p=thirdparty%2Funbound.git Fix auth nsec3 code (#1280) - Fix NSEC3 code to not break on broken auth zones that include unsigned out of zone (above apex) data. Could lead to hang while trying to prove a wildcard answer. Reported by Dmitrii Kuvaiskii from Amazon Web Services. - Tests for NSEC3 auth zones with out of zone data. --- diff --git a/services/authzone.c b/services/authzone.c index 3c3dc9ad0..7d1df032e 100644 --- a/services/authzone.c +++ b/services/authzone.c @@ -2413,14 +2413,12 @@ az_find_wildcard(struct auth_zone* z, struct query_info* qinfo, if(!dname_subdomain_c(nm, z->name)) return NULL; /* out of zone */ while((node=az_find_wildcard_domain(z, nm, nmlen))==NULL) { - /* see if we can go up to find the wildcard */ if(nmlen == z->namelen) return NULL; /* top of zone reached */ if(ce && nmlen == ce->namelen) return NULL; /* ce reached */ - if(dname_is_root(nm)) - return NULL; /* cannot go up */ - dname_remove_label(&nm, &nmlen); + if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) + return NULL; /* can't go up */ } return node; } @@ -2442,9 +2440,8 @@ az_find_candidate_ce(struct auth_zone* z, struct query_info* qinfo, n = az_find_name(z, nm, nmlen); /* delete labels and go up on name */ while(!n) { - if(dname_is_root(nm)) - return NULL; /* cannot go up */ - dname_remove_label(&nm, &nmlen); + if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) + return NULL; /* can't go up */ n = az_find_name(z, nm, nmlen); } return n; @@ -2456,8 +2453,7 @@ az_domain_go_up(struct auth_zone* z, struct auth_data* n) { uint8_t* nm = n->name; size_t nmlen = n->namelen; - while(!dname_is_root(nm)) { - dname_remove_label(&nm, &nmlen); + while(dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) { if((n=az_find_name(z, nm, nmlen)) != NULL) return n; } @@ -2788,9 +2784,9 @@ az_find_nsec_cover(struct auth_zone* z, struct auth_data** node) /* but there could be glue, and if this is node, then it has no NSEC. * Go up to find nonglue (previous) NSEC-holding nodes */ while((rrset=az_domain_rrset(*node, LDNS_RR_TYPE_NSEC)) == NULL) { - if(dname_is_root(nm)) return NULL; if(nmlen == z->namelen) return NULL; - dname_remove_label(&nm, &nmlen); + if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) + return NULL; /* can't go up */ /* adjust *node for the nsec rrset to find in */ *node = az_find_name(z, nm, nmlen); } @@ -3018,12 +3014,9 @@ az_nsec3_find_ce(struct auth_zone* z, uint8_t** cenm, size_t* cenmlen, struct auth_data* node; while((node = az_nsec3_find_exact(z, *cenm, *cenmlen, algo, iter, salt, saltlen)) == NULL) { - if(*cenmlen == z->namelen) { - /* next step up would take us out of the zone. fail */ - return NULL; - } + if(!dname_remove_label_limit_len(cenm, cenmlen, z->namelen)) + return NULL; /* can't go up */ *no_exact_ce = 1; - dname_remove_label(cenm, cenmlen); } return node; } @@ -3340,7 +3333,8 @@ az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo, } else if(ce) { uint8_t* wildup = wildcard->name; size_t wilduplen= wildcard->namelen; - dname_remove_label(&wildup, &wilduplen); + if(!dname_remove_label_limit_len(&wildup, &wilduplen, z->namelen)) + return 0; /* can't go up */ if(!az_add_nsec3_proof(z, region, msg, wildup, wilduplen, msg->qinfo.qname, msg->qinfo.qname_len, 0, insert_ce, 1, 0)) diff --git a/testcode/unitdname.c b/testcode/unitdname.c index 08a2dbad7..32a9a5fdc 100644 --- a/testcode/unitdname.c +++ b/testcode/unitdname.c @@ -476,6 +476,23 @@ dname_test_removelabel(void) unit_assert( l == 1 ); } +/** test dname_remove_label_limit_len */ +static void +dname_test_removelabellimitlen(void) +{ + uint8_t* orig = (uint8_t*)"\007example\003com\000"; + uint8_t* n = orig; + size_t l = 13; + size_t lenlimit = 5; /* com.*/ + unit_show_func("util/data/dname.c", "dname_remove_label_limit_len"); + unit_assert(dname_remove_label_limit_len(&n, &l, lenlimit) == 1); + unit_assert( n == orig+8 ); + unit_assert( l == 5 ); + unit_assert(dname_remove_label_limit_len(&n, &l, lenlimit) == 0); + unit_assert( n == orig+8 ); + unit_assert( l == 5 ); +} + /** test dname_signame_label_count */ static void dname_test_sigcount(void) @@ -1024,6 +1041,7 @@ void dname_test(void) dname_test_subdomain(); dname_test_isroot(); dname_test_removelabel(); + dname_test_removelabellimitlen(); dname_test_sigcount(); dname_test_iswild(); dname_test_canoncmp(); diff --git a/testdata/auth_nsec3_ent_with_out_of_zone_data.rpl b/testdata/auth_nsec3_ent_with_out_of_zone_data.rpl new file mode 100644 index 000000000..338151565 --- /dev/null +++ b/testdata/auth_nsec3_ent_with_out_of_zone_data.rpl @@ -0,0 +1,228 @@ +; config options +server: + target-fetch-policy: "0 0 0 0 0" + +auth-zone: + name: "unbound-auth-test.nlnetlabs.nl." + ## zonefile (or none). + ## zonefile: "example.com.zone" + ## master by IP address or hostname + ## can list multiple masters, each on one line. + ## master: + ## url for http fetch + ## url: + ## queries from downstream clients get authoritative answers. + ## for-downstream: yes + for-downstream: yes + ## queries are used to fetch authoritative answers from this zone, + ## instead of unbound itself sending queries there. + ## for-upstream: yes + for-upstream: yes + ## on failures with for-upstream, fallback to sending queries to + ## the authority servers + ## fallback-enabled: no + + ## this line generates zonefile: \n"/tmp/xxx.example.com"\n + zonefile: +TEMPFILE_NAME unbound-auth-test.nlnetlabs.nl + ## this is the inline file /tmp/xxx.unbound-auth-test.nlnetlabs.nl + ## the tempfiles are deleted when the testrun is over. +TEMPFILE_CONTENTS unbound-auth-test.nlnetlabs.nl +;; Zone: unbound-auth-test.nlnetlabs.nl. +; +unbound-auth-test.nlnetlabs.nl. 3600 IN SOA ns.nlnetlabs.nl. ralph.nlnetlabs.nl. 1554201247 14400 3600 604800 3600 +unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG SOA 13 3 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. NLFcC2oet+HC+1dhT4D/2JJFIcMiRtTM81KwvT7u8ybF3iDE4bnyrILvQk8DsizpYKwk+D3J3tMC3TV5+//qFw== +;; Out of zone record that shouldn't break NSEC3 proofs. +;; There was a bug that would keep removing labels and use this out of zone +;; record. +nlnetlabs.nl. 3600 IN NS ns.nlnetlabs.nl. +; +unbound-auth-test.nlnetlabs.nl. 3600 IN NS ns.nlnetlabs.nl. +unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NS 13 3 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. Gm0UF77ljiInG4/HZ6Tkzx7z9N45WwwmbBt9KxeN3z1BkdBLiy10Du71ZBFLP71b+USs1rv5SJQ0hteZFbl8sg== +unbound-auth-test.nlnetlabs.nl. 3600 IN DNSKEY 256 3 13 S3Da9HqpFj0pEbI8WXOdkvN3vgZ6qxNSz4XyKkmWWAG28kq5T+/lWp36DUDvnMI9wJNuixzUHtgZ6oZoAaVrPg== ;{id = 15486 (zsk), size = 256b} +unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG DNSKEY 13 3 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. 1cLFaDb6kP8KnRJujW1ieHUdS5Tgdv59TCZ+FloCRJMJBwQAow6UKAIY7HHlTb8IHTajyUrjlxX/dN8S/5VwuA== +unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3PARAM 1 0 1 - +unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3PARAM 13 3 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. GWgtJArNpfJ4ifoinUBUVRTlkk0CMemdozhMKY13dk3EQMP0jb4g49PcTAgEP2dBUs9efttQVQQpmFPyTGfN1w== +tvdhfml24jp7cott1qijj9812qu9ibh3.unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3 1 0 1 - 41pcah2j3fr8k99gj5pveh4igrjfc871 NS SOA RRSIG DNSKEY NSEC3PARAM ;{ flags: -, from: unbound-auth-test.nlnetlabs.nl. to: b.b.unbound-auth-test.nlnetlabs.nl.} +tvdhfml24jp7cott1qijj9812qu9ibh3.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3 13 4 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. DzwQTaZj4j29eHXEKllIFcq4yNWA7VMqkh8+gCrBO+GEek9+hGxL6ANsU0Hv6glyBmPDeYUZcy4xy0EEj1R4hQ== +; +;; Empty nonterminal: b.unbound-auth-test.nlnetlabs.nl. +apejmh1fqds9gir0nnsf4d5gtno10tg1.unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3 1 0 1 - dbs0aj50410urbvt3ghfr644n7h06gs5 ;{ flags: -, from: b.unbound-auth-test.nlnetlabs.nl. to: c.b.unbound-auth-test.nlnetlabs.nl.} +apejmh1fqds9gir0nnsf4d5gtno10tg1.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3 13 4 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. m9B0W8xDZF6ml/m8OujrZZBiF1O0wAeKciK/5FMT/hCjHR0hMrbXBPg/ZntpVJD/Pko2HcBvWKu87U721yTHyQ== +; +;; Empty nonterminal: a.b.unbound-auth-test.nlnetlabs.nl. +toqivctpt4pdcp5g19neqt19fvtgbgeu.unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3 1 0 1 - tvdhfml24jp7cott1qijj9812qu9ibh3 ;{ flags: -, from: a.b.unbound-auth-test.nlnetlabs.nl. to: unbound-auth-test.nlnetlabs.nl.} +toqivctpt4pdcp5g19neqt19fvtgbgeu.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3 13 4 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. Jr1oPPs+DGBVV13n4gG4AGVFsleItluLbtCIyQDcYZEA+e5JMkrLzfW3rXqXaUSUauR4iEu5FmTfs4GTsumdUw== +; +*.a.b.unbound-auth-test.nlnetlabs.nl. 3600 IN TXT "*.a.b" +*.a.b.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG TXT 13 5 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. NrMUaNzZp88lXit/HLL/iDBHspDSfoM//K+/0VwUYRZjmVJQQHCHtHBGgR4NgrLi3ffvCAWq2LNGxDm+YMSl3g== +jrtu61ssgd18lfjglqrbbs5b2vmbh6cl.unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3 1 0 1 - k8r2bchsbehs5dbu5d6ivjfnmjb3jc8s TXT RRSIG ;{ flags: -, from: *.a.b.unbound-auth-test.nlnetlabs.nl. to: *.c.b.unbound-auth-test.nlnetlabs.nl.} +jrtu61ssgd18lfjglqrbbs5b2vmbh6cl.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3 13 4 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. kLIhE9+iz1OybJwXbtRJZst+Mk5u4OAtpZGWSwJUfqD6dXAk+h6msKAR18jpPeL7cCjXjIAKIv3x4oYRkl+uKw== +; +;; Empty nonterminal: b.b.unbound-auth-test.nlnetlabs.nl. +41pcah2j3fr8k99gj5pveh4igrjfc871.unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3 1 0 1 - apejmh1fqds9gir0nnsf4d5gtno10tg1 ;{ flags: -, from: b.b.unbound-auth-test.nlnetlabs.nl. to: b.unbound-auth-test.nlnetlabs.nl.} +41pcah2j3fr8k99gj5pveh4igrjfc871.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3 13 4 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. XlIjnuF313w0GXn6vymrAcsyuxZSaN6IShFjxQ5T2HUFePHBNvtRkL+TtMQZNlR8nTR3+MWcON0cOZIGjVCCjg== +; +*.b.b.unbound-auth-test.nlnetlabs.nl. 3600 IN TXT "*.b.b" +*.b.b.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG TXT 13 5 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. FkS3ceWpoHyOKaa8OtywIl148Bwo0vkzBd263vqYe0puhuRa6IvNEk5ERdwfWt9eNEq+6IlizPT/dYxA2fXYXA== +ft7dasbom0copm9e2ak9k151dj08kjfs.unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3 1 0 1 - jrtu61ssgd18lfjglqrbbs5b2vmbh6cl TXT RRSIG ;{ flags: -, from: *.b.b.unbound-auth-test.nlnetlabs.nl. to: *.a.b.unbound-auth-test.nlnetlabs.nl.} +ft7dasbom0copm9e2ak9k151dj08kjfs.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3 13 4 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. 5QhLGohTRLQSGC8vstzDjqcwfrbOnLUG2OelSjvsZFy1smsWUxJBCQXQdx1+JX7xamZHlZESQtS+cELuZUqpvA== +; +;; Empty nonterminal: c.b.unbound-auth-test.nlnetlabs.nl. +dbs0aj50410urbvt3ghfr644n7h06gs5.unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3 1 0 1 - ft7dasbom0copm9e2ak9k151dj08kjfs ;{ flags: -, from: c.b.unbound-auth-test.nlnetlabs.nl. to: *.b.b.unbound-auth-test.nlnetlabs.nl.} +dbs0aj50410urbvt3ghfr644n7h06gs5.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3 13 4 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. hjk1foJWW68JK3O1Ktf0ZogoXVrMDw3mHVBBYTrpaBKX1gWR5icmJiOCYZWYx3z88PUnGkfH+kx4oDUjioqN+Q== +; +*.c.b.unbound-auth-test.nlnetlabs.nl. 3600 IN TXT "*.c.b" +*.c.b.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG TXT 13 5 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. b7rFR5tlx5Y5SQqNdYBtfD6DrkNx9h79GCmnZfWrUzRz+A256k2v08IPRJDK+WxEHuYHjfNnVWxjRr9M1OW2Iw== +k8r2bchsbehs5dbu5d6ivjfnmjb3jc8s.unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3 1 0 1 - toqivctpt4pdcp5g19neqt19fvtgbgeu TXT RRSIG ;{ flags: -, from: *.c.b.unbound-auth-test.nlnetlabs.nl. to: a.b.unbound-auth-test.nlnetlabs.nl.} +k8r2bchsbehs5dbu5d6ivjfnmjb3jc8s.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3 13 4 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. 34BS1ajedCNdfXgUfxTyiAK1ichfFLshhJ3TnfplrUps0UsZaQLEG+EIlP4wTBtro2c6V8YCSmOuxuce4gYoDw== +; +TEMPFILE_END + +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +CONFIG_END + +SCENARIO_BEGIN Test authority zone with NSEC3 empty nonterminal +; with exact match NSEC3 in existence (eg. not a CE-proof) + +; K.ROOT-SERVERS.NET. +RANGE_BEGIN 0 100 + ADDRESS 193.0.14.129 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. IN NS K.ROOT-SERVERS.NET. +SECTION ADDITIONAL +K.ROOT-SERVERS.NET. IN A 193.0.14.129 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +com. IN NS +SECTION AUTHORITY +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END +RANGE_END + +; a.gtld-servers.net. +RANGE_BEGIN 0 100 + ADDRESS 192.5.6.30 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +com. IN NS +SECTION ANSWER +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION AUTHORITY +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.44 +ENTRY_END +RANGE_END + +; ns.example.net. +RANGE_BEGIN 0 100 + ADDRESS 1.2.3.44 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.net. IN NS +SECTION ANSWER +example.net. IN NS ns.example.net. +SECTION ADDITIONAL +ns.example.net. IN A 1.2.3.44 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +ns.example.net. IN A +SECTION ANSWER +ns.example.net. IN A 1.2.3.44 +SECTION AUTHORITY +example.net. IN NS ns.example.net. +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +ns.example.net. IN AAAA +SECTION AUTHORITY +example.net. IN NS ns.example.net. +SECTION ADDITIONAL +www.example.net. IN A 1.2.3.44 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION ANSWER +example.com. IN NS ns.example.net. +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ENTRY_END +RANGE_END + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +a.b.unbound-auth-test.nlnetlabs.nl. IN TXT +ENTRY_END + +; recursion happens here. +STEP 20 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR AA RD RA DO NOERROR +SECTION QUESTION +a.b.unbound-auth-test.nlnetlabs.nl. IN TXT +SECTION ANSWER +SECTION AUTHORITY +unbound-auth-test.nlnetlabs.nl. 3600 IN SOA ns.nlnetlabs.nl. ralph.nlnetlabs.nl. 1554201247 14400 3600 604800 3600 +unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG SOA 13 3 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. NLFcC2oet+HC+1dhT4D/2JJFIcMiRtTM81KwvT7u8ybF3iDE4bnyrILv Qk8DsizpYKwk+D3J3tMC3TV5+//qFw== +toqivctpt4pdcp5g19neqt19fvtgbgeu.unbound-auth-test.nlnetlabs.nl. 3600 IN NSEC3 1 0 1 - TVDHFML24JP7COTT1QIJJ9812QU9IBH3 +toqivctpt4pdcp5g19neqt19fvtgbgeu.unbound-auth-test.nlnetlabs.nl. 3600 IN RRSIG NSEC3 13 4 3600 20190430103407 20190402103407 15486 unbound-auth-test.nlnetlabs.nl. Jr1oPPs+DGBVV13n4gG4AGVFsleItluLbtCIyQDcYZEA+e5JMkrLzfW3 rXqXaUSUauR4iEu5FmTfs4GTsumdUw== +ENTRY_END + +SCENARIO_END diff --git a/testdata/auth_nsec3_wild_with_out_of_zone_data.rpl b/testdata/auth_nsec3_wild_with_out_of_zone_data.rpl new file mode 100644 index 000000000..8c5a00861 --- /dev/null +++ b/testdata/auth_nsec3_wild_with_out_of_zone_data.rpl @@ -0,0 +1,234 @@ +; config options +server: + target-fetch-policy: "0 0 0 0 0" + +auth-zone: + name: "test-ns-signed.dev.internet.nl." + ## zonefile (or none). + ## zonefile: "example.com.zone" + ## master by IP address or hostname + ## can list multiple masters, each on one line. + ## master: + ## url for http fetch + ## url: + ## queries from downstream clients get authoritative answers. + ## for-downstream: yes + for-downstream: yes + ## queries are used to fetch authoritative answers from this zone, + ## instead of unbound itself sending queries there. + ## for-upstream: yes + for-upstream: yes + ## on failures with for-upstream, fallback to sending queries to + ## the authority servers + ## fallback-enabled: no + + ## this line generates zonefile: \n"/tmp/xxx.example.com"\n + zonefile: +TEMPFILE_NAME test-ns-signed.dev.internet.nl + ## this is the inline file /tmp/xxx.test-ns-signed.dev.internet.nl + ## the tempfiles are deleted when the testrun is over. +TEMPFILE_CONTENTS test-ns-signed.dev.internet.nl +test-ns-signed.dev.internet.nl. 3600 IN SOA ns.nlnetlabs.nl. ralph.nlnetlabs.nl. 4 14400 3600 604800 3600 +test-ns-signed.dev.internet.nl. 3600 IN RRSIG SOA 8 4 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. ybb0Hc7NC+QOFEEv4cX2+Umlk+miiOAHmeP2Uwvg6lqfxkk+3g7yWBEKMinXjLKz0odWZ6fki6M/3yBPQX8SV0OCRY5gYvAHAjbxAIHozIM+5iwOkRQhNF1DRgQ3BLjL93f6T5e5Z4y1812iOpu4GYswXW/UTOZACXz2UiaCPAg= +;; Out of zone record that shouldn't break NSEC3 proofs. +;; There was a bug that would keep removing labels and use this out of zone +;; record. +dev.internet.nl. 3600 IN NS ns.test-ns-signed.dev.internet.nl. +test-ns-signed.dev.internet.nl. 3600 IN NS ns.test-ns-signed.dev.internet.nl. +test-ns-signed.dev.internet.nl. 3600 IN RRSIG NS 8 4 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. KqiwTF3hKm1ZHGbgx6MVzZYHlS1p7+Xrikx4izMHFbWiD6ki6lrJBJsnH9j/hH1cwHxjXslOeJh0hdBdbn8la0meZPsebOyUbEjoLPzRLzKNLDBuA4BUJnRGQJy21CX7XooXAMAmR8YFipO8CojI9EogU2m2o9YkfbpacFWQoTk= +test-ns-signed.dev.internet.nl. 3600 IN DNSKEY 256 3 8 AwEAAc6c8tpMXBSOFLu/9n4aUUDK43wN4B7A2UDqZi0IOkyptxWCFghleyZeeN5uq6p9MoUt8lS73mFmIYC0ux5zBO3uVaJQ9u+00qRAEVg/RgBwa58y2f/zNtFV/f7mBSPcPTiEjUh0bwHSiTvUn/8JkrvjyAcbQMO0YOsRof5q6tzl ;{id = 32784 (zsk), size = 1024b} +test-ns-signed.dev.internet.nl. 3600 IN DNSKEY 257 3 8 AwEAAdC0hBJP1U8lbZ6JFXn0ouK6VipiraN7I8oog62SuEd/fqAupys7A/Ih6WK/UoJorjlnccEL8euNMaS4kNogvoBrFx8ciIWKcbot5mtwc4WDr3cnR+HIZNCUFVkIxsMqE7HCD0yn0zhkB60shED+ZHs8zpyU+cjnsOSizxOnIY+F ;{id = 54502 (ksk), size = 1024b} +test-ns-signed.dev.internet.nl. 3600 IN RRSIG DNSKEY 8 4 3600 20190205132351 20190108132351 54502 test-ns-signed.dev.internet.nl. X3qN+plfjf45FA4pr/tcUqUCR9ajDqwtNe4TS19WOJogVL/Gf/N5/ToOCrs3s+a7VrJl58WvSJquDM8xAS8f4oJggKgHFhopce8tMTGRxkRvJo4y+tt3vCveh/zjHLAnbOaBGA4CJ/IPhRqzHzcX/SjSv0EACWd6XpQIWogRv6c= +test-ns-signed.dev.internet.nl. 3600 IN NSEC3PARAM 1 0 1 - +test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3PARAM 8 4 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. A/1xUGO46uIz+9vjPGfWVD99akwU9bd/UlnVG9LPfoTzG7TMWSoZ4ksg8k8ub8K1TrkDmQokNHSW0Gt6qwoRh17c+p1h/SFlDVL83wgTc4NqG43OQjgGU9RV035XU+VESlO3lavifhlu8rHWBJTlhiXcMGq6H+zvoz4sx9p5GNM= +93stp7o7i5n9gb83uu7vv6h8qltk14ig.test-ns-signed.dev.internet.nl. 3600 IN NSEC3 1 0 1 - fee0c2kfhi6bnljce6vehaenqq3pbupu NS SOA RRSIG DNSKEY NSEC3PARAM +93stp7o7i5n9gb83uu7vv6h8qltk14ig.test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. YoTRDQ7sSvERcY1WwAH4oRRR7DmaAwA8/H70jdMeSU4wsnM/VM03kDcc2sgq5edmHiZoTWnq7nEb/1Y7Ro0YrqTUQdYFZvXi6UjZQrKI9nqAGnhdXZWlZJHmYpn2+2Emd+bYHkwvKaPnfnnKjUoGVBH8Hly0HBYKPUF1/viquB0= +kl94uofq16t2vlq0bmampf6e4o9k5hbi.test-ns-signed.dev.internet.nl. 3600 IN NSEC3 1 0 1 - 7ag3p2pfrvq09dpn63cvga8ub1rnrrg1 +kl94uofq16t2vlq0bmampf6e4o9k5hbi.test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. NI5zJ/k1kPVZ1abms5OoME/wazb77Ltduyk6ZevAnt4tKydZYwSsjEd0Ixknw9xnakCABn5rAYEXctARN0KCwCkNHR7TYlTAJT14hlDYjbad2u2HT9L1kzAnfj3BeLZl/LRADeMbTtzrkTSF3Dnezurb94fMnUnKt2hPfQfj560= +fee0c2kfhi6bnljce6vehaenqq3pbupu.test-ns-signed.dev.internet.nl. 3600 IN NSEC3 1 0 1 - i6pi4e3o98e7vtkpjfhqn7g77d3mjcnv +fee0c2kfhi6bnljce6vehaenqq3pbupu.test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. WIb3ISP1nlafbyWoWa4z7sG5IS+V86PyvEMHdD/64hgsFkrCu483XK7VNnBz28SL/631JXA1R19O+UxeWhTUyctp8QSt6cEZcMPY8b7yG97rNFNvhSw75rSXXt+JwgIYHPHQV5oqPtVmEpQM5SfJd+hs+Nn1bJcWB3UaESNNAMQ= +*.a.b.test-ns-signed.dev.internet.nl. 3600 IN TXT "a" +*.a.b.test-ns-signed.dev.internet.nl. 3600 IN RRSIG TXT 8 6 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. eNcJkQXdTO1z21od0sXbgqtABhhr/9tNC/Zx8zYbhXkfj7rufN71yk9xqgu6TG0MeJV26ISrqIGRVFJFmTRvO1LLxoKkEPhqe+08nqRztxXZajCV+dDeFoGIDcXJg6tAxB+MJznkKDtZPpIWvyt1WwdYfcMrGtE9AmR3K1/P/xE= +7ag3p2pfrvq09dpn63cvga8ub1rnrrg1.test-ns-signed.dev.internet.nl. 3600 IN NSEC3 1 0 1 - 93stp7o7i5n9gb83uu7vv6h8qltk14ig TXT RRSIG +7ag3p2pfrvq09dpn63cvga8ub1rnrrg1.test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. gtxoiTa3FRUqoRLvkWSxmWQ+DfijVd26gpKH3+GmGIcNB/sr/Cf8kERRwVVHvgzYIcvdJcys5b2LUXnZJwcdAlx7efZPWgNZzWxJrw6ES25LCWJOrp31isWn9FlAZGIbnpyEXxD2apBSmtyPnKbTgU6lHHS9jrsYHu4G8Zouv3k= +ns.test-ns-signed.dev.internet.nl. 3600 IN A 185.49.141.11 +ns.test-ns-signed.dev.internet.nl. 3600 IN RRSIG A 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. F9sXEVAmlRn+/84WbuvegiCwstNxMDMQLl0Obv2CTPpee4U6psbmXrlzczjjjkE6aLjsIHYdcXCzEWTrmukT+V9jzaGPRJvxNvC0ASWyzggAoh0Z++Hl4cVa9587o6I9ODayehFI9Pgdem+RVdb4zlWuzi9FmKXgeTlgWN54tPg= +ns.test-ns-signed.dev.internet.nl. 3600 IN AAAA 2a04:b900:0:100::11 +ns.test-ns-signed.dev.internet.nl. 3600 IN RRSIG AAAA 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. F1XRrx/QgfzJ1RS7d0m23QoIPx1G8WL1SrlTOm7pk5vWTL07w7HEw2TETblkjnitJGKfN9ebsIum/cDPUZc3UqLkguP2UCWpePnlllTJuwmG0Z+wyINIR4xF4PQlqttvzThBkD2JKWb/o0W8dQyXTj+jJ1vCZ0NjjA2N4+iJIQE= +i6pi4e3o98e7vtkpjfhqn7g77d3mjcnv.test-ns-signed.dev.internet.nl. 3600 IN NSEC3 1 0 1 - kl94uofq16t2vlq0bmampf6e4o9k5hbi A AAAA RRSIG +i6pi4e3o98e7vtkpjfhqn7g77d3mjcnv.test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. xLysIqn3r3rdHE3GvwVjZwUyuFClhkhgrQdwyc66RuHKE3MfSuhVr9cHTCJzhipF5TwQTbUpLOr74r99bzdiIY8Xkgjy2M0nc76v1ObSGJdPPjGTevbhDOnavUURwOR/q0NqqO2iPrgFjOVMZ+8uwRJtCty2iAVZfVG+qDzs8hU= +TEMPFILE_END + +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +CONFIG_END + +SCENARIO_BEGIN Test authority zone with NSEC3 wildcard + +; K.ROOT-SERVERS.NET. +RANGE_BEGIN 0 100 + ADDRESS 193.0.14.129 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. IN NS K.ROOT-SERVERS.NET. +SECTION ADDITIONAL +K.ROOT-SERVERS.NET. IN A 193.0.14.129 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +com. IN NS +SECTION AUTHORITY +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END +RANGE_END + +; a.gtld-servers.net. +RANGE_BEGIN 0 100 + ADDRESS 192.5.6.30 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +com. IN NS +SECTION ANSWER +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION AUTHORITY +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.44 +ENTRY_END +RANGE_END + +; ns.example.net. +RANGE_BEGIN 0 100 + ADDRESS 1.2.3.44 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.net. IN NS +SECTION ANSWER +example.net. IN NS ns.example.net. +SECTION ADDITIONAL +ns.example.net. IN A 1.2.3.44 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +ns.example.net. IN A +SECTION ANSWER +ns.example.net. IN A 1.2.3.44 +SECTION AUTHORITY +example.net. IN NS ns.example.net. +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +ns.example.net. IN AAAA +SECTION AUTHORITY +example.net. IN NS ns.example.net. +SECTION ADDITIONAL +www.example.net. IN A 1.2.3.44 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION ANSWER +example.com. IN NS ns.example.net. +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ENTRY_END +RANGE_END + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +something.a.b.test-ns-signed.dev.internet.nl. IN TXT +ENTRY_END + +; recursion happens here. +STEP 20 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR AA RD RA DO NOERROR +SECTION QUESTION +something.a.b.test-ns-signed.dev.internet.nl. IN TXT +SECTION ANSWER +something.a.b.test-ns-signed.dev.internet.nl. IN TXT "a" +something.a.b.test-ns-signed.dev.internet.nl. 3600 IN RRSIG TXT 8 6 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. eNcJkQXdTO1z21od0sXbgqtABhhr/9tNC/Zx8zYbhXkfj7rufN71yk9xqgu6TG0MeJV26ISrqIGRVFJFmTRvO1LLxoKkEPhqe+08nqRztxXZajCV+dDeFoGIDcXJg6tAxB+MJznkKDtZPpIWvyt1WwdYfcMrGtE9AmR3K1/P/xE= +SECTION AUTHORITY +i6pi4e3o98e7vtkpjfhqn7g77d3mjcnv.test-ns-signed.dev.internet.nl. 3600 IN NSEC3 1 0 1 - KL94UOFQ16T2VLQ0BMAMPF6E4O9K5HBI A AAAA RRSIG +i6pi4e3o98e7vtkpjfhqn7g77d3mjcnv.test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. xLysIqn3r3rdHE3GvwVjZwUyuFClhkhgrQdwyc66RuHKE3MfSuhVr9cHTCJzhipF5TwQTbUpLOr74r99bzdiIY8Xkgjy2M0nc76v1ObSGJdPPjGTevbhDOnavUURwOR/q0NqqO2iPrgFjOVMZ+8uwRJtCty2iAVZfVG+qDzs8hU= +ENTRY_END + +; Check that the reply for a wildcard nodata answer contains the NSEC3s. +; qname denial NSEC3, closest encloser NSEC3, and type bitmap NSEC3. +STEP 30 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +something.a.b.test-ns-signed.dev.internet.nl. IN AAAA +ENTRY_END + +STEP 40 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR AA RD RA DO NOERROR +SECTION QUESTION +something.a.b.test-ns-signed.dev.internet.nl. IN AAAA +SECTION ANSWER +SECTION AUTHORITY +test-ns-signed.dev.internet.nl. 3600 IN SOA ns.nlnetlabs.nl. ralph.nlnetlabs.nl. 4 14400 3600 604800 3600 +test-ns-signed.dev.internet.nl. 3600 IN RRSIG SOA 8 4 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. ybb0Hc7NC+QOFEEv4cX2+Umlk+miiOAHmeP2Uwvg6lqfxkk+3g7yWBEKMinXjLKz0odWZ6fki6M/3yBPQX8SV0OCRY5gYvAHAjbxAIHozIM+5iwOkRQhNF1DRgQ3BLjL93f6T5e5Z4y1812iOpu4GYswXW/UTOZACXz2UiaCPAg= ;{id = 32784} +7ag3p2pfrvq09dpn63cvga8ub1rnrrg1.test-ns-signed.dev.internet.nl. 3600 IN NSEC3 1 0 1 - 93stp7o7i5n9gb83uu7vv6h8qltk14ig TXT RRSIG +7ag3p2pfrvq09dpn63cvga8ub1rnrrg1.test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. gtxoiTa3FRUqoRLvkWSxmWQ+DfijVd26gpKH3+GmGIcNB/sr/Cf8kERRwVVHvgzYIcvdJcys5b2LUXnZJwcdAlx7efZPWgNZzWxJrw6ES25LCWJOrp31isWn9FlAZGIbnpyEXxD2apBSmtyPnKbTgU6lHHS9jrsYHu4G8Zouv3k= ;{id = 32784} +fee0c2kfhi6bnljce6vehaenqq3pbupu.test-ns-signed.dev.internet.nl. 3600 IN NSEC3 1 0 1 - i6pi4e3o98e7vtkpjfhqn7g77d3mjcnv +fee0c2kfhi6bnljce6vehaenqq3pbupu.test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. WIb3ISP1nlafbyWoWa4z7sG5IS+V86PyvEMHdD/64hgsFkrCu483XK7VNnBz28SL/631JXA1R19O+UxeWhTUyctp8QSt6cEZcMPY8b7yG97rNFNvhSw75rSXXt+JwgIYHPHQV5oqPtVmEpQM5SfJd+hs+Nn1bJcWB3UaESNNAMQ= ;{id = 32784} +i6pi4e3o98e7vtkpjfhqn7g77d3mjcnv.test-ns-signed.dev.internet.nl. 3600 IN NSEC3 1 0 1 - kl94uofq16t2vlq0bmampf6e4o9k5hbi A AAAA RRSIG +i6pi4e3o98e7vtkpjfhqn7g77d3mjcnv.test-ns-signed.dev.internet.nl. 3600 IN RRSIG NSEC3 8 5 3600 20190205132351 20190108132351 32784 test-ns-signed.dev.internet.nl. xLysIqn3r3rdHE3GvwVjZwUyuFClhkhgrQdwyc66RuHKE3MfSuhVr9cHTCJzhipF5TwQTbUpLOr74r99bzdiIY8Xkgjy2M0nc76v1ObSGJdPPjGTevbhDOnavUURwOR/q0NqqO2iPrgFjOVMZ+8uwRJtCty2iAVZfVG+qDzs8hU= ;{id = 32784} +ENTRY_END + +SCENARIO_END diff --git a/util/data/dname.c b/util/data/dname.c index f08760e2f..2fe7b171d 100644 --- a/util/data/dname.c +++ b/util/data/dname.c @@ -728,7 +728,7 @@ dname_is_root(uint8_t* dname) return (len == 0); } -void +void dname_remove_label(uint8_t** dname, size_t* len) { size_t lablen; @@ -742,7 +742,23 @@ dname_remove_label(uint8_t** dname, size_t* len) *dname += lablen+1; } -void +int +dname_remove_label_limit_len(uint8_t** dname, size_t* len, size_t lenlimit) +{ + size_t lablen; + log_assert(dname && *dname && len); + lablen = (*dname)[0]; + log_assert(!LABEL_IS_PTR(lablen)); + log_assert(*len > lablen); + if(lablen == 0) + return 0; /* do not modify root label */ + if(*len - (lablen + 1) < lenlimit) return 0; + *len -= lablen+1; + *dname += lablen+1; + return 1; +} + +void dname_remove_labels(uint8_t** dname, size_t* len, int n) { int i; diff --git a/util/data/dname.h b/util/data/dname.h index 6e4cf7ea3..e4a0313ac 100644 --- a/util/data/dname.h +++ b/util/data/dname.h @@ -262,10 +262,23 @@ int dname_is_root(uint8_t* dname); * Snip off first label from a dname, returning the parent zone. * @param dname: from what to strip off. uncompressed wireformat. * @param len: length, adjusted to become less. - * return stripped off, or "." if input was ".". + * return dname stripped off, or "." if input was ".". */ void dname_remove_label(uint8_t** dname, size_t* len); +/** + * Same as dname_remove_label but fails if removal would surpass lenlimit. + * If no failure, + * snip off first label from a dname, returning the parent zone. + * @param dname: from what to strip off. uncompressed wireformat. + * @param len: length, adjusted to become less. + * @param lenlimit: length limit that we can't surpass (usually the zone apex). + * return + * o 1, and dname stripped off, or "." if input was ".", else + * o 0, if going up would surpass lenlimit. + */ +int dname_remove_label_limit_len(uint8_t** dname, size_t* len, size_t lenlimit); + /** * Snip off first N labels from a dname, returning the parent zone. * @param dname: from what to strip off. uncompressed wireformat.