]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/tkey.cc
Merge pull request #2812 from cmouse/pkcs11-token-label
[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 L<<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 DNSRecord rec;
75 rec.d_name = name;
76 rec.d_ttl = 0;
77 rec.d_type = QType::TKEY;
78 rec.d_class = QClass::ANY;
79 rec.d_content = tkey_out;
80
81 DNSResourceRecord rr(rec);
82 rr.qclass = QClass::ANY;
83 rr.qtype = QType::TKEY;
84 rr.d_place = DNSResourceRecord::ANSWER;
85 r->addRecord(rr);
86
87 if (sign)
88 {
89 TSIGRecordContent trc;
90 trc.d_algoName = DNSName("gss-tsig");
91 trc.d_time = tkey_out->d_inception;
92 trc.d_fudge = 300;
93 trc.d_mac = "";
94 trc.d_origID = p->d.id;
95 trc.d_eRcode = 0;
96 trc.d_otherData = "";
97 // this should cause it to lookup name context
98 r->setTSIGDetails(trc, name, name.toStringNoDot(), "", false);
99 }
100
101 r->commitD();
102 }