]> granicus.if.org Git - pdns/commitdiff
implement 'narrow' NSEC3 generation w/o consulting the database ordering, based on...
authorBert Hubert <bert.hubert@netherlabs.nl>
Thu, 6 Jan 2011 09:15:39 +0000 (09:15 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Thu, 6 Jan 2011 09:15:39 +0000 (09:15 +0000)
This will probably have to be tuned further.

git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1810 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/dbdnsseckeeper.cc
pdns/dnsseckeeper.hh
pdns/packethandler.cc
pdns/packethandler.hh
pdns/pdnssec.cc

index 41aece34a2e34591accd0026e23322f636d1c1e9..7e47cc4c406560929bfdc744f3f7fdc701f980b4 100644 (file)
@@ -99,10 +99,16 @@ void DNSSECKeeper::activateKey(const std::string& zname, unsigned int id)
   d_db.activateDomainKey(zname, id);
 }
 
-bool DNSSECKeeper::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p)
+bool DNSSECKeeper::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p, bool* narrow)
 {
-  
   vector<string> meta;
+  if(narrow) {
+    d_db.getDomainMetadata(zname, "NSEC3NARROW", meta);
+    *narrow=false;
+    if(!meta.empty() && meta[0]=="1")
+      *narrow=true;
+  }
+  meta.clear();
   d_db.getDomainMetadata(zname, "NSEC3PARAM", meta);
   
   if(meta.empty())
@@ -122,12 +128,17 @@ bool DNSSECKeeper::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordConte
   return true;
 }
 
-void DNSSECKeeper::setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& ns3p)
+void DNSSECKeeper::setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& ns3p, const bool& narrow)
 {
   string descr = ns3p.getZoneRepresentation();
   vector<string> meta;
   meta.push_back(descr);
   d_db.setDomainMetadata(zname, "NSEC3PARAM", meta);
+  
+  meta.clear();
+  if(narrow)
+    meta.push_back("1");
+  d_db.setDomainMetadata(zname, "NSEC3NARROW", meta);
 }
 
 void DNSSECKeeper::unsetNSEC3PARAM(const std::string& zname)
index 00ec8775244840e92212bce6f6751a50d54eae81..1d117e662b9e5e30e89ef698794590855bbc80cb 100644 (file)
@@ -116,8 +116,8 @@ public:
 
   void secureZone(const std::string& fname, int algorithm);
 
-  bool getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* n3p=0);
-  void setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& n3p);
+  bool getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0);
+  void setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& n3p, const bool& narrow=false);
   void unsetNSEC3PARAM(const std::string& zname);
 };
 
index 00bcae3538feb01961c909374286ef87ded1b86a..b3fe3c43a77f81bf540e65f7cc1b9d29778f6d84 100644 (file)
@@ -512,7 +512,7 @@ void PacketHandler::emitNSEC3(const NSEC3PARAMRecordContent& ns3prc, const std::
   rr.ttl=3600;
   rr.qtype=QType::NSEC3;
   rr.content=n3rc.getZoneRepresentation();
-  cerr<<"nsec3: '"<<rr.content<<"'"<<endl;
+  //cerr<<"nsec3: '"<<rr.content<<"'"<<endl;
   rr.d_place = (mode == 2 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
   rr.auth = true;
   r->addRecord(rr);
@@ -530,9 +530,10 @@ void PacketHandler::addNSECX(DNSPacket *p, DNSPacket *r, const string& target, c
 {
   NSEC3PARAMRecordContent ns3rc;
   cerr<<"Doing NSEC3PARAM lookup for '"<<auth<<"', "<<p->qdomain<<"|"<<p->qtype.getName()<<": ";
-  if(d_dk.getNSEC3PARAM(auth, &ns3rc))  {
-    cerr<<"Present"<<endl;
-    addNSEC3(p, r, target, auth, ns3rc, mode);
+  bool narrow;
+  if(d_dk.getNSEC3PARAM(auth, &ns3rc, &narrow))  {
+    cerr<<"Present, narrow="<<narrow<<endl;
+    addNSEC3(p, r, target, auth, ns3rc, narrow, mode);
   }
   else {
     cerr<<"Not present"<<endl;
@@ -540,7 +541,37 @@ void PacketHandler::addNSECX(DNSPacket *p, DNSPacket *r, const string& target, c
   }
 }
 
-void PacketHandler::addNSEC3(DNSPacket *p, DNSPacket *r, const string& target, const string& auth, const NSEC3PARAMRecordContent& ns3rc, int mode)
+static void incrementHash(std::string& hash) // I wonder if this is correct, cmouse? ;-)
+{
+  if(hash.empty())
+    return;
+  for(string::size_type pos=hash.size(); pos; ) {
+    --pos;
+    unsigned char c = (unsigned char)hash[pos];
+    ++c;
+    hash[pos] = (char) c;
+    if(c)
+      break;
+  }
+}
+
+bool PacketHandler::getNSEC3Hashes(bool narrow, DNSBackend* db, int id, const std::string& hashed, string& unhashed, string& before, string& after)
+{
+  bool ret;
+  if(narrow) { // nsec3-narrow
+    ret=true;
+    before=hashed;
+    after=hashed;
+    incrementHash(after);
+  }
+  else {
+    ret=db->getBeforeAndAfterNamesAbsolute(id, hashed, unhashed, before, after);
+  }
+  // cerr<<"rgetNSEC3Hashes: "<<hashed<<", "<<unhashed<<", "<<before<<", "<<after<<endl;
+  return ret;
+}
+
+void PacketHandler::addNSEC3(DNSPacket *p, DNSPacket *r, const string& target, const string& auth, const NSEC3PARAMRecordContent& ns3rc, bool narrow, int mode)
 {
   string hashed;
   
@@ -550,25 +581,30 @@ void PacketHandler::addNSEC3(DNSPacket *p, DNSPacket *r, const string& target, c
     cerr<<"Could not get SOA for domain in NSEC3\n";
     return;
   }
-  cerr<<"salt in ph: '"<<makeHexDump(ns3rc.d_salt)<<"'"<<endl;
+  cerr<<"salt in ph: '"<<makeHexDump(ns3rc.d_salt)<<"', narrow="<<narrow<<endl;
   string unhashed, before,after;
   
   // now add the closest encloser
-  hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, auth)));
-  sd.db->getBeforeAndAfterNamesAbsolute(sd.domain_id,  hashed, unhashed, before, after); 
+  unhashed=auth;
+  hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, unhashed)));
+  
+  getNSEC3Hashes(narrow, sd.db, sd.domain_id,  hashed, unhashed, before, after); 
   cerr<<"Done calling for closest encloser, before='"<<before<<"', after='"<<after<<"'"<<endl;
   emitNSEC3(ns3rc, auth, unhashed, fromBase32Hex(before), fromBase32Hex(after), target, r, mode);
   
   // now add the main nsec3
-  hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, p->qdomain)));
-  sd.db->getBeforeAndAfterNamesAbsolute(sd.domain_id,  hashed, unhashed, before, after); 
+  unhashed = p->qdomain;
+  hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, unhashed)));
+  getNSEC3Hashes(narrow, sd.db,sd.domain_id,  hashed, unhashed, before, after); 
   cerr<<"Done calling for main, before='"<<before<<"', after='"<<after<<"'"<<endl;
   emitNSEC3( ns3rc, auth, unhashed, fromBase32Hex(before), fromBase32Hex(after), target, r, mode);
   
   
   // now add the *
-  hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, dotConcat("*", auth))));
-  sd.db->getBeforeAndAfterNamesAbsolute(sd.domain_id,  hashed, unhashed, before, after); 
+  unhashed=dotConcat("*", auth);
+  hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3rc.d_iterations, ns3rc.d_salt, unhashed)));
+  
+  getNSEC3Hashes(narrow, sd.db, sd.domain_id,  hashed, unhashed, before, after); 
   cerr<<"Done calling for '*', before='"<<before<<"', after='"<<after<<"'"<<endl;
   emitNSEC3( ns3rc, auth, unhashed, fromBase32Hex(before), fromBase32Hex(after), target, r, mode);
 }
@@ -911,7 +947,7 @@ void PacketHandler::synthesiseRRSIGs(DNSPacket* p, DNSPacket* r)
     nrc.d_set.insert(rr.qtype.getCode());
   }
 
-  // now get the fucking NSEC too (since we must sign it!)
+  // now get the NSEC too (since we must sign it!)
 
   SOAData sd;
   sd.db=(DNSBackend *)-1; // force uncached answer
index 8197ee855b0bd9852dded8bc022b5e4617fff09d..d48497e571db09ef3fffc659e82919e7f8157f51 100644 (file)
@@ -99,9 +99,10 @@ private:
   bool doDNSSECProcessing(DNSPacket* p, DNSPacket *r);
   void addNSECX(DNSPacket *p, DNSPacket* r, const string &target, const std::string& auth, int mode);
   void addNSEC(DNSPacket *p, DNSPacket* r, const string &target, const std::string& auth, int mode);
-  void addNSEC3(DNSPacket *p, DNSPacket* r, const string &target, const std::string& auth, const NSEC3PARAMRecordContent& nsec3param, int mode);
+  void addNSEC3(DNSPacket *p, DNSPacket* r, const string &target, const std::string& auth, const NSEC3PARAMRecordContent& nsec3param, bool narrow, int mode);
   void emitNSEC(const std::string& before, const std::string& after, const std::string& toNSEC, const std::string& auth, DNSPacket *r, int mode);
   void emitNSEC3(const NSEC3PARAMRecordContent &ns3rc, const std::string& auth, const std::string& unhashed, const std::string& begin, const std::string& end, const std::string& toNSEC3, DNSPacket *r, int mode);
+  bool getNSEC3Hashes(bool narrow, DNSBackend* db, int id, const std::string& hashed, string& unhashed, string& before, string& after);
 
   void synthesiseRRSIGs(DNSPacket* p, DNSPacket* r);
   void makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string& target, SOAData& sd);
index cb882eebca2c24b26ea88f0219968cc13b8d82e7..9c2b21125d71394efb33a69f0ed9d62c78f9c175 100644 (file)
@@ -218,12 +218,13 @@ try
     const string& zone=cmds[1];
 
     NSEC3PARAMRecordContent ns3pr;
-    dk.getNSEC3PARAM(zone, &ns3pr);
+    bool narrow;
+    dk.getNSEC3PARAM(zone, &ns3pr, &narrow);
     
     if(ns3pr.d_salt.empty()) 
       cerr<<"Zone has NSEC semantics"<<endl;
     else
-      cerr<<"Zone has hashed NSEC3 semantics, configuration: "<<ns3pr.getZoneRepresentation()<<endl;
+      cerr<<"Zone has " << (narrow ? "NARROW " : "") <<"hashed NSEC3 semantics, configuration: "<<ns3pr.getZoneRepresentation()<<endl;
     
     DNSSECKeeper::keyset_t keyset=dk.getKeys(zone);
 
@@ -309,9 +310,9 @@ try
   }
   else if(cmds[0]=="set-nsec3") {
     string nsec3params =  cmds.size() > 2 ? cmds[2] : "1 0 1 ab";
-      
+    bool narrow = cmds.size() > 3 && cmds[3]=="narrow";
     NSEC3PARAMRecordContent ns3pr(nsec3params);
-    dk.setNSEC3PARAM(cmds[1], ns3pr);
+    dk.setNSEC3PARAM(cmds[1], ns3pr, narrow);
   }
   else if(cmds[0]=="unset-nsec3") {
     dk.unsetNSEC3PARAM(cmds[1]);