]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Move Query policy handling to SyncRes.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 15 Jul 2020 09:47:54 +0000 (11:47 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 24 Aug 2020 14:51:08 +0000 (16:51 +0200)
This allows for intermediate CNAMEs to be subject to RPZ
processing.

pdns/filterpo.cc
pdns/filterpo.hh
pdns/pdns_recursor.cc
pdns/syncres.cc
pdns/syncres.hh

index 2ec5d3a0cd772dccbbf92a32411574098abfb393..2fd754959866f08a89961382f702a9ea950dc2e8 100644 (file)
@@ -227,7 +227,7 @@ bool DNSFilterEngine::getClientPolicy(const ComboAddress& ca, const std::unorder
   }
 
   if (allEmpty) {
-    cerr << " allempty" << endl;
+    //cerr << " allempty" << endl;
     return false;
   }
 
@@ -249,15 +249,15 @@ bool DNSFilterEngine::getClientPolicy(const ComboAddress& ca, const std::unorder
   return false;
 }
 
-bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies, Policy& pol) const
+bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies, Policy& pol, bool equalOK) const
 {
-  cerr<<"Got question for "<<qname<<' '<< pol.getPriority()<< endl;
+  //cerr<<"Got question for "<<qname<<' '<< pol.getPriority()<< endl;
   std::vector<bool> zoneEnabled(d_zones.size());
   size_t count = 0;
   bool allEmpty = true;
   for (const auto& z : d_zones) {
     bool enabled = true;
-    if (z->getPriority() >= pol.getPriority()) {
+    if (z->getPriority() > pol.getPriority() || (!equalOK && z->getPriority() == pol.getPriority())) {
       enabled = false;
     } else {
       const auto& zoneName = z->getName();
@@ -279,7 +279,7 @@ bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_
   }
 
   if (allEmpty) {
-    cerr << " allempty" << endl;
+    //cerr << " allempty" << endl;
     return false;
   }
 
@@ -309,7 +309,7 @@ bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_
         return true;
       }
     }
-    cerr << "no hit on " << qname << endl;
+    //cerr << "no hit on " << qname << endl;
     ++count;
   }
 
index 8dac89e37326476ce348e411f810d1e8e0442177..3828505bf1d510d524e4302bc5501d25d7ebed90 100644 (file)
@@ -342,7 +342,7 @@ public:
     }
   }
 
-  bool getQueryPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies, Policy& policy) const;
+  bool getQueryPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies, Policy& policy, bool equalOK = false) const;
   bool getClientPolicy(const ComboAddress& ca, const std::unordered_map<std::string,bool>& discardedPolicies, Policy& policy) const;
   bool getProcessingPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies, Policy& policy) const;
   bool getProcessingPolicy(const ComboAddress& address, const std::unordered_map<std::string,bool>& discardedPolicies, Policy& policy) const;
index 3cbdfabe0bf6b42739359ced202c54ac8d3b3ee9..77bfb1a549c9488f4aeea341eb9669a153a7caed 100644 (file)
@@ -835,6 +835,7 @@ static void protobufLogResponse(const RecProtoBufMessage& message)
 }
 #endif
 
+#if 0
 /**
  * Chases the CNAME provided by the PolicyCustom RPZ policy.
  *
@@ -860,6 +861,7 @@ static void handleRPZCustom(const DNSRecord& spoofed, const QType& qtype, SyncRe
     sr.setWantsRPZ(oldWantsRPZ);
   }
 }
+#endif
 
 static bool addRecordToPacket(DNSPacketWriter& pw, const DNSRecord& rec, uint32_t& minTTL, uint32_t ttlCap, const uint16_t maxAnswerSize)
 {
@@ -1230,8 +1232,9 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy
       return PolicyResult::HaveAnswer;
     }
     return PolicyResult::NoAction;
-
   case DNSFilterEngine::PolicyKind::Custom:
+    return PolicyResult::NoAction; // Now handled in syncres
+#if 0
     ret.clear();
     res = RCode::NoError;
     {
@@ -1258,6 +1261,7 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy
       }
     }
     return PolicyResult::HaveAnswer;
+#endif
   }
 
   return PolicyResult::NoAction;
index e9996a99e99952f0eaeb6319ded462ad13cba1fa..e5ec1fab5765d799533ac472f4ae900583a9e311 100644 (file)
@@ -638,11 +638,48 @@ int SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, con
   return ret;
 }
 
+bool SyncRes::qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype)
+{
+  //cerr << "wants: " << target << '/' << qtype.getName() << ' ' << d_wantsRPZ << ' ' << int(d_appliedPolicy.d_type) << ' ' <<  int(d_appliedPolicy.d_kind) << endl;
+  if (d_wantsRPZ) {
+    //cerr << "check" << endl;
+    bool match = dfe.getQueryPolicy(target, d_discardedPolicies, d_appliedPolicy, true);
+    if (match) {
+      mergePolicyTags(d_policyTags, d_appliedPolicy.getTags());
+      if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) {
+        LOG(" (CNAME hit by RPZ policy '" + d_appliedPolicy.getName() + "')");
+        if (d_appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom) {
+          auto spoofed = d_appliedPolicy.getCustomRecords(target, qtype.getCode());
+          for (auto& dr : spoofed) {
+            auto content = getRR<CNAMERecordContent>(dr);
+            if (content) {
+              target = content->getTarget();
+              //cerr << "NEW TARGET " << target << endl;
+              return false;
+            }
+          }
+        }
+        //cerr << "OTHER POLICY HIT" << endl;
+        return true;
+      }
+    }
+  }
+  //cerr << "NOMATCH" << endl;
+  return false;
+}
+
 #define QLOG(x) LOG(prefix << " child=" <<  child << ": " << x << endl)
 
-int SyncRes::doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state) {
+int SyncRes::doResolve(const DNSName &qnameArg, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state) {
 
-  // In the auth or recursive forward case, it does nt make sense to do qname-minimization
+  auto luaconfsLocal = g_luaconfs.getLocal();
+
+  DNSName qname(qnameArg);
+  bool hit = qnameRPZHit(luaconfsLocal->dfe, qname, qtype);
+  if (hit) {
+    throw PolicyHitException();
+  }
+  // In the auth or recursive forward case, it does not make sense to do qname-minimization
   if (!getQNameMinimization() || isRecursiveForwardOrAuth(qname)) {
     return doResolveNoQNameMinimization(qname, qtype, ret, depth, beenthere, state);
   }
index c327df0150e7fdc9b71bc914a6a36542ab16e5e1..b8536794ff435e9d04d79cc571e2c520088f1852 100644 (file)
@@ -823,6 +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);
   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);