]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/tkey.cc
Merge pull request #7628 from tcely/patch-3
[thirdparty/pdns.git] / pdns / tkey.cc
CommitLineData
25c87ff4
AT
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4#include "packethandler.hh"
5
6void PacketHandler::tkeyHandler(DNSPacket *p, DNSPacket *r) {
7 TKEYRecordContent tkey_in;
8 std::shared_ptr<TKEYRecordContent> tkey_out(new TKEYRecordContent());
f809c028 9 DNSName name;
25c87ff4
AT
10 bool sign = false;
11
f809c028 12 if (!p->getTKEYRecord(&tkey_in, &name)) {
e6a9dde5 13 g_log<<Logger::Error<<"TKEY request but no TKEY RR found"<<endl;
25c87ff4
AT
14 r->setRcode(RCode::FormErr);
15 return;
16 }
17
f809c028 18 // retain original name for response
25c87ff4
AT
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
1635f12b 25 GssContext ctx(name);
25c87ff4
AT
26
27 if (tkey_in.d_mode == 3) { // establish context
290a083d 28 if (tkey_in.d_algo == DNSName("gss-tsig.")) {
25c87ff4 29 std::vector<std::string> meta;
f809c028 30 DNSName tmpName(name);
21a3792f 31 do {
f809c028 32 if (B.getDomainMetadata(tmpName, "GSS-ACCEPTOR-PRINCIPAL", meta) && meta.size()>0) {
25c87ff4
AT
33 break;
34 }
f809c028 35 } while(tmpName.chopOff());
25c87ff4
AT
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
90ba52e0 74 DNSZoneRecord zrr;
25c87ff4 75
90ba52e0 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);
25c87ff4
AT
83
84 if (sign)
85 {
86 TSIGRecordContent trc;
290a083d 87 trc.d_algoName = DNSName("gss-tsig");
25c87ff4
AT
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 = "";
f809c028 94 // this should cause it to lookup name context
95 r->setTSIGDetails(trc, name, name.toStringNoDot(), "", false);
25c87ff4
AT
96 }
97
98 r->commitD();
99}