From: Aki Tuomi Date: Sat, 23 May 2015 13:59:45 +0000 (+0300) Subject: Add support for GSS and TSIG for AXFR X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~79^2~9^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0b122e8ff26e141d2706b5774d431e7e25f69877;p=pdns Add support for GSS and TSIG for AXFR --- diff --git a/pdns/saxfr.cc b/pdns/saxfr.cc index b2fbf8925..e572b0bcd 100644 --- a/pdns/saxfr.cc +++ b/pdns/saxfr.cc @@ -1,6 +1,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include "base64.hh" #include "dnsparser.hh" #include "sstuff.hh" #include "misc.hh" @@ -10,20 +11,52 @@ #include "base32.hh" #include "dnssecinfra.hh" #include +#include "dns_random.hh" +#include "gss_context.hh" StatBag S; +bool validateTSIG(const string& message, const TSIGHashEnum& algo, const string& key, const string& secret, const TSIGRecordContent *trc) { + int64_t now = time(0); + if(abs((int64_t)trc->d_time - now) > trc->d_fudge) { + cerr<<"TSIG (key '"<d_time - now)<<" > 'fudge' "<d_fudge<d_mac)) { + cerr<<"invalid mac"<d_mac; +} + + int main(int argc, char** argv) try { if(argc < 4) { - cerr<<"Syntax: saxfr IP-address port zone [showdetails] [showflags] [unhash]"< 4) { for(int i=4; i parts; + tsig=true; + stringtok(parts, argv[i], ":"); + if (parts.size()!=4) { + cerr<<"Invalid syntax for tsig"< packet; + uint16_t len; + ComboAddress dest(argv[1] + (*argv[1]=='@'), atoi(argv[2])); + Socket sock(dest.sin4.sin_family, SOCK_STREAM); + sock.connect(dest); + + if (gss) { +#ifndef ENABLE_GSS_TSIG + cerr<<"No GSS support compiled in"<id = dns_random(0xffff); + pwtkey.startRecord(gssctx.getLabel(), QType::TKEY, 3600, QClass::ANY, DNSPacketWriter::ADDITIONAL, false); + tkrc.toPacket(pwtkey); + pwtkey.commit(); + BOOST_FOREACH(const string& msg, gssctx.getErrorStrings()) { + cerr<(mdp.d_header.rcode)); + } + for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) { + if(i->first.d_type != QType::TKEY) continue; + // recover TKEY record + tkrc = TKEYRecordContent(i->first.d_content->getZoneRepresentation()); + input = tkrc.d_key; + } + } + + if (gssctx.valid() == false) { + cerr<<"Could not create GSS context"<id = dns_random(0xffff); + + if (tsig) { + TSIGRecordContent trc; + trc.d_algoName = getTSIGAlgoName(tsig_algo); + trc.d_time = time((time_t*)NULL); + trc.d_fudge = 300; + trc.d_origID=ntohs(pw.getHeader()->id); + trc.d_eRcode=0; + addTSIG(pw, &trc, tsig_key, tsig_secret, "", false); + } - ComboAddress dest(argv[1] + (*argv[1]=='@'), atoi(argv[2])); - Socket sock(dest.sin4.sin_family, SOCK_STREAM); - sock.connect(dest); - uint16_t len; len = htons(packet.size()); if(sock.write((char *) &len, 2) != 2) throw PDNSException("tcp write failed"); @@ -60,6 +211,8 @@ try NSEC3PARAMRecordContent ns3pr; while(soacount<2) { + TSIGRecordContent trc; + if(sock.read((char *) &len, 2) != 2) throw PDNSException("tcp read failed"); @@ -74,8 +227,21 @@ try n+=numread; } - MOADNSParser mdp(string(creply, len)); + string packet = string(creply, len); + + MOADNSParser mdp(packet); + if (mdp.d_header.rcode != 0) { + throw PDNSException(string("Remote server refused: ") + boost::lexical_cast(mdp.d_header.rcode)); + } for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) { + if (i->first.d_type == QType::TSIG) { + string message; + if (!tsig) { + std::cerr<<"Unexpected TSIG signature in data"<first.d_content->getZoneRepresentation()); + continue; + } if(i->first.d_type == QType::SOA) { ++soacount; @@ -134,6 +300,7 @@ try }while(chopOff(shorter)); } + delete[] creply; } @@ -159,6 +326,9 @@ try } } +catch(PDNSException &e2) { + cerr<<"Fatal: "<