]> granicus.if.org Git - pdns/commitdiff
Add and hook tkeyHandler
authorAki Tuomi <cmouse@cmouse.fi>
Wed, 18 Feb 2015 19:29:07 +0000 (21:29 +0200)
committerAki Tuomi <cmouse@desteem.org>
Thu, 26 Mar 2015 13:23:11 +0000 (15:23 +0200)
pdns/packethandler.cc
pdns/packethandler.hh

index 13da01b0d1e18005e78c360e3695f583fd303038..8c0bea453aa6d99176471b2defc0658910a4ade1 100644 (file)
@@ -1014,7 +1014,12 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
   }
   
   r=p->replyPacket();  // generate an empty reply packet, possibly with TSIG details inside
-  
+
+  if (p->qtype == QType::TKEY) {
+    this->tkeyHandler(p, r);
+    return r;
+  }
+
   try {    
 
     // XXX FIXME do this in DNSPacket::parse ?
@@ -1346,3 +1351,62 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
 
 }
 
+void PacketHandler::tkeyHandler(DNSPacket *p, DNSPacket *r) {
+  TKEYRecordContent tkey_in;
+  boost::shared_ptr<TKEYRecordContent> tkey_out(new TKEYRecordContent());
+  string label, lcLabel;
+
+  if (!p->getTKEYRecord(&tkey_in, &label)) {
+    L<<Logger::Error<<"TKEY request but no TKEY RR found"<<endl;
+    r->setRcode(RCode::FormErr);
+    return;
+  }
+
+  // retain original label for response
+  lcLabel = toLowerCanonic(label);
+
+  tkey_out->d_error = 0;
+  tkey_out->d_mode = tkey_in.d_mode;
+  tkey_out->d_algo = tkey_in.d_algo;
+  tkey_out->d_inception = time((time_t*)NULL);
+  tkey_out->d_expiration = tkey_out->d_inception+15;
+
+  if (tkey_in.d_mode == 3) {
+    tkey_out->d_error = 19; // BADMODE
+  } else if (tkey_in.d_mode == 5) {
+    if (p->d_havetsig == false) { // unauthenticated
+      if (p->d.opcode == Opcode::Update)
+        r->setRcode(RCode::Refused);
+      else
+        r->setRcode(RCode::NotAuth);
+      return;
+    }
+    tkey_out->d_error = 20; // BADNAME (because we have no support for anything here)
+  } else {
+    if (p->d_havetsig == false && tkey_in.d_mode != 2) { // unauthenticated
+      if (p->d.opcode == Opcode::Update)
+        r->setRcode(RCode::Refused);
+      else
+        r->setRcode(RCode::NotAuth);
+      return;
+    }
+    tkey_out->d_error = 19; // BADMODE
+  }
+
+  tkey_out->d_keysize = tkey_out->d_key.size();
+  tkey_out->d_othersize = tkey_out->d_other.size();
+
+  DNSRecord rec;
+  rec.d_label = label;
+  rec.d_ttl = 0;
+  rec.d_type = QType::TKEY;
+  rec.d_class = QClass::ANY;
+  rec.d_content = tkey_out;
+
+  DNSResourceRecord rr(rec);
+  rr.qclass = QClass::ANY;
+  rr.qtype = QType::TKEY;
+  rr.d_place = DNSResourceRecord::ANSWER;
+  r->addRecord(rr);
+  r->commitD();
+}
index b03a46e586a940426d54ae521f6ce6cfc85b844d..756b58fdc03baa1755344b60b46e6ef7a107f7ee 100644 (file)
@@ -101,7 +101,9 @@ private:
   bool tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, string &target, string &wildcard, bool& retargeted, bool& nodata);
   bool addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const string& dsname);
   void completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target);
-  
+
+  void tkeyHandler(DNSPacket *p, DNSPacket *r);
+
   static AtomicCounter s_count;
   static pthread_mutex_t s_rfc2136lock;
   bool d_doRecursion;