]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/recursordist/test-syncres_cc.cc
rec: CVE-2023-50387 and CVE-2023-50868
[thirdparty/pdns.git] / pdns / recursordist / test-syncres_cc.cc
index a9058e15ae40424bd460bead274b180349765c73..0aa0ceccc2389d6f5af8c47cdbb2cda21fadcbc3 100644 (file)
@@ -1,4 +1,7 @@
+#ifndef BOOST_TEST_DYN_LINK
 #define BOOST_TEST_DYN_LINK
+#endif
+
 #include <boost/test/unit_test.hpp>
 
 #include "aggressive_nsec.hh"
@@ -7,6 +10,7 @@
 #include "root-dnssec.hh"
 #include "rec-taskqueue.hh"
 #include "test-syncres_cc.hh"
+#include "recpacketcache.hh"
 
 GlobalStateHolder<LuaConfigItems> g_luaconfs;
 GlobalStateHolder<SuffixMatchNode> g_xdnssec;
@@ -32,16 +36,16 @@ BaseLua4::~BaseLua4()
 {
 }
 
-void BaseLua4::getFeatures(Features&)
+void BaseLua4::getFeatures(Features& /* features */)
 {
 }
 
-bool RecursorLua4::preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret, RecEventTrace& et, const struct timeval& tv) const
+bool RecursorLua4::preoutquery(const ComboAddress& /* ns */, const ComboAddress& /* requestor */, const DNSName& /* query */, const QType& /* qtype */, bool /* isTcp */, vector<DNSRecord>& /* res */, int& /* ret */, RecEventTrace& /* et */, const struct timeval& /* tv */) const
 {
   return false;
 }
 
-bool RecursorLua4::policyHitEventFilter(const ComboAddress& remote, const DNSName& qname, const QType& qtype, bool tcp, DNSFilterEngine::Policy& policy, std::unordered_set<std::string>& tags, std::unordered_map<std::string, bool>& discardedPolicies) const
+bool RecursorLua4::policyHitEventFilter(const ComboAddress& /* remote */, const DNSName& /* qname */, const QType& /* qtype */, bool /* tcp */, DNSFilterEngine::Policy& /* policy */, std::unordered_set<std::string>& /* tags */, std::unordered_map<std::string, bool>& /* discardedPolicies */) const
 {
   return false;
 }
@@ -58,11 +62,11 @@ void RecursorLua4::postLoad()
 {
 }
 
-void RecursorLua4::getFeatures(Features& features)
+void RecursorLua4::getFeatures(Features& /* features */)
 {
 }
 
-LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, const std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& outgoingLoggers, const std::shared_ptr<std::vector<std::unique_ptr<FrameStreamLogger>>>& fstrmLoggers, const std::set<uint16_t>& exportTypes, LWResult* res, bool* chained)
+LWResult::Result asyncresolve(const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, const std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& /* outgoingLoggers */, const std::shared_ptr<std::vector<std::unique_ptr<FrameStreamLogger>>>& /* fstrmLoggers */, const std::set<uint16_t>& /* exportTypes */, LWResult* /* res */, bool* /* chained */)
 {
   return LWResult::Result::Timeout;
 }
@@ -96,22 +100,22 @@ bool primeHints(time_t now)
     templ[sizeof(templ) - 1] = '\0';
     *templ = c;
     aaaarr.d_name = arr.d_name = DNSName(templ);
-    nsrr.d_content = std::make_shared<NSRecordContent>(DNSName(templ));
-    arr.d_content = std::make_shared<ARecordContent>(ComboAddress(rootIps4[c - 'a']));
+    nsrr.setContent(std::make_shared<NSRecordContent>(DNSName(templ)));
+    arr.setContent(std::make_shared<ARecordContent>(ComboAddress(rootIps4[c - 'a'])));
     vector<DNSRecord> aset;
     aset.push_back(arr);
-    g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname);
-    if (rootIps6[c - 'a'] != NULL) {
-      aaaarr.d_content = std::make_shared<AAAARecordContent>(ComboAddress(rootIps6[c - 'a']));
+    g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector<std::shared_ptr<const RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname);
+    if (!rootIps6[c - 'a'].empty()) {
+      aaaarr.setContent(std::make_shared<AAAARecordContent>(ComboAddress(rootIps6[c - 'a'])));
 
       vector<DNSRecord> aaaaset;
       aaaaset.push_back(aaaarr);
-      g_recCache->replace(now, DNSName(templ), QType(QType::AAAA), aaaaset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname);
+      g_recCache->replace(now, DNSName(templ), QType(QType::AAAA), aaaaset, vector<std::shared_ptr<const RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname);
     }
 
     nsset.push_back(nsrr);
   }
-  g_recCache->replace(now, g_rootdnsname, QType(QType::NS), nsset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname); // and stuff in the cache
+  g_recCache->replace(now, g_rootdnsname, QType(QType::NS), nsset, vector<std::shared_ptr<const RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname); // and stuff in the cache
   return true;
 }
 
@@ -139,6 +143,7 @@ void initSR(bool debug)
     g_log.toConsole(Logger::Error);
   }
 
+  RecursorPacketCache::s_refresh_ttlperc = 0;
   MemRecursorCache::s_maxServedStaleExtensions = 0;
   NegCache::s_maxServedStaleExtensions = 0;
   g_recCache = std::make_unique<MemRecursorCache>();
@@ -181,6 +186,8 @@ void initSR(bool debug)
   SyncRes::s_save_parent_ns_set = true;
   SyncRes::s_maxnsperresolve = 13;
   SyncRes::s_locked_ttlperc = 0;
+  SyncRes::s_minimize_one_label = 4;
+  SyncRes::s_max_minimize_count = 10;
 
   SyncRes::clearNSSpeeds();
   BOOST_CHECK_EQUAL(SyncRes::getNSSpeedsSize(), 0U);
@@ -218,6 +225,7 @@ void initSR(bool debug)
   ::arg().set("version-string", "string reported on version.pdns or version.bind") = "PowerDNS Unit Tests";
   ::arg().set("rng") = "auto";
   ::arg().set("entropy-source") = "/dev/urandom";
+  ::arg().set("hint-file") = "";
 }
 
 void initSR(std::unique_ptr<SyncRes>& sr, bool dnssec, bool debug, time_t fakeNow)
@@ -273,14 +281,14 @@ void addRecordToLW(LWResult* res, const std::string& name, uint16_t type, const
 bool isRootServer(const ComboAddress& ip)
 {
   if (ip.isIPv4()) {
-    for (size_t idx = 0; idx < rootIps4Count; idx++) {
+    for (size_t idx = 0; idx < rootIps4.size(); idx++) {
       if (ip.toString() == rootIps4[idx]) {
         return true;
       }
     }
   }
   else {
-    for (size_t idx = 0; idx < rootIps6Count; idx++) {
+    for (size_t idx = 0; idx < rootIps6.size(); idx++) {
       if (ip.toString() == rootIps6[idx]) {
         return true;
       }
@@ -325,30 +333,48 @@ bool addRRSIG(const testkeysset_t& keys, std::vector<DNSRecord>& records, const
     throw std::runtime_error("No DNSKEY found for " + signer.toLogString() + ", unable to compute the requested RRSIG");
   }
 
-  size_t recordsCount = records.size();
-  const DNSName& name = records[recordsCount - 1].d_name;
-  const uint16_t type = records[recordsCount - 1].d_type;
+  DNSName name;
+  uint16_t type{QType::ENT};
+  DNSResourceRecord::Place place{DNSResourceRecord::ANSWER};
+  uint32_t ttl{0};
+  bool found = false;
+
+  /* locate the last non-RRSIG record */
+  for (auto recordIterator = records.rbegin(); recordIterator != records.rend(); ++recordIterator) {
+    if (recordIterator->d_type != QType::RRSIG) {
+      name = recordIterator->d_name;
+      type = recordIterator->d_type;
+      place = recordIterator->d_place;
+      ttl = recordIterator->d_ttl;
+      found = true;
+      break;
+    }
+  }
+
+  if (!found) {
+    throw std::runtime_error("Unable to locate the record that the RRSIG should cover");
+  }
 
   sortedRecords_t recordcontents;
   for (const auto& record : records) {
     if (record.d_name == name && record.d_type == type) {
-      recordcontents.insert(record.d_content);
+      recordcontents.insert(record.getContent());
     }
   }
 
   RRSIGRecordContent rrc;
-  computeRRSIG(it->second.first, signer, wildcard ? *wildcard : records[recordsCount - 1].d_name, records[recordsCount - 1].d_type, records[recordsCount - 1].d_ttl, sigValidity, rrc, recordcontents, algo, boost::none, now);
+  computeRRSIG(it->second.first, signer, wildcard ? *wildcard : name, type, ttl, sigValidity, rrc, recordcontents, algo, boost::none, now);
   if (broken) {
     rrc.d_signature[0] ^= 42;
   }
 
   DNSRecord rec;
   rec.d_type = QType::RRSIG;
-  rec.d_place = records[recordsCount - 1].d_place;
-  rec.d_name = records[recordsCount - 1].d_name;
-  rec.d_ttl = records[recordsCount - 1].d_ttl;
+  rec.d_place = place;
+  rec.d_name = name;
+  rec.d_ttl = ttl;
 
-  rec.d_content = std::make_shared<RRSIGRecordContent>(rrc);
+  rec.setContent(std::make_shared<RRSIGRecordContent>(rrc));
   records.push_back(rec);
 
   return true;
@@ -367,7 +393,7 @@ void addDNSKEY(const testkeysset_t& keys, const DNSName& signer, uint32_t ttl, s
   rec.d_type = QType::DNSKEY;
   rec.d_ttl = ttl;
 
-  rec.d_content = std::make_shared<DNSKEYRecordContent>(it->second.first.getDNSKEY());
+  rec.setContent(std::make_shared<DNSKEYRecordContent>(it->second.first.getDNSKEY()));
   records.push_back(rec);
 }
 
@@ -383,7 +409,7 @@ bool addDS(const DNSName& domain, uint32_t ttl, std::vector<DNSRecord>& records,
   rec.d_type = QType::DS;
   rec.d_place = place;
   rec.d_ttl = ttl;
-  rec.d_content = std::make_shared<DSRecordContent>(it->second.second);
+  rec.setContent(std::make_shared<DSRecordContent>(it->second.second));
 
   records.push_back(rec);
   return true;
@@ -401,7 +427,7 @@ void addNSECRecordToLW(const DNSName& domain, const DNSName& next, const std::se
   rec.d_name = domain;
   rec.d_ttl = ttl;
   rec.d_type = QType::NSEC;
-  rec.d_content = std::make_shared<NSECRecordContent>(std::move(nrc));
+  rec.setContent(std::make_shared<NSECRecordContent>(std::move(nrc)));
   rec.d_place = DNSResourceRecord::AUTHORITY;
 
   records.push_back(rec);
@@ -423,7 +449,7 @@ void addNSEC3RecordToLW(const DNSName& hashedName, const std::string& hashedNext
   rec.d_name = hashedName;
   rec.d_ttl = ttl;
   rec.d_type = QType::NSEC3;
-  rec.d_content = std::make_shared<NSEC3RecordContent>(std::move(nrc));
+  rec.setContent(std::make_shared<NSEC3RecordContent>(std::move(nrc)));
   rec.d_place = DNSResourceRecord::AUTHORITY;
 
   records.push_back(rec);