]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/tkey.cc
Move libcurl detection to its own function
[thirdparty/pdns.git] / pdns / tkey.cc
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #include "packethandler.hh"
5
6 void PacketHandler::tkeyHandler(DNSPacket *p, DNSPacket *r) {
7 TKEYRecordContent tkey_in;
8 std::shared_ptr<TKEYRecordContent> tkey_out(new TKEYRecordContent());
9 DNSName name;
10 bool sign = false;
11
12 if (!p->getTKEYRecord(&tkey_in, &name)) {
13 g_log<<Logger::Error<<"TKEY request but no TKEY RR found"<<endl;
14 r->setRcode(RCode::FormErr);
15 return;
16 }
17
18 // retain original name for response
19 tkey_out->d_error = 0;
20 tkey_out->d_mode = tkey_in.d_mode;
21 tkey_out->d_algo = tkey_in.d_algo;
22 tkey_out->d_inception = time((time_t*)NULL);
23 tkey_out->d_expiration = tkey_out->d_inception+15;
24
25 GssContext ctx(name);
26
27 if (tkey_in.d_mode == 3) { // establish context
28 if (tkey_in.d_algo == DNSName("gss-tsig.")) {
29 std::vector<std::string> meta;
30 DNSName tmpName(name);
31 do {
32 if (B.getDomainMetadata(tmpName, "GSS-ACCEPTOR-PRINCIPAL", meta) && meta.size()>0) {
33 break;
34 }
35 } while(tmpName.chopOff());
36
37 if (meta.size()>0) {
38 ctx.setLocalPrincipal(meta[0]);
39 }
40 // try to get a context
41 if (!ctx.accept(tkey_in.d_key, tkey_out->d_key))
42 tkey_out->d_error = 19;
43 else
44 sign = true;
45 } else {
46 tkey_out->d_error = 21; // BADALGO
47 }
48 } else if (tkey_in.d_mode == 5) { // destroy context
49 if (p->d_havetsig == false) { // unauthenticated
50 if (p->d.opcode == Opcode::Update)
51 r->setRcode(RCode::Refused);
52 else
53 r->setRcode(RCode::NotAuth);
54 return;
55 }
56 if (ctx.valid())
57 ctx.destroy();
58 else
59 tkey_out->d_error = 20; // BADNAME (because we have no support for anything here)
60 } else {
61 if (p->d_havetsig == false && tkey_in.d_mode != 2) { // unauthenticated
62 if (p->d.opcode == Opcode::Update)
63 r->setRcode(RCode::Refused);
64 else
65 r->setRcode(RCode::NotAuth);
66 return;
67 }
68 tkey_out->d_error = 19; // BADMODE
69 }
70
71 tkey_out->d_keysize = tkey_out->d_key.size();
72 tkey_out->d_othersize = tkey_out->d_other.size();
73
74 DNSZoneRecord zrr;
75
76 zrr.dr.d_name = name;
77 zrr.dr.d_ttl = 0;
78 zrr.dr.d_type = QType::TKEY;
79 zrr.dr.d_class = QClass::ANY;
80 zrr.dr.d_content = tkey_out;
81 zrr.dr.d_place = DNSResourceRecord::ANSWER;
82 r->addRecord(zrr);
83
84 if (sign)
85 {
86 TSIGRecordContent trc;
87 trc.d_algoName = DNSName("gss-tsig");
88 trc.d_time = tkey_out->d_inception;
89 trc.d_fudge = 300;
90 trc.d_mac = "";
91 trc.d_origID = p->d.id;
92 trc.d_eRcode = 0;
93 trc.d_otherData = "";
94 // this should cause it to lookup name context
95 r->setTSIGDetails(trc, name, name.toStringNoDot(), "", false);
96 }
97
98 r->commitD();
99 }