]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Correctly count NSEC3s considered when chasing the closest encloser 13992/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 26 Mar 2024 13:44:15 +0000 (14:44 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 27 Mar 2024 11:39:26 +0000 (12:39 +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.

(cherry picked from commit c4f4d09654bde9d389e83f0bc8eadc6b665e9de9)

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

index 2474ae67e3f03fa259551fa6a74115918509c0f8..526fa70d89588c1ff02abbdc0117a63430632562 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 6833ab9baa14330139eafb0bfcd8aec5c1fe49a3..793b67e6767a98d5775d1ed4bb319a6a64e4c111 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) {