From: Pieter Lexis Date: Tue, 21 Jul 2015 13:38:00 +0000 (+0200) Subject: Add CDS publishing support X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~27^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef542223c831c0f791fb4909c4f5d06ed67398da;p=thirdparty%2Fpdns.git Add CDS publishing support --- diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index df9ad06e2b..1f69673a5e 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -295,6 +295,35 @@ bool DNSSECKeeper::unsetPresigned(const DNSName& zname) return d_keymetadb->setDomainMetadata(zname, "PRESIGNED", vector()); } +/** + * Add domainmetadata to allow publishing CDS records for zone zname + * + * @param zname DNSName of the zone + * @param digestAlgos string with comma-separated numbers that describe the + * used digest algorithms. This is copied to the database + * verbatim + * @return true if the data was inserted, false otherwise + */ +bool DNSSECKeeper::setPublishCDS(const DNSName& zname, const string& digestAlgos) +{ + clearCaches(zname); + vector meta; + meta.push_back(digestAlgos); + return d_keymetadb->setDomainMetadata(zname, "PUBLISH_CDS", meta); +} + +/** + * Remove domainmetadata to stop publishing CDS records for zone zname + * + * @param zname DNSName of the zone + * @return true if the operation was successful, false otherwise + */ +bool DNSSECKeeper::unsetPublishCDS(const DNSName& zname) +{ + clearCaches(zname); + return d_keymetadb->setDomainMetadata(zname, "PUBLISH_CDS", vector()); +} + /** * Add domainmetadata to allow publishing CDNSKEY records.for zone zname * diff --git a/pdns/dnsseckeeper.hh b/pdns/dnsseckeeper.hh index f2c0f87b60..652865e874 100644 --- a/pdns/dnsseckeeper.hh +++ b/pdns/dnsseckeeper.hh @@ -92,6 +92,8 @@ public: bool unsetPresigned(const DNSName& zname); bool setPublishCDNSKEY(const DNSName& zname); bool unsetPublishCDNSKEY(const DNSName& zname); + bool setPublishCDS(const DNSName& zname, const string& digestAlgos); + bool unsetPublishCDS(const DNSName& zname); bool TSIGGrantsAccess(const DNSName& zone, const DNSName& keyname); bool getTSIGForAccess(const DNSName& zone, const string& master, DNSName* keyname); diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index ebac6f702a..dbb62a15b0 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -184,6 +184,60 @@ bool PacketHandler::addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd, boo return haveOne; } +/** + * This adds CDS records to the answer packet r. + * + * @param p Pointer to the DNSPacket containing the original question. + * @param r Pointer to the DNSPacket where the records should be inserted into. + * @param sd SOAData of the zone for which CDS records sets should be added, + * used to determine record TTL. + * @return bool that shows if any records were added. +**/ +bool PacketHandler::addCDS(DNSPacket *p, DNSPacket *r, const SOAData& sd) +{ + string publishCDS; + d_dk.getFromMeta(p->qdomain, "PUBLISH_CDS", publishCDS); + if (publishCDS.empty()) + return false; + + vector digestAlgos; + stringtok(digestAlgos, publishCDS, ", "); + + DNSResourceRecord rr; + rr.qtype=QType::CDS; + rr.ttl=sd.default_ttl; + rr.qname=p->qdomain; + rr.auth=true; + + bool haveOne=false; + DNSSECPrivateKey dpk; + + DNSSECKeeper::keyset_t keyset = d_dk.getKeys(p->qdomain); + + for(auto value : keyset) { + if (!value.second.keyOrZone) { + // Don't send out CDS records for ZSKs + continue; + } + for(auto digestAlgo : digestAlgos){ + rr.content=makeDSFromDNSKey(p->qdomain, value.first.getDNSKEY(), lexical_cast(digestAlgo)).getZoneRepresentation(); + r->addRecord(rr); + haveOne=true; + } + } + + if(::arg().mustDo("direct-dnskey")) { + B.lookup(QType(QType::CDS), p->qdomain, p, sd.domain_id); + + while(B.get(rr)) { + rr.ttl=sd.default_ttl; + r->addRecord(rr); + haveOne=true; + } + } + + return haveOne; +} /** This adds NSEC3PARAM records. Returns true if one was added */ bool PacketHandler::addNSEC3PARAM(DNSPacket *p, DNSPacket *r, const SOAData& sd) @@ -419,6 +473,10 @@ void PacketHandler::emitNSEC(DNSPacket *r, const SOAData& sd, const DNSName& nam d_dk.getFromMeta(name, "PUBLISH_CDNSKEY", publishCDNSKEY); if (publishCDNSKEY == "1") nrc.d_set.insert(QType::CDNSKEY); + string publishCDS; + d_dk.getFromMeta(name, "PUBLISH_CDS", publishCDS); + if (! publishCDS.empty()) + nrc.d_set.insert(QType::CDS); } DNSResourceRecord rr; @@ -459,6 +517,10 @@ void PacketHandler::emitNSEC3(DNSPacket *r, const SOAData& sd, const NSEC3PARAMR d_dk.getFromMeta(name, "PUBLISH_CDNSKEY", publishCDNSKEY); if (publishCDNSKEY == "1") n3rc.d_set.insert(QType::CDNSKEY); + string publishCDS; + d_dk.getFromMeta(name, "PUBLISH_CDS", publishCDS); + if (! publishCDS.empty()) + n3rc.d_set.insert(QType::CDS); } B.lookup(QType(QType::ANY), name, NULL, sd.domain_id); @@ -985,6 +1047,7 @@ void PacketHandler::completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, c if(pdns_iequals(sd.qname, p->qdomain)) { addDNSKEY(p, r, sd); addDNSKEY(p, r, sd, true); + addCDS(p, r, sd); addNSEC3PARAM(p, r, sd); } } @@ -1234,6 +1297,11 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) if(addDNSKEY(p,r, sd, true)) goto sendit; } + else if(p->qtype.getCode() == QType::CDS) + { + if(addCDS(p,r, sd)) + goto sendit; + } else if(p->qtype.getCode() == QType::NSEC3PARAM) { if(addNSEC3PARAM(p,r, sd)) diff --git a/pdns/packethandler.hh b/pdns/packethandler.hh index 7eca58b2da..550358465a 100644 --- a/pdns/packethandler.hh +++ b/pdns/packethandler.hh @@ -72,6 +72,7 @@ private: void addRootReferral(DNSPacket *r); int doChaosRequest(DNSPacket *p, DNSPacket *r, DNSName &target); bool addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd, bool doCDNSKEY); + bool addCDS(DNSPacket *p, DNSPacket *r, const SOAData& sd); bool addNSEC3PARAM(DNSPacket *p, DNSPacket *r, const SOAData& sd); int doAdditionalProcessingAndDropAA(DNSPacket *p, DNSPacket *r, const SOAData& sd, bool retargeted); void addNSECX(DNSPacket *p, DNSPacket* r, const DNSName &target, const DNSName &wildcard, const DNSName &auth, int mode); diff --git a/pdns/pdnssec.cc b/pdns/pdnssec.cc index 87422a2a7f..70918c739c 100644 --- a/pdns/pdnssec.cc +++ b/pdns/pdnssec.cc @@ -1364,12 +1364,15 @@ try cerr<<"set-nsec3 ZONE ['params' [narrow]] Enable NSEC3 with PARAMs. Optionally narrow"<