]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Check for valid hostnames in SRV, NS and MX records 5062/head
authorPieter Lexis <pieter.lexis@powerdns.com>
Tue, 21 Feb 2017 12:08:49 +0000 (13:08 +0100)
committerPieter Lexis <pieter.lexis@powerdns.com>
Tue, 28 Feb 2017 12:06:59 +0000 (13:06 +0100)
Fixes #512

pdns/dnsname.cc
pdns/dnsname.hh
pdns/pdnsutil.cc

index 8c6bf150ff9a39e949900b60d764d9ef1ed18d12..10dbbf8b8cae0c7e25bcb2bf9fdba5ac7f8989c3 100644 (file)
@@ -345,6 +345,16 @@ bool DNSName::isWildcard() const
   return (*p == 0x01 && *++p == '*');
 }
 
+/*
+ * Returns true if the DNSName is a valid RFC 1123 hostname, this function uses
+ * a regex on the string, so it is probably best not used when speed is essential.
+ */
+bool DNSName::isHostname() const
+{
+  static Regex hostNameRegex = Regex("^(([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)\\.)+$");
+  return hostNameRegex.match(this->toString());
+}
+
 unsigned int DNSName::countLabels() const
 {
   unsigned int count=0;
index 21b8d84680ef6d1725f73dc251da6570571b86bd..a2a8dccd65d23bdfba824637865319e31ac1766e 100644 (file)
@@ -96,6 +96,7 @@ public:
   void makeUsRelative(const DNSName& zone);
   DNSName labelReverse() const;
   bool isWildcard() const;
+  bool isHostname() const;
   unsigned int countLabels() const;
   size_t wirelength() const; //!< Number of total bytes in the name
   bool empty() const { return d_storage.empty(); }
index b6b86387a29bdc1d5080c7eb7362a85664226ae8..2179ec6b64a9160b4d886fdb409fa921d3aef71a 100644 (file)
@@ -579,13 +579,27 @@ int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone, const vect
       }
     }
 
-    if(rr.qtype.getCode() == QType::A || rr.qtype.getCode() == QType::AAAA)
-    {
-      Regex hostnameRegex=Regex("^(([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)\\.)+$");
-      if (!hostnameRegex.match(rr.qname.toString()))
-      {
-        cout<<"[Info] A or AAAA record found at '"<<rr.qname.toString()<<"'. This name is not a valid hostname."<<endl;
-        continue;
+    if((rr.qtype.getCode() == QType::A || rr.qtype.getCode() == QType::AAAA) && !rr.qname.isWildcard() && !rr.qname.isHostname())
+      cout<<"[Info] "<<rr.qname.toString()<<" record for '"<<rr.qtype.getName()<<"' is not a valid hostname."<<endl;
+
+    // Check if the DNSNames that should be hostnames, are hostnames
+    if (rr.qtype.getCode() == QType::NS || rr.qtype.getCode() == QType::MX || rr.qtype.getCode() == QType::SRV) {
+      DNSName toCheck;
+      if (rr.qtype.getCode() == QType::SRV) {
+        vector<string> parts;
+        stringtok(parts, rr.getZoneRepresentation());
+        toCheck = DNSName(parts[3]);
+      } else if (rr.qtype.getCode() == QType::MX) {
+        vector<string> parts;
+        stringtok(parts, rr.getZoneRepresentation());
+        toCheck = DNSName(parts[1]);
+      } else {
+        toCheck = DNSName(rr.content);
+      }
+
+      if (!toCheck.isHostname()) {
+        cout<<"[Warning] "<<rr.qtype.getName()<<" record in zone '"<<zone<<"' has non-hostname content '"<<toCheck<<"'."<<endl;
+        numwarnings++;
       }
     }