]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Merge pull request #10570 from rgacogne/rec-hunt-cuts-on-bogus
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 28 Jul 2021 06:00:07 +0000 (08:00 +0200)
committerGitHub <noreply@github.com>
Wed, 28 Jul 2021 06:00:07 +0000 (08:00 +0200)
rec: Make really sure we did not miss a cut on validation failure

1  2 
pdns/syncres.cc
pdns/syncres.hh

diff --cc pdns/syncres.cc
index e9de7d779f2082f70f385423c01d7b31e0bed8a6,87c2ae40dc956a8ed00d60874198d85d93cfc7a2..86ee77ae5b12808e20a376f68de7af8858532ae2
@@@ -2853,49 -2908,19 +2908,59 @@@ vState SyncRes::validateRecordsWithSigs
    }
  
    LOG(d_prefix<<vStateToString(state)<<"!"<<endl);
-   return state;
+   /* try again to get the missed cuts, harder this time */
+   auto zState = getValidationStatus(name, false, type == QType::DS, depth);
+   LOG(d_prefix<<"checking whether we missed a zone cut before returning a Bogus state"<<endl);
+   if (zState == vState::Secure) {
+     /* too bad */
+     LOG(d_prefix<<"we are still in a Secure zone, returning "<<vStateToString(state)<<endl);
+     return state;
+   }
+   else {
+     return zState;
+   }
  }
  
 +/* This function will check whether the answer should have the AA bit set, and will set if it should be set and isn't.
 +   This is unfortunately needed to deal with very crappy so-called DNS servers */
 +void SyncRes::fixupAnswer(const std::string& prefix, LWResult& lwr, const DNSName& qname, const QType qtype, const DNSName& auth, bool wasForwarded, bool rdQuery)
 +{
 +  const bool wasForwardRecurse = wasForwarded && rdQuery;
 +
 +  if (wasForwardRecurse || lwr.d_aabit) {
 +    /* easy */
 +    return;
 +  }
 +
 +  for (const auto& rec : lwr.d_records) {
 +
 +    if (rec.d_type == QType::OPT) {
 +      continue;
 +    }
 +
 +    if (rec.d_class != QClass::IN) {
 +      continue;
 +    }
 +
 +    if (rec.d_type == QType::ANY) {
 +      continue;
 +    }
 +
 +    if (rec.d_place == DNSResourceRecord::ANSWER && (rec.d_type == qtype || rec.d_type == QType::CNAME || qtype == QType::ANY) && rec.d_name == qname && rec.d_name.isPartOf(auth)) {
 +      /* This is clearly an answer to the question we were asking, from an authoritative server that is allowed to send it.
 +         We are going to assume this server is broken and does not know it should set the AA bit, even though it is DNS 101 */
 +      LOG(prefix<<"Received a record for "<<rec.d_name<<"|"<<DNSRecordContent::NumberToType(rec.d_type)<<" in the answer section from "<<auth<<", without the AA bit set. Assuming this server is clueless and setting the AA bit."<<endl);
 +      lwr.d_aabit = true;
 +      return;
 +    }
 +
 +    if (rec.d_place != DNSResourceRecord::ANSWER) {
 +      /* we have scanned all the records in the answer section, if any, we are done */
 +      return;
 +    }
 +  }
 +}
 +
  static bool allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals, const DNSRecord& rec)
  {
    switch(rec.d_type) {
diff --cc pdns/syncres.hh
Simple merge