]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Correctly count NSEC3s considered when chasing the closest encloser 13984/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 26 Mar 2024 13:44:15 +0000 (14:44 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 26 Mar 2024 13:44:15 +0000 (14:44 +0100)
We need to count the number of NSEC3s that are present in the response,
not the number of times we have to consider possible NSEC3s when
looking for the NSEC3 closest encloser, label by label.

pdns/recursordist/test-syncres_cc8.cc
pdns/validate.cc

index 901c8b7784cc2071f95af85f54b7c2b64eca2d0e..464f33d672c93949d30ab3de6f3ef4f4e0adb419 100644 (file)
@@ -887,6 +887,68 @@ BOOST_AUTO_TEST_CASE(test_nsec3_denial_too_many_iterations)
   BOOST_CHECK_EQUAL(denialState, dState::INSECURE);
 }
 
+BOOST_AUTO_TEST_CASE(test_nsec3_many_labels_between_name_and_closest_encloser)
+{
+  initSR();
+
+  testkeysset_t keys;
+  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
+
+  vector<DNSRecord> records;
+
+  sortedRecords_t recordContents;
+  vector<shared_ptr<const RRSIGRecordContent>> signatureContents;
+
+  ContentSigPair pair;
+  cspmap_t denialMap;
+
+  const DNSName requestedName("_ldap._tcp.a.b.c.d.powerdns.com.");
+  const DNSName zone("powerdns.com.");
+  /* Add NSEC3 for the closest encloser */
+  recordContents.clear();
+  signatureContents.clear();
+  records.clear();
+  addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), zone, "whatever", {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
+  recordContents.insert(records.at(0).getContent());
+  addRRSIG(keys, records, zone, 300);
+  signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
+
+  pair.records = recordContents;
+  pair.signatures = signatureContents;
+  denialMap[std::pair(records.at(0).d_name, records.at(0).d_type)] = pair;
+
+  /* Add NSEC3 for the next closer */
+  recordContents.clear();
+  signatureContents.clear();
+  records.clear();
+  addNSEC3NarrowRecordToLW(DNSName("d.powerdns.com."), zone, {QType::A, QType::TXT, QType::RRSIG, QType::NSEC3}, 600, records);
+  recordContents.insert(records.at(0).getContent());
+  addRRSIG(keys, records, zone, 300);
+  signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
+
+  pair.records = recordContents;
+  pair.signatures = signatureContents;
+  denialMap[std::pair(records.at(0).d_name, records.at(0).d_type)] = pair;
+
+  /* add wildcard denial */
+  recordContents.clear();
+  signatureContents.clear();
+  records.clear();
+  addNSEC3NarrowRecordToLW(DNSName("*.powerdns.com."), zone, {QType::A, QType::TXT, QType::RRSIG, QType::NSEC3}, 600, records);
+  recordContents.insert(records.at(0).getContent());
+  addRRSIG(keys, records, zone, 300);
+  signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
+
+  pair.records = recordContents;
+  pair.signatures = signatureContents;
+  denialMap[std::pair(records.at(0).d_name, records.at(0).d_type)] = pair;
+
+  g_maxNSEC3sPerRecordToConsider = 10;
+  auto denialState = getDenial(denialMap, requestedName, QType::A, false, true);
+  g_maxNSEC3sPerRecordToConsider = 0;
+  BOOST_CHECK_EQUAL(denialState, dState::NXDOMAIN);
+}
+
 BOOST_AUTO_TEST_CASE(test_nsec3_insecure_delegation_denial)
 {
   initSR();
index 33e6ecbd5729643c74e9662d1feb280133eac77d..d8f60c11504ea59a78c1e27688e30c1f8a83e775 100644 (file)
@@ -781,7 +781,6 @@ dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16
   DNSName closestEncloser(qname);
   bool found = false;
   if (needWildcardProof) {
-    nsec3sConsidered = 0;
     /* We now need to look for a NSEC3 covering the closest (provable) encloser
        RFC 5155 section-7.2.1
        RFC 7129 section-5.5
@@ -789,6 +788,7 @@ dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16
     VLOG(log, qname << ": Now looking for the closest encloser for "<<qname<<endl);
 
     while (!found && closestEncloser.chopOff() && closestEncloser.countLabels() >= numberOfLabelsOfParentZone) {
+      nsec3sConsidered = 0;
 
       for(const auto& validset : validrrsets) {
         if(validset.first.second==QType::NSEC3) {