• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 12595591960

03 Jan 2025 09:27AM UTC coverage: 62.774% (+2.5%) from 60.245%
12595591960

Pull #15008

github

web-flow
Merge c2a2749d3 into 788f396a7
Pull Request #15008: Do not follow CNAME records for ANY or CNAME queries

30393 of 78644 branches covered (38.65%)

Branch coverage included in aggregate %.

105822 of 138350 relevant lines covered (76.49%)

4613078.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.43
/pdns/recursordist/test-syncres_cc7.cc
1
#ifndef BOOST_TEST_DYN_LINK
2
#define BOOST_TEST_DYN_LINK
3
#endif
4

5
#include <boost/test/unit_test.hpp>
6

7
#include "test-syncres_cc.hh"
8

9
BOOST_AUTO_TEST_SUITE(syncres_cc7)
10

11
BOOST_AUTO_TEST_CASE(test_dnssec_insecure_to_ta_skipped_cut)
12
{
2✔
13
  std::unique_ptr<SyncRes> sr;
2✔
14
  initSR(sr, true);
2✔
15

16
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
17

18
  primeHints();
2✔
19
  const DNSName target("www.sub.powerdns.com.");
2✔
20
  const ComboAddress targetAddr("192.0.2.42");
2✔
21
  testkeysset_t keys;
2✔
22

23
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
24
  luaconfsCopy.dsAnchors.clear();
2✔
25
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
26
  /* No key material for .com */
27
  /* But TA for sub.powerdns.com. */
28
  generateKeyMaterial(DNSName("sub.powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
29
  luaconfsCopy.dsAnchors[DNSName("sub.powerdns.com.")].insert(keys[DNSName("sub.powerdns.com.")].second);
2✔
30
  g_luaconfs.setState(luaconfsCopy);
2✔
31

32
  size_t queriesCount = 0;
2✔
33

34
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
10✔
35
    queriesCount++;
10✔
36

37
    if (type == QType::DS) {
10!
38
      if (domain == DNSName("www.sub.powerdns.com")) {
×
39
        setLWResult(res, 0, true, false, true);
×
40
        addRecordToLW(res, DNSName("sub.powerdns.com"), QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
41
        addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com"), 300);
×
42
        addNSECRecordToLW(DNSName("www.sub.powerdns.com"), DNSName("vww.sub.powerdns.com."), {QType::A}, 600, res->d_records);
×
43
        addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com"), 300);
×
44
      }
×
45
      else {
×
46
        setLWResult(res, 0, true, false, true);
×
47

48
        if (domain == DNSName("com.")) {
×
49
          addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
50
          addRRSIG(keys, res->d_records, DNSName("."), 300);
×
51
          /* no DS */
52
          addNSECRecordToLW(DNSName("com."), DNSName("dom."), {QType::NS}, 600, res->d_records);
×
53
          addRRSIG(keys, res->d_records, DNSName("."), 300);
×
54
        }
×
55
        else {
×
56
          setLWResult(res, 0, true, false, true);
×
57
          addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
58
        }
×
59
      }
×
60
      return LWResult::Result::Success;
×
61
    }
×
62
    if (type == QType::DNSKEY) {
10✔
63
      if (domain == g_rootdnsname || domain == DNSName("sub.powerdns.com.")) {
4!
64
        setLWResult(res, 0, true, false, true);
4✔
65
        addDNSKEY(keys, domain, 300, res->d_records);
4✔
66
        addRRSIG(keys, res->d_records, domain, 300);
4✔
67
        return LWResult::Result::Success;
4✔
68
      }
4✔
69
    }
4✔
70
    else {
6✔
71
      if (isRootServer(address)) {
6✔
72
        setLWResult(res, 0, false, false, true);
2✔
73
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
74
        /* no DS */
75
        addNSECRecordToLW(DNSName("com."), DNSName("dom."), {QType::NS}, 600, res->d_records);
2✔
76
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
77
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
78
        return LWResult::Result::Success;
2✔
79
      }
2✔
80
      if (address == ComboAddress("192.0.2.1:53")) {
4✔
81
        if (domain == DNSName("com.")) {
2!
82
          setLWResult(res, 0, true, false, true);
×
83
          addRecordToLW(res, DNSName("com."), QType::NS, "a.gtld-servers.com.");
×
84
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
85
        }
×
86
        else if (domain.isPartOf(DNSName("powerdns.com."))) {
2!
87
          setLWResult(res, 0, false, false, true);
2✔
88
          addRecordToLW(res, DNSName("powerdns.com."), QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
89
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
2✔
90
        }
2✔
91
        return LWResult::Result::Success;
2✔
92
      }
2✔
93
      if (address == ComboAddress("192.0.2.2:53")) {
2!
94
        setLWResult(res, 0, true, false, true);
2✔
95
        if (type == QType::NS) {
2!
96
          if (domain == DNSName("www.sub.powerdns.com.")) {
×
97
            addRecordToLW(res, DNSName("sub.powerdns.com"), QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
98
            addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com"), 300);
×
99
            addNSECRecordToLW(DNSName("www.sub.powerdns.com"), DNSName("vww.sub.powerdns.com."), {QType::A}, 600, res->d_records);
×
100
            addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com"), 300);
×
101
          }
×
102
          else if (domain == DNSName("sub.powerdns.com.")) {
×
103
            addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
104
            addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com."), 300);
×
105
          }
×
106
          else if (domain == DNSName("powerdns.com.")) {
×
107
            addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
108
          }
×
109
        }
×
110
        else if (domain == DNSName("www.sub.powerdns.com.")) {
2!
111
          addRecordToLW(res, domain, QType::A, targetAddr.toString(), DNSResourceRecord::ANSWER, 3600);
2✔
112
          addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com."), 300);
2✔
113
        }
2✔
114
        return LWResult::Result::Success;
2✔
115
      }
2✔
116
    }
2✔
117

118
    return LWResult::Result::Timeout;
×
119
  });
10✔
120

121
  vector<DNSRecord> ret;
2✔
122
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
123
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
124
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
125
  BOOST_REQUIRE_EQUAL(ret.size(), 2U);
2✔
126
  BOOST_CHECK(ret[0].d_type == QType::A);
2✔
127
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
128

129
  /* again, to test the cache */
130
  ret.clear();
2✔
131
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
132
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
133
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
134
  BOOST_REQUIRE_EQUAL(ret.size(), 2U);
2✔
135
  BOOST_CHECK(ret[0].d_type == QType::A);
2✔
136
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
137
}
2✔
138

139
BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_nodata)
140
{
2✔
141
  std::unique_ptr<SyncRes> sr;
2✔
142
  initSR(sr, true);
2✔
143

144
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
145

146
  primeHints();
2✔
147
  const DNSName target("powerdns.com.");
2✔
148
  testkeysset_t keys;
2✔
149

150
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
151
  luaconfsCopy.dsAnchors.clear();
2✔
152
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
153
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
154

155
  g_luaconfs.setState(luaconfsCopy);
2✔
156

157
  size_t queriesCount = 0;
2✔
158

159
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
12✔
160
    queriesCount++;
12✔
161

162
    if (type == QType::DS) {
12✔
163
      if (domain == target) {
2!
164
        setLWResult(res, 0, true, false, true);
2✔
165
        addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
2✔
166
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
167
        addNSECRecordToLW(domain, DNSName("z.powerdns.com."), {QType::NS}, 600, res->d_records);
2✔
168
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
169
        return LWResult::Result::Success;
2✔
170
      }
2✔
171
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
×
172
    }
2✔
173
    else if (type == QType::DNSKEY) {
10✔
174
      if (domain == g_rootdnsname || domain == DNSName("com.")) {
4!
175
        setLWResult(res, 0, true, false, true);
4✔
176
        addDNSKEY(keys, domain, 300, res->d_records);
4✔
177
        addRRSIG(keys, res->d_records, domain, 300);
4✔
178
        return LWResult::Result::Success;
4✔
179
      }
4✔
180
      setLWResult(res, 0, true, false, true);
×
181
      addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
182
      return LWResult::Result::Success;
×
183
    }
4✔
184
    else {
6✔
185
      if (isRootServer(address)) {
6✔
186
        setLWResult(res, 0, false, false, true);
2✔
187
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
188
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
189
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
190
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
191
        return LWResult::Result::Success;
2✔
192
      }
2✔
193
      if (address == ComboAddress("192.0.2.1:53")) {
4✔
194
        if (domain == DNSName("com.")) {
2!
195
          setLWResult(res, 0, true, false, true);
×
196
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
197
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
198
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
199
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
200
        }
×
201
        else {
2✔
202
          setLWResult(res, 0, false, false, true);
2✔
203
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
204
          /* no DS */
205
          addNSECRecordToLW(domain, DNSName("z.powerdns.com."), {QType::NS}, 600, res->d_records);
2✔
206
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
207
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
2✔
208
        }
2✔
209
        return LWResult::Result::Success;
2✔
210
      }
2✔
211
      if (address == ComboAddress("192.0.2.2:53")) {
2!
212
        if (type == QType::NS) {
2!
213
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
214
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
×
215
        }
×
216
        else {
2✔
217
          setLWResult(res, 0, true, false, true);
2✔
218
          addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
2✔
219
        }
2✔
220
        return LWResult::Result::Success;
2✔
221
      }
2✔
222
    }
2✔
223

224
    return LWResult::Result::Timeout;
×
225
  });
12✔
226

227
  vector<DNSRecord> ret;
2✔
228
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
229
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
230
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
231
  BOOST_REQUIRE_EQUAL(ret.size(), 1U);
2✔
232
  /* 4 NS (com from root, com from com, powerdns.com from com,
233
     powerdns.com from powerdns.com)
234
     2 DNSKEY (. and com., none for powerdns.com because no DS)
235
     1 query for A
236
  */
237
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
238

239
  /* again, to test the cache */
240
  ret.clear();
2✔
241
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
242
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
243
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
244
  BOOST_REQUIRE_EQUAL(ret.size(), 1U);
2✔
245
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
246

247
  /* Request the DS for powerdns.com, which does not exist. We should get
248
     the denial proof AND the SOA */
249
  ret.clear();
2✔
250
  res = sr->beginResolve(target, QType(QType::DS), QClass::IN, ret);
2✔
251
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
252
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
253
  BOOST_REQUIRE_EQUAL(ret.size(), 4U);
2✔
254
  bool soaFound = false;
2✔
255
  for (const auto& record : ret) {
2!
256
    if (record.d_type == QType::SOA) {
2!
257
      soaFound = true;
2✔
258
      break;
2✔
259
    }
2✔
260
  }
2✔
261
  BOOST_CHECK_EQUAL(soaFound, true);
2✔
262
  BOOST_CHECK_EQUAL(queriesCount, 6U);
2✔
263
}
2✔
264

265
BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_cname)
266
{
2✔
267
  std::unique_ptr<SyncRes> sr;
2✔
268
  initSR(sr, true);
2✔
269

270
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
271

272
  primeHints();
2✔
273
  const DNSName target("powerdns.com.");
2✔
274
  const DNSName targetCName("power-dns.com.");
2✔
275
  const ComboAddress targetCNameAddr("192.0.2.42");
2✔
276
  testkeysset_t keys;
2✔
277

278
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
279
  luaconfsCopy.dsAnchors.clear();
2✔
280
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
281
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
282
  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
283
  g_luaconfs.setState(luaconfsCopy);
2✔
284

285
  size_t queriesCount = 0;
2✔
286

287
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
16✔
288
    queriesCount++;
16✔
289

290
    if (type == QType::DS) {
16!
291
      if (domain == targetCName) {
×
292
        setLWResult(res, 0, true, false, true);
×
293
        addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
294
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
295
        addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
×
296
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
297
        return LWResult::Result::Success;
×
298
      }
×
299
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
×
300
    }
×
301
    if (type == QType::DNSKEY) {
16✔
302
      if (domain == g_rootdnsname || domain == DNSName("com.") || domain == DNSName("powerdns.com.")) {
6!
303
        setLWResult(res, 0, true, false, true);
6✔
304
        addDNSKEY(keys, domain, 300, res->d_records);
6✔
305
        addRRSIG(keys, res->d_records, domain, 300);
6✔
306
        return LWResult::Result::Success;
6✔
307
      }
6✔
308
      setLWResult(res, 0, true, false, true);
×
309
      addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
310
      return LWResult::Result::Success;
×
311
    }
6✔
312
    else {
10✔
313
      if (isRootServer(address)) {
10✔
314
        setLWResult(res, 0, false, false, true);
2✔
315
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
316
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
317
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
318
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
319
        return LWResult::Result::Success;
2✔
320
      }
2✔
321
      if (address == ComboAddress("192.0.2.1:53")) {
8✔
322
        setLWResult(res, 0, false, false, true);
4✔
323
        if (domain == DNSName("com.")) {
4!
324
          setLWResult(res, 0, true, false, true);
×
325
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
326
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
327
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
328
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
329
        }
×
330
        else {
4✔
331
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
4✔
332
          if (domain == DNSName("powerdns.com.")) {
4✔
333
            addDS(DNSName("powerdns.com."), 300, res->d_records, keys);
2✔
334
          }
2✔
335
          else if (domain == targetCName) {
2!
336
            addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
2✔
337
          }
2✔
338
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
4✔
339
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
4✔
340
        }
4✔
341

342
        return LWResult::Result::Success;
4✔
343
      }
4✔
344
      if (address == ComboAddress("192.0.2.2:53")) {
4!
345
        setLWResult(res, 0, true, false, true);
4✔
346

347
        if (type == QType::NS) {
4!
348
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
349
          if (domain == DNSName("powerdns.com.")) {
×
350
            addRRSIG(keys, res->d_records, domain, 300);
×
351
          }
×
352
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
×
353
          if (domain == DNSName("powerdns.com.")) {
×
354
            addRRSIG(keys, res->d_records, domain, 300);
×
355
          }
×
356
        }
×
357
        else {
4✔
358
          if (domain == DNSName("powerdns.com.")) {
4✔
359
            addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
2✔
360
            addRRSIG(keys, res->d_records, domain, 300);
2✔
361
          }
2✔
362
          else if (domain == targetCName) {
2!
363
            addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
2✔
364
          }
2✔
365
        }
4✔
366

367
        return LWResult::Result::Success;
4✔
368
      }
4✔
369
    }
4✔
370

371
    return LWResult::Result::Timeout;
×
372
  });
16✔
373

374
  vector<DNSRecord> ret;
2✔
375
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
376
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
377
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
378
  BOOST_REQUIRE_EQUAL(ret.size(), 3U);
2✔
379
  BOOST_CHECK_EQUAL(queriesCount, 8U);
2✔
380

381
  /* again, to test the cache */
382
  ret.clear();
2✔
383
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
384
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
385
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
386
  BOOST_REQUIRE_EQUAL(ret.size(), 3U);
2✔
387
  BOOST_CHECK_EQUAL(queriesCount, 8U);
2✔
388
}
2✔
389

390
BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_cname_glue)
391
{
2✔
392
  std::unique_ptr<SyncRes> sr;
2✔
393
  initSR(sr, true);
2✔
394

395
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
396

397
  primeHints();
2✔
398
  const DNSName target("powerdns.com.");
2✔
399
  const DNSName targetCName1("cname.sub.powerdns.com.");
2✔
400
  const DNSName targetCName2("cname2.sub.powerdns.com.");
2✔
401
  const ComboAddress targetCName2Addr("192.0.2.42");
2✔
402
  testkeysset_t keys;
2✔
403

404
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
405
  luaconfsCopy.dsAnchors.clear();
2✔
406
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
407
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
408
  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
409
  g_luaconfs.setState(luaconfsCopy);
2✔
410

411
  size_t queriesCount = 0;
2✔
412

413
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
18✔
414
    queriesCount++;
18✔
415

416
    if (type == QType::DS || type == QType::DNSKEY) {
18✔
417
      if (domain == DNSName("sub.powerdns.com")) {
8✔
418
        setLWResult(res, 0, true, false, true);
2✔
419
        addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
2✔
420
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
421
        addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
2✔
422
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
423
        return LWResult::Result::Success;
2✔
424
      }
2✔
425
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
6✔
426
    }
8✔
427
    {
10✔
428
      if (isRootServer(address)) {
10✔
429
        setLWResult(res, 0, false, false, true);
2✔
430
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
431
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
432
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
433
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
434
        return LWResult::Result::Success;
2✔
435
      }
2✔
436
      if (address == ComboAddress("192.0.2.1:53")) {
8✔
437
        setLWResult(res, 0, false, false, true);
2✔
438
        if (domain == DNSName("com.")) {
2!
439
          setLWResult(res, 0, true, false, true);
×
440
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
441
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
442
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
443
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
444
        }
×
445
        else {
2✔
446
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
447
          if (domain == DNSName("powerdns.com.")) {
2!
448
            addDS(DNSName("powerdns.com."), 300, res->d_records, keys);
2✔
449
          }
2✔
450
          else if (domain == DNSName("sub.powerdns.com")) {
×
451
            addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
×
452
          }
×
453
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
454
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
2✔
455
        }
2✔
456

457
        return LWResult::Result::Success;
2✔
458
      }
2✔
459
      if (address == ComboAddress("192.0.2.2:53")) {
6!
460
        setLWResult(res, 0, true, false, true);
6✔
461

462
        if (type == QType::NS) {
6!
463
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
464
          if (domain == DNSName("powerdns.com.")) {
×
465
            addRRSIG(keys, res->d_records, domain, 300);
×
466
          }
×
467
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
×
468
          if (domain == DNSName("powerdns.com.")) {
×
469
            addRRSIG(keys, res->d_records, domain, 300);
×
470
          }
×
471
        }
×
472
        else {
6✔
473
          if (domain == DNSName("powerdns.com.")) {
6✔
474
            addRecordToLW(res, domain, QType::CNAME, targetCName1.toString());
2✔
475
            addRRSIG(keys, res->d_records, domain, 300);
2✔
476
            /* add the CNAME target as a glue, with no RRSIG since the sub zone is insecure */
477
            addRecordToLW(res, targetCName1, QType::CNAME, targetCName2.toString());
2✔
478
            addRecordToLW(res, targetCName2, QType::A, targetCName2Addr.toString());
2✔
479
          }
2✔
480
          else if (domain == targetCName1) {
4✔
481
            addRecordToLW(res, domain, QType::CNAME, targetCName2.toString());
2✔
482
          }
2✔
483
          else if (domain == targetCName2) {
2!
484
            addRecordToLW(res, domain, QType::A, targetCName2Addr.toString());
2✔
485
          }
2✔
486
        }
6✔
487

488
        return LWResult::Result::Success;
6✔
489
      }
6✔
490
    }
6✔
491

492
    return LWResult::Result::Timeout;
×
493
  });
6✔
494

495
  vector<DNSRecord> ret;
2✔
496
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
497
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
498
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
499
  BOOST_REQUIRE_EQUAL(ret.size(), 4U);
2✔
500
  BOOST_CHECK_EQUAL(queriesCount, 9U);
2✔
501

502
  /* again, to test the cache */
503
  ret.clear();
2✔
504
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
505
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
506
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
507
  BOOST_REQUIRE_EQUAL(ret.size(), 4U);
2✔
508
  BOOST_CHECK_EQUAL(queriesCount, 9U);
2✔
509
}
2✔
510

511
BOOST_AUTO_TEST_CASE(test_dnssec_insecure_to_secure_cname)
512
{
2✔
513
  std::unique_ptr<SyncRes> sr;
2✔
514
  initSR(sr, true);
2✔
515

516
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
517

518
  primeHints();
2✔
519
  const DNSName target("power-dns.com.");
2✔
520
  const DNSName targetCName("powerdns.com.");
2✔
521
  const ComboAddress targetCNameAddr("192.0.2.42");
2✔
522
  testkeysset_t keys;
2✔
523

524
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
525
  luaconfsCopy.dsAnchors.clear();
2✔
526
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
527
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
528
  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
529
  g_luaconfs.setState(luaconfsCopy);
2✔
530

531
  size_t queriesCount = 0;
2✔
532

533
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
16✔
534
    queriesCount++;
16✔
535

536
    if (type == QType::DS) {
16!
537
      if (domain == DNSName("power-dns.com.")) {
×
538
        setLWResult(res, 0, true, false, true);
×
539
        addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
540
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
541
        addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
×
542
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
543
        return LWResult::Result::Success;
×
544
      }
×
545
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
×
546
    }
×
547
    if (type == QType::DNSKEY) {
16✔
548
      if (domain == g_rootdnsname || domain == DNSName("com.") || domain == DNSName("powerdns.com.")) {
6!
549
        setLWResult(res, 0, true, false, true);
6✔
550
        addDNSKEY(keys, domain, 300, res->d_records);
6✔
551
        addRRSIG(keys, res->d_records, domain, 300);
6✔
552
        return LWResult::Result::Success;
6✔
553
      }
6✔
554
      setLWResult(res, 0, true, false, true);
×
555
      addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
556
      return LWResult::Result::Success;
×
557
    }
6✔
558
    else {
10✔
559
      if (isRootServer(address)) {
10✔
560
        setLWResult(res, 0, false, false, true);
2✔
561
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
562
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
563
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
564
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
565
        return LWResult::Result::Success;
2✔
566
      }
2✔
567
      if (address == ComboAddress("192.0.2.1:53")) {
8✔
568
        if (domain == DNSName("com.")) {
4!
569
          setLWResult(res, 0, true, false, true);
×
570
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
571
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
572
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
573
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
574
        }
×
575
        else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
4!
576
          setLWResult(res, 0, false, false, true);
4✔
577
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
4✔
578
          if (domain == targetCName) {
4✔
579
            addDS(DNSName("powerdns.com."), 300, res->d_records, keys);
2✔
580
          }
2✔
581
          else if (domain == target) {
2!
582
            addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
2✔
583
          }
2✔
584
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
4✔
585
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
4✔
586
        }
4✔
587
        return LWResult::Result::Success;
4✔
588
      }
4✔
589
      if (address == ComboAddress("192.0.2.2:53")) {
4!
590
        setLWResult(res, 0, true, false, true);
4✔
591
        if (type == QType::NS) {
4!
592
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
593
          if (domain == DNSName("powerdns.com.")) {
×
594
            addRRSIG(keys, res->d_records, domain, 300);
×
595
          }
×
596
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
×
597
          if (domain == DNSName("powerdns.com.")) {
×
598
            addRRSIG(keys, res->d_records, domain, 300);
×
599
          }
×
600
        }
×
601
        else {
4✔
602
          if (domain == target) {
4✔
603
            addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
2✔
604
          }
2✔
605
          else if (domain == targetCName) {
2!
606
            addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
2✔
607
            addRRSIG(keys, res->d_records, domain, 300);
2✔
608
          }
2✔
609
        }
4✔
610
        return LWResult::Result::Success;
4✔
611
      }
4✔
612
    }
4✔
613

614
    return LWResult::Result::Timeout;
×
615
  });
16✔
616

617
  vector<DNSRecord> ret;
2✔
618
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
619
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
620
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
621
  BOOST_REQUIRE_EQUAL(ret.size(), 3U);
2✔
622
  BOOST_CHECK_EQUAL(queriesCount, 8U);
2✔
623

624
  /* again, to test the cache */
625
  ret.clear();
2✔
626
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
627
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
628
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
629
  BOOST_REQUIRE_EQUAL(ret.size(), 3U);
2✔
630
  BOOST_CHECK_EQUAL(queriesCount, 8U);
2✔
631
}
2✔
632

633
BOOST_AUTO_TEST_CASE(test_dnssec_bogus_to_secure_cname)
634
{
2✔
635
  std::unique_ptr<SyncRes> sr;
2✔
636
  initSR(sr, true);
2✔
637

638
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
639

640
  primeHints();
2✔
641
  const DNSName target("power-dns.com.");
2✔
642
  const DNSName targetCName("powerdns.com.");
2✔
643
  const ComboAddress targetCNameAddr("192.0.2.42");
2✔
644
  testkeysset_t keys;
2✔
645

646
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
647
  luaconfsCopy.dsAnchors.clear();
2✔
648
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
649
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
650
  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
651
  generateKeyMaterial(DNSName("power-dns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
652
  g_luaconfs.setState(luaconfsCopy);
2✔
653

654
  size_t queriesCount = 0;
2✔
655

656
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
16✔
657
    queriesCount++;
16✔
658

659
    if (type == QType::DS || type == QType::DNSKEY) {
16!
660
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
6✔
661
    }
6✔
662
    {
10✔
663
      if (isRootServer(address)) {
10✔
664
        setLWResult(res, 0, false, false, true);
2✔
665
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
666
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
667
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
668
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
669
        return LWResult::Result::Success;
2✔
670
      }
2✔
671
      if (address == ComboAddress("192.0.2.1:53")) {
8✔
672
        if (domain == DNSName("com.")) {
4!
673
          setLWResult(res, 0, true, false, true);
×
674
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
675
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
676
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
677
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
678
        }
×
679
        else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
4!
680
          setLWResult(res, 0, false, false, true);
4✔
681
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
4✔
682
          addDS(DNSName(domain), 300, res->d_records, keys);
4✔
683
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
4✔
684
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
4✔
685
        }
4✔
686
        return LWResult::Result::Success;
4✔
687
      }
4✔
688
      if (address == ComboAddress("192.0.2.2:53")) {
4!
689
        setLWResult(res, 0, true, false, true);
4✔
690
        if (type == QType::NS) {
4!
691
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
692
          addRRSIG(keys, res->d_records, domain, 300);
×
693
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
×
694
          addRRSIG(keys, res->d_records, domain, 300);
×
695
        }
×
696
        else {
4✔
697
          if (domain == target) {
4✔
698
            addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
2✔
699
            /* No RRSIG, leading to bogus */
700
          }
2✔
701
          else if (domain == targetCName) {
2!
702
            addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
2✔
703
            addRRSIG(keys, res->d_records, domain, 300);
2✔
704
          }
2✔
705
        }
4✔
706
        return LWResult::Result::Success;
4✔
707
      }
4✔
708
    }
4✔
709

710
    return LWResult::Result::Timeout;
×
711
  });
4✔
712

713
  vector<DNSRecord> ret;
2✔
714
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
715
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
716
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
2✔
717
  BOOST_REQUIRE_EQUAL(ret.size(), 3U);
2✔
718
  BOOST_CHECK_EQUAL(queriesCount, 8U);
2✔
719

720
  /* again, to test the cache */
721
  ret.clear();
2✔
722
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
723
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
724
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
2✔
725
  BOOST_REQUIRE_EQUAL(ret.size(), 3U);
2✔
726
  BOOST_CHECK_EQUAL(queriesCount, 8U);
2✔
727
}
2✔
728

729
BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_bogus_cname)
730
{
2✔
731
  std::unique_ptr<SyncRes> sr;
2✔
732
  initSR(sr, true);
2✔
733

734
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
735

736
  primeHints();
2✔
737
  const DNSName target("power-dns.com.");
2✔
738
  const DNSName targetCName("powerdns.com.");
2✔
739
  const ComboAddress targetCNameAddr("192.0.2.42");
2✔
740
  testkeysset_t keys;
2✔
741

742
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
743
  luaconfsCopy.dsAnchors.clear();
2✔
744
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
745
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
746
  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
747
  generateKeyMaterial(DNSName("power-dns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
748
  g_luaconfs.setState(luaconfsCopy);
2✔
749

750
  size_t queriesCount = 0;
2✔
751

752
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
16✔
753
    queriesCount++;
16✔
754

755
    if (type == QType::DS || type == QType::DNSKEY) {
16!
756
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
6✔
757
    }
6✔
758
    {
10✔
759
      if (isRootServer(address)) {
10✔
760
        setLWResult(res, 0, false, false, true);
2✔
761
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
762
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
763
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
764
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
765
        return LWResult::Result::Success;
2✔
766
      }
2✔
767
      if (address == ComboAddress("192.0.2.1:53")) {
8✔
768
        if (domain == DNSName("com.")) {
4!
769
          setLWResult(res, 0, true, false, true);
×
770
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
771
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
772
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
773
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
774
        }
×
775
        else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
4!
776
          setLWResult(res, 0, false, false, true);
4✔
777
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
4✔
778
          addDS(DNSName(domain), 300, res->d_records, keys);
4✔
779
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
4✔
780
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
4✔
781
        }
4✔
782
        return LWResult::Result::Success;
4✔
783
      }
4✔
784
      if (address == ComboAddress("192.0.2.2:53")) {
4!
785
        setLWResult(res, 0, true, false, true);
4✔
786
        if (type == QType::NS) {
4!
787
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
788
          addRRSIG(keys, res->d_records, domain, 300);
×
789
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
×
790
          addRRSIG(keys, res->d_records, domain, 300);
×
791
        }
×
792
        else {
4✔
793
          if (domain == target) {
4✔
794
            addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
2✔
795
            addRRSIG(keys, res->d_records, domain, 300);
2✔
796
          }
2✔
797
          else if (domain == targetCName) {
2!
798
            addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
2✔
799
            /* No RRSIG, leading to bogus */
800
          }
2✔
801
        }
4✔
802
        return LWResult::Result::Success;
4✔
803
      }
4✔
804
    }
4✔
805

806
    return LWResult::Result::Timeout;
×
807
  });
4✔
808

809
  vector<DNSRecord> ret;
2✔
810
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
811
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
812
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
2✔
813
  BOOST_REQUIRE_EQUAL(ret.size(), 3U);
2✔
814
  BOOST_CHECK_EQUAL(queriesCount, 8U);
2✔
815

816
  /* again, to test the cache */
817
  ret.clear();
2✔
818
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
819
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
820
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
2✔
821
  BOOST_REQUIRE_EQUAL(ret.size(), 3U);
2✔
822
  BOOST_CHECK_EQUAL(queriesCount, 8U);
2✔
823
}
2✔
824

825
BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_secure_cname)
826
{
2✔
827
  std::unique_ptr<SyncRes> sr;
2✔
828
  initSR(sr, true);
2✔
829

830
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
831

832
  primeHints();
2✔
833
  const DNSName target("power-dns.com.");
2✔
834
  const DNSName targetCName("powerdns.com.");
2✔
835
  const ComboAddress targetCNameAddr("192.0.2.42");
2✔
836
  testkeysset_t keys;
2✔
837

838
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
839
  luaconfsCopy.dsAnchors.clear();
2✔
840
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
841
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
842
  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
843
  generateKeyMaterial(DNSName("power-dns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
844
  g_luaconfs.setState(luaconfsCopy);
2✔
845

846
  size_t queriesCount = 0;
2✔
847

848
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
18✔
849
    queriesCount++;
18✔
850

851
    if (type == QType::DS || type == QType::DNSKEY) {
18!
852
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
8✔
853
    }
8✔
854
    {
10✔
855
      if (isRootServer(address)) {
10✔
856
        setLWResult(res, 0, false, false, true);
2✔
857
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
858
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
859
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
860
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
861
        return LWResult::Result::Success;
2✔
862
      }
2✔
863
      if (address == ComboAddress("192.0.2.1:53")) {
8✔
864
        if (domain == DNSName("com.")) {
4!
865
          setLWResult(res, 0, true, false, true);
×
866
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
867
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
868
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
869
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
870
        }
×
871
        else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
4!
872
          setLWResult(res, 0, false, false, true);
4✔
873
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
4✔
874
          addDS(DNSName(domain), 300, res->d_records, keys);
4✔
875
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
4✔
876
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
4✔
877
        }
4✔
878
        return LWResult::Result::Success;
4✔
879
      }
4✔
880
      if (address == ComboAddress("192.0.2.2:53")) {
4!
881
        setLWResult(res, 0, true, false, true);
4✔
882
        if (type == QType::NS) {
4!
883
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
884
          addRRSIG(keys, res->d_records, domain, 300);
×
885
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
×
886
          addRRSIG(keys, res->d_records, domain, 300);
×
887
        }
×
888
        else {
4✔
889
          if (domain == target) {
4✔
890
            addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
2✔
891
            addRRSIG(keys, res->d_records, domain, 300);
2✔
892
          }
2✔
893
          else if (domain == targetCName) {
2!
894
            addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
2✔
895
            addRRSIG(keys, res->d_records, domain, 300);
2✔
896
          }
2✔
897
        }
4✔
898
        return LWResult::Result::Success;
4✔
899
      }
4✔
900
    }
4✔
901

902
    return LWResult::Result::Timeout;
×
903
  });
4✔
904

905
  vector<DNSRecord> ret;
2✔
906
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
907
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
908
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
909
  BOOST_REQUIRE_EQUAL(ret.size(), 4U);
2✔
910
  BOOST_CHECK_EQUAL(queriesCount, 9U);
2✔
911

912
  /* again, to test the cache */
913
  ret.clear();
2✔
914
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
915
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
916
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
917
  BOOST_REQUIRE_EQUAL(ret.size(), 4U);
2✔
918
  BOOST_CHECK_EQUAL(queriesCount, 9U);
2✔
919
}
2✔
920

921
BOOST_AUTO_TEST_CASE(test_dnssec_bogus_to_insecure_cname)
922
{
2✔
923
  std::unique_ptr<SyncRes> sr;
2✔
924
  initSR(sr, true);
2✔
925

926
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
927

928
  primeHints();
2✔
929
  const DNSName target("powerdns.com.");
2✔
930
  const DNSName targetCName("power-dns.com.");
2✔
931
  const ComboAddress targetCNameAddr("192.0.2.42");
2✔
932
  testkeysset_t keys;
2✔
933

934
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
935
  luaconfsCopy.dsAnchors.clear();
2✔
936
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
937
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
938
  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
939
  generateKeyMaterial(DNSName("power-dns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
940
  g_luaconfs.setState(luaconfsCopy);
2✔
941

942
  size_t queriesCount = 0;
2✔
943

944
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
14✔
945
    queriesCount++;
14✔
946

947
    if (type == QType::DS) {
14!
948
      if (domain == DNSName("power-dns.com.")) {
×
949
        setLWResult(res, 0, true, false, true);
×
950
        addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
951
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
952
        addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
×
953
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
954
        return LWResult::Result::Success;
×
955
      }
×
956
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
×
957
    }
×
958
    if (type == QType::DNSKEY) {
14✔
959
      if (domain == g_rootdnsname || domain == DNSName("com.") || domain == DNSName("powerdns.com.")) {
4!
960
        setLWResult(res, 0, true, false, true);
4✔
961
        addDNSKEY(keys, domain, 300, res->d_records);
4✔
962
        addRRSIG(keys, res->d_records, domain, 300);
4✔
963
        return LWResult::Result::Success;
4✔
964
      }
4✔
965
      setLWResult(res, 0, true, false, true);
×
966
      addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
967
      return LWResult::Result::Success;
×
968
    }
4✔
969
    else {
10✔
970
      if (isRootServer(address)) {
10✔
971
        setLWResult(res, 0, false, false, true);
2✔
972
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
973
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
974
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
975
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
976
        return LWResult::Result::Success;
2✔
977
      }
2✔
978
      if (address == ComboAddress("192.0.2.1:53")) {
8✔
979
        if (domain == DNSName("com.")) {
4!
980
          setLWResult(res, 0, true, false, true);
×
981
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
982
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
983
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
984
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
985
        }
×
986
        else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
4!
987
          setLWResult(res, 0, false, false, true);
4✔
988
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
4✔
989
          if (domain == DNSName("powerdns.com.")) {
4✔
990
            addDS(DNSName("powerdns.com."), 300, res->d_records, keys);
2✔
991
          }
2✔
992
          else if (domain == targetCName) {
2!
993
            addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
2✔
994
          }
2✔
995
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
4✔
996
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
4✔
997
        }
4✔
998
        return LWResult::Result::Success;
4✔
999
      }
4✔
1000
      if (address == ComboAddress("192.0.2.2:53")) {
4!
1001
        setLWResult(res, 0, true, false, true);
4✔
1002
        if (type == QType::NS) {
4!
1003
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
1004
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
×
1005
        }
×
1006
        else {
4✔
1007
          if (domain == DNSName("powerdns.com.")) {
4✔
1008
            addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
2✔
1009
            /* No RRSIG -> Bogus */
1010
          }
2✔
1011
          else if (domain == targetCName) {
2!
1012
            addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
2✔
1013
          }
2✔
1014
        }
4✔
1015
        return LWResult::Result::Success;
4✔
1016
      }
4✔
1017
    }
4✔
1018

1019
    return LWResult::Result::Timeout;
×
1020
  });
14✔
1021

1022
  vector<DNSRecord> ret;
2✔
1023
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1024
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1025
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
2✔
1026
  /* no RRSIG to show */
1027
  BOOST_CHECK_EQUAL(ret.size(), 2U);
2✔
1028
  BOOST_CHECK_EQUAL(queriesCount, 7U);
2✔
1029

1030
  /* again, to test the cache */
1031
  ret.clear();
2✔
1032
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1033
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1034
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
2✔
1035
  BOOST_CHECK_EQUAL(ret.size(), 2U);
2✔
1036
  BOOST_CHECK_EQUAL(queriesCount, 7U);
2✔
1037
}
2✔
1038

1039
BOOST_AUTO_TEST_CASE(test_dnssec_insecure_ta)
1040
{
2✔
1041
  std::unique_ptr<SyncRes> sr;
2✔
1042
  initSR(sr, true);
2✔
1043

1044
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1045

1046
  primeHints();
2✔
1047
  const DNSName target("powerdns.com.");
2✔
1048
  const ComboAddress targetAddr("192.0.2.42");
2✔
1049
  testkeysset_t keys;
2✔
1050

1051
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1052
  luaconfsCopy.dsAnchors.clear();
2✔
1053
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1054
  /* No key material for .com */
1055
  generateKeyMaterial(target, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
1056
  luaconfsCopy.dsAnchors[target].insert(keys[target].second);
2✔
1057
  g_luaconfs.setState(luaconfsCopy);
2✔
1058

1059
  size_t queriesCount = 0;
2✔
1060

1061
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
10✔
1062
    queriesCount++;
10✔
1063

1064
    if (type == QType::DNSKEY) {
10✔
1065
      if (domain == g_rootdnsname || domain == DNSName("powerdns.com.")) {
4!
1066
        setLWResult(res, 0, true, false, true);
4✔
1067
        addDNSKEY(keys, domain, 300, res->d_records);
4✔
1068
        addRRSIG(keys, res->d_records, domain, 300);
4✔
1069
        return LWResult::Result::Success;
4✔
1070
      }
4✔
1071
      if (domain == DNSName("com.")) {
×
1072
        setLWResult(res, 0, true, false, true);
×
1073
        addRecordToLW(res, domain, QType::SOA, ". yop. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
1074
        return LWResult::Result::Success;
×
1075
      }
×
1076
    }
×
1077
    else {
6✔
1078
      if (isRootServer(address)) {
6✔
1079
        setLWResult(res, 0, false, false, true);
2✔
1080
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
1081
        addNSECRecordToLW(DNSName("com."), DNSName("com."), {QType::NS}, 600, res->d_records);
2✔
1082
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
1083
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1084
        return LWResult::Result::Success;
2✔
1085
      }
2✔
1086
      if (address == ComboAddress("192.0.2.1:53")) {
4✔
1087
        if (target == domain) {
2!
1088
          setLWResult(res, 0, false, false, true);
2✔
1089
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
1090
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1091
        }
2✔
1092
        else if (domain == DNSName("com.")) {
×
1093
          setLWResult(res, 0, true, false, true);
×
1094
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
1095
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
1096
        }
×
1097
        return LWResult::Result::Success;
2✔
1098
      }
2✔
1099
      if (address == ComboAddress("192.0.2.2:53")) {
2!
1100
        setLWResult(res, 0, true, false, true);
2✔
1101
        if (type == QType::NS) {
2!
1102
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
1103
        }
×
1104
        else {
2✔
1105
          addRecordToLW(res, domain, QType::A, targetAddr.toString(), DNSResourceRecord::ANSWER, 3600);
2✔
1106
        }
2✔
1107
        addRRSIG(keys, res->d_records, domain, 300);
2✔
1108
        return LWResult::Result::Success;
2✔
1109
      }
2✔
1110
    }
2✔
1111

1112
    return LWResult::Result::Timeout;
×
1113
  });
10✔
1114

1115
  vector<DNSRecord> ret;
2✔
1116
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1117
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1118
  /* should be insecure but we have a TA for powerdns.com. */
1119
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
1120
  /* We got a RRSIG */
1121
  BOOST_REQUIRE_EQUAL(ret.size(), 2U);
2✔
1122
  BOOST_CHECK(ret[0].d_type == QType::A);
2✔
1123
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
1124

1125
  /* again, to test the cache */
1126
  ret.clear();
2✔
1127
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1128
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1129
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
1130
  BOOST_REQUIRE_EQUAL(ret.size(), 2U);
2✔
1131
  BOOST_CHECK(ret[0].d_type == QType::A);
2✔
1132
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
1133
}
2✔
1134

1135
BOOST_AUTO_TEST_CASE(test_dnssec_insecure_ta_norrsig)
1136
{
2✔
1137
  std::unique_ptr<SyncRes> sr;
2✔
1138
  initSR(sr, true);
2✔
1139

1140
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1141

1142
  primeHints();
2✔
1143
  const DNSName target("powerdns.com.");
2✔
1144
  const ComboAddress targetAddr("192.0.2.42");
2✔
1145
  testkeysset_t keys;
2✔
1146

1147
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1148
  luaconfsCopy.dsAnchors.clear();
2✔
1149
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1150
  /* No key material for .com */
1151
  generateKeyMaterial(target, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
1152
  luaconfsCopy.dsAnchors[target].insert(keys[target].second);
2✔
1153
  g_luaconfs.setState(luaconfsCopy);
2✔
1154

1155
  size_t queriesCount = 0;
2✔
1156

1157
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
8✔
1158
    queriesCount++;
8✔
1159

1160
    if (type == QType::DNSKEY) {
8✔
1161
      if (domain == g_rootdnsname || domain == DNSName("powerdns.com.")) {
2!
1162
        setLWResult(res, 0, true, false, true);
2✔
1163
        addDNSKEY(keys, domain, 300, res->d_records);
2✔
1164
        addRRSIG(keys, res->d_records, domain, 300);
2✔
1165
        return LWResult::Result::Success;
2✔
1166
      }
2✔
1167
      if (domain == DNSName("com.")) {
×
1168
        setLWResult(res, 0, true, false, true);
×
1169
        addRecordToLW(res, domain, QType::SOA, ". yop. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
1170
        return LWResult::Result::Success;
×
1171
      }
×
1172
    }
×
1173
    else {
6✔
1174
      if (target.isPartOf(domain) && isRootServer(address)) {
6!
1175
        setLWResult(res, 0, false, false, true);
2✔
1176
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
1177
        addNSECRecordToLW(DNSName("com."), DNSName("com."), {QType::NS}, 600, res->d_records);
2✔
1178
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
1179
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1180
        return LWResult::Result::Success;
2✔
1181
      }
2✔
1182
      if (address == ComboAddress("192.0.2.1:53")) {
4✔
1183
        if (target == domain) {
2!
1184
          setLWResult(res, 0, false, false, true);
2✔
1185
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
1186
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1187
        }
2✔
1188
        else if (domain == DNSName("com.")) {
×
1189
          setLWResult(res, 0, true, false, true);
×
1190
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
1191
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
1192
        }
×
1193
        return LWResult::Result::Success;
2✔
1194
      }
2✔
1195
      if (domain == target && address == ComboAddress("192.0.2.2:53")) {
2!
1196
        setLWResult(res, 0, true, false, true);
2✔
1197
        if (type == QType::NS) {
2!
1198
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
1199
        }
×
1200
        else {
2✔
1201
          addRecordToLW(res, domain, QType::A, targetAddr.toString(), DNSResourceRecord::ANSWER, 3600);
2✔
1202
        }
2✔
1203
        /* No RRSIG in a now (thanks to TA) Secure zone -> Bogus*/
1204
        return LWResult::Result::Success;
2✔
1205
      }
2✔
1206
    }
2✔
1207

1208
    return LWResult::Result::Timeout;
×
1209
  });
8✔
1210

1211
  vector<DNSRecord> ret;
2✔
1212
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1213
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1214
  /* should be insecure but we have a TA for powerdns.com., but no RRSIG so Bogus */
1215
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
2✔
1216
  /* No RRSIG */
1217
  BOOST_REQUIRE_EQUAL(ret.size(), 1U);
2✔
1218
  BOOST_CHECK(ret[0].d_type == QType::A);
2✔
1219
  BOOST_CHECK_EQUAL(queriesCount, 4U);
2✔
1220

1221
  /* again, to test the cache */
1222
  ret.clear();
2✔
1223
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1224
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1225
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
2✔
1226
  BOOST_REQUIRE_EQUAL(ret.size(), 1U);
2✔
1227
  BOOST_CHECK(ret[0].d_type == QType::A);
2✔
1228
  BOOST_CHECK_EQUAL(queriesCount, 4U);
2✔
1229
}
2✔
1230

1231
BOOST_AUTO_TEST_CASE(test_dnssec_nta)
1232
{
2✔
1233
  std::unique_ptr<SyncRes> sr;
2✔
1234
  initSR(sr, true);
2✔
1235

1236
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1237

1238
  primeHints();
2✔
1239
  const DNSName target(".");
2✔
1240
  testkeysset_t keys;
2✔
1241

1242
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1243
  luaconfsCopy.dsAnchors.clear();
2✔
1244
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1245
  /* Add a NTA for "." */
1246
  luaconfsCopy.negAnchors[g_rootdnsname] = "NTA for Root";
2✔
1247
  g_luaconfs.setState(luaconfsCopy);
2✔
1248

1249
  size_t queriesCount = 0;
2✔
1250

1251
  sr->setAsyncCallback([&](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
2✔
1252
    queriesCount++;
2✔
1253

1254
    if (domain == target && type == QType::NS) {
2!
1255

1256
      setLWResult(res, 0, true, false, true);
2✔
1257
      char addr[] = "a.root-servers.net.";
2✔
1258
      for (char idx = 'a'; idx <= 'm'; idx++) {
28✔
1259
        addr[0] = idx;
26✔
1260
        addRecordToLW(res, domain, QType::NS, std::string(addr), DNSResourceRecord::ANSWER, 3600);
26✔
1261
      }
26✔
1262

1263
      addRRSIG(keys, res->d_records, domain, 300);
2✔
1264

1265
      addRecordToLW(res, "a.root-servers.net.", QType::A, "198.41.0.4", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1266
      addRecordToLW(res, "a.root-servers.net.", QType::AAAA, "2001:503:ba3e::2:30", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1267

1268
      return LWResult::Result::Success;
2✔
1269
    }
2✔
1270
    if (domain == target && type == QType::DNSKEY) {
×
1271

1272
      setLWResult(res, 0, true, false, true);
×
1273

1274
      /* No DNSKEY */
1275

1276
      return LWResult::Result::Success;
×
1277
    }
×
1278

1279
    return LWResult::Result::Timeout;
×
1280
  });
×
1281

1282
  vector<DNSRecord> ret;
2✔
1283
  int res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
2✔
1284
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1285
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1286
  /* 13 NS + 1 RRSIG */
1287
  BOOST_REQUIRE_EQUAL(ret.size(), 14U);
2✔
1288
  BOOST_CHECK_EQUAL(queriesCount, 1U);
2✔
1289

1290
  /* again, to test the cache */
1291
  ret.clear();
2✔
1292
  res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
2✔
1293
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1294
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1295
  BOOST_REQUIRE_EQUAL(ret.size(), 14U);
2✔
1296
  BOOST_CHECK_EQUAL(queriesCount, 1U);
2✔
1297
}
2✔
1298

1299
BOOST_AUTO_TEST_CASE(test_dnssec_no_ta)
1300
{
2✔
1301
  std::unique_ptr<SyncRes> sr;
2✔
1302
  initSR(sr, true);
2✔
1303

1304
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1305

1306
  primeHints();
2✔
1307
  const DNSName target(".");
2✔
1308
  testkeysset_t keys;
2✔
1309

1310
  /* Remove the root DS */
1311
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1312
  luaconfsCopy.dsAnchors.clear();
2✔
1313
  g_luaconfs.setState(luaconfsCopy);
2✔
1314

1315
  size_t queriesCount = 0;
2✔
1316

1317
  sr->setAsyncCallback([&](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
2✔
1318
    queriesCount++;
2✔
1319

1320
    if (domain == target && type == QType::NS) {
2!
1321

1322
      setLWResult(res, 0, true, false, true);
2✔
1323
      char addr[] = "a.root-servers.net.";
2✔
1324
      for (char idx = 'a'; idx <= 'm'; idx++) {
28✔
1325
        addr[0] = idx;
26✔
1326
        addRecordToLW(res, domain, QType::NS, std::string(addr), DNSResourceRecord::ANSWER, 3600);
26✔
1327
      }
26✔
1328

1329
      addRecordToLW(res, "a.root-servers.net.", QType::A, "198.41.0.4", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1330
      addRecordToLW(res, "a.root-servers.net.", QType::AAAA, "2001:503:ba3e::2:30", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1331

1332
      return LWResult::Result::Success;
2✔
1333
    }
2✔
1334

1335
    return LWResult::Result::Timeout;
×
1336
  });
2✔
1337

1338
  vector<DNSRecord> ret;
2✔
1339
  int res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
2✔
1340
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1341
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1342
  /* 13 NS + 0 RRSIG */
1343
  BOOST_REQUIRE_EQUAL(ret.size(), 13U);
2✔
1344
  BOOST_CHECK_EQUAL(queriesCount, 1U);
2✔
1345

1346
  /* again, to test the cache */
1347
  ret.clear();
2✔
1348
  res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
2✔
1349
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1350
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1351
  BOOST_REQUIRE_EQUAL(ret.size(), 13U);
2✔
1352
  BOOST_CHECK_EQUAL(queriesCount, 1U);
2✔
1353
}
2✔
1354

1355
BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nodata)
1356
{
2✔
1357
  std::unique_ptr<SyncRes> sr;
2✔
1358
  initSR(sr, true);
2✔
1359

1360
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1361

1362
  primeHints();
2✔
1363
  const DNSName target("powerdns.com.");
2✔
1364
  testkeysset_t keys;
2✔
1365

1366
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1367
  luaconfsCopy.dsAnchors.clear();
2✔
1368
  generateKeyMaterial(DNSName("."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1369
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1370
  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
1371
  g_luaconfs.setState(luaconfsCopy);
2✔
1372

1373
  size_t queriesCount = 0;
2✔
1374

1375
  sr->setAsyncCallback([&](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
10✔
1376
    queriesCount++;
10✔
1377

1378
    if (type == QType::DS || type == QType::DNSKEY) {
10✔
1379
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
4✔
1380
    }
4✔
1381
    if (type == QType::A) {
6!
1382
      if (domain == DNSName("com.")) {
6✔
1383
        setLWResult(res, 0, true, false, true);
2✔
1384
        addRecordToLW(res, DNSName("com"), QType::SOA, "whatever.com. blah.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
2✔
1385
        addRRSIG(keys, res->d_records, DNSName("com"), 300);
2✔
1386
        addNSECRecordToLW(DNSName("com"), DNSName("com."), {QType::SOA}, 600, res->d_records);
2✔
1387
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
1388
        return LWResult::Result::Success;
2✔
1389
      }
2✔
1390
      if (domain == target) {
4!
1391
        setLWResult(res, 0, true, false, true);
4✔
1392
        return LWResult::Result::Success;
4✔
1393
      }
4✔
1394
    }
4✔
1395

1396
    return LWResult::Result::Timeout;
×
1397
  });
6✔
1398

1399
  vector<DNSRecord> ret;
2✔
1400
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1401
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1402
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
2✔
1403
  BOOST_REQUIRE_EQUAL(ret.size(), 0U);
2✔
1404
  /* powerdns.com|A, com|A, com|DNSKEY, powerdns.com|DS */
1405
  BOOST_CHECK_EQUAL(queriesCount, 4U);
2✔
1406

1407
  /* again, to test the cache */
1408
  ret.clear();
2✔
1409
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1410
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1411
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
2✔
1412
  BOOST_REQUIRE_EQUAL(ret.size(), 0U);
2✔
1413
  /* we don't store empty results */
1414
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
1415
}
2✔
1416

1417
BOOST_AUTO_TEST_CASE(test_dnssec_insecure_missing_soa_on_nodata)
1418
{
2✔
1419
  std::unique_ptr<SyncRes> sr;
2✔
1420
  initSR(sr, true);
2✔
1421

1422
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1423

1424
  primeHints();
2✔
1425
  const DNSName target("powerdns.com.");
2✔
1426
  testkeysset_t keys;
2✔
1427

1428
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1429
  luaconfsCopy.dsAnchors.clear();
2✔
1430
  generateKeyMaterial(DNSName("."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1431
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1432
  g_luaconfs.setState(luaconfsCopy);
2✔
1433

1434
  size_t queriesCount = 0;
2✔
1435

1436
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
10✔
1437
    queriesCount++;
10✔
1438

1439
    if (type == QType::DS || type == QType::DNSKEY) {
10✔
1440
      if (domain.isPartOf(target)) {
4✔
1441
        /* proves cut */
1442
        return genericDSAndDNSKEYHandler(res, domain, domain, type, keys, true);
2✔
1443
      }
2✔
1444
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
2✔
1445
    }
4✔
1446
    if (isRootServer(address)) {
6✔
1447
      setLWResult(res, 0, false, false, true);
2✔
1448
      addRecordToLW(res, "com.", QType::NS, "ns1.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
1449
      addDS(DNSName("com."), 300, res->d_records, keys);
2✔
1450
      addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
1451
      addRecordToLW(res, "ns1.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1452
      return LWResult::Result::Success;
2✔
1453
    }
2✔
1454
    else {
4✔
1455
      if (domain == DNSName("com.")) {
4!
1456
        setLWResult(res, 0, true, false, true);
×
1457
        addRecordToLW(res, DNSName("com"), QType::SOA, "whatever.com. blah.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
1458
        addRRSIG(keys, res->d_records, DNSName("com"), 300);
×
1459
        addNSECRecordToLW(DNSName("com"), DNSName("com."), {QType::SOA}, 600, res->d_records);
×
1460
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
1461
        return LWResult::Result::Success;
×
1462
      }
×
1463
      if (domain == target) {
4!
1464
        setLWResult(res, 0, true, false, true);
4✔
1465
        return LWResult::Result::Success;
4✔
1466
      }
4✔
1467
    }
4✔
1468

1469
    return LWResult::Result::Timeout;
×
1470
  });
6✔
1471

1472
  vector<DNSRecord> ret;
2✔
1473
  int res = sr->beginResolve(target, QType(QType::AAAA), QClass::IN, ret);
2✔
1474
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1475
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1476
  BOOST_REQUIRE_EQUAL(ret.size(), 0U);
2✔
1477
  /* powerdns.com|A, com|A, com|DNSKEY, powerdns.com|DS */
1478
  BOOST_CHECK_EQUAL(queriesCount, 4U);
2✔
1479

1480
  /* again, to test the cache */
1481
  ret.clear();
2✔
1482
  res = sr->beginResolve(target, QType(QType::AAAA), QClass::IN, ret);
2✔
1483
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1484
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1485
  BOOST_REQUIRE_EQUAL(ret.size(), 0U);
2✔
1486
  /* we don't store empty results */
1487
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
1488
}
2✔
1489

1490
BOOST_AUTO_TEST_CASE(test_dnssec_insecure_missing_soa_on_nxd)
1491
{
2✔
1492
  std::unique_ptr<SyncRes> sr;
2✔
1493
  initSR(sr, true);
2✔
1494

1495
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1496

1497
  primeHints();
2✔
1498
  const DNSName target("powerdns.com.");
2✔
1499
  testkeysset_t keys;
2✔
1500

1501
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1502
  luaconfsCopy.dsAnchors.clear();
2✔
1503
  generateKeyMaterial(DNSName("."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1504
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1505
  g_luaconfs.setState(luaconfsCopy);
2✔
1506

1507
  size_t queriesCount = 0;
2✔
1508

1509
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
10✔
1510
    queriesCount++;
10✔
1511

1512
    if (type == QType::DS || type == QType::DNSKEY) {
10✔
1513
      if (domain.isPartOf(target)) {
4✔
1514
        /* proves cut */
1515
        return genericDSAndDNSKEYHandler(res, domain, domain, type, keys, true);
2✔
1516
      }
2✔
1517
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
2✔
1518
    }
4✔
1519
    if (isRootServer(address)) {
6✔
1520
      setLWResult(res, 0, false, false, true);
2✔
1521
      addRecordToLW(res, "com.", QType::NS, "ns1.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
1522
      addDS(DNSName("com."), 300, res->d_records, keys);
2✔
1523
      addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
1524
      addRecordToLW(res, "ns1.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1525
      return LWResult::Result::Success;
2✔
1526
    }
2✔
1527
    else {
4✔
1528
      if (domain == DNSName("com.")) {
4!
1529
        setLWResult(res, 0, true, false, true);
×
1530
        addRecordToLW(res, DNSName("com"), QType::SOA, "whatever.com. blah.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
1531
        addRRSIG(keys, res->d_records, DNSName("com"), 300);
×
1532
        addNSECRecordToLW(DNSName("com"), DNSName("com."), {QType::SOA}, 600, res->d_records);
×
1533
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
1534
        return LWResult::Result::Success;
×
1535
      }
×
1536
      if (domain == target) {
4!
1537
        setLWResult(res, RCode::NXDomain, true, false, true);
4✔
1538
        return LWResult::Result::Success;
4✔
1539
      }
4✔
1540
    }
4✔
1541

1542
    return LWResult::Result::Timeout;
×
1543
  });
6✔
1544

1545
  vector<DNSRecord> ret;
2✔
1546
  int res = sr->beginResolve(target, QType(QType::AAAA), QClass::IN, ret);
2✔
1547
  BOOST_CHECK_EQUAL(res, RCode::NXDomain);
2✔
1548
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1549
  BOOST_REQUIRE_EQUAL(ret.size(), 0U);
2✔
1550
  /* powerdns.com|A, com|A, com|DNSKEY, powerdns.com|DS */
1551
  BOOST_CHECK_EQUAL(queriesCount, 4U);
2✔
1552

1553
  /* again, to test the cache */
1554
  ret.clear();
2✔
1555
  res = sr->beginResolve(target, QType(QType::AAAA), QClass::IN, ret);
2✔
1556
  BOOST_CHECK_EQUAL(res, RCode::NXDomain);
2✔
1557
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1558
  BOOST_REQUIRE_EQUAL(ret.size(), 0U);
2✔
1559
  /* we don't store empty results */
1560
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
1561
}
2✔
1562

1563
BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nxdomain)
1564
{
2✔
1565
  std::unique_ptr<SyncRes> sr;
2✔
1566
  initSR(sr, true);
2✔
1567

1568
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1569

1570
  primeHints();
2✔
1571
  const DNSName target("powerdns.com.");
2✔
1572
  testkeysset_t keys;
2✔
1573

1574
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1575
  luaconfsCopy.dsAnchors.clear();
2✔
1576
  generateKeyMaterial(DNSName("."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1577
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1578
  generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
1579
  g_luaconfs.setState(luaconfsCopy);
2✔
1580

1581
  size_t queriesCount = 0;
2✔
1582

1583
  sr->setAsyncCallback([&](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
10✔
1584
    queriesCount++;
10✔
1585

1586
    if (type == QType::DS || type == QType::DNSKEY) {
10✔
1587
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
4✔
1588
    }
4✔
1589
    if (type == QType::A) {
6!
1590
      if (domain == DNSName("com.")) {
6✔
1591
        setLWResult(res, 0, true, false, true);
2✔
1592
        addRecordToLW(res, DNSName("com"), QType::SOA, "whatever.com. blah.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
2✔
1593
        addRRSIG(keys, res->d_records, DNSName("com"), 300);
2✔
1594
        addNSECRecordToLW(DNSName("com"), DNSName("com."), {QType::SOA}, 600, res->d_records);
2✔
1595
        addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
1596
        return LWResult::Result::Success;
2✔
1597
      }
2✔
1598
      if (domain == target) {
4!
1599
        setLWResult(res, RCode::NXDomain, true, false, true);
4✔
1600
        return LWResult::Result::Success;
4✔
1601
      }
4✔
1602
    }
4✔
1603

1604
    return LWResult::Result::Timeout;
×
1605
  });
6✔
1606

1607
  vector<DNSRecord> ret;
2✔
1608
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1609
  BOOST_CHECK_EQUAL(res, RCode::NXDomain);
2✔
1610
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
2✔
1611
  BOOST_REQUIRE_EQUAL(ret.size(), 0U);
2✔
1612

1613
  /* powerdns.com|A, com|A, powerdns.com|DS, com|DNSKEY */
1614
  BOOST_CHECK_EQUAL(queriesCount, 4U);
2✔
1615

1616
  /* again, to test the cache */
1617
  ret.clear();
2✔
1618
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1619
  BOOST_CHECK_EQUAL(res, RCode::NXDomain);
2✔
1620
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
2✔
1621
  BOOST_REQUIRE_EQUAL(ret.size(), 0U);
2✔
1622
  /* we don't store empty results */
1623
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
1624
}
2✔
1625

1626
BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_cut_with_cname_at_apex)
1627
{
2✔
1628
  std::unique_ptr<SyncRes> sr;
2✔
1629
  initSR(sr, true);
2✔
1630

1631
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1632

1633
  primeHints();
2✔
1634
  const DNSName target("powerdns.com.");
2✔
1635
  const DNSName targetCName("power-dns.com.");
2✔
1636
  const ComboAddress targetCNameAddr("192.0.2.42");
2✔
1637
  testkeysset_t keys;
2✔
1638

1639
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1640
  luaconfsCopy.dsAnchors.clear();
2✔
1641
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1642
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
1643
  g_luaconfs.setState(luaconfsCopy);
2✔
1644

1645
  size_t queriesCount = 0;
2✔
1646

1647
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
20✔
1648
    queriesCount++;
20✔
1649

1650
    if (type == QType::DS) {
20✔
1651
      if (domain == DNSName("www.powerdns.com.") || domain == DNSName("www2.powerdns.com.")) {
2!
1652
        return genericDSAndDNSKEYHandler(res, domain, domain, type, keys, false);
×
1653
      }
×
1654
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
2✔
1655
    }
2✔
1656
    if (type == QType::DNSKEY) {
18✔
1657
      if (domain == g_rootdnsname || domain == DNSName("com.")) {
4!
1658
        setLWResult(res, 0, true, false, true);
4✔
1659
        addDNSKEY(keys, domain, 300, res->d_records);
4✔
1660
        addRRSIG(keys, res->d_records, domain, 300);
4✔
1661
        return LWResult::Result::Success;
4✔
1662
      }
4✔
1663
      setLWResult(res, 0, true, false, true);
×
1664
      addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
1665
      return LWResult::Result::Success;
×
1666
    }
4✔
1667
    else {
14✔
1668
      if (isRootServer(address)) {
14✔
1669
        setLWResult(res, 0, false, false, true);
2✔
1670
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
1671
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
1672
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
1673
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1674
        return LWResult::Result::Success;
2✔
1675
      }
2✔
1676
      if (address == ComboAddress("192.0.2.1:53")) {
12✔
1677
        setLWResult(res, 0, false, false, true);
4✔
1678
        if (domain == DNSName("com.")) {
4!
1679
          setLWResult(res, 0, true, false, true);
×
1680
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
1681
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
1682
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
1683
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
1684
        }
×
1685
        else {
4✔
1686
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
4✔
1687
          if (domain.isPartOf(DNSName("powerdns.com."))) {
4✔
1688
            addNSECRecordToLW(domain, DNSName("z.powerdns.com."), {QType::NS}, 600, res->d_records);
2✔
1689
          }
2✔
1690
          else if (domain == targetCName) {
2!
1691
            addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
2✔
1692
          }
2✔
1693
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
4✔
1694
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
4✔
1695
        }
4✔
1696

1697
        return LWResult::Result::Success;
4✔
1698
      }
4✔
1699
      if (address == ComboAddress("192.0.2.2:53")) {
8!
1700
        setLWResult(res, 0, true, false, true);
8✔
1701

1702
        if (type == QType::NS) {
8!
1703
          addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
×
1704
          addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
×
1705
        }
×
1706
        else {
8✔
1707
          if (domain == DNSName("powerdns.com.")) {
8✔
1708
            addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
2✔
1709
          }
2✔
1710
          else if (domain == DNSName("www.powerdns.com.") || domain == DNSName("www2.powerdns.com.")) {
6✔
1711
            addRecordToLW(res, domain, QType::A, "192.0.2.43");
4✔
1712
          }
4✔
1713
          else if (domain == targetCName) {
2!
1714
            addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
2✔
1715
          }
2✔
1716
        }
8✔
1717

1718
        return LWResult::Result::Success;
8✔
1719
      }
8✔
1720
    }
8✔
1721

1722
    return LWResult::Result::Timeout;
×
1723
  });
18✔
1724

1725
  vector<DNSRecord> ret;
2✔
1726
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1727
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1728
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1729
  BOOST_REQUIRE_EQUAL(ret.size(), 2U);
2✔
1730
  BOOST_CHECK_EQUAL(queriesCount, 7U);
2✔
1731

1732
  /* again, to test the cache */
1733
  ret.clear();
2✔
1734
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1735
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1736
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1737
  BOOST_REQUIRE_EQUAL(ret.size(), 2U);
2✔
1738
  BOOST_CHECK_EQUAL(queriesCount, 7U);
2✔
1739

1740
  /* this time we ask for www.powerdns.com, let's make sure the CNAME does not get in the way */
1741
  ret.clear();
2✔
1742
  res = sr->beginResolve(DNSName("www.powerdns.com."), QType(QType::A), QClass::IN, ret);
2✔
1743
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1744
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1745
  BOOST_REQUIRE_EQUAL(ret.size(), 1U);
2✔
1746
  BOOST_CHECK_EQUAL(queriesCount, 8U);
2✔
1747

1748
  /* now we remove the denial of powerdns.com DS from the cache and ask www2 */
1749
  BOOST_REQUIRE_EQUAL(g_negCache->wipe(target, false), 1U);
2✔
1750
  ret.clear();
2✔
1751
  res = sr->beginResolve(DNSName("www2.powerdns.com."), QType(QType::A), QClass::IN, ret);
2✔
1752
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1753
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
2✔
1754
  BOOST_REQUIRE_EQUAL(ret.size(), 1U);
2✔
1755
  BOOST_CHECK_EQUAL(queriesCount, 10U);
2✔
1756
}
2✔
1757

1758
BOOST_AUTO_TEST_CASE(test_dnssec_cname_inside_secure_zone)
1759
{
2✔
1760
  /* this test makes sure we don't request the DS
1761
     again and again when there is a CNAME inside a
1762
     Secure zone */
1763
  std::unique_ptr<SyncRes> sr;
2✔
1764
  initSR(sr, true);
2✔
1765

1766
  setDNSSECValidation(sr, DNSSECMode::ValidateAll);
2✔
1767

1768
  primeHints();
2✔
1769
  const DNSName target("powerdns.com.");
2✔
1770
  const DNSName targetCName("power-dns.com.");
2✔
1771
  const ComboAddress targetCNameAddr("192.0.2.42");
2✔
1772
  testkeysset_t keys;
2✔
1773

1774
  auto luaconfsCopy = g_luaconfs.getCopy();
2✔
1775
  luaconfsCopy.dsAnchors.clear();
2✔
1776
  generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
2✔
1777
  generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
2✔
1778
  g_luaconfs.setState(luaconfsCopy);
2✔
1779

1780
  size_t queriesCount = 0;
2✔
1781

1782
  sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
14✔
1783
    queriesCount++;
14✔
1784

1785
    if (type == QType::DS) {
14!
1786
      if (domain.isPartOf(DNSName("powerdns.com.")) || domain.isPartOf(DNSName("power-dns.com."))) {
×
1787
        /* no cut */
1788
        /* technically the zone is com., but we are going to chop off in genericDSAndDNSKEYHandler() */
1789
        return genericDSAndDNSKEYHandler(res, domain, DNSName("powerdns.com."), type, keys, false);
×
1790
      }
×
1791
      return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
×
1792
    }
×
1793
    if (type == QType::DNSKEY) {
14✔
1794
      if (domain == g_rootdnsname || domain == DNSName("com.")) {
4!
1795
        setLWResult(res, 0, true, false, true);
4✔
1796
        addDNSKEY(keys, domain, 300, res->d_records);
4✔
1797
        addRRSIG(keys, res->d_records, domain, 300);
4✔
1798
        return LWResult::Result::Success;
4✔
1799
      }
4✔
1800
      setLWResult(res, 0, true, false, true);
×
1801
      addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
×
1802
      return LWResult::Result::Success;
×
1803
    }
4✔
1804
    else {
10✔
1805
      if (isRootServer(address)) {
10✔
1806
        setLWResult(res, 0, false, false, true);
2✔
1807
        addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
2✔
1808
        addDS(DNSName("com."), 300, res->d_records, keys);
2✔
1809
        addRRSIG(keys, res->d_records, DNSName("."), 300);
2✔
1810
        addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
2✔
1811
        return LWResult::Result::Success;
2✔
1812
      }
2✔
1813
      if (address == ComboAddress("192.0.2.1:53")) {
8!
1814
        setLWResult(res, 0, true, false, true);
8✔
1815

1816
        if (domain == DNSName("com.")) {
8!
1817
          addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
×
1818
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
1819
          addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
×
1820
          addRRSIG(keys, res->d_records, DNSName("com."), 300);
×
1821
        }
×
1822
        else {
8✔
1823
          if (domain == DNSName("powerdns.com.")) {
8✔
1824
            addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
2✔
1825
            addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
1826
          }
2✔
1827
          else if (domain == DNSName("www.powerdns.com.") || domain == DNSName("www2.powerdns.com.")) {
6✔
1828
            addRecordToLW(res, domain, QType::A, "192.0.2.43");
4✔
1829
            addRRSIG(keys, res->d_records, DNSName("com."), 300);
4✔
1830
          }
4✔
1831
          else if (domain == targetCName) {
2!
1832
            addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
2✔
1833
            addRRSIG(keys, res->d_records, DNSName("com."), 300);
2✔
1834
          }
2✔
1835
        }
8✔
1836

1837
        return LWResult::Result::Success;
8✔
1838
      }
8✔
1839
    }
8✔
1840

1841
    return LWResult::Result::Timeout;
×
1842
  });
14✔
1843

1844
  vector<DNSRecord> ret;
2✔
1845
  int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1846
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1847
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
1848
  BOOST_REQUIRE_EQUAL(ret.size(), 4U);
2✔
1849
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
1850

1851
  /* again, to test the cache */
1852
  ret.clear();
2✔
1853
  res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
2✔
1854
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1855
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
1856
  BOOST_REQUIRE_EQUAL(ret.size(), 4U);
2✔
1857
  BOOST_CHECK_EQUAL(queriesCount, 5U);
2✔
1858

1859
  /* this time we ask for www.powerdns.com, let's make sure the CNAME does not get in the way */
1860
  ret.clear();
2✔
1861
  res = sr->beginResolve(DNSName("www.powerdns.com."), QType(QType::A), QClass::IN, ret);
2✔
1862
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1863
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
1864
  BOOST_REQUIRE_EQUAL(ret.size(), 2U);
2✔
1865
  BOOST_CHECK_EQUAL(queriesCount, 6U);
2✔
1866

1867
  /* now we remove the denial of powerdns.com DS from the cache and ask www2 */
1868
  g_negCache->wipe(target, false);
2✔
1869
  ret.clear();
2✔
1870
  res = sr->beginResolve(DNSName("www2.powerdns.com."), QType(QType::A), QClass::IN, ret);
2✔
1871
  BOOST_CHECK_EQUAL(res, RCode::NoError);
2✔
1872
  BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
2✔
1873
  BOOST_REQUIRE_EQUAL(ret.size(), 2U);
2✔
1874
  BOOST_CHECK_EQUAL(queriesCount, 7U);
2✔
1875
}
2✔
1876

1877
BOOST_AUTO_TEST_SUITE_END()
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc