]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add and hook tkeyHandler
authorAki Tuomi <cmouse@cmouse.fi>
Wed, 18 Feb 2015 19:29:07 +0000 (21:29 +0200)
committerAki Tuomi <cmouse@cmouse.fi>
Mon, 9 Mar 2015 19:43:46 +0000 (21:43 +0200)
pdns/packethandler.cc
pdns/packethandler.hh

index ef5599d4149bc6f2e698881e0f633d3a3b5606f8..008d60a43d991e763de0b06d04c6030c9b5e72a3 100644 (file)
@@ -1064,7 +1064,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 ?
@@ -1414,3 +1419,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 dda2ed7bbaa0c53f85c9e8e057009dc40340fc9f..645e8fca5fe826c4fe0c9308235fe075c8ac9ac0 100644 (file)
@@ -96,7 +96,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;