Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.1:Update
pdns
pdns-3.4.10-tsig-165253_port.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pdns-3.4.10-tsig-165253_port.patch of Package pdns
Index: pdns-3.4.6/pdns/dnspacket.cc =================================================================== --- pdns-3.4.6.orig/pdns/dnspacket.cc +++ pdns-3.4.6/pdns/dnspacket.cc @@ -466,7 +466,7 @@ bool DNSPacket::getTSIGDetails(TSIGRecor bool gotit=false; for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) { - if(i->first.d_type == QType::TSIG) { + if(i->first.d_type == QType::TSIG && i->first.d_class == QType::ANY) { // cast can fail, f.e. if d_content is an UnknownRecordContent. shared_ptr<TSIGRecordContent> content = boost::dynamic_pointer_cast<TSIGRecordContent>(i->first.d_content); if (!content) { @@ -643,7 +643,10 @@ bool checkForCorrectTSIG(const DNSPacket { string message; - q->getTSIGDetails(trc, keyname, &message); + if (!q->getTSIGDetails(trc, keyname, &message)) { + return false; + } + uint64_t now = time(0); if(abs(trc->d_time - now) > trc->d_fudge) { L<<Logger::Error<<"Packet for '"<<q->qdomain<<"' denied: TSIG (key '"<<*keyname<<"') time delta "<< abs(trc->d_time - now)<<" > 'fudge' "<<trc->d_fudge<<endl; @@ -669,7 +672,7 @@ bool checkForCorrectTSIG(const DNSPacket } B64Decode(secret64, *secret); - bool result=calculateHMAC(*secret, message, algo) == trc->d_mac; + bool result=constantTimeStringEquals(calculateHMAC(*secret, message, algo), trc->d_mac); if(!result) { L<<Logger::Error<<"Packet for domain '"<<q->qdomain<<"' denied: TSIG signature mismatch using '"<<*keyname<<"' and algorithm '"<<trc->d_algoName<<"'"<<endl; } Index: pdns-3.4.6/pdns/dnsparser.cc =================================================================== --- pdns-3.4.6.orig/pdns/dnsparser.cc +++ pdns-3.4.6/pdns/dnsparser.cc @@ -287,8 +287,12 @@ void MOADNSParser::init(bool query, cons d_answers.push_back(make_pair(dr, pr.d_pos)); - if(dr.d_type == QType::TSIG && dr.d_class == 0xff) + if(dr.d_type == QType::TSIG && dr.d_class == QClass::ANY) { + if(dr.d_place != DNSRecord::Additional || n != (unsigned int)(d_header.ancount + d_header.nscount + d_header.arcount) - 1) { + throw MOADNSException("Packet ("+d_qname+"|#"+lexical_cast<string>(d_qtype)+") has a TSIG record in an invalid position."); + } d_tsigPos = recordStartPos + sizeof(struct dnsheader); + } } #if 0 Index: pdns-3.4.6/pdns/dnsparser.hh =================================================================== --- pdns-3.4.6.orig/pdns/dnsparser.hh +++ pdns-3.4.6/pdns/dnsparser.hh @@ -335,7 +335,7 @@ public: return pr; } - uint16_t getTSIGPos() + uint16_t getTSIGPos() const { return d_tsigPos; } Index: pdns-3.4.6/pdns/dnssecinfra.cc =================================================================== --- pdns-3.4.6.orig/pdns/dnssecinfra.cc +++ pdns-3.4.6/pdns/dnssecinfra.cc @@ -517,7 +517,7 @@ string calculateSHAHMAC(const std::strin break; }; default: - throw new PDNSException("Unknown hash algorithm requested for SHA"); + throw PDNSException("Unknown hash algorithm requested for SHA"); }; return res; @@ -531,6 +531,23 @@ string calculateHMAC(const std::string& return calculateSHAHMAC(key, text, hash); } +bool constantTimeStringEquals(const std::string& a, const std::string& b) +{ + if (a.size() != b.size()) { + return false; + } + const size_t size = a.size(); + const volatile unsigned char *_a = (const volatile unsigned char *) a.c_str(); + const volatile unsigned char *_b = (const volatile unsigned char *) b.c_str(); + unsigned char res = 0; + + for (size_t idx = 0; idx < size; idx++) { + res |= _a[idx] ^ _b[idx]; + } + + return res == 0; +} + string makeTSIGMessageFromTSIGPacket(const string& opacket, unsigned int tsigOffset, const string& keyname, const TSIGRecordContent& trc, const string& previous, bool timersonly, unsigned int dnsHeaderOffset) { string message; Index: pdns-3.4.6/pdns/dnssecinfra.hh =================================================================== --- pdns-3.4.6.orig/pdns/dnssecinfra.hh +++ pdns-3.4.6/pdns/dnssecinfra.hh @@ -134,6 +134,7 @@ typedef enum { TSIG_MD5, TSIG_SHA1, TSIG string calculateMD5HMAC(const std::string& key, const std::string& text); string calculateSHAHMAC(const std::string& key, const std::string& text, TSIGHashEnum hash); string calculateHMAC(const std::string& key, const std::string& text, TSIGHashEnum hash); +bool constantTimeStringEquals(const std::string& a, const std::string& b); string makeTSIGMessageFromTSIGPacket(const string& opacket, unsigned int tsigoffset, const string& keyname, const TSIGRecordContent& trc, const string& previous, bool timersonly, unsigned int dnsHeaderOffset=0); bool getTSIGHashEnum(const string &algoName, TSIGHashEnum& algoEnum); Index: pdns-3.4.6/pdns/resolver.cc =================================================================== --- pdns-3.4.6.orig/pdns/resolver.cc +++ pdns-3.4.6/pdns/resolver.cc @@ -500,6 +500,7 @@ int AXFRRetriever::getChunk(Resolver::re shared_ptr<TSIGRecordContent> trc = boost::dynamic_pointer_cast<TSIGRecordContent>(answer.first.d_content); theirMac = trc->d_mac; d_trc.d_time = trc->d_time; + d_trc.d_fudge = trc->d_fudge; checkTSIG = true; } } @@ -512,6 +513,11 @@ int AXFRRetriever::getChunk(Resolver::re if (theirMac.empty()) throw ResolverException("No TSIG on AXFR response from "+d_remote.toStringWithPort()+" , should be signed with TSIG key '"+d_tsigkeyname+"'"); + uint64_t delta = std::abs((int64_t)d_trc.d_time - (int64_t)time(0)); + if(delta > d_trc.d_fudge) { + throw ResolverException("Invalid TSIG time delta " + lexical_cast<string>(delta) + " > fudge " + lexical_cast<string>(d_trc.d_fudge)); + } + string message; if (!d_prevMac.empty()) { message = makeTSIGMessageFromTSIGPacket(d_signData, d_tsigPos, d_tsigkeyname, d_trc, d_prevMac, true, d_signData.size()-len); @@ -527,7 +533,7 @@ int AXFRRetriever::getChunk(Resolver::re string ourMac=calculateHMAC(d_tsigsecret, message, algo); // ourMac[0]++; // sabotage == for testing :-) - if(ourMac != theirMac) { + if(!constantTimeStringEquals(ourMac, theirMac)) { throw ResolverException("Signature failed to validate on AXFR response from "+d_remote.toStringWithPort()+" signed with TSIG key '"+d_tsigkeyname+"'"); } Index: pdns-3.4.6/pdns/tcpreceiver.cc =================================================================== --- pdns-3.4.6.orig/pdns/tcpreceiver.cc +++ pdns-3.4.6/pdns/tcpreceiver.cc @@ -590,9 +590,9 @@ int TCPNameserver::doAXFR(const string & TSIGRecordContent trc; string tsigkeyname, tsigsecret; - q->getTSIGDetails(&trc, &tsigkeyname, 0); + bool haveTSIGDetails = q->getTSIGDetails(&trc, &tsigkeyname, 0); - if(!tsigkeyname.empty()) { + if(haveTSIGDetails && !tsigkeyname.empty()) { string tsig64; string algorithm=toLowerCanonic(trc.d_algoName); if (algorithm == "hmac-md5.sig-alg.reg.int") @@ -616,7 +616,7 @@ int TCPNameserver::doAXFR(const string & addRRSigs(dk, signatureDB, authSet, outpacket->getRRS()); } - if(!tsigkeyname.empty()) + if(haveTSIGDetails && !tsigkeyname.empty()) outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac); // first answer is 'normal' sendPacket(outpacket, outsock); @@ -798,7 +798,7 @@ int TCPNameserver::doAXFR(const string & for(;;) { outpacket->getRRS() = csp.getChunk(); if(!outpacket->getRRS().empty()) { - if(!tsigkeyname.empty()) + if(haveTSIGDetails && !tsigkeyname.empty()) outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true); sendPacket(outpacket, outsock); trc.d_mac=outpacket->d_trc.d_mac; @@ -849,7 +849,7 @@ int TCPNameserver::doAXFR(const string & for(;;) { outpacket->getRRS() = csp.getChunk(); if(!outpacket->getRRS().empty()) { - if(!tsigkeyname.empty()) + if(haveTSIGDetails && !tsigkeyname.empty()) outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true); sendPacket(outpacket, outsock); trc.d_mac=outpacket->d_trc.d_mac; @@ -884,7 +884,7 @@ int TCPNameserver::doAXFR(const string & for(;;) { outpacket->getRRS() = csp.getChunk(); if(!outpacket->getRRS().empty()) { - if(!tsigkeyname.empty()) + if(haveTSIGDetails && !tsigkeyname.empty()) outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true); sendPacket(outpacket, outsock); trc.d_mac=outpacket->d_trc.d_mac; @@ -905,7 +905,7 @@ int TCPNameserver::doAXFR(const string & for(;;) { outpacket->getRRS() = csp.getChunk(true); // flush the pipe if(!outpacket->getRRS().empty()) { - if(!tsigkeyname.empty()) + if(haveTSIGDetails && !tsigkeyname.empty()) outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true); // first answer is 'normal' sendPacket(outpacket, outsock); trc.d_mac=outpacket->d_trc.d_mac; @@ -924,7 +924,7 @@ int TCPNameserver::doAXFR(const string & outpacket=getFreshAXFRPacket(q); outpacket->addRecord(soa); editSOA(dk, sd.qname, outpacket.get()); - if(!tsigkeyname.empty()) + if(haveTSIGDetails && !tsigkeyname.empty()) outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true); sendPacket(outpacket, outsock); @@ -1026,9 +1026,9 @@ int TCPNameserver::doIXFR(shared_ptr<DNS TSIGRecordContent trc; string tsigkeyname, tsigsecret; - q->getTSIGDetails(&trc, &tsigkeyname, 0); + bool haveTSIGDetails = q->getTSIGDetails(&trc, &tsigkeyname, 0); - if(!tsigkeyname.empty()) { + if(haveTSIGDetails && !tsigkeyname.empty()) { string tsig64; string algorithm=toLowerCanonic(trc.d_algoName); if (algorithm == "hmac-md5.sig-alg.reg.int") @@ -1051,7 +1051,7 @@ int TCPNameserver::doIXFR(shared_ptr<DNS addRRSigs(dk, signatureDB, authSet, outpacket->getRRS()); } - if(!tsigkeyname.empty()) + if(haveTSIGDetails && !tsigkeyname.empty()) outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac); // first answer is 'normal' sendPacket(outpacket, outsock); Index: pdns-3.4.6/pdns/toysdig.cc =================================================================== --- pdns-3.4.6.orig/pdns/toysdig.cc +++ pdns-3.4.6/pdns/toysdig.cc @@ -42,7 +42,7 @@ try string reply; sock.recvFrom(reply, dest); - MOADNSParser mdp(reply); + MOADNSParser mdp(false, reply); cout<<"Reply to question for qname='"<<mdp.d_qname<<"', qtype="<<DNSRecordContent::NumberToType(mdp.d_qtype)<<endl; cout<<"Rcode: "<<mdp.d_header.rcode<<", RD: "<<mdp.d_header.rd<<", QR: "<<mdp.d_header.qr; cout<<", TC: "<<mdp.d_header.tc<<", AA: "<<mdp.d_header.aa<<", opcode: "<<mdp.d_header.opcode<<endl;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor