From: Peter van Dijk Date: Mon, 29 Oct 2012 11:15:09 +0000 (+0000) Subject: various fixes related to the interaction between CNAMEs, wilcards, ANY queries and... X-Git-Tag: auth-3.2-rc1~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5c4fbdcfb172bec1803d4dbcdceb622c965c385;p=thirdparty%2Fpdns.git various fixes related to the interaction between CNAMEs, wilcards, ANY queries and NSEC(3), by Kees Monshouwer git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@2825 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/modules/tinydnsbackend/data b/modules/tinydnsbackend/data index 382eeacd60..27fac43f5b 100644 --- a/modules/tinydnsbackend/data +++ b/modules/tinydnsbackend/data @@ -20029,6 +20029,7 @@ Cloop3.example.com:loop1.example.com.:120 :multitext.example.com:16:\015text\040part\040one\015text\040part\040two\017text\040part\040three:120 +ns1.example.com:192.168.1.1:120 +ns2.example.com:192.168.1.2:120 +Cnxd.example.com:nxdomain.example.com.:120 +outpost.example.com:192.168.2.1:120 Csemi-external.example.com:bla.something.wtest.com.:120 Cserver1.example.com:server1.france.example.com.:120 @@ -20036,6 +20037,7 @@ Cserver1.example.com:server1.france.example.com.:120 +smtp-servers.example.com:192.168.0.3:120 +smtp-servers.example.com:192.168.0.4:120 Csmtp1.example.com:outpost.example.com.:120 +Cstart.example.com:x.y.z.w1.example.com.:120 Cstart1.example.com:start2.example.com.:120 Cstart2.example.com:start3.example.com.:120 Cstart3.example.com:start4.example.com.:120 @@ -20118,10 +20120,16 @@ Cstart3.example.com:start4.example.com.:120 +toomuchinfo-b.example.com:192.168.99.88:120 +toomuchinfo-b.example.com:192.168.99.89:120 +toomuchinfo-b.example.com:192.168.99.90:120 +Cunauth.example.com:no-idea.example.org.:120 &usa.example.com::usa-ns1.usa.example.com.:120 &usa.example.com::usa-ns2.usa.example.com.:120 +usa-ns1.usa.example.com:192.168.4.1:120 +usa-ns2.usa.example.com:192.168.4.2:120 +C\052.w1.example.com:x.y.z.w2.example.com.:120 +C\052.w2.example.com:x.y.z.w3.example.com.:120 +C\052.w3.example.com:x.y.z.w4.example.com.:120 +C\052.w4.example.com:x.y.z.w5.example.com.:120 ++\052.w5.example.com:1.2.3.5:120 Cwww.example.com:outpost.example.com.:120 #2005092501 auto axfr-get Ztest.com:ns1.test.com.:ahu.example.com.:2005092501:28800:7200:604800:86400:3600 diff --git a/modules/tinydnsbackend/data.cdb b/modules/tinydnsbackend/data.cdb index e73ef68fd2..e77a5dfde8 100644 Binary files a/modules/tinydnsbackend/data.cdb and b/modules/tinydnsbackend/data.cdb differ diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index 44fde37fe7..f732ec4bb8 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -304,7 +304,7 @@ void DNSPacket::wrapup() drc->toPacket(pw); if(pw.size() + 20U > (d_tcp ? 65535 : getMaxReplyLen())) { // 20 = room for EDNS0 pw.rollback(); - if(pos->d_place == DNSResourceRecord::ANSWER) { + if(pos->d_place == DNSResourceRecord::ANSWER || pos->d_place == DNSResourceRecord::AUTHORITY) { pw.getHeader()->tc=1; } goto noCommit; diff --git a/pdns/nsec3dig.cc b/pdns/nsec3dig.cc index ac7ec94337..dd5c58da79 100644 --- a/pdns/nsec3dig.cc +++ b/pdns/nsec3dig.cc @@ -82,12 +82,32 @@ try pw.addOpt(2800, 0, EDNSOpts::DNSSECOK); pw.commit(); - Socket sock(InterNetwork, Datagram); + Socket sock(InterNetwork, Stream); ComboAddress dest(argv[1] + (*argv[1]=='@'), atoi(argv[2])); - sock.sendTo(string((char*)&*packet.begin(), (char*)&*packet.end()), dest); + sock.connect(dest); + uint16_t len; + len = htons(packet.size()); + if(sock.write((char *) &len, 2) != 2) + throw AhuException("tcp write failed"); + + sock.writen(string((char*)&*packet.begin(), (char*)&*packet.end())); - string reply; - sock.recvFrom(reply, dest); + if(sock.read((char *) &len, 2) != 2) + throw AhuException("tcp read failed"); + + len=ntohs(len); + char *creply = new char[len]; + int n=0; + int numread; + while(nfirst.d_label<<"')"<first.d_label); - namesseen.insert(i->first.d_label); + names.insert(stripDot(i->first.d_label)); + namesseen.insert(stripDot(i->first.d_label)); + } + + if(i->first.d_type == QType::CNAME) + { + namesseen.insert(stripDot(i->first.d_content->getZoneRepresentation())); } cout<first.d_place-1<<"\t"<first.d_label<<"\tIN\t"<first.d_type); @@ -139,6 +164,7 @@ try cout<<"== nsec3 prove/deny report follows =="< proven; set denied; + namesseen.insert(stripDot(qname)); BOOST_FOREACH(string n, namesseen) { string shorter(n); diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index 05237c6df9..fa282f3088 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -486,18 +486,18 @@ void PacketHandler::emitNSEC3(const NSEC3PARAMRecordContent& ns3prc, const SOADa mode 4 = Name Error Responses mode 5 = ANY or direct NSEC request */ -void PacketHandler::addNSECX(DNSPacket *p, DNSPacket *r, const string& target, const string& target3, const string& auth, int mode) +void PacketHandler::addNSECX(DNSPacket *p, DNSPacket *r, const string& target, const string& wildcard, const string& auth, int mode) { NSEC3PARAMRecordContent ns3rc; // cerr<<"Doing NSEC3PARAM lookup for '"<qdomain<<"|"<qtype.getName()<<": "; bool narrow; if(d_dk.getNSEC3PARAM(auth, &ns3rc, &narrow)) { // cerr<<"Present, narrow="<qdomain); + string next(target); do { unhashed=next; } @@ -629,7 +625,7 @@ void PacketHandler::addNSEC3(DNSPacket *p, DNSPacket *r, const string& target, c } } -void PacketHandler::addNSEC(DNSPacket *p, DNSPacket *r, const string& target, const string& auth, int mode) +void PacketHandler::addNSEC(DNSPacket *p, DNSPacket *r, const string& target, const string& wildcard, const string& auth, int mode) { if(!p->d_dnssecOk) return; @@ -651,15 +647,14 @@ void PacketHandler::addNSEC(DNSPacket *p, DNSPacket *r, const string& target, co if (mode == 2) { // wildcard NO-DATA - sd.db->getBeforeAndAfterNames(sd.domain_id, auth, p->qdomain, before, after); - emitNSEC(before, after, target, sd, r, mode); sd.db->getBeforeAndAfterNames(sd.domain_id, auth, target, before, after); + emitNSEC(before, after, target, sd, r, mode); + sd.db->getBeforeAndAfterNames(sd.domain_id, auth, wildcard, before, after); } - else { + else sd.db->getBeforeAndAfterNames(sd.domain_id, auth, target, before, after); - } emitNSEC(before, after, target, sd, r, mode); - + if (mode == 4) { // this one does wildcard denial, if applicable sd.db->getBeforeAndAfterNames(sd.domain_id, auth, auth, before, after); @@ -892,7 +887,7 @@ void PacketHandler::synthesiseRRSIGs(DNSPacket* p, DNSPacket* r) } } -void PacketHandler::makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& nextcloser, SOAData& sd) +void PacketHandler::makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& wildcard, SOAData& sd) { DNSResourceRecord rr; rr.qname=sd.qname; @@ -907,13 +902,13 @@ void PacketHandler::makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string& r->addRecord(rr); if(p->d_dnssecOk && d_dk.isSecuredZone(sd.qname)) - addNSECX(p, r, target, nextcloser, sd.qname, 4); + addNSECX(p, r, target, wildcard, sd.qname, 4); r->setRcode(RCode::NXDomain); S.ringAccount("nxdomain-queries",p->qdomain+"/"+p->qtype.getName()); } -void PacketHandler::makeNOError(DNSPacket* p, DNSPacket* r, const std::string& target, SOAData& sd, int mode) +void PacketHandler::makeNOError(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& wildcard, SOAData& sd, int mode) { DNSResourceRecord rr; rr.qname=sd.qname; @@ -928,7 +923,7 @@ void PacketHandler::makeNOError(DNSPacket* p, DNSPacket* r, const std::string& t r->addRecord(rr); if(p->d_dnssecOk && d_dk.isSecuredZone(sd.qname)) - addNSECX(p, r, target, target, sd.qname, mode); + addNSECX(p, r, target, wildcard, sd.qname, mode); S.ringAccount("noerror-queries",p->qdomain+"/"+p->qtype.getName()); } @@ -964,7 +959,7 @@ bool PacketHandler::tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const st r->setA(false); if(p->d_dnssecOk && d_dk.isSecuredZone(sd.qname) && !addDSforNS(p, r, sd, rrset.begin()->qname)) - addNSECX(p, r, rrset.begin()->qname, rrset.begin()->qname, sd.qname, 1); + addNSECX(p, r, rrset.begin()->qname, "", sd.qname, 1); return true; } @@ -978,7 +973,7 @@ void PacketHandler::completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, c if(!d_dk.isSecuredZone(sd.qname)) return; - addNSECX(p, r, target, target, sd.qname, 5); + addNSECX(p, r, target, "", sd.qname, 5); if(pdns_iequals(sd.qname, p->qdomain)) { addDNSKEY(p, r, sd); addNSEC3PARAM(p, r, sd); @@ -988,6 +983,7 @@ void PacketHandler::completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, c bool PacketHandler::tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, string &target, string &wildcard, bool& retargeted, bool& nodata) { retargeted = nodata = false; + string bestmatch; vector rrset; if(!getBestWildcard(p, sd, target, wildcard, &rrset)) @@ -1001,7 +997,7 @@ bool PacketHandler::tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, string & DLOG(L<<"The best wildcard match: "<qname<d_dnssecOk && d_dk.isSecuredZone(sd.qname) && !nodata) { - addNSECX(p, r, p->qdomain, wildcard, sd.qname, 3); + addNSECX(p, r, bestmatch, wildcard, sd.qname, 3); } return true; } @@ -1176,7 +1172,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) // this TRUMPS a cname! if(p->qtype.getCode() == QType::NSEC && p->d_dnssecOk && d_dk.isSecuredZone(sd.qname) && !d_dk.getNSEC3PARAM(sd.qname, 0)) { - addNSEC(p, r, target, sd.qname, 5); // only NSEC please + addNSEC(p, r, target, "", sd.qname, 5); // only NSEC please goto sendit; } @@ -1226,7 +1222,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) DLOG(L<<"After first ANY query for '"<qtype.getCode() == QType::CNAME) || (p->qtype.getCode() == QType::ANY)) && retargetcount > 0)) + makeNXDomain(p, r, target, wildcard, sd); } goto sendit; @@ -1288,7 +1284,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) completeANYRecords(p, r, sd, target); } else - makeNOError(p, r, rr.qname, sd, 0); + makeNOError(p, r, rr.qname, "", sd, 0); goto sendit; } @@ -1300,7 +1296,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) } else { DLOG(L<<"Have some data, but not the right data"< getBestReferralNS(DNSPacket *p, SOAData& sd, const string &target); bool tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target); diff --git a/pdns/sdig.cc b/pdns/sdig.cc index 9878f47dcd..7462adf73a 100644 --- a/pdns/sdig.cc +++ b/pdns/sdig.cc @@ -4,6 +4,7 @@ #include "dnswriter.hh" #include "dnsrecords.hh" #include "statbag.hh" +#include StatBag S; int main(int argc, char** argv) @@ -11,6 +12,7 @@ try { bool dnssec=false; bool recurse=false; + bool tcp=false; reportAllTypes(); @@ -24,6 +26,12 @@ try { dnssec=true; } + + if(argc > 5 && strcmp(argv[5], "dnssec-tcp")==0) + { + dnssec=true; + tcp=true; + } if(argc > 5 && strcmp(argv[5], "recurse")==0) { @@ -72,13 +80,44 @@ try // pw.addOpt(5200, 0, 0); // pw.commit(); - Socket sock(InterNetwork, Datagram); - ComboAddress dest(argv[1] + (*argv[1]=='@'), atoi(argv[2])); - sock.sendTo(string((char*)&*packet.begin(), (char*)&*packet.end()), dest); - string reply; - sock.recvFrom(reply, dest); + if(tcp) { + Socket sock(InterNetwork, Stream); + ComboAddress dest(argv[1] + (*argv[1]=='@'), atoi(argv[2])); + sock.connect(dest); + uint16_t len; + len = htons(packet.size()); + if(sock.write((char *) &len, 2) != 2) + throw AhuException("tcp write failed"); + + sock.writen(string((char*)&*packet.begin(), (char*)&*packet.end())); + + if(sock.read((char *) &len, 2) != 2) + throw AhuException("tcp read failed"); + + len=ntohs(len); + char *creply = new char[len]; + int n=0; + int numread; + while(n