]>
Commit | Line | Data |
---|---|---|
12471842 PL |
1 | /* |
2 | * This file is part of PowerDNS or dnsdist. | |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
644dd1da | 22 | #include "filterpo.hh" |
23 | #include <iostream> | |
24 | #include "namespaces.hh" | |
25 | #include "dnsrecords.hh" | |
26 | ||
27 | DNSFilterEngine::DNSFilterEngine() | |
28 | { | |
29 | } | |
30 | ||
a2d0450e | 31 | static bool findNamedPolicy(const std::unordered_map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol) |
644dd1da | 32 | { |
5678437b PL |
33 | /* for www.powerdns.com, we need to check: |
34 | www.powerdns.com. | |
35 | *.powerdns.com. | |
36 | *.com. | |
37 | *. | |
38 | */ | |
0a273054 | 39 | |
a2d0450e RG |
40 | std::unordered_map<DNSName, DNSFilterEngine::Policy>::const_iterator iter; |
41 | iter = polmap.find(qname); | |
bef458b2 PL |
42 | |
43 | if(iter != polmap.end()) { | |
44 | pol=iter->second; | |
45 | return true; | |
46 | } | |
5678437b | 47 | |
a2d0450e | 48 | DNSName s(qname); |
bef458b2 | 49 | while(s.chopOff()){ |
12c06211 | 50 | iter = polmap.find(g_wildcarddnsname+s); |
5678437b PL |
51 | if(iter != polmap.end()) { |
52 | pol=iter->second; | |
53 | return true; | |
54 | } | |
bef458b2 | 55 | } |
644dd1da | 56 | return false; |
57 | } | |
58 | ||
0a273054 | 59 | DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies) const |
644dd1da | 60 | { |
39ec5d29 | 61 | // cout<<"Got question for nameserver name "<<qname<<endl; |
1f1ca368 | 62 | Policy pol; |
644dd1da | 63 | for(const auto& z : d_zones) { |
0a273054 RG |
64 | if(z.name && discardedPolicies.find(*z.name) != discardedPolicies.end()) { |
65 | continue; | |
66 | } | |
67 | ||
644dd1da | 68 | if(findNamedPolicy(z.propolName, qname, pol)) { |
de0f72ba | 69 | // cerr<<"Had a hit on the nameserver ("<<qname<<") used to process the query"<<endl; |
644dd1da | 70 | return pol; |
71 | } | |
72 | } | |
73 | return pol; | |
b8470add | 74 | } |
644dd1da | 75 | |
0a273054 | 76 | DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const ComboAddress& address, const std::unordered_map<std::string,bool>& discardedPolicies) const |
b8470add PL |
77 | { |
78 | // cout<<"Got question for nameserver IP "<<address.toString()<<endl; | |
79 | for(const auto& z : d_zones) { | |
0a273054 RG |
80 | if(z.name && discardedPolicies.find(*z.name) != discardedPolicies.end()) { |
81 | continue; | |
82 | } | |
83 | ||
b8470add PL |
84 | if(auto fnd=z.propolNSAddr.lookup(address)) { |
85 | // cerr<<"Had a hit on the nameserver ("<<address.toString()<<") used to process the query"<<endl; | |
86 | return fnd->second;; | |
87 | } | |
88 | } | |
1f1ca368 | 89 | return Policy(); |
b8470add | 90 | } |
644dd1da | 91 | |
0a273054 | 92 | DNSFilterEngine::Policy DNSFilterEngine::getQueryPolicy(const DNSName& qname, const ComboAddress& ca, const std::unordered_map<std::string,bool>& discardedPolicies) const |
644dd1da | 93 | { |
de0f72ba | 94 | // cout<<"Got question for "<<qname<<" from "<<ca.toString()<<endl; |
1f1ca368 | 95 | Policy pol; |
644dd1da | 96 | for(const auto& z : d_zones) { |
0a273054 RG |
97 | if(z.name && discardedPolicies.find(*z.name) != discardedPolicies.end()) { |
98 | continue; | |
99 | } | |
100 | ||
644dd1da | 101 | if(findNamedPolicy(z.qpolName, qname, pol)) { |
de0f72ba | 102 | // cerr<<"Had a hit on the name of the query"<<endl; |
644dd1da | 103 | return pol; |
104 | } | |
105 | ||
0e760497 | 106 | if(auto fnd=z.qpolAddr.lookup(ca)) { |
107 | // cerr<<"Had a hit on the IP address ("<<ca.toString()<<") of the client"<<endl; | |
108 | return fnd->second; | |
644dd1da | 109 | } |
110 | } | |
111 | ||
39ec5d29 | 112 | return pol; |
644dd1da | 113 | } |
114 | ||
0a273054 | 115 | DNSFilterEngine::Policy DNSFilterEngine::getPostPolicy(const vector<DNSRecord>& records, const std::unordered_map<std::string,bool>& discardedPolicies) const |
644dd1da | 116 | { |
117 | ComboAddress ca; | |
644dd1da | 118 | for(const auto& r : records) { |
589ad24b | 119 | if(r.d_place != DNSResourceRecord::ANSWER) |
644dd1da | 120 | continue; |
ba3c54cb RG |
121 | if(r.d_type == QType::A) { |
122 | if (auto rec = getRR<ARecordContent>(r)) { | |
123 | ca = rec->getCA(); | |
124 | } | |
125 | } | |
126 | else if(r.d_type == QType::AAAA) { | |
127 | if (auto rec = getRR<AAAARecordContent>(r)) { | |
128 | ca = rec->getCA(); | |
129 | } | |
130 | } | |
644dd1da | 131 | else |
132 | continue; | |
133 | ||
134 | for(const auto& z : d_zones) { | |
0a273054 RG |
135 | if(z.name && discardedPolicies.find(*z.name) != discardedPolicies.end()) { |
136 | continue; | |
137 | } | |
138 | ||
0e760497 | 139 | if(auto fnd=z.postpolAddr.lookup(ca)) |
140 | return fnd->second; | |
644dd1da | 141 | } |
142 | } | |
1f1ca368 | 143 | return Policy(); |
644dd1da | 144 | } |
145 | ||
0a273054 | 146 | void DNSFilterEngine::assureZones(size_t zone) |
644dd1da | 147 | { |
0a273054 | 148 | if(d_zones.size() <= zone) |
644dd1da | 149 | d_zones.resize(zone+1); |
644dd1da | 150 | } |
151 | ||
0a273054 | 152 | void DNSFilterEngine::clear(size_t zone) |
7eafc52f | 153 | { |
154 | assureZones(zone); | |
155 | auto& z = d_zones[zone]; | |
156 | z.qpolAddr.clear(); | |
157 | z.postpolAddr.clear(); | |
158 | z.propolName.clear(); | |
2ae56398 | 159 | z.propolNSAddr.clear(); |
7eafc52f | 160 | z.qpolName.clear(); |
161 | } | |
162 | ||
0a7ef1b8 RG |
163 | void DNSFilterEngine::clear() |
164 | { | |
165 | for(auto& z : d_zones) { | |
166 | z.qpolAddr.clear(); | |
167 | z.postpolAddr.clear(); | |
168 | z.propolName.clear(); | |
2ae56398 | 169 | z.propolNSAddr.clear(); |
0a7ef1b8 RG |
170 | z.qpolName.clear(); |
171 | } | |
172 | } | |
173 | ||
0a273054 | 174 | void DNSFilterEngine::addClientTrigger(const Netmask& nm, Policy pol, size_t zone) |
644dd1da | 175 | { |
176 | assureZones(zone); | |
0a273054 | 177 | pol.d_name = d_zones[zone].name; |
0e760497 | 178 | d_zones[zone].qpolAddr.insert(nm).second=pol; |
644dd1da | 179 | } |
180 | ||
0a273054 | 181 | void DNSFilterEngine::addResponseTrigger(const Netmask& nm, Policy pol, size_t zone) |
644dd1da | 182 | { |
183 | assureZones(zone); | |
0a273054 | 184 | pol.d_name = d_zones[zone].name; |
0e760497 | 185 | d_zones[zone].postpolAddr.insert(nm).second=pol; |
644dd1da | 186 | } |
187 | ||
0a273054 | 188 | void DNSFilterEngine::addQNameTrigger(const DNSName& n, Policy pol, size_t zone) |
644dd1da | 189 | { |
190 | assureZones(zone); | |
0a273054 | 191 | pol.d_name = d_zones[zone].name; |
644dd1da | 192 | d_zones[zone].qpolName[n]=pol; |
193 | } | |
194 | ||
0a273054 | 195 | void DNSFilterEngine::addNSTrigger(const DNSName& n, Policy pol, size_t zone) |
644dd1da | 196 | { |
197 | assureZones(zone); | |
0a273054 | 198 | pol.d_name = d_zones[zone].name; |
644dd1da | 199 | d_zones[zone].propolName[n]=pol; |
200 | } | |
39ec5d29 | 201 | |
0a273054 | 202 | void DNSFilterEngine::addNSIPTrigger(const Netmask& nm, Policy pol, size_t zone) |
b8470add PL |
203 | { |
204 | assureZones(zone); | |
0a273054 | 205 | pol.d_name = d_zones[zone].name; |
b8470add PL |
206 | d_zones[zone].propolNSAddr.insert(nm).second = pol; |
207 | } | |
208 | ||
0a273054 | 209 | bool DNSFilterEngine::rmClientTrigger(const Netmask& nm, Policy pol, size_t zone) |
39ec5d29 | 210 | { |
211 | assureZones(zone); | |
212 | ||
213 | auto& qpols = d_zones[zone].qpolAddr; | |
0e760497 | 214 | qpols.erase(nm); |
39ec5d29 | 215 | return true; |
216 | } | |
217 | ||
0a273054 | 218 | bool DNSFilterEngine::rmResponseTrigger(const Netmask& nm, Policy pol, size_t zone) |
39ec5d29 | 219 | { |
220 | assureZones(zone); | |
221 | auto& postpols = d_zones[zone].postpolAddr; | |
0e760497 | 222 | postpols.erase(nm); |
39ec5d29 | 223 | return true; |
224 | } | |
225 | ||
0a273054 | 226 | bool DNSFilterEngine::rmQNameTrigger(const DNSName& n, Policy pol, size_t zone) |
39ec5d29 | 227 | { |
228 | assureZones(zone); | |
229 | d_zones[zone].qpolName.erase(n); // XXX verify we had identical policy? | |
230 | return true; | |
231 | } | |
232 | ||
0a273054 | 233 | bool DNSFilterEngine::rmNSTrigger(const DNSName& n, Policy pol, size_t zone) |
39ec5d29 | 234 | { |
235 | assureZones(zone); | |
236 | d_zones[zone].propolName.erase(n); // XXX verify policy matched? =pol; | |
237 | return true; | |
238 | } | |
b8470add | 239 | |
0a273054 | 240 | bool DNSFilterEngine::rmNSIPTrigger(const Netmask& nm, Policy pol, size_t zone) |
b8470add PL |
241 | { |
242 | assureZones(zone); | |
243 | auto& pols = d_zones[zone].propolNSAddr; | |
244 | pols.erase(nm); | |
245 | return true; | |
246 | } |