]>
Commit | Line | Data |
---|---|---|
25c87ff4 AT |
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()); | |
f809c028 | 9 | DNSName name; |
25c87ff4 AT |
10 | bool sign = false; |
11 | ||
f809c028 | 12 | if (!p->getTKEYRecord(&tkey_in, &name)) { |
25c87ff4 AT |
13 | L<<Logger::Error<<"TKEY request but no TKEY RR found"<<endl; |
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 | } |