]> granicus.if.org Git - pdns/commitdiff
implement 'pdnssec set-presigned', allowing PowerDNSSEC to serve pre-signed zones...
authorBert Hubert <bert.hubert@netherlabs.nl>
Tue, 18 Jan 2011 14:55:39 +0000 (14:55 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Tue, 18 Jan 2011 14:55:39 +0000 (14:55 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1893 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/dbdnsseckeeper.cc
pdns/dnsseckeeper.hh
pdns/dnssecsigner.cc
pdns/htimer.cc
pdns/packethandler.cc
pdns/pdnssec.cc
pdns/slavecommunicator.cc
pdns/tcpreceiver.cc

index 04344315ce694f2b2e21ccafff995b2889f647a7..88138ccdd4b054f78d0ac38c4b2c9bfd842303ea 100644 (file)
@@ -40,8 +40,11 @@ DNSSECKeeper::nseccache_t DNSSECKeeper::s_nseccache;
 pthread_mutex_t DNSSECKeeper::s_nseccachelock = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t DNSSECKeeper::s_keycachelock = PTHREAD_MUTEX_INITIALIZER;
 
-bool DNSSECKeeper::haveActiveKSKFor(const std::string& zone) 
+bool DNSSECKeeper::isSecuredZone(const std::string& zone) 
 {
+  if(isPresigned(zone))
+       return true;
+       
   {
     Lock l(&s_keycachelock);
     keycache_t::const_iterator iter = s_keycache.find(zone);
@@ -64,6 +67,14 @@ bool DNSSECKeeper::haveActiveKSKFor(const std::string& zone)
   return false;
 }
 
+bool DNSSECKeeper::isPresigned(const std::string& name)
+{
+  vector<string> meta;
+  d_db.getDomainMetadata(name, "PRESIGNED", meta);
+  if(meta.empty())
+       return false;
+  return meta[0]=="1";
+}
 
 void DNSSECKeeper::addKey(const std::string& name, bool keyOrZone, int algorithm, int bits, bool active)
 {
@@ -228,6 +239,21 @@ void DNSSECKeeper::unsetNSEC3PARAM(const std::string& zname)
 }
 
 
+void DNSSECKeeper::setPresigned(const std::string& zname)
+{
+  clearCaches(zname);
+  vector<string> meta;
+  meta.push_back("1");
+  d_db.setDomainMetadata(zname, "PRESIGNED", meta);
+}
+
+void DNSSECKeeper::unsetPresigned(const std::string& zname)
+{
+  clearCaches(zname);
+  d_db.setDomainMetadata(zname, "PRESIGNED", vector<string>());
+}
+
+
 DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const std::string& zone, boost::tribool allOrKeyOrZone) 
 {
   unsigned int now = time(0);
@@ -288,3 +314,20 @@ void DNSSECKeeper::secureZone(const std::string& name, int algorithm)
   clearCaches(name); // just to be sure ;)
   addKey(name, true, algorithm);
 }
+
+bool DNSSECKeeper::getPreRRSIGs(const std::string& signer, const std::string& qname, const QType& qtype, 
+       DNSPacketWriter::Place signPlace, vector<DNSResourceRecord>& rrsigs)
+{
+       d_db.lookup(QType(QType::RRSIG), qname);
+       DNSResourceRecord rr;
+       while(d_db.get(rr)) { 
+               cerr<<"Considering for '"<<qtype.getName()<<"' RRSIG '"<<rr.content<<"'\n";
+               if(boost::starts_with(rr.content, qtype.getName()+" ")) {
+                       cerr<<"Got it"<<endl;
+                       rr.d_place = (DNSResourceRecord::Place)signPlace;
+                       rrsigs.push_back(rr);
+               }
+               else cerr<<"Skipping!"<<endl;
+       }
+       return true;
+}
index 40c6ba758e0505509f669cae18ec918c25de291c..2e3bf8b844ed6e9957eb22c6cc9d32dc8ec6ee23 100644 (file)
@@ -127,7 +127,7 @@ private:
   UeberBackend d_db;
 public:
   DNSSECKeeper() : d_db("key-only"){}
-  bool haveActiveKSKFor(const std::string& zone);
+  bool isSecuredZone(const std::string& zone);
   
   keyset_t getKeys(const std::string& zone, boost::tribool allOrKeyOrZone = boost::indeterminate);
   DNSSECPrivateKey getKeyById(const std::string& zone, unsigned int id);
@@ -143,6 +143,10 @@ public:
   void setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& n3p, const bool& narrow=false);
   void unsetNSEC3PARAM(const std::string& zname);
   void clearCaches(const std::string& name);
+  bool getPreRRSIGs(const std::string& signer, const std::string& qname, const QType& qtype, DNSPacketWriter::Place, vector<DNSResourceRecord>& rrsigs);
+  bool isPresigned(const std::string& zname);
+  void setPresigned(const std::string& zname);
+  void unsetPresigned(const std::string& zname);
 private:  
   struct KeyCacheEntry
   {
index 1153479920226bd8a384eed72d0c91408ccea13f..31295ffd8d9b4724d1aa5bec5972155f93705e54 100644 (file)
@@ -21,7 +21,7 @@
 #include "dnsseckeeper.hh"
 #include "lock.hh"
 
-/* this is where the RRSIGs begin, key apex *name* gets found, keys are retrieved,
+/* this is where the RRSIGs begin, keys are retrieved,
    but the actual signing happens in fillOutRRSIG */
 int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string& signer, const std::string signQName, uint16_t signQType, uint32_t signTTL, 
                     vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent>& rrcs, bool ksk)
@@ -31,7 +31,6 @@ int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string& signer, const std::st
   RRSIGRecordContent rrc;
   rrc.d_type=signQType;
 
-  
   rrc.d_labels=countLabels(signQName); 
   rrc.d_originalttl=signTTL; 
   rrc.d_siginception=getCurrentInception();;
@@ -79,15 +78,17 @@ void addSignature(DNSSECKeeper& dk, const std::string& signer, const std::string
   vector<shared_ptr<DNSRecordContent> >& toSign, vector<DNSResourceRecord>& outsigned)
 {
   // cerr<<"Asked to sign '"<<signQName<<"'|"<<DNSRecordContent::NumberToType(signQType)<<", "<<toSign.size()<<" records\n";
-
-  vector<RRSIGRecordContent> rrcs;
   if(toSign.empty())
     return;
-
-  if(getRRSIGsForRRSET(dk, signer, wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrcs, signQType == QType::DNSKEY) < 0) {
+  vector<RRSIGRecordContent> rrcs;
+  if(dk.isPresigned(signer)) {
+       dk.getPreRRSIGs(signer, signQName, QType(signQType), signPlace, outsigned);
+  }
+  else if(getRRSIGsForRRSET(dk, signer, wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrcs, signQType == QType::DNSKEY) < 0) {
     // cerr<<"Error signing a record!"<<endl;
     return;
   }
+  
   DNSResourceRecord rr;
   rr.qname=signQName;
   rr.qtype=QType::RRSIG;
index c5ee839bb5ebd38f763753ac679c2425b068bfa1..393a833678d7038dce0bd0b43ab2287b3c3efbad 100644 (file)
@@ -35,10 +35,6 @@ using namespace std;
    Waiting for packets
 */
 
-  
-
-
-
 #define RDTSC(qp) \
 do { \
   unsigned long lowPart, highPart;                                     \
index 785d52cdbbe84a4b089999e3631ff0dd9c1f0d4a..d5eb543e75e004684dd6e4e6099a496fb02c94ef 100644 (file)
@@ -1,6 +1,6 @@
 /*
     PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002-2010  PowerDNS.COM BV
+    Copyright (C) 2002-2011  PowerDNS.COM BV
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as 
@@ -1017,7 +1017,7 @@ void PacketHandler::makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string&
   rr.auth = 1;
   r->addRecord(rr);
   
-  if(p->d_dnssecOk && d_dk.haveActiveKSKFor(sd.qname))
+  if(p->d_dnssecOk && d_dk.isSecuredZone(sd.qname))
     addNSECX(p, r, target, sd.qname, 1);
   
   r->setRcode(RCode::NXDomain);  
@@ -1036,7 +1036,7 @@ void PacketHandler::makeNOError(DNSPacket* p, DNSPacket* r, const std::string& t
   rr.auth = 1;
   r->addRecord(rr);
 
-  if(p->d_dnssecOk && d_dk.haveActiveKSKFor(sd.qname))
+  if(p->d_dnssecOk && d_dk.isSecuredZone(sd.qname))
     addNSECX(p, r, target, sd.qname, 0);
 
   S.ringAccount("noerror-queries",p->qdomain+"/"+p->qtype.getName());
@@ -1070,7 +1070,7 @@ bool PacketHandler::tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const st
   }
   r->setA(false);
 
-  if(p->d_dnssecOk && d_dk.haveActiveKSKFor(sd.qname) && !addDSforNS(p, r, sd, rrset.begin()->qname))
+  if(p->d_dnssecOk && d_dk.isSecuredZone(sd.qname) && !addDSforNS(p, r, sd, rrset.begin()->qname))
     addNSECX(p, r, rrset.begin()->qname, sd.qname, 0);
   
   return true;
@@ -1082,7 +1082,7 @@ void PacketHandler::completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, c
     cerr<<"Need to add all the RRSIGs too for '"<<target<<"', should do this manually since DNSSEC was not requested"<<endl;
   //  cerr<<"Need to add all the NSEC too.."<<endl; /// XXX FIXME THE ABOVE IF IS WEIRD
   
-  if(!d_dk.haveActiveKSKFor(sd.qname))
+  if(!d_dk.isSecuredZone(sd.qname))
     return;
     
   addNSECX(p, r, target, sd.qname, 2); 
index 32f0e85082d3efff0838978b814b826fb1fc4cc9..0f09914678dc0d4d063fc81a73ebbea223eb542e 100644 (file)
@@ -55,8 +55,6 @@ void loadMainConfig(const std::string& configdir)
 
   string configname=::arg()["config-dir"]+"/"+s_programname+".conf";
   cleanSlashes(configname);
-
-  cerr<<"configname: '"<<configname<<"'\n";
   
   ::arg().laxFile(configname.c_str());
   ::arg().set("module-dir","Default directory for modules")=LIBDIR;
@@ -178,6 +176,10 @@ void checkZone(DNSSECKeeper& dk, const std::string& zone)
 
 void showZone(DNSSECKeeper& dk, const std::string& zone)
 {
+  if(!dk.isSecuredZone(zone)) {
+       cerr<<"Zone is not secured\n";
+       return;
+  }
   NSEC3PARAMRecordContent ns3pr;
   bool narrow;
   bool haveNSEC3=dk.getNSEC3PARAM(zone, &ns3pr, &narrow);
@@ -187,6 +189,8 @@ void showZone(DNSSECKeeper& dk, const std::string& zone)
   else
     cout<<"Zone has " << (narrow ? "NARROW " : "") <<"hashed NSEC3 semantics, configuration: "<<ns3pr.getZoneRepresentation()<<endl;
   
+  cout <<"Zone is " << (dk.isPresigned(zone) ? "" : "not ") << "presigned\n";
+  
   DNSSECKeeper::keyset_t keyset=dk.getKeys(zone);
 
   if(keyset.empty())  {
@@ -334,14 +338,14 @@ try
     const string& zone=cmds[1];
     DNSSECPrivateKey dpk;
     
-    if(dk.haveActiveKSKFor(zone)) {
-      cerr << "There is a KSK already for zone '"<<zone<<"', remove with pdnssec remove-zone-key if needed"<<endl;
+    if(dk.isSecuredZone(zone)) {
+      cerr << "Zone '"<<zone<<"' already secure, remove with pdnssec remove-zone-key if needed"<<endl;
       return 0;
     }
       
     dk.secureZone(zone, 8);
 
-    if(!dk.haveActiveKSKFor(zone)) {
+    if(!dk.isSecuredZone(zone)) {
       cerr << "This should not happen, still no key!" << endl;
       return 0;
     }
@@ -364,6 +368,18 @@ try
     NSEC3PARAMRecordContent ns3pr(nsec3params);
     dk.setNSEC3PARAM(cmds[1], ns3pr, narrow);
   }
+  else if(cmds[0]=="set-presigned") {
+       if(cmds.size() < 2) {
+               cerr<<"Wrong number of arguments, syntax: set-presigned DOMAIN"<<endl;
+       }
+    dk.setPresigned(cmds[1]);
+  }
+  else if(cmds[0]=="unset-presigned") {
+       if(cmds.size() < 2) {
+               cerr<<"Wrong number of arguments, syntax: unset-presigned DOMAIN"<<endl;
+       }
+    dk.unsetPresigned(cmds[1]);
+  }
   else if(cmds[0]=="hash-zone-record") {
     if(cmds.size() < 3) {
       cerr<<"Wrong number of arguments, syntax: hash-zone-record ZONE RECORD"<<endl;
index e722762ff0ac9850c0dd68df761bb594dcaf37a0..f271a1d53ea9c6a662e8ee5a92988b61f3ae7c44 100644 (file)
@@ -78,7 +78,7 @@ void CommunicatorClass::suck(const string &domain,const string &remote)
     DNSSECKeeper dk;
     bool dnssecZone = false;
     bool haveNSEC3=false;
-    if(dk.haveActiveKSKFor(domain)) {
+    if(dk.isSecuredZone(domain)) {
       dnssecZone=true;
       haveNSEC3=dk.getNSEC3PARAM(domain, &ns3pr, &narrow);
       string hashed;
index 724676813b7c7260152d56a7a9a7befb67e38b13..2277246d86d8138559d47eb6bbf4b18b0216e282 100644 (file)
@@ -542,7 +542,7 @@ int TCPNameserver::doAXFR(const string &target, shared_ptr<DNSPacket> q, int out
     }
   }
   
-  if(dk.haveActiveKSKFor(target)) {
+  if(dk.isSecuredZone(target)) {
    
     if(NSEC3Zone) {
       for(nsecxrepo_t::const_iterator iter = nsecxrepo.begin(); iter != nsecxrepo.end(); ++iter) {