]> granicus.if.org Git - pdns/commitdiff
Validate length of the zonename for NSEC3
authorPieter Lexis <pieter.lexis@powerdns.com>
Fri, 2 Oct 2015 12:21:01 +0000 (14:21 +0200)
committerPieter Lexis <pieter.lexis@powerdns.com>
Mon, 26 Oct 2015 18:13:24 +0000 (19:13 +0100)
If the zonename is too long, don't add NSEC3 semantics. Also give an
error when the zone is checked. Closes #2402.

pdns/dnsname.cc
pdns/dnsname.hh
pdns/pdnssec.cc

index 5b5567648e63a133761d7c35a7d73788c4e3ea39..055b4d666e9f1285cdbe99fdb17c7122c214b2f2 100644 (file)
@@ -105,6 +105,15 @@ size_t DNSName::length() const {
   return this->toString().length();
 }
 
+/**
+ * Get the length of the DNSName on the wire
+ *
+ * @return the total wirelength of the DNSName
+ */
+size_t DNSName::wirelength() const {
+  return d_storage.length() + 1;
+}
+
 // are WE part of parent
 bool DNSName::isPartOf(const DNSName& parent) const
 {
index bdb191433a13309fc16ea19b606bace7b43afc68..6bf98d32aa79ceb0ad97e24e25824f18a1fc7bee 100644 (file)
@@ -49,6 +49,7 @@ public:
   bool isWildcard() const;
   unsigned int countLabels() const;
   size_t length() const; // FIXME400 remove me?
+  size_t wirelength() const; //!< Number of total bytes in the name
   bool empty() const { return d_empty; }
   bool isRoot() const { return !d_empty && d_storage.empty(); }
   void clear() { d_storage.clear(); d_empty=true; }
index 8c078bb8ddf73eca5533efc969d1683befb3fefb..7dc0c43ce76b1a5dc15f4848db164f019c6a58ee 100644 (file)
@@ -418,6 +418,10 @@ int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone)
   DNSResourceRecord rr;
   uint64_t numrecords=0, numerrors=0, numwarnings=0;
 
+  if (haveNSEC3 && isSecure && zone.wirelength() > 222) {
+    numerrors++;
+    cerr<<"[Error] zone '" << zone.toStringNoDot() << "' has NSEC3 semantics but is too long to have the hash prepended. Zone name is " << zone.wirelength() << " bytes long, whereas the maximum is 222 bytes." << endl;
+  }
 
   // Check for delegation in parent zone
   DNSName parent(zone);
@@ -1729,6 +1733,10 @@ try
     NSEC3PARAMRecordContent ns3pr(nsec3params);
 
     DNSName zone(cmds[1]);
+    if (zone.wirelength() > 222) {
+      cerr<<"Cannot enable NSEC3 for " << zone.toString() << " as it is too long (" << zone.wirelength() << " bytes, maximum is 222 bytes)"<<endl;
+      return 1;
+    }
     if (! dk.setNSEC3PARAM(zone, ns3pr, narrow)) {
       cerr<<"Cannot set NSEC3 param for " << zone.toString() << endl;
       return 1;