From: Otto Moerbeek Date: Wed, 15 Jul 2020 09:47:54 +0000 (+0200) Subject: Move Query policy handling to SyncRes. X-Git-Tag: rec-4.4.0-beta1~1^2~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c348b09b51aee93386a63fe041fb8a5b255b8adf;p=thirdparty%2Fpdns.git Move Query policy handling to SyncRes. This allows for intermediate CNAMEs to be subject to RPZ processing. --- diff --git a/pdns/filterpo.cc b/pdns/filterpo.cc index 2ec5d3a0cd..2fd7549598 100644 --- a/pdns/filterpo.cc +++ b/pdns/filterpo.cc @@ -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& discardedPolicies, Policy& pol) const +bool DNSFilterEngine::getQueryPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& pol, bool equalOK) const { - cerr<<"Got question for "< 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; } diff --git a/pdns/filterpo.hh b/pdns/filterpo.hh index 8dac89e373..3828505bf1 100644 --- a/pdns/filterpo.hh +++ b/pdns/filterpo.hh @@ -342,7 +342,7 @@ public: } } - bool getQueryPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& policy) const; + bool getQueryPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& policy, bool equalOK = false) const; bool getClientPolicy(const ComboAddress& ca, const std::unordered_map& discardedPolicies, Policy& policy) const; bool getProcessingPolicy(const DNSName& qname, const std::unordered_map& discardedPolicies, Policy& policy) const; bool getProcessingPolicy(const ComboAddress& address, const std::unordered_map& discardedPolicies, Policy& policy) const; diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 3cbdfabe0b..77bfb1a549 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -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; diff --git a/pdns/syncres.cc b/pdns/syncres.cc index e9996a99e9..e5ec1fab57 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -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(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&ret, unsigned int depth, set& beenthere, vState& state) { +int SyncRes::doResolve(const DNSName &qnameArg, const QType &qtype, vector&ret, unsigned int depth, set& 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); } diff --git a/pdns/syncres.hh b/pdns/syncres.hh index c327df0150..b8536794ff 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -823,6 +823,7 @@ private: bool doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType& qtype, LWResult& lwr, boost::optional& 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 ednsmask, bool sendRDQuery, NsSet &nameservers, std::vector& 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&ret, unsigned int depth, set& beenthere, vState& state); int doResolveNoQNameMinimization(const DNSName &qname, const QType &qtype, vector&ret, unsigned int depth, set& beenthere, vState& state, bool* fromCache = NULL, StopAtDelegation* stopAtDelegation = NULL, bool considerforwards = true); bool doOOBResolve(const AuthDomain& domain, const DNSName &qname, const QType &qtype, vector&ret, int& res);