diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index 324399cd3ca8..8588f2c21a15 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -535,6 +535,17 @@ bool DNSPacket::getTSIGDetails(TSIGRecordContent* trc, DNSName* keyname, uint16_ return true; } +bool DNSPacket::validateTSIG(const TSIGTriplet& tsigTriplet, const TSIGRecordContent& tsigContent, const std::string& previousMAC, const std::string& theirMAC, bool timersOnly) const +{ + MOADNSParser mdp(d_isQuery, d_rawpacket); + uint16_t tsigPos = mdp.getTSIGPos(); + if (tsigPos == 0) { + return false; + } + + return ::validateTSIG(d_rawpacket, tsigPos, tsigTriplet, tsigContent, previousMAC, theirMAC, timersOnly); +} + bool DNSPacket::getTKEYRecord(TKEYRecordContent *tr, DNSName *keyname) const { MOADNSParser mdp(d_isQuery, d_rawpacket); @@ -724,43 +735,6 @@ void DNSPacket::commitD() d_rawpacket.replace(0,12,(char *)&d,12); // copy in d } -bool DNSPacket::checkForCorrectTSIG(UeberBackend* B, DNSName* keyname, string* secret, TSIGRecordContent* trc) const -{ - uint16_t tsigPos; - - if (!this->getTSIGDetails(trc, keyname, &tsigPos)) { - return false; - } - - TSIGTriplet tt; - tt.name = *keyname; - tt.algo = trc->d_algoName; - if (tt.algo == DNSName("hmac-md5.sig-alg.reg.int")) - tt.algo = DNSName("hmac-md5"); - - if (tt.algo != DNSName("gss-tsig")) { - string secret64; - if(!B->getTSIGKey(*keyname, tt.algo, secret64)) { - g_log << Logger::Error << "Packet for domain '" << this->qdomain << "' denied: can't find TSIG key with name '" << *keyname << "' and algorithm '" << tt.algo << "'" << endl; - return false; - } - B64Decode(secret64, *secret); - tt.secret = *secret; - } - - bool result; - - try { - result = validateTSIG(d_rawpacket, tsigPos, tt, *trc, "", trc->d_mac, false); - } - catch(const std::runtime_error& err) { - g_log<qdomain<<"' denied: "<& getRRS() { return d_rrs; } - bool checkForCorrectTSIG(UeberBackend* B, DNSName* keyname, string* secret, TSIGRecordContent* trc) const; static uint16_t s_udpTruncationThreshold; static bool s_doEDNSSubnetProcessing; diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index 3d385ed7b54c..d06e4724e127 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -25,6 +25,7 @@ #include "packetcache.hh" #include "utility.hh" #include "base32.hh" +#include "base64.hh" #include #include #include @@ -1336,6 +1337,7 @@ bool PacketHandler::tryWildcard(DNSPacket& p, std::unique_ptr& r, DNS } //! Called by the Distributor to ask a question. Returns 0 in case of an error +// NOLINTNEXTLINE(readability-function-cognitive-complexity): TODO Clean this function up. std::unique_ptr PacketHandler::doQuestion(DNSPacket& p) { DNSZoneRecord rr; @@ -1394,10 +1396,10 @@ std::unique_ptr PacketHandler::doQuestion(DNSPacket& p) } if(p.d_havetsig) { - DNSName keyname; + DNSName tsigkeyname; string secret; TSIGRecordContent trc; - if(!p.checkForCorrectTSIG(&B, &keyname, &secret, &trc)) { + if (!checkForCorrectTSIG(p, &tsigkeyname, &secret, &trc)) { r=p.replyPacket(); // generate an empty reply packet if(d_logDNSDetails) g_log< PacketHandler::doQuestion(DNSPacket& p) getTSIGHashEnum(trc.d_algoName, p.d_tsig_algo); #ifdef ENABLE_GSS_TSIG if (g_doGssTSIG && p.d_tsig_algo == TSIG_GSS) { - GssContext gssctx(keyname); + GssContext gssctx(tsigkeyname); if (!gssctx.getPeerPrincipal(p.d_peer_principal)) { - g_log< PacketHandler::doQuestion(DNSPacket& p) return r; } + +bool PacketHandler::checkForCorrectTSIG(const DNSPacket& packet, DNSName* tsigkeyname, string* secret, TSIGRecordContent* tsigContent) +{ + uint16_t tsigPos{0}; + + if (!packet.getTSIGDetails(tsigContent, tsigkeyname, &tsigPos)) { + return false; + } + + TSIGTriplet tsigTriplet; + tsigTriplet.name = *tsigkeyname; + tsigTriplet.algo = tsigContent->d_algoName; + if (tsigTriplet.algo == DNSName("hmac-md5.sig-alg.reg.int")) { + tsigTriplet.algo = DNSName("hmac-md5"); + } + + if (tsigTriplet.algo != DNSName("gss-tsig")) { + string secret64; + if (!B.getTSIGKey(*tsigkeyname, tsigTriplet.algo, secret64)) { + g_log << Logger::Error << "Packet for domain '" << packet.qdomain << "' denied: can't find TSIG key with name '" << *tsigkeyname << "' and algorithm '" << tsigTriplet.algo << "'" << endl; + return false; + } + B64Decode(secret64, *secret); + tsigTriplet.secret = *secret; + } + + try { + return packet.validateTSIG(tsigTriplet, *tsigContent, "", tsigContent->d_mac, false); + } + catch(const std::runtime_error& err) { + g_log< s_forwardNotify; static bool s_SVCAutohints; diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 8dfa95731588..c4696a8f72cc 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -463,18 +463,18 @@ bool TCPNameserver::canDoAXFR(std::unique_ptr& q, bool isAXFR, std::u string logPrefix=string(isAXFR ? "A" : "I")+"XFR-out zone '"+q->qdomain.toLogString()+"', client '"+q->getInnerRemote().toStringWithPort()+"', "; if(q->d_havetsig) { // if you have one, it must be good - TSIGRecordContent trc; - DNSName keyname; + TSIGRecordContent tsigContent; + DNSName tsigkeyname; string secret; - if(!q->checkForCorrectTSIG(packetHandler->getBackend(), &keyname, &secret, &trc)) { + if (!packetHandler->checkForCorrectTSIG(*q, &tsigkeyname, &secret, &tsigContent)) { return false; } else { - getTSIGHashEnum(trc.d_algoName, q->d_tsig_algo); + getTSIGHashEnum(tsigContent.d_algoName, q->d_tsig_algo); #ifdef ENABLE_GSS_TSIG if (g_doGssTSIG && q->d_tsig_algo == TSIG_GSS) { - GssContext gssctx(keyname); + GssContext gssctx(tsigkeyname); if (!gssctx.getPeerPrincipal(q->d_peer_principal)) { - g_log<& q, bool isAXFR, std::u return false; } #endif - if(!dk.TSIGGrantsAccess(q->qdomain, keyname)) { - g_log<d_tsig_algo)<<"' does not grant access"<qdomain, tsigkeyname)) { + g_log<d_tsig_algo)<<"' does not grant access"<d_tsig_algo)<<"'"<d_tsig_algo)<<"'"<