From: Bert Hubert Date: Tue, 18 Jan 2011 14:55:39 +0000 (+0000) Subject: implement 'pdnssec set-presigned', allowing PowerDNSSEC to serve pre-signed zones... X-Git-Tag: auth-3.0~354 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d3e7090cfbad8b9b1bda9468fcb4d2e48c74c8f8;p=pdns implement 'pdnssec set-presigned', allowing PowerDNSSEC to serve pre-signed zones. Rather experimental, but does appear to work git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1893 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index 04344315c..88138ccdd 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -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 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 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()); +} + + 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& rrsigs) +{ + d_db.lookup(QType(QType::RRSIG), qname); + DNSResourceRecord rr; + while(d_db.get(rr)) { + cerr<<"Considering for '"<& rrsigs); + bool isPresigned(const std::string& zname); + void setPresigned(const std::string& zname); + void unsetPresigned(const std::string& zname); private: struct KeyCacheEntry { diff --git a/pdns/dnssecsigner.cc b/pdns/dnssecsigner.cc index 115347992..31295ffd8 100644 --- a/pdns/dnssecsigner.cc +++ b/pdns/dnssecsigner.cc @@ -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 >& toSign, vector& 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 >& toSign, vector& outsigned) { // cerr<<"Asked to sign '"< rrcs; if(toSign.empty()) return; - - if(getRRSIGsForRRSET(dk, signer, wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrcs, signQType == QType::DNSKEY) < 0) { + vector 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!"<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 '"< 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) {