From: W.C.A. Wijngaards Date: Thu, 11 Sep 2025 14:21:38 +0000 (+0200) Subject: - xfr-tsig, fix notify tsig answer, fix parse edns allows TSIG, X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=64e102aacb9823ed977e91a47998bc5e516148ee;p=thirdparty%2Funbound.git - xfr-tsig, fix notify tsig answer, fix parse edns allows TSIG, unit test for auth zone with notify with tsig and notify answer with tsig. --- diff --git a/daemon/worker.c b/daemon/worker.c index b40d9b153..3112df724 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1221,6 +1221,7 @@ answer_notify(struct worker* w, struct query_info* qinfo, sldns_buffer_read_u16_at(pkt, 2), edns); LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY); } + sldns_buffer_flip(pkt); /* The tsig veriable is allocated in the scratch region. */ } } diff --git a/testdata/auth_tsig.rpl b/testdata/auth_tsig.rpl new file mode 100644 index 000000000..373eec6d7 --- /dev/null +++ b/testdata/auth_tsig.rpl @@ -0,0 +1,125 @@ +; config options +server: + target-fetch-policy: "0 0 0 0 0" + log-queries: yes + access-control: 127.0.0.1 allow + access-control: 192.0.2.1 allow + +; This tsig key is used for testing. +tsig-key: + name: "test.key" + algorithm: sha256 + secret: "K2tf3TRjvQkVCmJF3/Z9vA==" + +auth-zone: + name: "example.com." + master-tsig: 1.2.3.44 test.key + allow-notify-tsig: 192.0.2.1 test.key + for-downstream: yes + for-upstream: yes + + ## this line generates zonefile: \n"/tmp/xxx.example.com"\n + zonefile: +TEMPFILE_NAME example.com + ## this is the inline file /tmp/xxx.example.com + ## the tempfiles are deleted when the testrun is over. +TEMPFILE_CONTENTS example.com +example.com. IN SOA ns.example.com. netadm.example.com. 2025090900 7200 3600 604800 3600 +www.example.com. IN A 1.2.3.4 +TEMPFILE_END + +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +CONFIG_END + +SCENARIO_BEGIN Test authority zone with zone transfer with TSIG + +; ns.example.com. +RANGE_BEGIN 0 100 + ADDRESS 1.2.3.44 +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +SECTION QUESTION +example.com. IN SOA +SECTION ANSWER +example.com. IN SOA ns.example.com. netadm.example.com. 2025090901 7200 3600 604800 3600 +SECTION ADDITIONAL +test.key. 0 ANY TSIG hmac-sha256. 1757593030 300 32 F7jAcAXEgvrs1gEFRIf/6SaXnBBXkmP6O97mBu3xFXI= 6149 NOERROR 0 +ENTRY_END +RANGE_END + +; Check that the zonefile was read in. +; before time is set, so that the zone is not expired yet. +STEP 10 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +; recursion happens here. +STEP 20 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR AA RD RA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 1.2.3.4 +ENTRY_END + +; Set the time for TSIG operations to give the same output. +; Thu 11 Sep 14:17:10 CEST 2025 +STEP 30 TIME_PASSES ELAPSE 1757593030 +; the zone is now waiting for the SOA refresh timer for an update, after +; setting its notify addresses. Because of elapsed time, the zone is expired. + +; - notify TSIG check on incoming. +STEP 40 QUERY +ENTRY_BEGIN +REPLY NOTIFY +SECTION QUESTION +example.com. IN A +ENTRY_END + +; without TSIG notify is refused. +STEP 50 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RA NOTIFY REFUSED +SECTION QUESTION +example.com. IN A +ENTRY_END + +STEP 60 QUERY ADDRESS 192.0.2.1 +ENTRY_BEGIN +REPLY NOTIFY +SECTION QUESTION +example.com. IN A +SECTION ADDITIONAL +test.key. 0 ANY TSIG hmac-sha256. 1757593030 300 32 m9xopNtJTm6dnNbFCnkl4jfQJDH3MwpXTTL0n7OGKn8= 0 NOERROR 0 +ENTRY_END + +STEP 70 CHECK_ANSWER +ENTRY_BEGIN +REPLY QR RA NOTIFY +MATCH all +SECTION QUESTION +example.com. IN A +SECTION ADDITIONAL +test.key. 0 ANY TSIG hmac-sha256. 1757593030 300 32 ELaTFUdcCmHErm2pJX2ooYlW0lqaG50D5IKEWZesrYE= 0 NOERROR 0 +ENTRY_END + +; Resolve the SOA lookup. +STEP 80 TRAFFIC + + +; - notify reply has TSIG reply. +; - SOA probe TSIG +; - SOA probe TSIG reply +; - XFR TSIG +; - check XFR TSIG + +SCENARIO_END diff --git a/util/data/msgparse.c b/util/data/msgparse.c index 6963d8501..438d0e5b0 100644 --- a/util/data/msgparse.c +++ b/util/data/msgparse.c @@ -1282,10 +1282,32 @@ parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns, return LDNS_RCODE_FORMERR; } /* check edns section is present */ - if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) { - return LDNS_RCODE_FORMERR; - } - if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) == 0) { + if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 0) { + int i, edns_found = 0; + for(i=0; i<(int)LDNS_ARCOUNT(sldns_buffer_begin(pkt)); i++) { + if(sldns_buffer_remaining(pkt) < 1) + return LDNS_RCODE_FORMERR; + if(sldns_buffer_current(pkt)[0] == 0) { + /* The domain name is the root of length 1. */ + /* See if the RR Type is OPT. */ + if(sldns_buffer_remaining(pkt) < 3) + return LDNS_RCODE_FORMERR; + if(sldns_buffer_read_u16_at(pkt, + sldns_buffer_position(pkt)+1) == + LDNS_RR_TYPE_OPT) { + /* This is the EDNS OPT record */ + edns_found = 1; + break; + } + } + if(!skip_pkt_rrs(pkt, 1)) + return LDNS_RCODE_FORMERR; + } + if(!edns_found) { + edns->udp_size = 512; + return 0; + } + } else if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) == 0) { edns->udp_size = 512; return 0; }