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)6 void 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