From: Pieter Lexis Date: Tue, 21 Jul 2015 13:37:11 +0000 (+0200) Subject: Add CDNSKEY support X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~27^2~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=088370cd587096453fdb81afe16c90e8d364a33f;p=pdns Add CDNSKEY support This commit adds support to the packethandler, the dnssec infrastructure and pdnssec for the CDNSKEY record. Users can now use the domain metadata "PUBLISH_CDNSKEY" to reply to CDNSKEY queries with their active DNSKEYs that are KSKs. --- diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index 591208575..df9ad06e2 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -295,6 +295,31 @@ bool DNSSECKeeper::unsetPresigned(const DNSName& zname) return d_keymetadb->setDomainMetadata(zname, "PRESIGNED", vector()); } +/** + * Add domainmetadata to allow publishing CDNSKEY records.for zone zname + * + * @param zname DNSName of the zone + * @return true if the data was inserted, false otherwise + */ +bool DNSSECKeeper::setPublishCDNSKEY(const DNSName& zname) +{ + clearCaches(zname); + vector meta; + meta.push_back("1"); + return d_keymetadb->setDomainMetadata(zname, "PUBLISH_CDNSKEY", meta); +} + +/** + * Remove domainmetadata to stop publishing CDNSKEY records for zone zname + * + * @param zname DNSName of the zone + * @return true if the operation was successful, false otherwise + */ +bool DNSSECKeeper::unsetPublishCDNSKEY(const DNSName& zname) +{ + clearCaches(zname); + return d_keymetadb->setDomainMetadata(zname, "PUBLISH_CDNSKEY", vector()); +} DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const DNSName& zone, boost::tribool allOrKeyOrZone, bool useCache) { diff --git a/pdns/dnsseckeeper.hh b/pdns/dnsseckeeper.hh index 3643c60d2..f2c0f87b6 100644 --- a/pdns/dnsseckeeper.hh +++ b/pdns/dnsseckeeper.hh @@ -90,6 +90,8 @@ public: bool isPresigned(const DNSName& zname); bool setPresigned(const DNSName& zname); bool unsetPresigned(const DNSName& zname); + bool setPublishCDNSKEY(const DNSName& zname); + bool unsetPublishCDNSKEY(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 b84c48ae9..ebac6f702 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -131,16 +131,35 @@ void PacketHandler::addRootReferral(DNSPacket* r) } } -/** This adds DNSKEY records. Returns true if one was added */ -bool PacketHandler::addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd) +/** + * This adds DNSKEY records to the answer packet. Returns true if one was added. + * The optional doCDNSKEY parameter signifies that we need to add a CDNSKEY (RFC 7344) + * instead of DNSKEY. + * + * @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 DNSKEY records sets should be added + * @param doCDNSKEY When set to true, add CDNSKEYs instead of DNSKEYs + * @return bool that shows if any records were added +**/ +bool PacketHandler::addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd, bool doCDNSKEY=false) { + string publishCDNSKEY; + d_dk.getFromMeta(p->qdomain, "PUBLISH_CDNSKEY", publishCDNSKEY); + if (doCDNSKEY && publishCDNSKEY != "1") + return false; + DNSResourceRecord rr; bool haveOne=false; DNSSECPrivateKey dpk; DNSSECKeeper::keyset_t keyset = d_dk.getKeys(p->qdomain); for(const auto& value: keyset) { - rr.qtype=QType::DNSKEY; + if (doCDNSKEY && !value.second.keyOrZone) { + // Don't send out CDNSKEY records for ZSKs + continue; + } + rr.qtype=doCDNSKEY ? QType::CDNSKEY : QType::DNSKEY; rr.ttl=sd.default_ttl; rr.qname=p->qdomain; rr.content=value.first.getDNSKEY().getZoneRepresentation(); @@ -150,7 +169,11 @@ bool PacketHandler::addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd) } if(::arg().mustDo("direct-dnskey")) { - B.lookup(QType(QType::DNSKEY), p->qdomain, p, sd.domain_id); + if(doCDNSKEY) + B.lookup(QType(QType::CDNSKEY), p->qdomain, p, sd.domain_id); + else + B.lookup(QType(QType::DNSKEY), p->qdomain, p, sd.domain_id); + while(B.get(rr)) { rr.ttl=sd.default_ttl; r->addRecord(rr); @@ -392,6 +415,10 @@ void PacketHandler::emitNSEC(DNSPacket *r, const SOAData& sd, const DNSName& nam if(sd.qname == name) { nrc.d_set.insert(QType::SOA); // 1dfd8ad SOA can live outside the records table nrc.d_set.insert(QType::DNSKEY); + string publishCDNSKEY; + d_dk.getFromMeta(name, "PUBLISH_CDNSKEY", publishCDNSKEY); + if (publishCDNSKEY == "1") + nrc.d_set.insert(QType::CDNSKEY); } DNSResourceRecord rr; @@ -428,6 +455,10 @@ void PacketHandler::emitNSEC3(DNSPacket *r, const SOAData& sd, const NSEC3PARAMR n3rc.d_set.insert(QType::SOA); // 1dfd8ad SOA can live outside the records table n3rc.d_set.insert(QType::NSEC3PARAM); n3rc.d_set.insert(QType::DNSKEY); + string publishCDNSKEY; + d_dk.getFromMeta(name, "PUBLISH_CDNSKEY", publishCDNSKEY); + if (publishCDNSKEY == "1") + n3rc.d_set.insert(QType::CDNSKEY); } B.lookup(QType(QType::ANY), name, NULL, sd.domain_id); @@ -953,6 +984,7 @@ void PacketHandler::completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, c addNSECX(p, r, target, "", sd.qname, 5); if(pdns_iequals(sd.qname, p->qdomain)) { addDNSKEY(p, r, sd); + addDNSKEY(p, r, sd, true); addNSEC3PARAM(p, r, sd); } } @@ -1197,6 +1229,11 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) if(addDNSKEY(p, r, sd)) goto sendit; } + else if(p->qtype.getCode() == QType::CDNSKEY) + { + if(addDNSKEY(p,r, sd, true)) + 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 2c52f781b..7eca58b2d 100644 --- a/pdns/packethandler.hh +++ b/pdns/packethandler.hh @@ -71,7 +71,7 @@ private: int processNotify(DNSPacket *); void addRootReferral(DNSPacket *r); int doChaosRequest(DNSPacket *p, DNSPacket *r, DNSName &target); - bool addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd); + bool addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd, bool doCDNSKEY); 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 758ef2d28..87422a2a7 100644 --- a/pdns/pdnssec.cc +++ b/pdns/pdnssec.cc @@ -1363,11 +1363,13 @@ try cerr<<"secure-zone ZONE [ZONE ..] Add KSK and two ZSKs"<