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);
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)
{
}
+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);
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;
+}
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);
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
{
#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)
RRSIGRecordContent rrc;
rrc.d_type=signQType;
-
rrc.d_labels=countLabels(signQName);
rrc.d_originalttl=signTTL;
rrc.d_siginception=getCurrentInception();;
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;
Waiting for packets
*/
-
-
-
-
#define RDTSC(qp) \
do { \
unsigned long lowPart, highPart; \
/*
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
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);
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());
}
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;
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);
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;
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);
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()) {
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;
}
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;
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;
}
}
- if(dk.haveActiveKSKFor(target)) {
+ if(dk.isSecuredZone(target)) {
if(NSEC3Zone) {
for(nsecxrepo_t::const_iterator iter = nsecxrepo.begin(); iter != nsecxrepo.end(); ++iter) {