]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Added depth check for qnameRPZHit() and some comments.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 4 Aug 2020 08:47:25 +0000 (10:47 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 24 Aug 2020 14:51:09 +0000 (16:51 +0200)
pdns/syncres.cc
pdns/syncres.hh

index 51113114557d2891c34ead599670563c116f724f..97ce0595cac58cfda8db625f0b2dcf3debbada09 100644 (file)
@@ -638,11 +638,18 @@ int SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, con
   return ret;
 }
 
-bool SyncRes::qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype, vector<DNSRecord> &ret)
+bool SyncRes::qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype, vector<DNSRecord> &ret, unsigned int depth)
 {
   if (!d_wantsRPZ) {
     return false;
   }
+  if (s_maxdepth && depth > s_maxdepth) {
+    string prefix = d_prefix;
+    prefix.append(depth, ' ');
+    string msg = "More than " + std::to_string(s_maxdepth) + " (max-recursion-depth) levels of recursion needed while resolving " + target.toLogString();
+    LOG(prefix << target << ": " << msg << endl);
+    throw ImmediateServFailException(msg);
+  }
 
   bool match = dfe.getQueryPolicy(target, d_discardedPolicies, d_appliedPolicy, true);
   if (!match) {
@@ -662,6 +669,8 @@ bool SyncRes::qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QTy
     return true;
   }
   auto spoofed = d_appliedPolicy.getCustomRecords(target, qtype.getCode());
+
+  // Add the record to the result vector being built, chase if we hit a CNAME
   for (const auto& dr : spoofed) {
     if (dr.d_place != DNSResourceRecord::ANSWER) {
       continue;
@@ -670,7 +679,9 @@ bool SyncRes::qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QTy
     auto content = getRR<CNAMERecordContent>(dr);
     if (content) {
       target = content->getTarget();
-      return qnameRPZHit(dfe, target, qtype, ret);
+      // This call wil return true if we hit a policy that needs an throw PolicyHitException
+      // For CNAME chasing, we don't want that since resolving should continue with the new target
+      return qnameRPZHit(dfe, target, qtype, ret, depth + 1);
     }
   }
 
@@ -685,7 +696,7 @@ int SyncRes::doResolve(const DNSName &qnameArg, const QType &qtype, vector<DNSRe
   auto luaconfsLocal = g_luaconfs.getLocal();
 
   // Can change qname
-  bool hit = qnameRPZHit(luaconfsLocal->dfe, qname, qtype, ret);
+  bool hit = qnameRPZHit(luaconfsLocal->dfe, qname, qtype, ret, depth + 1);
   if (hit) {
     throw PolicyHitException();
   }
index 426c0480754588d7ddd243079fba4b6bc4783878..48d4ea86f6f996deb653978e2727dfab7b03a45b 100644 (file)
@@ -823,7 +823,7 @@ private:
   bool doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType& qtype, LWResult& lwr, boost::optional<Netmask>& ednsmask, const DNSName& auth, bool const sendRDQuery, const DNSName& nsName, const ComboAddress& remoteIP, bool doTCP, bool* truncated);
   bool processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType& qtype, DNSName& auth, bool wasForwarded, const boost::optional<Netmask> ednsmask, bool sendRDQuery, NsSet &nameservers, std::vector<DNSRecord>& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state);
 
-  bool qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype, vector<DNSRecord>& ret);
+  bool qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype, vector<DNSRecord>& ret, unsigned int depth);
   int doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state);
   int doResolveNoQNameMinimization(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state, bool* fromCache = NULL, StopAtDelegation* stopAtDelegation = NULL, bool considerforwards = true);
   bool doOOBResolve(const AuthDomain& domain, const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, int& res);