]>
Commit | Line | Data |
---|---|---|
6da513b2 RG |
1 | |
2 | #define BOOST_TEST_DYN_LINK | |
3 | #define BOOST_TEST_NO_MAIN | |
4 | ||
5 | #ifdef HAVE_CONFIG_H | |
6 | #include "config.h" | |
7 | #endif | |
8 | #include <boost/test/unit_test.hpp> | |
9 | ||
10 | #include "dnsrecords.hh" | |
11 | #include "filterpo.hh" | |
12 | ||
42dcf516 OM |
13 | BOOST_AUTO_TEST_CASE(test_filter_policies_basic) |
14 | { | |
6da513b2 RG |
15 | DNSFilterEngine dfe; |
16 | ||
17 | std::string zoneName("Unit test policy 0"); | |
18 | auto zone = std::make_shared<DNSFilterEngine::Zone>(); | |
19 | zone->setName(zoneName); | |
b502d522 | 20 | BOOST_CHECK_EQUAL(zone->getName(), zoneName); |
6da513b2 RG |
21 | zone->setDomain(DNSName("powerdns.com.")); |
22 | BOOST_CHECK_EQUAL(zone->getDomain(), DNSName("powerdns.com.")); | |
23 | zone->setSerial(42); | |
690b86b7 | 24 | BOOST_CHECK_EQUAL(zone->getSerial(), 42U); |
6da513b2 | 25 | zone->setRefresh(99); |
690b86b7 | 26 | BOOST_CHECK_EQUAL(zone->getRefresh(), 99U); |
6da513b2 RG |
27 | |
28 | const ComboAddress nsIP("192.0.2.1"); | |
29 | const DNSName nsName("ns.bad.wolf."); | |
d96f1e86 | 30 | const DNSName nsWildcardName("*.wildcard.wolf."); |
6da513b2 RG |
31 | const ComboAddress clientIP("192.0.2.128"); |
32 | const DNSName blockedName("blocked."); | |
d96f1e86 | 33 | const DNSName blockedWildcardName("*.wildcard-blocked."); |
6da513b2 | 34 | const ComboAddress responseIP("192.0.2.254"); |
690b86b7 | 35 | BOOST_CHECK_EQUAL(zone->size(), 0U); |
562c1c1d | 36 | zone->addClientTrigger(Netmask(clientIP, 31), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::ClientIP)); |
690b86b7 | 37 | BOOST_CHECK_EQUAL(zone->size(), 1U); |
6da513b2 | 38 | zone->addQNameTrigger(blockedName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::QName)); |
690b86b7 | 39 | BOOST_CHECK_EQUAL(zone->size(), 2U); |
d96f1e86 | 40 | zone->addQNameTrigger(blockedWildcardName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::QName)); |
690b86b7 | 41 | BOOST_CHECK_EQUAL(zone->size(), 3U); |
562c1c1d | 42 | zone->addNSIPTrigger(Netmask(nsIP, 31), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::NSIP)); |
690b86b7 | 43 | BOOST_CHECK_EQUAL(zone->size(), 4U); |
d96f1e86 | 44 | zone->addNSTrigger(nsName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::NSDName)); |
690b86b7 | 45 | BOOST_CHECK_EQUAL(zone->size(), 5U); |
d96f1e86 | 46 | zone->addNSTrigger(nsWildcardName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::NSDName)); |
690b86b7 | 47 | BOOST_CHECK_EQUAL(zone->size(), 6U); |
562c1c1d | 48 | zone->addResponseTrigger(Netmask(responseIP, 31), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::ResponseIP)); |
690b86b7 | 49 | BOOST_CHECK_EQUAL(zone->size(), 7U); |
6da513b2 RG |
50 | |
51 | size_t zoneIdx = dfe.addZone(zone); | |
52 | ||
690b86b7 | 53 | BOOST_CHECK_EQUAL(dfe.size(), 1U); |
6da513b2 RG |
54 | BOOST_CHECK(dfe.getZone(zoneName) == zone); |
55 | BOOST_CHECK(dfe.getZone(zoneIdx) == zone); | |
56 | ||
57 | dfe.setZone(zoneIdx, zone); | |
58 | ||
690b86b7 | 59 | BOOST_CHECK_EQUAL(dfe.size(), 1U); |
6da513b2 RG |
60 | BOOST_CHECK(dfe.getZone(zoneName) == zone); |
61 | BOOST_CHECK(dfe.getZone(zoneIdx) == zone); | |
62 | ||
63 | { | |
64 | /* blocked NS name */ | |
e37e5795 | 65 | auto matchingPolicy = dfe.getProcessingPolicy(nsName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
66 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::NSDName); |
67 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop); | |
d96f1e86 | 68 | |
6da513b2 | 69 | DNSFilterEngine::Policy zonePolicy; |
d96f1e86 RG |
70 | BOOST_CHECK(zone->findExactNSPolicy(nsName, zonePolicy)); |
71 | BOOST_CHECK(zonePolicy == matchingPolicy); | |
72 | ||
73 | /* but a subdomain should not be blocked (not a wildcard, and this is not suffix domain matching */ | |
e37e5795 | 74 | matchingPolicy = dfe.getProcessingPolicy(DNSName("sub") + nsName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
d96f1e86 RG |
75 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
76 | BOOST_CHECK(zone->findExactNSPolicy(DNSName("sub") + nsName, zonePolicy) == false); | |
77 | } | |
78 | ||
79 | { | |
80 | /* blocked NS name via wildcard */ | |
e37e5795 | 81 | const auto matchingPolicy = dfe.getProcessingPolicy(DNSName("sub.sub.wildcard.wolf."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
d96f1e86 RG |
82 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::NSDName); |
83 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop); | |
562c1c1d O |
84 | BOOST_CHECK_EQUAL(matchingPolicy.d_trigger, DNSName("*.wildcard.wolf.rpz-nsdname")); |
85 | BOOST_CHECK_EQUAL(matchingPolicy.d_hit, "sub.sub.wildcard.wolf"); | |
d96f1e86 RG |
86 | |
87 | /* looking for wildcard.wolf. should not match *.wildcard-blocked. */ | |
e37e5795 | 88 | const auto notMatchingPolicy = dfe.getProcessingPolicy(DNSName("wildcard.wolf."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
d96f1e86 RG |
89 | BOOST_CHECK(notMatchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
90 | ||
91 | /* a direct lookup would not match */ | |
92 | DNSFilterEngine::Policy zonePolicy; | |
93 | BOOST_CHECK(zone->findExactNSPolicy(DNSName("sub.sub.wildcard.wolf."), zonePolicy) == false); | |
94 | /* except if we look exactly for the wildcard */ | |
95 | BOOST_CHECK(zone->findExactNSPolicy(nsWildcardName, zonePolicy)); | |
6da513b2 | 96 | BOOST_CHECK(zonePolicy == matchingPolicy); |
562c1c1d O |
97 | BOOST_CHECK_EQUAL(zonePolicy.d_trigger, DNSName("*.wildcard.wolf.rpz-nsdname")); |
98 | BOOST_CHECK_EQUAL(zonePolicy.d_hit, nsWildcardName.toStringNoDot()); | |
6da513b2 RG |
99 | } |
100 | ||
101 | { | |
102 | /* allowed NS name */ | |
e37e5795 | 103 | const auto matchingPolicy = dfe.getProcessingPolicy(DNSName("ns.bad.rabbit."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
104 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
105 | DNSFilterEngine::Policy zonePolicy; | |
d96f1e86 | 106 | BOOST_CHECK(zone->findExactNSPolicy(DNSName("ns.bad.rabbit."), zonePolicy) == false); |
6da513b2 RG |
107 | } |
108 | ||
109 | { | |
110 | /* blocked NS IP */ | |
e37e5795 | 111 | const auto matchingPolicy = dfe.getProcessingPolicy(nsIP, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
112 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::NSIP); |
113 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop); | |
114 | DNSFilterEngine::Policy zonePolicy; | |
562c1c1d | 115 | BOOST_CHECK(zone->findNSIPPolicy(nsIP, zonePolicy)); |
6da513b2 | 116 | BOOST_CHECK(zonePolicy == matchingPolicy); |
562c1c1d | 117 | BOOST_CHECK_EQUAL(zonePolicy.d_trigger, DNSName("31.0.2.0.192.rpz-nsip")); |
f9de1f7f | 118 | BOOST_CHECK_EQUAL(zonePolicy.d_hit, nsIP.toString()); |
6da513b2 RG |
119 | } |
120 | ||
121 | { | |
122 | /* allowed NS IP */ | |
e37e5795 | 123 | const auto matchingPolicy = dfe.getProcessingPolicy(ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
124 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
125 | DNSFilterEngine::Policy zonePolicy; | |
562c1c1d | 126 | BOOST_CHECK(zone->findNSIPPolicy(ComboAddress("192.0.2.142"), zonePolicy) == false); |
6da513b2 RG |
127 | } |
128 | ||
129 | { | |
130 | /* blocked qname */ | |
baaed53b | 131 | auto matchingPolicy = dfe.getQueryPolicy(blockedName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
132 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
133 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop); | |
134 | DNSFilterEngine::Policy zonePolicy; | |
d96f1e86 RG |
135 | BOOST_CHECK(zone->findExactQNamePolicy(blockedName, zonePolicy)); |
136 | BOOST_CHECK(zonePolicy == matchingPolicy); | |
562c1c1d O |
137 | BOOST_CHECK_EQUAL(zonePolicy.d_trigger, blockedName); |
138 | BOOST_CHECK_EQUAL(zonePolicy.d_hit, blockedName.toStringNoDot()); | |
d96f1e86 RG |
139 | |
140 | /* but a subdomain should not be blocked (not a wildcard, and this is not suffix domain matching */ | |
baaed53b | 141 | matchingPolicy = dfe.getQueryPolicy(DNSName("sub") + blockedName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
d96f1e86 RG |
142 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
143 | BOOST_CHECK(zone->findExactQNamePolicy(DNSName("sub") + blockedName, zonePolicy) == false); | |
144 | } | |
145 | ||
146 | { | |
147 | /* blocked NS name via wildcard */ | |
baaed53b | 148 | const auto matchingPolicy = dfe.getQueryPolicy(DNSName("sub.sub.wildcard-blocked."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
d96f1e86 RG |
149 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
150 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop); | |
562c1c1d O |
151 | BOOST_CHECK_EQUAL(matchingPolicy.d_trigger, blockedWildcardName); |
152 | BOOST_CHECK_EQUAL(matchingPolicy.d_hit, "sub.sub.wildcard-blocked"); | |
d96f1e86 RG |
153 | |
154 | /* looking for wildcard-blocked. should not match *.wildcard-blocked. */ | |
baaed53b | 155 | const auto notMatchingPolicy = dfe.getQueryPolicy(DNSName("wildcard-blocked."), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
d96f1e86 RG |
156 | BOOST_CHECK(notMatchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
157 | ||
158 | /* a direct lookup would not match */ | |
159 | DNSFilterEngine::Policy zonePolicy; | |
160 | BOOST_CHECK(zone->findExactQNamePolicy(DNSName("sub.sub.wildcard-blocked."), zonePolicy) == false); | |
161 | /* except if we look exactly for the wildcard */ | |
162 | BOOST_CHECK(zone->findExactQNamePolicy(blockedWildcardName, zonePolicy)); | |
6da513b2 | 163 | BOOST_CHECK(zonePolicy == matchingPolicy); |
562c1c1d O |
164 | BOOST_CHECK_EQUAL(zonePolicy.d_trigger, blockedWildcardName); |
165 | BOOST_CHECK_EQUAL(zonePolicy.d_hit, blockedWildcardName.toStringNoDot()); | |
6da513b2 RG |
166 | } |
167 | ||
168 | { | |
169 | /* blocked client IP */ | |
baaed53b | 170 | const auto matchingPolicy = dfe.getClientPolicy(clientIP, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
171 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ClientIP); |
172 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop); | |
173 | DNSFilterEngine::Policy zonePolicy; | |
562c1c1d | 174 | BOOST_CHECK(zone->findClientPolicy(clientIP, zonePolicy)); |
6da513b2 | 175 | BOOST_CHECK(zonePolicy == matchingPolicy); |
562c1c1d | 176 | BOOST_CHECK_EQUAL(zonePolicy.d_trigger, DNSName("31.128.2.0.192.rpz-client-ip")); |
f9de1f7f | 177 | BOOST_CHECK_EQUAL(zonePolicy.d_hit, clientIP.toString()); |
6da513b2 RG |
178 | } |
179 | ||
180 | { | |
181 | /* not blocked */ | |
baaed53b | 182 | const auto matchingPolicy = dfe.getClientPolicy(ComboAddress("192.0.2.142"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
183 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
184 | DNSFilterEngine::Policy zonePolicy; | |
562c1c1d | 185 | BOOST_CHECK(zone->findClientPolicy(ComboAddress("192.0.2.142"), zonePolicy) == false); |
d96f1e86 | 186 | BOOST_CHECK(zone->findExactQNamePolicy(DNSName("totally.legit."), zonePolicy) == false); |
6da513b2 RG |
187 | } |
188 | ||
189 | { | |
190 | /* blocked A */ | |
191 | DNSRecord dr; | |
192 | dr.d_type = QType::A; | |
d525b58b | 193 | dr.setContent(DNSRecordContent::make(QType::A, QClass::IN, responseIP.toString())); |
e37e5795 | 194 | const auto matchingPolicy = dfe.getPostPolicy({dr}, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
195 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ResponseIP); |
196 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop); | |
197 | DNSFilterEngine::Policy zonePolicy; | |
562c1c1d | 198 | BOOST_CHECK(zone->findResponsePolicy(responseIP, zonePolicy)); |
6da513b2 | 199 | BOOST_CHECK(zonePolicy == matchingPolicy); |
562c1c1d | 200 | BOOST_CHECK_EQUAL(zonePolicy.d_trigger, DNSName("31.254.2.0.192.rpz-ip")); |
f9de1f7f | 201 | BOOST_CHECK_EQUAL(zonePolicy.d_hit, responseIP.toString()); |
6da513b2 RG |
202 | } |
203 | ||
204 | { | |
205 | /* allowed A */ | |
206 | DNSRecord dr; | |
207 | dr.d_type = QType::A; | |
d525b58b | 208 | dr.setContent(DNSRecordContent::make(QType::A, QClass::IN, "192.0.2.142")); |
e37e5795 | 209 | const auto matchingPolicy = dfe.getPostPolicy({dr}, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
210 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
211 | DNSFilterEngine::Policy zonePolicy; | |
562c1c1d | 212 | BOOST_CHECK(zone->findResponsePolicy(ComboAddress("192.0.2.142"), zonePolicy) == false); |
6da513b2 RG |
213 | } |
214 | ||
690b86b7 | 215 | BOOST_CHECK_EQUAL(zone->size(), 7U); |
562c1c1d | 216 | zone->rmClientTrigger(Netmask(clientIP, 31), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::ClientIP)); |
690b86b7 | 217 | BOOST_CHECK_EQUAL(zone->size(), 6U); |
6da513b2 | 218 | zone->rmQNameTrigger(blockedName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::QName)); |
690b86b7 | 219 | BOOST_CHECK_EQUAL(zone->size(), 5U); |
d96f1e86 | 220 | zone->rmQNameTrigger(blockedWildcardName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::QName)); |
690b86b7 | 221 | BOOST_CHECK_EQUAL(zone->size(), 4U); |
562c1c1d | 222 | zone->rmNSIPTrigger(Netmask(nsIP, 31), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::NSIP)); |
690b86b7 | 223 | BOOST_CHECK_EQUAL(zone->size(), 3U); |
6da513b2 | 224 | zone->rmNSTrigger(nsName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::NSDName)); |
690b86b7 | 225 | BOOST_CHECK_EQUAL(zone->size(), 2U); |
d96f1e86 | 226 | zone->rmNSTrigger(nsWildcardName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::NSDName)); |
690b86b7 | 227 | BOOST_CHECK_EQUAL(zone->size(), 1U); |
562c1c1d | 228 | zone->rmResponseTrigger(Netmask(responseIP, 31), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, DNSFilterEngine::PolicyType::ResponseIP)); |
690b86b7 | 229 | BOOST_CHECK_EQUAL(zone->size(), 0U); |
6da513b2 RG |
230 | |
231 | /* DNSFilterEngine::clear() calls clear() on all zones, but keeps the zones */ | |
232 | dfe.clear(); | |
690b86b7 | 233 | BOOST_CHECK_EQUAL(dfe.size(), 1U); |
6da513b2 RG |
234 | BOOST_CHECK(dfe.getZone(zoneName) == zone); |
235 | BOOST_CHECK(dfe.getZone(zoneIdx) == zone); | |
236 | } | |
237 | ||
42dcf516 OM |
238 | BOOST_AUTO_TEST_CASE(test_filter_policies_wildcard_with_enc) |
239 | { | |
164874e0 | 240 | DNSFilterEngine dfe; |
42dcf516 | 241 | |
164874e0 OM |
242 | std::string zoneName("Unit test policy wc"); |
243 | auto zone = std::make_shared<DNSFilterEngine::Zone>(); | |
244 | zone->setName(zoneName); | |
245 | zone->setDomain(DNSName("powerdns.com.")); | |
246 | zone->setSerial(42); | |
247 | zone->setRefresh(99); | |
248 | ||
249 | zone->addQNameTrigger(DNSName("bcbsks.com.102.112.2o7.net."), | |
7ca490f0 O |
250 | DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::NoAction, |
251 | DNSFilterEngine::PolicyType::QName)); | |
164874e0 | 252 | zone->addQNameTrigger(DNSName("2o7.net."), |
7ca490f0 O |
253 | DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, |
254 | DNSFilterEngine::PolicyType::QName)); | |
164874e0 | 255 | zone->addQNameTrigger(DNSName("*.2o7.net."), |
7ca490f0 O |
256 | DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Drop, |
257 | DNSFilterEngine::PolicyType::QName)); | |
164874e0 OM |
258 | |
259 | dfe.addZone(zone); | |
260 | ||
261 | ComboAddress address("192.0.2.142"); | |
42dcf516 | 262 | |
164874e0 OM |
263 | { |
264 | const DNSName tstName("bcbsks.com.102.112.2o7.net."); | |
baaed53b | 265 | auto matchingPolicy = dfe.getQueryPolicy(tstName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
164874e0 OM |
266 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
267 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction); | |
268 | } | |
269 | ||
270 | { | |
271 | const DNSName tstName("2o7.net."); | |
baaed53b | 272 | auto matchingPolicy = dfe.getQueryPolicy(tstName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
164874e0 OM |
273 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
274 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop); | |
275 | } | |
276 | ||
83665159 | 277 | // Once fixed the BOOST_WARN should becomes BOOST_CHECK |
d2205b89 | 278 | const string m("Please fix issue #8231"); |
42dcf516 | 279 | |
164874e0 OM |
280 | { |
281 | const DNSName tstName("112.2o7.net."); | |
baaed53b | 282 | auto matchingPolicy = dfe.getQueryPolicy(tstName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
83665159 OM |
283 | BOOST_WARN_MESSAGE(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None, m); |
284 | BOOST_WARN_MESSAGE(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction, m); | |
164874e0 | 285 | } |
42dcf516 | 286 | |
164874e0 OM |
287 | { |
288 | const DNSName tstName("102.112.2o7.net."); | |
baaed53b | 289 | auto matchingPolicy = dfe.getQueryPolicy(tstName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
83665159 OM |
290 | BOOST_WARN_MESSAGE(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None, m); |
291 | BOOST_WARN_MESSAGE(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction, m); | |
164874e0 OM |
292 | } |
293 | ||
294 | { | |
295 | const DNSName tstName("com.112.2o7.net."); | |
baaed53b | 296 | auto matchingPolicy = dfe.getQueryPolicy(tstName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
83665159 OM |
297 | BOOST_WARN_MESSAGE(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None, m); |
298 | BOOST_WARN_MESSAGE(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction, m); | |
164874e0 | 299 | } |
42dcf516 | 300 | |
164874e0 OM |
301 | { |
302 | const DNSName tstName("wcmatch.2o7.net."); | |
baaed53b | 303 | auto matchingPolicy = dfe.getQueryPolicy(tstName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
164874e0 OM |
304 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
305 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Drop); | |
306 | } | |
164874e0 OM |
307 | } |
308 | ||
42dcf516 OM |
309 | BOOST_AUTO_TEST_CASE(test_filter_policies_local_data) |
310 | { | |
6da513b2 RG |
311 | DNSFilterEngine dfe; |
312 | ||
313 | std::string zoneName("Unit test policy local data"); | |
314 | auto zone = std::make_shared<DNSFilterEngine::Zone>(); | |
315 | zone->setName(zoneName); | |
316 | ||
317 | const DNSName bad1("bad1.example.com."); | |
318 | const DNSName bad2("bad2.example.com."); | |
319 | ||
d525b58b | 320 | zone->addQNameTrigger(bad1, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "garden.example.net.")})); |
690b86b7 | 321 | BOOST_CHECK_EQUAL(zone->size(), 1U); |
6da513b2 | 322 | |
d525b58b | 323 | zone->addQNameTrigger(bad2, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "192.0.2.1")})); |
690b86b7 | 324 | BOOST_CHECK_EQUAL(zone->size(), 2U); |
6da513b2 | 325 | |
d525b58b | 326 | zone->addQNameTrigger(bad2, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "192.0.2.2")})); |
690b86b7 | 327 | BOOST_CHECK_EQUAL(zone->size(), 2U); |
6da513b2 | 328 | |
d525b58b | 329 | zone->addQNameTrigger(bad2, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::MX, QClass::IN, "10 garden-mail.example.net.")})); |
690b86b7 | 330 | BOOST_CHECK_EQUAL(zone->size(), 2U); |
6da513b2 RG |
331 | |
332 | dfe.addZone(zone); | |
333 | ||
334 | { | |
335 | /* exact type does not exist, but we have a CNAME */ | |
baaed53b | 336 | const auto matchingPolicy = dfe.getQueryPolicy(bad1, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
337 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
338 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
339 | auto records = matchingPolicy.getCustomRecords(bad1, QType::A); | |
690b86b7 | 340 | BOOST_CHECK_EQUAL(records.size(), 1U); |
6da513b2 RG |
341 | const auto& record = records.at(0); |
342 | BOOST_CHECK(record.d_type == QType::CNAME); | |
343 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 344 | auto content = getRR<CNAMERecordContent>(record); |
6da513b2 RG |
345 | BOOST_CHECK(content != nullptr); |
346 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "garden.example.net."); | |
347 | } | |
348 | ||
349 | { | |
350 | /* exact type exists */ | |
baaed53b | 351 | const auto matchingPolicy = dfe.getQueryPolicy(bad2, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
352 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
353 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
354 | ||
355 | { | |
356 | auto records = matchingPolicy.getCustomRecords(bad2, QType::A); | |
690b86b7 | 357 | BOOST_REQUIRE_EQUAL(records.size(), 2U); |
6da513b2 RG |
358 | { |
359 | const auto& record = records.at(0); | |
360 | BOOST_CHECK(record.d_type == QType::A); | |
361 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 362 | auto content = getRR<ARecordContent>(record); |
6da513b2 RG |
363 | BOOST_CHECK(content != nullptr); |
364 | BOOST_CHECK_EQUAL(content->getCA().toString(), "192.0.2.1"); | |
365 | } | |
366 | { | |
367 | const auto& record = records.at(1); | |
368 | BOOST_CHECK(record.d_type == QType::A); | |
369 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 370 | auto content = getRR<ARecordContent>(record); |
6da513b2 RG |
371 | BOOST_CHECK(content != nullptr); |
372 | BOOST_CHECK_EQUAL(content->getCA().toString(), "192.0.2.2"); | |
373 | } | |
374 | } | |
375 | ||
376 | { | |
377 | auto records = matchingPolicy.getCustomRecords(bad2, QType::MX); | |
690b86b7 | 378 | BOOST_CHECK_EQUAL(records.size(), 1U); |
6da513b2 RG |
379 | const auto& record = records.at(0); |
380 | BOOST_CHECK(record.d_type == QType::MX); | |
381 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 382 | auto content = getRR<MXRecordContent>(record); |
6da513b2 RG |
383 | BOOST_CHECK(content != nullptr); |
384 | BOOST_CHECK_EQUAL(content->d_mxname.toString(), "garden-mail.example.net."); | |
385 | } | |
386 | ||
387 | { | |
388 | /* the name exists but there is no CNAME nor matching type, so NODATA */ | |
389 | auto records = matchingPolicy.getCustomRecords(bad2, QType::AAAA); | |
690b86b7 | 390 | BOOST_CHECK_EQUAL(records.size(), 0U); |
6da513b2 RG |
391 | } |
392 | } | |
393 | ||
394 | /* remove only one entry, one of the A local records */ | |
d525b58b | 395 | zone->rmQNameTrigger(bad2, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "192.0.2.1")})); |
690b86b7 | 396 | BOOST_CHECK_EQUAL(zone->size(), 2U); |
6da513b2 RG |
397 | |
398 | { | |
399 | /* exact type exists */ | |
baaed53b | 400 | const auto matchingPolicy = dfe.getQueryPolicy(bad2, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
401 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
402 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
403 | ||
404 | { | |
405 | auto records = matchingPolicy.getCustomRecords(bad2, QType::A); | |
690b86b7 | 406 | BOOST_REQUIRE_EQUAL(records.size(), 1U); |
6da513b2 RG |
407 | { |
408 | const auto& record = records.at(0); | |
409 | BOOST_CHECK(record.d_type == QType::A); | |
410 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 411 | auto content = getRR<ARecordContent>(record); |
6da513b2 RG |
412 | BOOST_CHECK(content != nullptr); |
413 | BOOST_CHECK_EQUAL(content->getCA().toString(), "192.0.2.2"); | |
414 | } | |
415 | } | |
416 | ||
417 | { | |
418 | auto records = matchingPolicy.getCustomRecords(bad2, QType::MX); | |
690b86b7 | 419 | BOOST_CHECK_EQUAL(records.size(), 1U); |
6da513b2 RG |
420 | const auto& record = records.at(0); |
421 | BOOST_CHECK(record.d_type == QType::MX); | |
422 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 423 | auto content = getRR<MXRecordContent>(record); |
6da513b2 RG |
424 | BOOST_CHECK(content != nullptr); |
425 | BOOST_CHECK_EQUAL(content->d_mxname.toString(), "garden-mail.example.net."); | |
426 | } | |
427 | ||
428 | { | |
429 | /* the name exists but there is no CNAME nor matching type, so NODATA */ | |
430 | auto records = matchingPolicy.getCustomRecords(bad2, QType::AAAA); | |
690b86b7 | 431 | BOOST_CHECK_EQUAL(records.size(), 0U); |
6da513b2 RG |
432 | } |
433 | } | |
434 | } | |
435 | ||
f6a28268 OM |
436 | BOOST_AUTO_TEST_CASE(test_filter_policies_local_data_netmask) |
437 | { | |
438 | DNSFilterEngine dfe; | |
439 | ||
440 | std::string zoneName("Unit test policy local data using netmasks"); | |
441 | auto zone = std::make_shared<DNSFilterEngine::Zone>(); | |
442 | zone->setName(zoneName); | |
443 | ||
444 | const DNSName name("foo.example.com"); | |
445 | const Netmask nm1("192.168.1.0/24"); | |
446 | ||
d525b58b KM |
447 | zone->addClientTrigger(nm1, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "1.2.3.4")})); |
448 | zone->addClientTrigger(nm1, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "1.2.3.5")})); | |
449 | zone->addClientTrigger(nm1, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::AAAA, QClass::IN, "::1234")})); | |
f6a28268 OM |
450 | BOOST_CHECK_EQUAL(zone->size(), 1U); |
451 | ||
452 | dfe.addZone(zone); | |
453 | ||
454 | { // A query should match two records | |
baaed53b | 455 | const auto matchingPolicy = dfe.getClientPolicy(ComboAddress("192.168.1.1"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
f6a28268 OM |
456 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ClientIP); |
457 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
458 | auto records = matchingPolicy.getCustomRecords(DNSName(), QType::A); | |
459 | BOOST_CHECK_EQUAL(records.size(), 2U); | |
460 | const auto& record1 = records.at(0); | |
461 | BOOST_CHECK(record1.d_type == QType::A); | |
462 | BOOST_CHECK(record1.d_class == QClass::IN); | |
d06dcda4 | 463 | auto content1 = getRR<ARecordContent>(record1); |
f6a28268 OM |
464 | BOOST_CHECK(content1 != nullptr); |
465 | BOOST_CHECK_EQUAL(content1->getCA().toString(), "1.2.3.4"); | |
466 | ||
467 | const auto& record2 = records.at(1); | |
468 | BOOST_CHECK(record2.d_type == QType::A); | |
469 | BOOST_CHECK(record2.d_class == QClass::IN); | |
d06dcda4 | 470 | auto content2 = getRR<ARecordContent>(record2); |
f6a28268 OM |
471 | BOOST_CHECK(content2 != nullptr); |
472 | BOOST_CHECK_EQUAL(content2->getCA().toString(), "1.2.3.5"); | |
473 | } | |
474 | ||
475 | { // AAAA query should match 1 record | |
baaed53b | 476 | const auto matchingPolicy = dfe.getClientPolicy(ComboAddress("192.168.1.1"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
f6a28268 OM |
477 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ClientIP); |
478 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
479 | auto records = matchingPolicy.getCustomRecords(DNSName(), QType::AAAA); | |
480 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
481 | const auto& record1 = records.at(0); | |
482 | BOOST_CHECK(record1.d_type == QType::AAAA); | |
483 | BOOST_CHECK(record1.d_class == QClass::IN); | |
d06dcda4 | 484 | auto content1 = getRR<AAAARecordContent>(record1); |
f6a28268 OM |
485 | BOOST_CHECK(content1 != nullptr); |
486 | BOOST_CHECK_EQUAL(content1->getCA().toString(), "::1234"); | |
487 | } | |
488 | ||
489 | // Try to zap 1 nonexisting record | |
d525b58b | 490 | zone->rmClientTrigger(nm1, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "1.1.1.1")})); |
f6a28268 OM |
491 | |
492 | // Zap a record using a wider netmask | |
d525b58b | 493 | zone->rmClientTrigger(Netmask("192.168.0.0/16"), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "1.2.3.4")})); |
f6a28268 OM |
494 | |
495 | // Zap a record using a narrow netmask | |
d525b58b | 496 | zone->rmClientTrigger(Netmask("192.168.1.1/32"), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "1.2.3.4")})); |
f6a28268 OM |
497 | |
498 | // Zap 1 existing record | |
d525b58b | 499 | zone->rmClientTrigger(nm1, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "1.2.3.5")})); |
f6a28268 OM |
500 | |
501 | { // A query should match one record now | |
baaed53b | 502 | const auto matchingPolicy = dfe.getClientPolicy(ComboAddress("192.168.1.1"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
f6a28268 OM |
503 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ClientIP); |
504 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
505 | auto records = matchingPolicy.getCustomRecords(DNSName(), QType::A); | |
506 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
507 | const auto& record1 = records.at(0); | |
508 | BOOST_CHECK(record1.d_type == QType::A); | |
509 | BOOST_CHECK(record1.d_class == QClass::IN); | |
d06dcda4 | 510 | auto content1 = getRR<ARecordContent>(record1); |
f6a28268 OM |
511 | BOOST_CHECK(content1 != nullptr); |
512 | BOOST_CHECK_EQUAL(content1->getCA().toString(), "1.2.3.4"); | |
513 | } | |
514 | { // AAAA query should still match one record | |
baaed53b | 515 | const auto matchingPolicy = dfe.getClientPolicy(ComboAddress("192.168.1.1"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
f6a28268 OM |
516 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ClientIP); |
517 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
518 | auto records = matchingPolicy.getCustomRecords(DNSName(), QType::AAAA); | |
519 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
520 | const auto& record1 = records.at(0); | |
521 | BOOST_CHECK(record1.d_type == QType::AAAA); | |
522 | BOOST_CHECK(record1.d_class == QClass::IN); | |
d06dcda4 | 523 | auto content1 = getRR<AAAARecordContent>(record1); |
f6a28268 OM |
524 | BOOST_CHECK(content1 != nullptr); |
525 | BOOST_CHECK_EQUAL(content1->getCA().toString(), "::1234"); | |
526 | } | |
527 | ||
528 | // Zap one more A record | |
d525b58b | 529 | zone->rmClientTrigger(nm1, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "1.2.3.4")})); |
f6a28268 OM |
530 | |
531 | // Zap now nonexisting record | |
d525b58b | 532 | zone->rmClientTrigger(nm1, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::A, QClass::IN, "1.2.3.4")})); |
f6a28268 OM |
533 | |
534 | { // AAAA query should still match one record | |
baaed53b | 535 | const auto matchingPolicy = dfe.getClientPolicy(ComboAddress("192.168.1.1"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
f6a28268 OM |
536 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ClientIP); |
537 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
538 | auto records = matchingPolicy.getCustomRecords(DNSName(), QType::AAAA); | |
539 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
540 | const auto& record1 = records.at(0); | |
541 | BOOST_CHECK(record1.d_type == QType::AAAA); | |
542 | BOOST_CHECK(record1.d_class == QClass::IN); | |
d06dcda4 | 543 | auto content1 = getRR<AAAARecordContent>(record1); |
f6a28268 OM |
544 | BOOST_CHECK(content1 != nullptr); |
545 | BOOST_CHECK_EQUAL(content1->getCA().toString(), "::1234"); | |
546 | } | |
547 | ||
548 | // Zap AAAA record | |
d525b58b | 549 | zone->rmClientTrigger(nm1, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::AAAA, QClass::IN, "::1234")})); |
f6a28268 OM |
550 | |
551 | { // there should be no match left | |
baaed53b | 552 | const auto matchingPolicy = dfe.getClientPolicy(ComboAddress("192.168.1.1"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
f6a28268 OM |
553 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
554 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction); | |
555 | } | |
f6a28268 OM |
556 | } |
557 | ||
42dcf516 OM |
558 | BOOST_AUTO_TEST_CASE(test_multiple_filter_policies) |
559 | { | |
6da513b2 RG |
560 | DNSFilterEngine dfe; |
561 | ||
562 | auto zone1 = std::make_shared<DNSFilterEngine::Zone>(); | |
563 | zone1->setName("Unit test policy 0"); | |
564 | ||
565 | auto zone2 = std::make_shared<DNSFilterEngine::Zone>(); | |
566 | zone2->setName("Unit test policy 1"); | |
567 | ||
568 | const DNSName bad("bad.example.com."); | |
06cfa23f RG |
569 | const DNSName badWildcard("*.bad-wildcard.example.com."); |
570 | const DNSName badUnderWildcard("sub.bad-wildcard.example.com."); | |
6da513b2 | 571 | |
d525b58b KM |
572 | zone1->addQNameTrigger(bad, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "garden1a.example.net.")})); |
573 | zone2->addQNameTrigger(bad, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "garden2a.example.net.")})); | |
574 | zone1->addQNameTrigger(badWildcard, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "garden1b.example.net.")})); | |
575 | zone2->addQNameTrigger(badUnderWildcard, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "garden2b.example.net.")})); | |
6da513b2 RG |
576 | |
577 | dfe.addZone(zone1); | |
578 | dfe.addZone(zone2); | |
579 | ||
580 | { | |
581 | /* zone 1 should match first */ | |
baaed53b | 582 | const auto matchingPolicy = dfe.getQueryPolicy(bad, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
6da513b2 RG |
583 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
584 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
585 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
690b86b7 | 586 | BOOST_CHECK_EQUAL(records.size(), 1U); |
6da513b2 RG |
587 | const auto& record = records.at(0); |
588 | BOOST_CHECK(record.d_type == QType::CNAME); | |
589 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 590 | auto content = getRR<CNAMERecordContent>(record); |
06cfa23f | 591 | BOOST_CHECK(content != nullptr); |
f1ff3d4f | 592 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "garden1a.example.net."); |
06cfa23f RG |
593 | } |
594 | ||
595 | { | |
596 | /* zone 2 has an exact match for badUnderWildcard, but the wildcard from the first zone should match first */ | |
baaed53b | 597 | const auto matchingPolicy = dfe.getQueryPolicy(badUnderWildcard, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
06cfa23f RG |
598 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
599 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
600 | auto records = matchingPolicy.getCustomRecords(badUnderWildcard, QType::A); | |
601 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
602 | const auto& record = records.at(0); | |
603 | BOOST_CHECK(record.d_type == QType::CNAME); | |
604 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 605 | auto content = getRR<CNAMERecordContent>(record); |
6da513b2 | 606 | BOOST_CHECK(content != nullptr); |
f1ff3d4f | 607 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "garden1b.example.net."); |
6da513b2 RG |
608 | } |
609 | ||
610 | { | |
611 | /* zone 1 should still match if zone 2 has been disabled */ | |
baaed53b | 612 | const auto matchingPolicy = dfe.getQueryPolicy(bad, {{zone2->getName(), true}}, DNSFilterEngine::maximumPriority); |
6da513b2 RG |
613 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
614 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
615 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
690b86b7 | 616 | BOOST_CHECK_EQUAL(records.size(), 1U); |
6da513b2 RG |
617 | const auto& record = records.at(0); |
618 | BOOST_CHECK(record.d_type == QType::CNAME); | |
619 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 620 | auto content = getRR<CNAMERecordContent>(record); |
6da513b2 | 621 | BOOST_CHECK(content != nullptr); |
f1ff3d4f | 622 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "garden1a.example.net."); |
6da513b2 RG |
623 | } |
624 | ||
625 | { | |
626 | /* if zone 1 is disabled, zone 2 should match */ | |
baaed53b | 627 | const auto matchingPolicy = dfe.getQueryPolicy(bad, {{zone1->getName(), true}}, DNSFilterEngine::maximumPriority); |
6da513b2 RG |
628 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
629 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
630 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
690b86b7 | 631 | BOOST_CHECK_EQUAL(records.size(), 1U); |
6da513b2 RG |
632 | const auto& record = records.at(0); |
633 | BOOST_CHECK(record.d_type == QType::CNAME); | |
634 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 635 | auto content = getRR<CNAMERecordContent>(record); |
6da513b2 | 636 | BOOST_CHECK(content != nullptr); |
f1ff3d4f | 637 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "garden2a.example.net."); |
6da513b2 RG |
638 | } |
639 | ||
640 | { | |
641 | /* if both zones are disabled, we should not match */ | |
baaed53b | 642 | const auto matchingPolicy = dfe.getQueryPolicy(bad, {{zone1->getName(), true}, {zone2->getName(), true}}, DNSFilterEngine::maximumPriority); |
6da513b2 RG |
643 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
644 | } | |
6da513b2 | 645 | } |
d2205b89 RG |
646 | |
647 | BOOST_AUTO_TEST_CASE(test_multiple_filter_policies_order) | |
648 | { | |
649 | DNSFilterEngine dfe; | |
650 | ||
651 | auto zone1 = std::make_shared<DNSFilterEngine::Zone>(); | |
652 | zone1->setName("Unit test policy 0"); | |
653 | ||
654 | auto zone2 = std::make_shared<DNSFilterEngine::Zone>(); | |
655 | zone2->setName("Unit test policy 1"); | |
656 | ||
657 | const ComboAddress clientIP("192.0.2.128"); | |
658 | const DNSName bad("bad.example.com."); | |
659 | const ComboAddress nsIP("192.0.2.1"); | |
660 | const DNSName nsName("ns.bad.wolf."); | |
661 | const ComboAddress responseIP("192.0.2.254"); | |
662 | ||
d525b58b KM |
663 | zone1->addClientTrigger(Netmask(clientIP, 32), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "client1a.example.net.")})); |
664 | zone1->addQNameTrigger(bad, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "garden1a.example.net.")})); | |
665 | zone1->addNSIPTrigger(Netmask(nsIP, 32), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::NSIP, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "nsip1a.example.net.")})); | |
666 | zone1->addNSTrigger(nsName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::NSDName, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "nsname1a.example.net.")})); | |
667 | zone1->addResponseTrigger(Netmask(responseIP, 32), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ResponseIP, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "response1a.example.net.")})); | |
d2205b89 | 668 | |
d525b58b KM |
669 | zone2->addClientTrigger(Netmask(clientIP, 32), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ClientIP, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "client2a.example.net.")})); |
670 | zone2->addQNameTrigger(bad, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::QName, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "garden2a.example.net.")})); | |
671 | zone2->addNSIPTrigger(Netmask(nsIP, 32), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::NSIP, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "nsip2a.example.net.")})); | |
672 | zone2->addNSTrigger(nsName, DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::NSDName, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "nsname2a.example.net.")})); | |
673 | zone2->addResponseTrigger(Netmask(responseIP, 32), DNSFilterEngine::Policy(DNSFilterEngine::PolicyKind::Custom, DNSFilterEngine::PolicyType::ResponseIP, 0, nullptr, {DNSRecordContent::make(QType::CNAME, QClass::IN, "response2a.example.net.")})); | |
d2205b89 RG |
674 | |
675 | dfe.addZone(zone1); | |
676 | dfe.addZone(zone2); | |
677 | BOOST_CHECK_EQUAL(zone1->getPriority(), 0); | |
678 | BOOST_CHECK_EQUAL(zone2->getPriority(), 1); | |
679 | ||
680 | { | |
681 | /* client IP should match before qname */ | |
baaed53b | 682 | const auto matchingPolicy = dfe.getClientPolicy(ComboAddress("192.0.2.128"), std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
d2205b89 RG |
683 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ClientIP); |
684 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
685 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
686 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
687 | const auto& record = records.at(0); | |
688 | BOOST_CHECK(record.d_type == QType::CNAME); | |
689 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 690 | auto content = getRR<CNAMERecordContent>(record); |
d2205b89 RG |
691 | BOOST_CHECK(content != nullptr); |
692 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "client1a.example.net."); | |
693 | } | |
694 | ||
695 | { | |
696 | /* client IP and qname should match, but zone 1 is disabled and zone2's priority is too high */ | |
baaed53b | 697 | const auto matchingPolicy = dfe.getClientPolicy(ComboAddress("192.0.2.128"), {{zone1->getName(), true}}, 1); |
d2205b89 RG |
698 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
699 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction); | |
700 | } | |
701 | ||
702 | { | |
703 | /* zone 1 should match first */ | |
baaed53b | 704 | const auto matchingPolicy = dfe.getQueryPolicy(bad, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
d2205b89 RG |
705 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
706 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
707 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
708 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
709 | const auto& record = records.at(0); | |
710 | BOOST_CHECK(record.d_type == QType::CNAME); | |
711 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 712 | auto content = getRR<CNAMERecordContent>(record); |
d2205b89 RG |
713 | BOOST_CHECK(content != nullptr); |
714 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "garden1a.example.net."); | |
715 | } | |
716 | ||
717 | { | |
718 | /* zone 1 should still match if we require a priority < 1 */ | |
baaed53b | 719 | const auto matchingPolicy = dfe.getQueryPolicy(bad, std::unordered_map<std::string, bool>(), 1); |
d2205b89 RG |
720 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
721 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
722 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
723 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
724 | const auto& record = records.at(0); | |
725 | BOOST_CHECK(record.d_type == QType::CNAME); | |
726 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 727 | auto content = getRR<CNAMERecordContent>(record); |
d2205b89 RG |
728 | BOOST_CHECK(content != nullptr); |
729 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "garden1a.example.net."); | |
730 | } | |
731 | ||
732 | { | |
733 | /* nothing should match if we require a priority < 0 */ | |
baaed53b | 734 | const auto matchingPolicy = dfe.getQueryPolicy(bad, std::unordered_map<std::string, bool>(), 0); |
d2205b89 RG |
735 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
736 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction); | |
737 | } | |
738 | ||
739 | { | |
740 | /* if we disable zone 1, zone 2 should match */ | |
baaed53b | 741 | const auto matchingPolicy = dfe.getQueryPolicy(bad, {{zone1->getName(), true}}, DNSFilterEngine::maximumPriority); |
d2205b89 RG |
742 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::QName); |
743 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
744 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
745 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
746 | const auto& record = records.at(0); | |
747 | BOOST_CHECK(record.d_type == QType::CNAME); | |
748 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 749 | auto content = getRR<CNAMERecordContent>(record); |
d2205b89 RG |
750 | BOOST_CHECK(content != nullptr); |
751 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "garden2a.example.net."); | |
752 | } | |
753 | ||
754 | { | |
755 | /* if we disable zone 1, zone 2 should match, except if we require a priority < 1 */ | |
baaed53b | 756 | const auto matchingPolicy = dfe.getQueryPolicy(bad, {{zone1->getName(), true}}, 1); |
d2205b89 RG |
757 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
758 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction); | |
759 | } | |
760 | ||
761 | { | |
762 | /* blocked NS name */ | |
763 | auto matchingPolicy = dfe.getProcessingPolicy(nsName, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); | |
764 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::NSDName); | |
765 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
766 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
767 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
768 | const auto& record = records.at(0); | |
769 | BOOST_CHECK(record.d_type == QType::CNAME); | |
770 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 771 | auto content = getRR<CNAMERecordContent>(record); |
d2205b89 RG |
772 | BOOST_CHECK(content != nullptr); |
773 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "nsname1a.example.net."); | |
774 | } | |
775 | ||
776 | { | |
777 | /* blocked NS name, except policy 1 is disabled and policy2's priority is too high */ | |
b502d522 | 778 | auto matchingPolicy = dfe.getProcessingPolicy(nsName, {{zone1->getName(), true}}, 1); |
d2205b89 RG |
779 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
780 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction); | |
781 | } | |
782 | ||
783 | { | |
784 | /* blocked NS IP */ | |
785 | const auto matchingPolicy = dfe.getProcessingPolicy(nsIP, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); | |
786 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::NSIP); | |
787 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
788 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
789 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
790 | const auto& record = records.at(0); | |
791 | BOOST_CHECK(record.d_type == QType::CNAME); | |
792 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 793 | auto content = getRR<CNAMERecordContent>(record); |
d2205b89 RG |
794 | BOOST_CHECK(content != nullptr); |
795 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "nsip1a.example.net."); | |
796 | } | |
797 | ||
798 | { | |
799 | /* blocked NS ip, except policy 1 is disabled and policy2's priority is too high */ | |
b502d522 | 800 | auto matchingPolicy = dfe.getProcessingPolicy(nsIP, {{zone1->getName(), true}}, 1); |
d2205b89 RG |
801 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
802 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction); | |
803 | } | |
804 | ||
805 | { | |
806 | /* blocked A in the response */ | |
807 | DNSRecord dr; | |
808 | dr.d_type = QType::A; | |
d525b58b | 809 | dr.setContent(DNSRecordContent::make(QType::A, QClass::IN, responseIP.toString())); |
d2205b89 RG |
810 | const auto matchingPolicy = dfe.getPostPolicy({dr}, std::unordered_map<std::string, bool>(), DNSFilterEngine::maximumPriority); |
811 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::ResponseIP); | |
812 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom); | |
813 | auto records = matchingPolicy.getCustomRecords(bad, QType::A); | |
814 | BOOST_CHECK_EQUAL(records.size(), 1U); | |
815 | const auto& record = records.at(0); | |
816 | BOOST_CHECK(record.d_type == QType::CNAME); | |
817 | BOOST_CHECK(record.d_class == QClass::IN); | |
d06dcda4 | 818 | auto content = getRR<CNAMERecordContent>(record); |
d2205b89 RG |
819 | BOOST_CHECK(content != nullptr); |
820 | BOOST_CHECK_EQUAL(content->getTarget().toString(), "response1a.example.net."); | |
821 | } | |
822 | ||
823 | { | |
824 | /* blocked A in the response, except 1 is disabled and 2's priority is too high */ | |
825 | DNSRecord dr; | |
826 | dr.d_type = QType::A; | |
d525b58b | 827 | dr.setContent(DNSRecordContent::make(QType::A, QClass::IN, responseIP.toString())); |
b502d522 | 828 | const auto matchingPolicy = dfe.getPostPolicy({dr}, {{zone1->getName(), true}}, 1); |
d2205b89 RG |
829 | BOOST_CHECK(matchingPolicy.d_type == DNSFilterEngine::PolicyType::None); |
830 | BOOST_CHECK(matchingPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction); | |
831 | } | |
d2205b89 | 832 | } |
bbe6cfec PD |
833 | |
834 | BOOST_AUTO_TEST_CASE(test_mask_to_rpz) | |
835 | { | |
836 | BOOST_CHECK_EQUAL(DNSFilterEngine::Zone::maskToRPZ(Netmask("::2/127")).toString(), "127.2.zz."); | |
837 | BOOST_CHECK_EQUAL(DNSFilterEngine::Zone::maskToRPZ(Netmask("1::2/127")).toString(), "127.2.zz.1."); | |
838 | BOOST_CHECK_EQUAL(DNSFilterEngine::Zone::maskToRPZ(Netmask("2::/127")).toString(), "127.zz.2."); | |
839 | BOOST_CHECK_EQUAL(DNSFilterEngine::Zone::maskToRPZ(Netmask("1abc:2::/127")).toString(), "127.zz.2.1abc."); | |
840 | BOOST_CHECK_EQUAL(DNSFilterEngine::Zone::maskToRPZ(Netmask("1:2:3:4:5:6:7::/127")).toString(), "127.0.7.6.5.4.3.2.1."); | |
841 | BOOST_CHECK_EQUAL(DNSFilterEngine::Zone::maskToRPZ(Netmask("1:2:3:4:5:6::/127")).toString(), "127.zz.6.5.4.3.2.1."); | |
842 | BOOST_CHECK_EQUAL(DNSFilterEngine::Zone::maskToRPZ(Netmask("1:0:0:0:2:0:0:0/127")).toString(), "127.zz.2.0.0.0.1."); | |
0d70e98b PD |
843 | BOOST_CHECK_EQUAL(DNSFilterEngine::Zone::maskToRPZ(Netmask("1:0:0:2:0:0:0:0/127")).toString(), "127.zz.2.0.0.1."); |
844 | BOOST_CHECK_EQUAL(DNSFilterEngine::Zone::maskToRPZ(Netmask("1:0:0:0:0:2:0:0/127")).toString(), "127.0.0.2.zz.1."); | |
bbe6cfec | 845 | } |