1 #ifdef HAVE_CONFIG_H 2 #include "config.h" 3 #endif 4 #include "packethandler.hh" 5 tkeyHandler(const DNSPacket & p,std::unique_ptr<DNSPacket> & r)6void PacketHandler::tkeyHandler(const DNSPacket& p, std::unique_ptr<DNSPacket>& r) { 7 TKEYRecordContent tkey_in; 8 std::shared_ptr<TKEYRecordContent> tkey_out(new TKEYRecordContent()); 9 DNSName name; 10 11 if (!p.getTKEYRecord(&tkey_in, &name)) { 12 g_log<<Logger::Error<<"TKEY request but no TKEY RR found"<<endl; 13 r->setRcode(RCode::FormErr); 14 return; 15 } 16 17 // retain original name for response 18 tkey_out->d_error = 0; 19 tkey_out->d_mode = tkey_in.d_mode; 20 tkey_out->d_algo = tkey_in.d_algo; 21 tkey_out->d_inception = time((time_t*)nullptr); 22 tkey_out->d_expiration = tkey_out->d_inception+15; 23 24 if (tkey_in.d_mode == 3) { // establish context 25 if (tkey_in.d_algo == DNSName("gss-tsig.")) { 26 tkey_out->d_error = 19; 27 } else { 28 tkey_out->d_error = 21; // BADALGO 29 } 30 } else if (tkey_in.d_mode == 5) { // destroy context 31 if (p.d_havetsig == false) { // unauthenticated 32 if (p.d.opcode == Opcode::Update) 33 r->setRcode(RCode::Refused); 34 else 35 r->setRcode(RCode::NotAuth); 36 return; 37 } 38 39 tkey_out->d_error = 20; // BADNAME (because we have no support for anything here) 40 } else { 41 if (p.d_havetsig == false && tkey_in.d_mode != 2) { // unauthenticated 42 if (p.d.opcode == Opcode::Update) 43 r->setRcode(RCode::Refused); 44 else 45 r->setRcode(RCode::NotAuth); 46 return; 47 } 48 tkey_out->d_error = 19; // BADMODE 49 } 50 51 tkey_out->d_keysize = tkey_out->d_key.size(); 52 tkey_out->d_othersize = tkey_out->d_other.size(); 53 54 DNSZoneRecord zrr; 55 56 zrr.dr.d_name = name; 57 zrr.dr.d_ttl = 0; 58 zrr.dr.d_type = QType::TKEY; 59 zrr.dr.d_class = QClass::ANY; 60 zrr.dr.d_content = tkey_out; 61 zrr.dr.d_place = DNSResourceRecord::ANSWER; 62 r->addRecord(std::move(zrr)); 63 r->commitD(); 64 } 65