diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 3e0506c9d2af..b8691d592883 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -454,6 +454,7 @@ namespace { { set d_set; unsigned int d_ttl; + bool d_auth; }; DNSResourceRecord makeDNSRRFromSOAData(const SOAData& sd) @@ -651,11 +652,12 @@ int TCPNameserver::doAXFR(const string &target, shared_ptr q, int out continue; records++; - if(securedZone && (rr.auth || (!NSEC3Zone && rr.qtype.getCode() == QType::NS) || rr.qtype.getCode() == QType::DS)) { // this is probably NSEC specific, NSEC3 is different + if(securedZone && (rr.auth || rr.qtype.getCode() == QType::NS)) { if (NSEC3Zone || rr.qtype.getCode()) { keyname = NSEC3Zone ? hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, rr.qname) : labelReverse(rr.qname); NSECXEntry& ne = nsecxrepo[keyname]; ne.d_ttl = sd.default_ttl; + ne.d_auth = (ne.d_auth || rr.auth); if (rr.qtype.getCode()) { ne.d_set.insert(rr.qtype.getCode()); } @@ -689,42 +691,49 @@ int TCPNameserver::doAXFR(const string &target, shared_ptr q, int out cerr<<"Outstanding: "<second.d_set; - if (n3rc.d_set.size()) - n3rc.d_set.insert(QType::RRSIG); - n3rc.d_salt=ns3pr.d_salt; - n3rc.d_flags = ns3pr.d_flags; - n3rc.d_iterations = ns3pr.d_iterations; - n3rc.d_algorithm = 1; // SHA1, fixed in PowerDNS for now - if(boost::next(iter) != nsecxrepo.end()) { - n3rc.d_nexthash = boost::next(iter)->first; - } - else - n3rc.d_nexthash=nsecxrepo.begin()->first; - - rr.qname = dotConcat(toLower(toBase32Hex(iter->first)), sd.qname); - - rr.ttl = sd.default_ttl; - rr.content = n3rc.getZoneRepresentation(); - rr.qtype = QType::NSEC3; - rr.d_place = DNSResourceRecord::ANSWER; - rr.auth=true; - if(csp.submit(rr)) { - for(;;) { - outpacket->getRRS() = csp.getChunk(); - if(!outpacket->getRRS().empty()) { - if(!tsigkeyname.empty()) - outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true); - sendPacket(outpacket, outsock); - trc.d_mac=outpacket->d_trc.d_mac; - outpacket=getFreshAXFRPacket(q); + if(iter->second.d_auth) { + NSEC3RecordContent n3rc; + n3rc.d_set = iter->second.d_set; + if (n3rc.d_set.size() && (n3rc.d_set.size() != 1 || !n3rc.d_set.count(QType::NS))) + n3rc.d_set.insert(QType::RRSIG); + n3rc.d_salt=ns3pr.d_salt; + n3rc.d_flags = ns3pr.d_flags; + n3rc.d_iterations = ns3pr.d_iterations; + n3rc.d_algorithm = 1; // SHA1, fixed in PowerDNS for now + nsecxrepo_t::const_iterator inext = iter; + inext++; + if(inext == nsecxrepo.end()) + inext = nsecxrepo.begin(); + while(!(inext->second.d_auth) && inext != iter) + { + inext++; + if(inext == nsecxrepo.end()) + inext = nsecxrepo.begin(); + } + n3rc.d_nexthash = inext->first; + rr.qname = dotConcat(toLower(toBase32Hex(iter->first)), sd.qname); + + rr.ttl = sd.default_ttl; + rr.content = n3rc.getZoneRepresentation(); + rr.qtype = QType::NSEC3; + rr.d_place = DNSResourceRecord::ANSWER; + rr.auth=true; + if(csp.submit(rr)) { + for(;;) { + outpacket->getRRS() = csp.getChunk(); + if(!outpacket->getRRS().empty()) { + if(!tsigkeyname.empty()) + outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true); + sendPacket(outpacket, outsock); + trc.d_mac=outpacket->d_trc.d_mac; + outpacket=getFreshAXFRPacket(q); + } + else + break; } - else - break; } } } diff --git a/regression-tests/dnssec-parent.com b/regression-tests/dnssec-parent.com index 0f8f1ae79d11..5515ad7631ed 100644 --- a/regression-tests/dnssec-parent.com +++ b/regression-tests/dnssec-parent.com @@ -16,4 +16,9 @@ delegated IN NS ns1.delegated.dnssec-parent.com. delegated IN NS ns2.delegated.dnssec-parent.com. ns1.delegated IN A 4.5.6.7 ns2.delegated IN A 5.6.7.8 +secure-delegated IN DS 54319 8 2 a0b9c38cd324182af0ef66830d0a0e85a1d58979c9834e18c871779e040857b7 +secure-delegated IN NS ns1.secure-delegated.dnssec-parent.com. +secure-delegated IN NS ns2.secure-delegated.dnssec-parent.com. +ns1.secure-delegated IN A 1.2.3.4 +ns2.secure-delegated IN A 5.6.7.8 diff --git a/regression-tests/ds-at-unsecure-zone-cut/expected_result.nsec3 b/regression-tests/ds-at-unsecure-zone-cut/expected_result.nsec3 index 78bf3123297f..c8ccc4cba75b 100644 --- a/regression-tests/ds-at-unsecure-zone-cut/expected_result.nsec3 +++ b/regression-tests/ds-at-unsecure-zone-cut/expected_result.nsec3 @@ -1,5 +1,5 @@ -1 29ceqcf4ekgl2gr9i0vjjtk62h5lqs40.dnssec-parent.com. IN NSEC3 86400 1 1 1 abcd DVKUO8KJA65GCSQ600E6DI9U719LSJ8U A RRSIG -1 29ceqcf4ekgl2gr9i0vjjtk62h5lqs40.dnssec-parent.com. IN RRSIG 86400 NSEC3 8 3 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... +1 7on3vems0f8k9999ikei0ig4lfijekdr.dnssec-parent.com. IN NSEC3 86400 1 1 1 abcd DVKUO8KJA65GCSQ600E6DI9U719LSJ8U NS DS RRSIG +1 7on3vems0f8k9999ikei0ig4lfijekdr.dnssec-parent.com. IN RRSIG 86400 NSEC3 8 3 86400 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. IN RRSIG 3600 SOA 8 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. IN SOA 3600 ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. IN NSEC3 86400 1 1 1 abcd 1SCAQA30LQ0DO5EIRNE4KPJFBEBFGR54 A NS SOA RRSIG DNSKEY NSEC3PARAM