]>
Commit | Line | Data |
---|---|---|
60a1c204 RG |
1 | |
2 | #include "tsigverifier.hh" | |
3 | #include "dnssecinfra.hh" | |
4 | #include "gss_context.hh" | |
5 | ||
6 | bool TSIGTCPVerifier::check(const string& data, const MOADNSParser& mdp) | |
7 | { | |
8 | if(d_tt.name.empty()) { // TSIG verify message | |
9 | return true; | |
10 | } | |
11 | ||
12 | string theirMac; | |
13 | bool checkTSIG = false; | |
14 | // If we have multiple messages, we need to concatenate them together. We also need to make sure we know the location of | |
15 | // the TSIG record so we can remove it in makeTSIGMessageFromTSIGPacket | |
16 | d_signData.append(data); | |
17 | if (mdp.getTSIGPos() == 0) { | |
18 | d_tsigPos += data.size(); | |
19 | } | |
20 | else { | |
21 | d_tsigPos += mdp.getTSIGPos(); | |
22 | } | |
23 | ||
24 | for(const auto& answer : mdp.d_answers) { | |
25 | if (answer.first.d_type == QType::SOA) { | |
26 | // A SOA is either the first or the last record. We need to check TSIG if that's the case. | |
27 | checkTSIG = true; | |
28 | } | |
29 | ||
30 | if(answer.first.d_type == QType::TSIG) { | |
31 | shared_ptr<TSIGRecordContent> trc = getRR<TSIGRecordContent>(answer.first); | |
32 | if(trc) { | |
33 | theirMac = trc->d_mac; | |
34 | d_trc.d_time = trc->d_time; | |
35 | d_trc.d_fudge = trc->d_fudge; | |
ea3816cf RG |
36 | d_trc.d_eRcode = trc->d_eRcode; |
37 | d_trc.d_origID = trc->d_origID; | |
60a1c204 RG |
38 | checkTSIG = true; |
39 | } | |
40 | } | |
41 | } | |
42 | ||
43 | if(!checkTSIG && d_nonSignedMessages > 99) { // We're allowed to get 100 digest without a TSIG. | |
44 | throw std::runtime_error("No TSIG message received in last 100 messages of AXFR transfer."); | |
45 | } | |
46 | ||
47 | if (checkTSIG) { | |
48 | if (theirMac.empty()) { | |
86f1af1c | 49 | throw std::runtime_error("No TSIG on AXFR response from "+d_remote.toStringWithPort()+" , should be signed with TSIG key '"+d_tt.name.toLogString()+"'"); |
60a1c204 RG |
50 | } |
51 | ||
ea3816cf RG |
52 | try { |
53 | if (!d_prevMac.empty()) { | |
54 | validateTSIG(d_signData, d_tsigPos, d_tt, d_trc, d_prevMac, theirMac, true, d_signData.size()-data.size()); | |
60a1c204 | 55 | } |
ea3816cf RG |
56 | else { |
57 | validateTSIG(d_signData, d_tsigPos, d_tt, d_trc, d_trc.d_mac, theirMac, false); | |
60a1c204 RG |
58 | } |
59 | } | |
ea3816cf RG |
60 | catch(const std::runtime_error& err) { |
61 | throw std::runtime_error("Error while validating TSIG signature on AXFR response from "+d_remote.toStringWithPort()+":"+err.what()); | |
62 | } | |
60a1c204 RG |
63 | |
64 | // Reset and store some values for the next chunks. | |
65 | d_prevMac = theirMac; | |
66 | d_nonSignedMessages = 0; | |
67 | d_signData.clear(); | |
68 | d_tsigPos = 0; | |
69 | } | |
70 | else | |
71 | d_nonSignedMessages++; | |
72 | ||
73 | return true; | |
74 | } |