]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
implement TSIG for IXFR slaving, make ixplore use that infrastructure. Todo: hook...
authorbert hubert <bert.hubert@netherlabs.nl>
Wed, 6 Jan 2016 20:32:31 +0000 (21:32 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Wed, 6 Jan 2016 20:32:31 +0000 (21:32 +0100)
pdns/ixfr.cc
pdns/ixfr.hh
pdns/ixplore.cc

index f1eb0b8d8878ed1886aa32df55d9860110ac7279..ca31143ce446da265fd1c45f6ab94317e0b97782 100644 (file)
@@ -2,9 +2,9 @@
 #include "sstuff.hh"
 #include "dns_random.hh"
 #include "dnsrecords.hh"
+#include "dnssecinfra.hh"
 
-
-vector<pair<vector<DNSRecord>, vector<DNSRecord> > >   getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& oursr)
+vector<pair<vector<DNSRecord>, vector<DNSRecord> > >   getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& oursr, const DNSName& tsigalgo, const DNSName& tsigname, const std::string& tsigsecret)
 {
   vector<pair<vector<DNSRecord>, vector<DNSRecord> > >  ret;
   vector<uint8_t> packet;
@@ -12,10 +12,19 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord> > >   getIXFRDeltas(const Combo
   pw.getHeader()->qr=0;
   pw.getHeader()->rd=0;
   pw.getHeader()->id=dns_random(0xffff);
-  pw.startRecord(zone, QType::SOA, 3600, QClass::IN, DNSResourceRecord::AUTHORITY);
+  pw.startRecord(zone, QType::SOA, 0, QClass::IN, DNSResourceRecord::AUTHORITY);
   oursr.d_content->toPacket(pw);
+
   pw.commit();
-  
+  if(!tsigalgo.empty()) {
+    TSIGRecordContent trc;
+    trc.d_algoName = tsigalgo;
+    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, tsigname, tsigsecret, "", false);
+  }
   uint16_t len=htons(packet.size());
   string msg((const char*)&len, 2);
   msg.append((const char*)&packet[0], packet.size());
@@ -45,8 +54,13 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord> > >   getIXFRDeltas(const Combo
     char reply[len]; 
     readn2(s.getHandle(), reply, len);
     MOADNSParser mdp(string(reply, len));
+    if(mdp.d_header.rcode) 
+      throw std::runtime_error("Got an error trying to IXFR zone '"+zone.toString()+"' from master '"+master.toStringWithPort()+"': "+RCode::to_s(mdp.d_header.rcode));
+
     //    cout<<"Got a response, rcode: "<<mdp.d_header.rcode<<", got "<<mdp.d_answers.size()<<" answers"<<endl;
     for(auto& r: mdp.d_answers) {
+      if(r.first.d_type == QType::TSIG) 
+        continue;
       //      cout<<r.first.d_name<< " " <<r.first.d_content->getZoneRepresentation()<<endl;
       r.first.d_name = r.first.d_name.makeRelative(zone);
       records.push_back(r.first);
index 27a936342420518e214729ef8208495a272b4ec5..40d70659c3292ce8a8e1ba68e08dd828a9e7480f 100644 (file)
@@ -2,4 +2,5 @@
 #include "iputils.hh"
 #include "dnsparser.hh"
 
-vector<pair<vector<DNSRecord>, vector<DNSRecord> > >   getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& sr);
+vector<pair<vector<DNSRecord>, vector<DNSRecord> > >   getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& sr,
+                                                                     const DNSName& tsigalgo=DNSName(), const DNSName& tsigname=DNSName(), const std::string& tsigsecret="");
index 3a21d6b02a56abdc322896ed5e1b0e6d8139727e..4e77c22de0a11b4e72f917a7afe519cae0bb4974 100644 (file)
@@ -25,7 +25,6 @@
 using namespace boost::multi_index;
 StatBag S;
 
-
 ArgvMap &arg()
 {
   static ArgvMap theArg;
@@ -57,10 +56,19 @@ typedef multi_index_container<
     >
   >records_t;
 
-uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr<SOARecordContent>& sr)
+uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr<SOARecordContent>& sr, const DNSName& tsigalgo=DNSName(), const DNSName& tsigname=DNSName(), const std::string& tsigsecret="")
 {
   vector<uint8_t> packet;
   DNSPacketWriter pw(packet, zone, QType::SOA);
+  if(!tsigalgo.empty()) {
+    TSIGRecordContent trc;
+    trc.d_algoName = tsigalgo;
+    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, tsigname, tsigsecret, "", false);
+  }
   
   Socket s(master.sin4.sin_family, SOCK_DGRAM);
   s.connect(master);
@@ -175,11 +183,10 @@ try
   string command;
   if(argc < 5 || (command=argv[1], (command!="diff" && command !="track"))) {
     cerr<<"Syntax: ixplore diff zone file1 file2"<<endl;
-    cerr<<"Syntax: ixplore track IP-address port zone directory"<<endl;
+    cerr<<"Syntax: ixplore track IP-address port zone directory [tsigkey tsigalgo tsigsecret]"<<endl;
     exit(EXIT_FAILURE);
   }
   if(command=="diff") {
-
     records_t before, after;
     DNSName zone(argv[2]);
     cout<<"Loading before from "<<argv[3]<<endl;
@@ -222,6 +229,19 @@ try
 
   cout<<"Loading zone, our highest available serial is "<< ourSerial<<endl;
 
+  DNSName tsigkey, tsigalgo;
+  if(argc > 6)
+    tsigkey=DNSName(toLower(argv[6]));
+  if(argc > 7)
+    tsigalgo=DNSName(toLower(argv[7]));
+  string tsigsecret;
+  if(argc > 8) {
+    if(B64Decode(argv[8], tsigsecret) < 0) {
+      cerr<<"Could not decode tsig secret!"<<endl;
+      exit(EXIT_FAILURE);
+    }
+  }
+
   try {
     if(!ourSerial)
       throw std::runtime_error("There is no local zone available");
@@ -242,6 +262,8 @@ try
     time_t last=0;
     while(axfr.getChunk(nop, &chunk)) {
       for(auto& dr : chunk) {
+        if(dr.d_type == QType::TSIG)
+          continue;
        dr.d_name.makeUsRelative(zone);
        records.insert(dr);
        nrecords++;
@@ -266,7 +288,7 @@ try
     cout<<"Checking for update, our serial number is "<<ourSerial<<".. ";
     cout.flush();
     shared_ptr<SOARecordContent> sr;
-    uint32_t serial = getSerialFromMaster(master, zone, sr);
+    uint32_t serial = getSerialFromMaster(master, zone, sr, tsigalgo, tsigkey, tsigsecret);
     if(ourSerial == serial) {
       cout<<"still up to date, their serial is "<<serial<<", sleeping "<<sr->d_st.refresh<<" seconds"<<endl;
       sleep(sr->d_st.refresh);
@@ -274,7 +296,7 @@ try
     }
 
     cout<<"got new serial: "<<serial<<", initiating IXFR!"<<endl;
-    auto deltas = getIXFRDeltas(master, zone, ourSoa);
+    auto deltas = getIXFRDeltas(master, zone, ourSoa, tsigalgo, tsigkey, tsigsecret);
     cout<<"Got "<<deltas.size()<<" deltas, applying.."<<endl;
 
     for(const auto& delta : deltas) {