From 1bd49828f77a118a158e5caad1b5f1d0b2166aa0 Mon Sep 17 00:00:00 2001 From: Pieter Lexis Date: Thu, 26 May 2016 23:36:22 +0200 Subject: [PATCH] Implement Negative Trust Anchors --- pdns/rec-lua-conf.cc | 14 ++++++++++++++ pdns/rec-lua-conf.hh | 1 + pdns/validate-recursor.cc | 2 ++ pdns/validate.cc | 37 +++++++++++++++++++++++++++++++++++-- pdns/validate.hh | 2 +- 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/pdns/rec-lua-conf.cc b/pdns/rec-lua-conf.cc index 4dd1010bb3..cf1a5aa982 100644 --- a/pdns/rec-lua-conf.cc +++ b/pdns/rec-lua-conf.cc @@ -225,6 +225,20 @@ void loadRecursorLuaConfig(const std::string& fname) lci.dsAnchors.clear(); }); + Lua.writeFunction("addNTA", [&lci](const std::string& who, const boost::optional why) { + if(why) + lci.negAnchors[DNSName(who)] = static_cast(*why); + else + lci.negAnchors[DNSName(who)] = ""; + }); + + Lua.writeFunction("clearNTA", [&lci](boost::optional who) { + if(who) + lci.negAnchors.erase(DNSName(*who)); + else + lci.negAnchors.clear(); + }); + #if HAVE_PROTOBUF Lua.writeFunction("protobufServer", [&lci](const string& server_, const boost::optional timeout, const boost::optional maxQueuedEntries, const boost::optional reconnectWaitTime) { try { diff --git a/pdns/rec-lua-conf.hh b/pdns/rec-lua-conf.hh index a9349b1ab7..57f1f9ed49 100644 --- a/pdns/rec-lua-conf.hh +++ b/pdns/rec-lua-conf.hh @@ -11,6 +11,7 @@ public: SortList sortlist; DNSFilterEngine dfe; map dsAnchors; + map negAnchors; std::shared_ptr protobufServer{nullptr}; }; diff --git a/pdns/validate-recursor.cc b/pdns/validate-recursor.cc index 5e6579ff76..227f9ddf81 100644 --- a/pdns/validate-recursor.cc +++ b/pdns/validate-recursor.cc @@ -49,6 +49,8 @@ vState validateRecords(const vector& recs) for(const auto& csp : cspmap) { for(const auto& sig : csp.second.signatures) { state = getKeysFor(sro, sig->d_signer, keys); // XXX check validity here + if(state == NTA) + return Insecure; LOG("! state = "< keyset_t; vector getByTag(const keyset_t& keys, uint16_t tag) @@ -165,6 +165,40 @@ cspmap_t harvestCSPFromRecs(const vector& recs) vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset) { + auto luaLocal = g_luaconfs.getLocal(); + auto anchors = luaLocal->dsAnchors; + + // Before searching for the keys, see if we have a Negative Trust Anchor. If + // so, test if the NTA is valid and return an NTA state + auto negAnchors = luaLocal->negAnchors; + + if (!negAnchors.empty()) { + DNSName lowestNTA, lowestTA; + + for (auto const &negAnchor : negAnchors) + if (zone.isPartOf(negAnchor.first) && lowestNTA.countLabels() < negAnchor.first.countLabels()) + lowestNTA = negAnchor.first; + + for (auto const &anchor : anchors) + if (zone.isPartOf(anchor.first) && lowestTA.countLabels() < anchor.first.countLabels()) + lowestTA = anchor.first; + + if(!lowestNTA.empty()) { + LOG("Found a Negative Trust Anchor for "< labels = zone.getRawLabels(); vState state; @@ -176,7 +210,6 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, keyset_t &keyset) DNSName qname("."); state = Secure; // the root is secure - auto luaLocal = g_luaconfs.getLocal(); while(zone.isPartOf(qname)) { if(auto ds = rplookup(luaLocal->dsAnchors, qname)) diff --git a/pdns/validate.hh b/pdns/validate.hh index f72a98cfc7..a0a7f35782 100644 --- a/pdns/validate.hh +++ b/pdns/validate.hh @@ -9,7 +9,7 @@ extern bool g_dnssecLOG; // 4033 5 -enum vState { Indeterminate, Bogus, Insecure, Secure }; +enum vState { Indeterminate, Bogus, Insecure, Secure, NTA }; extern const char *vStates[]; // NSEC(3) results -- 2.47.2