To avoid DNSPacket pulling UeberBackend.
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);
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<<Logger::Error<<"Packet for '"<<this->qdomain<<"' denied: "<<err.what()<<endl;
- return false;
- }
-
- return result;
-}
-
const DNSName& DNSPacket::getTSIGKeyname() const {
return d_tsigkeyname;
}
#include "pdnsexception.hh"
#include "dnsrecords.hh"
-class UeberBackend;
-class DNSSECKeeper;
-
//! This class represents DNS packets, either received or to be sent.
class DNSPacket
bool getTSIGDetails(TSIGRecordContent* tr, DNSName* keyname, uint16_t* tsigPos=nullptr) const;
void setTSIGDetails(const TSIGRecordContent& tr, const DNSName& keyname, const string& secret, const string& previous, bool timersonly=false);
+ bool validateTSIG(const TSIGTriplet& tsigTriplet, const TSIGRecordContent& tsigContent, const std::string& previousMAC, const std::string& theirMAC, bool timersOnly) const;
bool getTKEYRecord(TKEYRecordContent* tr, DNSName* keyname) const;
vector<DNSZoneRecord>& getRRS() { return d_rrs; }
- bool checkForCorrectTSIG(UeberBackend* B, DNSName* keyname, string* secret, TSIGRecordContent* trc) const;
static uint16_t s_udpTruncationThreshold;
static bool s_doEDNSSubnetProcessing;
#include "packetcache.hh"
#include "utility.hh"
#include "base32.hh"
+#include "base64.hh"
#include <string>
#include <sys/types.h>
#include <boost/algorithm/string.hpp>
}
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<<Logger::Error<<"Received a TSIG signed message with a non-validating key"<<endl;
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<<Logger::Warning<<"Failed to extract peer principal from GSS context with keyname '"<<keyname<<"'"<<endl;
+ g_log<<Logger::Warning<<"Failed to extract peer principal from GSS context with keyname '"<<tsigkeyname<<"'"<<endl;
}
}
#endif
}
- p.setTSIGDetails(trc, keyname, secret, trc.d_mac); // this will get copied by replyPacket()
+ p.setTSIGDetails(trc, tsigkeyname, secret, trc.d_mac); // this will get copied by replyPacket()
noCache=true;
}
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<<Logger::Error<<"Packet for '"<<packet.qdomain<<"' denied: "<<err.what()<<endl;
+ return false;
+ }
+}
UeberBackend *getBackend();
int tryAutoPrimarySynchronous(const DNSPacket& p, const DNSName& tsigkeyname);
+ bool checkForCorrectTSIG(const DNSPacket& packet, DNSName* tsigkeyname, string* secret, TSIGRecordContent* tsigContent);
static NetmaskGroup s_allowNotifyFrom;
static set<string> s_forwardNotify;
static bool s_SVCAutohints;
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<<Logger::Warning<<"Failed to extract peer principal from GSS context with keyname '"<<keyname<<"'"<<endl;
+ g_log<<Logger::Warning<<"Failed to extract peer principal from GSS context with keyname '"<<tsigkeyname<<"'"<<endl;
}
}
#endif
return false;
}
#endif
- if(!dk.TSIGGrantsAccess(q->qdomain, keyname)) {
- g_log<<Logger::Warning<<logPrefix<<"denied: key with name '"<<keyname<<"' and algorithm '"<<getTSIGAlgoName(q->d_tsig_algo)<<"' does not grant access"<<endl;
+ if(!dk.TSIGGrantsAccess(q->qdomain, tsigkeyname)) {
+ g_log<<Logger::Warning<<logPrefix<<"denied: key with name '"<<tsigkeyname<<"' and algorithm '"<<getTSIGAlgoName(q->d_tsig_algo)<<"' does not grant access"<<endl;
return false;
}
else {
- g_log<<Logger::Notice<<logPrefix<<"allowed: TSIG signed request with authorized key '"<<keyname<<"' and algorithm '"<<getTSIGAlgoName(q->d_tsig_algo)<<"'"<<endl;
+ g_log<<Logger::Notice<<logPrefix<<"allowed: TSIG signed request with authorized key '"<<tsigkeyname<<"' and algorithm '"<<getTSIGAlgoName(q->d_tsig_algo)<<"'"<<endl;
return true;
}
}