]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Ignore unsupported RPZ entries
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 20 Feb 2017 09:27:39 +0000 (10:27 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 21 Feb 2017 09:33:22 +0000 (10:33 +0100)
pdns/dnsname.cc
pdns/dnsname.hh
pdns/rpzloader.cc
pdns/test-dnsname_cc.cc

index 8c6bf150ff9a39e949900b60d764d9ef1ed18d12..c3ad8e2f0095c6fde0c5746a86414bf97019776f 100644 (file)
@@ -328,6 +328,17 @@ vector<string> DNSName::getRawLabels() const
   return ret;
 }
 
+std::string DNSName::getRawLabel(unsigned int pos) const
+{
+  unsigned int currentPos = 0;
+  for(const unsigned char* p = (const unsigned char*) d_storage.c_str(); p < ((const unsigned char*) d_storage.c_str()) + d_storage.size() && *p; p+=*p+1, currentPos++) {
+    if (currentPos == pos) {
+      return std::string((const char*)p+1, (size_t)*p);
+    }
+  }
+
+  throw std::out_of_range("trying to get label at position "+std::to_string(pos)+" of a DNSName that only has "+std::to_string(currentPos)+" labels");
+}
 
 bool DNSName::chopOff()
 {
index 21b8d84680ef6d1725f73dc251da6570571b86bd..408fc555e14542d102087962b6738629845ffbaf 100644 (file)
@@ -82,6 +82,7 @@ public:
   void appendRawLabel(const char* start, unsigned int length); //!< Append this unescaped label
   void prependRawLabel(const std::string& str); //!< Prepend this unescaped label
   std::vector<std::string> getRawLabels() const; //!< Individual raw unescaped labels
+  std::string getRawLabel(unsigned int pos) const; //!< Get the specified raw unescaped label
   bool chopOff();                               //!< Turn www.powerdns.com. into powerdns.com., returns false for .
   DNSName makeRelative(const DNSName& zone) const;
   DNSName makeLowerCase() const
index cbda6e05ccd428af00dca0c18bf025bc733b92f4..67c36f6ce05771386e1433d0386463f02902db1a 100644 (file)
@@ -63,6 +63,7 @@ void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, bool addOrR
   static const DNSName drop("rpz-drop."), truncate("rpz-tcp-only."), noaction("rpz-passthru.");
   static const DNSName rpzClientIP("rpz-client-ip"), rpzIP("rpz-ip"),
     rpzNSDname("rpz-nsdname"), rpzNSIP("rpz-nsip.");
+  static const std::string rpzPrefix("rpz-");
 
   DNSFilterEngine::Policy pol;
 
@@ -98,6 +99,19 @@ void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, bool addOrR
       // cerr<<"Wants NOACTION for "<<dr.d_name<<": ";
       pol.d_kind = DNSFilterEngine::PolicyKind::NoAction;
     }
+    /* "The special RPZ encodings which are not to be taken as Local Data are
+       CNAMEs with targets that are:
+       +  "."  (NXDOMAIN action),
+       +  "*." (NODATA action),
+       +  a top level domain starting with "rpz-",
+       +  a child of a top level domain starting with "rpz-".
+    */
+    else if(!crcTarget.empty() && !crcTarget.isRoot() && crcTarget.getRawLabel(crcTarget.countLabels() - 1).compare(0, rpzPrefix.length(), rpzPrefix) == 0) {
+      /* this is very likely an higher format number or a configuration error,
+         let's just ignore it. */
+      L<<Logger::Info<<"Discarding unsupported RPZ entry "<<crcTarget.toString()<<" for "<<dr.d_name<<endl;
+      return;
+    }
     else {
       pol.d_kind = DNSFilterEngine::PolicyKind::Custom;
       pol.d_custom = dr.d_content;
@@ -122,7 +136,7 @@ void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, bool addOrR
   }
 
   // now to DO something with that
-  
+
   if(dr.d_name.isPartOf(rpzNSDname)) {
     DNSName filt=dr.d_name.makeRelative(rpzNSDname);
     if(addOrRemove)
index cb24308f76f80eee3ba81613443fe9287d4cca29..bb829614e91660c7cf0886e22212199a3c2f2134 100644 (file)
@@ -849,5 +849,13 @@ BOOST_AUTO_TEST_CASE(test_wirelength) { // Testing if we get the correct value f
   BOOST_CHECK_EQUAL(sname.wirelength(), 19);
 }
 
+BOOST_AUTO_TEST_CASE(test_getrawlabel) {
+  DNSName name("a.bb.ccc.dddd.");
+  BOOST_CHECK_EQUAL(name.getRawLabel(0), "a");
+  BOOST_CHECK_EQUAL(name.getRawLabel(1), "bb");
+  BOOST_CHECK_EQUAL(name.getRawLabel(2), "ccc");
+  BOOST_CHECK_EQUAL(name.getRawLabel(3), "dddd");
+  BOOST_CHECK_THROW(name.getRawLabel(name.countLabels()), std::out_of_range);
+}
 
 BOOST_AUTO_TEST_SUITE_END()