]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/recursordist/test-filterpo_cc.cc
Merge pull request #13387 from omoerbeek/rec-b-root-servers
[thirdparty/pdns.git] / pdns / recursordist / test-filterpo_cc.cc
CommitLineData
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
13BOOST_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
238BOOST_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
309BOOST_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
436BOOST_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
558BOOST_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
647BOOST_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
834BOOST_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}