You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1460 lines
61 KiB

  1. #define BOOST_TEST_DYN_LINK
  2. #include <boost/test/unit_test.hpp>
  3. #include "test-syncres_cc.hh"
  4. BOOST_AUTO_TEST_SUITE(syncres_cc7)
  5. BOOST_AUTO_TEST_CASE(test_dnssec_insecure_to_ta_skipped_cut)
  6. {
  7. std::unique_ptr<SyncRes> sr;
  8. initSR(sr, true);
  9. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  10. primeHints();
  11. const DNSName target("www.sub.powerdns.com.");
  12. const ComboAddress targetAddr("192.0.2.42");
  13. testkeysset_t keys;
  14. auto luaconfsCopy = g_luaconfs.getCopy();
  15. luaconfsCopy.dsAnchors.clear();
  16. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  17. /* No key material for .com */
  18. /* But TA for sub.powerdns.com. */
  19. generateKeyMaterial(DNSName("sub.powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  20. luaconfsCopy.dsAnchors[DNSName("sub.powerdns.com.")].insert(keys[DNSName("sub.powerdns.com.")].second);
  21. g_luaconfs.setState(luaconfsCopy);
  22. size_t queriesCount = 0;
  23. sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  24. queriesCount++;
  25. if (type == QType::DS) {
  26. if (domain == DNSName("www.sub.powerdns.com")) {
  27. setLWResult(res, 0, true, false, true);
  28. 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);
  29. addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com"), 300);
  30. addNSECRecordToLW(DNSName("www.sub.powerdns.com"), DNSName("vww.sub.powerdns.com."), {QType::A}, 600, res->d_records);
  31. addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com"), 300);
  32. }
  33. else {
  34. setLWResult(res, 0, true, false, true);
  35. if (domain == DNSName("com.")) {
  36. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  37. addRRSIG(keys, res->d_records, DNSName("."), 300);
  38. /* no DS */
  39. addNSECRecordToLW(DNSName("com."), DNSName("dom."), {QType::NS}, 600, res->d_records);
  40. addRRSIG(keys, res->d_records, DNSName("."), 300);
  41. }
  42. else {
  43. setLWResult(res, 0, true, false, true);
  44. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  45. }
  46. }
  47. return 1;
  48. }
  49. else if (type == QType::DNSKEY) {
  50. if (domain == g_rootdnsname || domain == DNSName("sub.powerdns.com.")) {
  51. setLWResult(res, 0, true, false, true);
  52. addDNSKEY(keys, domain, 300, res->d_records);
  53. addRRSIG(keys, res->d_records, domain, 300);
  54. return 1;
  55. }
  56. }
  57. else {
  58. if (isRootServer(ip)) {
  59. setLWResult(res, 0, false, false, true);
  60. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  61. /* no DS */
  62. addNSECRecordToLW(DNSName("com."), DNSName("dom."), {QType::NS}, 600, res->d_records);
  63. addRRSIG(keys, res->d_records, DNSName("."), 300);
  64. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  65. return 1;
  66. }
  67. else if (ip == ComboAddress("192.0.2.1:53")) {
  68. if (domain == DNSName("com.")) {
  69. setLWResult(res, 0, true, false, true);
  70. addRecordToLW(res, DNSName("com."), QType::NS, "a.gtld-servers.com.");
  71. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  72. }
  73. else if (domain.isPartOf(DNSName("powerdns.com."))) {
  74. setLWResult(res, 0, false, false, true);
  75. addRecordToLW(res, DNSName("powerdns.com."), QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  76. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  77. }
  78. return 1;
  79. }
  80. else if (ip == ComboAddress("192.0.2.2:53")) {
  81. setLWResult(res, 0, true, false, true);
  82. if (type == QType::NS) {
  83. if (domain == DNSName("www.sub.powerdns.com.")) {
  84. 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);
  85. addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com"), 300);
  86. addNSECRecordToLW(DNSName("www.sub.powerdns.com"), DNSName("vww.sub.powerdns.com."), {QType::A}, 600, res->d_records);
  87. addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com"), 300);
  88. }
  89. else if (domain == DNSName("sub.powerdns.com.")) {
  90. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  91. addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com."), 300);
  92. }
  93. else if (domain == DNSName("powerdns.com.")) {
  94. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  95. }
  96. }
  97. else if (domain == DNSName("www.sub.powerdns.com.")) {
  98. addRecordToLW(res, domain, QType::A, targetAddr.toString(), DNSResourceRecord::ANSWER, 3600);
  99. addRRSIG(keys, res->d_records, DNSName("sub.powerdns.com."), 300);
  100. }
  101. return 1;
  102. }
  103. }
  104. return 0;
  105. });
  106. vector<DNSRecord> ret;
  107. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  108. BOOST_CHECK_EQUAL(res, RCode::NoError);
  109. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
  110. BOOST_REQUIRE_EQUAL(ret.size(), 2U);
  111. BOOST_CHECK(ret[0].d_type == QType::A);
  112. BOOST_CHECK_EQUAL(queriesCount, 7U);
  113. /* again, to test the cache */
  114. ret.clear();
  115. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  116. BOOST_CHECK_EQUAL(res, RCode::NoError);
  117. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
  118. BOOST_REQUIRE_EQUAL(ret.size(), 2U);
  119. BOOST_CHECK(ret[0].d_type == QType::A);
  120. BOOST_CHECK_EQUAL(queriesCount, 7U);
  121. }
  122. BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_nodata)
  123. {
  124. std::unique_ptr<SyncRes> sr;
  125. initSR(sr, true);
  126. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  127. primeHints();
  128. const DNSName target("powerdns.com.");
  129. testkeysset_t keys;
  130. auto luaconfsCopy = g_luaconfs.getCopy();
  131. luaconfsCopy.dsAnchors.clear();
  132. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  133. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  134. g_luaconfs.setState(luaconfsCopy);
  135. size_t queriesCount = 0;
  136. sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  137. queriesCount++;
  138. if (type == QType::DS) {
  139. if (domain == target) {
  140. setLWResult(res, 0, true, false, true);
  141. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  142. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  143. addNSECRecordToLW(domain, DNSName("z.powerdns.com."), {QType::NS}, 600, res->d_records);
  144. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  145. return 1;
  146. }
  147. else {
  148. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  149. }
  150. }
  151. else if (type == QType::DNSKEY) {
  152. if (domain == g_rootdnsname || domain == DNSName("com.")) {
  153. setLWResult(res, 0, true, false, true);
  154. addDNSKEY(keys, domain, 300, res->d_records);
  155. addRRSIG(keys, res->d_records, domain, 300);
  156. return 1;
  157. }
  158. else {
  159. setLWResult(res, 0, true, false, true);
  160. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  161. return 1;
  162. }
  163. }
  164. else {
  165. if (isRootServer(ip)) {
  166. setLWResult(res, 0, false, false, true);
  167. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  168. addDS(DNSName("com."), 300, res->d_records, keys);
  169. addRRSIG(keys, res->d_records, DNSName("."), 300);
  170. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  171. return 1;
  172. }
  173. else if (ip == ComboAddress("192.0.2.1:53")) {
  174. if (domain == DNSName("com.")) {
  175. setLWResult(res, 0, true, false, true);
  176. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  177. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  178. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  179. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  180. }
  181. else {
  182. setLWResult(res, 0, false, false, true);
  183. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  184. /* no DS */
  185. addNSECRecordToLW(domain, DNSName("z.powerdns.com."), {QType::NS}, 600, res->d_records);
  186. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  187. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  188. }
  189. return 1;
  190. }
  191. else if (ip == ComboAddress("192.0.2.2:53")) {
  192. if (type == QType::NS) {
  193. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  194. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  195. }
  196. else {
  197. setLWResult(res, 0, true, false, true);
  198. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  199. }
  200. return 1;
  201. }
  202. }
  203. return 0;
  204. });
  205. vector<DNSRecord> ret;
  206. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  207. BOOST_CHECK_EQUAL(res, RCode::NoError);
  208. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  209. BOOST_REQUIRE_EQUAL(ret.size(), 1U);
  210. /* 4 NS (com from root, com from com, powerdns.com from com,
  211. powerdns.com from powerdns.com)
  212. 2 DNSKEY (. and com., none for powerdns.com because no DS)
  213. 1 query for A
  214. */
  215. BOOST_CHECK_EQUAL(queriesCount, 7U);
  216. /* again, to test the cache */
  217. ret.clear();
  218. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  219. BOOST_CHECK_EQUAL(res, RCode::NoError);
  220. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  221. BOOST_REQUIRE_EQUAL(ret.size(), 1U);
  222. BOOST_CHECK_EQUAL(queriesCount, 7U);
  223. }
  224. BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_cname)
  225. {
  226. std::unique_ptr<SyncRes> sr;
  227. initSR(sr, true);
  228. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  229. primeHints();
  230. const DNSName target("powerdns.com.");
  231. const DNSName targetCName("power-dns.com.");
  232. const ComboAddress targetCNameAddr("192.0.2.42");
  233. testkeysset_t keys;
  234. auto luaconfsCopy = g_luaconfs.getCopy();
  235. luaconfsCopy.dsAnchors.clear();
  236. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  237. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  238. generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  239. g_luaconfs.setState(luaconfsCopy);
  240. size_t queriesCount = 0;
  241. sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  242. queriesCount++;
  243. if (type == QType::DS) {
  244. if (domain == targetCName) {
  245. setLWResult(res, 0, true, false, true);
  246. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  247. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  248. addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
  249. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  250. return 1;
  251. }
  252. else {
  253. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  254. }
  255. }
  256. else if (type == QType::DNSKEY) {
  257. if (domain == g_rootdnsname || domain == DNSName("com.") || domain == DNSName("powerdns.com.")) {
  258. setLWResult(res, 0, true, false, true);
  259. addDNSKEY(keys, domain, 300, res->d_records);
  260. addRRSIG(keys, res->d_records, domain, 300);
  261. return 1;
  262. }
  263. else {
  264. setLWResult(res, 0, true, false, true);
  265. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  266. return 1;
  267. }
  268. }
  269. else {
  270. if (isRootServer(ip)) {
  271. setLWResult(res, 0, false, false, true);
  272. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  273. addDS(DNSName("com."), 300, res->d_records, keys);
  274. addRRSIG(keys, res->d_records, DNSName("."), 300);
  275. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  276. return 1;
  277. }
  278. else if (ip == ComboAddress("192.0.2.1:53")) {
  279. setLWResult(res, 0, false, false, true);
  280. if (domain == DNSName("com.")) {
  281. setLWResult(res, 0, true, false, true);
  282. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  283. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  284. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  285. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  286. }
  287. else {
  288. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  289. if (domain == DNSName("powerdns.com.")) {
  290. addDS(DNSName("powerdns.com."), 300, res->d_records, keys);
  291. }
  292. else if (domain == targetCName) {
  293. addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
  294. }
  295. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  296. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  297. }
  298. return 1;
  299. }
  300. else if (ip == ComboAddress("192.0.2.2:53")) {
  301. setLWResult(res, 0, true, false, true);
  302. if (type == QType::NS) {
  303. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  304. if (domain == DNSName("powerdns.com.")) {
  305. addRRSIG(keys, res->d_records, domain, 300);
  306. }
  307. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  308. if (domain == DNSName("powerdns.com.")) {
  309. addRRSIG(keys, res->d_records, domain, 300);
  310. }
  311. }
  312. else {
  313. if (domain == DNSName("powerdns.com.")) {
  314. addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
  315. addRRSIG(keys, res->d_records, domain, 300);
  316. }
  317. else if (domain == targetCName) {
  318. addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
  319. }
  320. }
  321. return 1;
  322. }
  323. }
  324. return 0;
  325. });
  326. vector<DNSRecord> ret;
  327. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  328. BOOST_CHECK_EQUAL(res, RCode::NoError);
  329. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  330. BOOST_REQUIRE_EQUAL(ret.size(), 3U);
  331. BOOST_CHECK_EQUAL(queriesCount, 11U);
  332. /* again, to test the cache */
  333. ret.clear();
  334. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  335. BOOST_CHECK_EQUAL(res, RCode::NoError);
  336. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  337. BOOST_REQUIRE_EQUAL(ret.size(), 3U);
  338. BOOST_CHECK_EQUAL(queriesCount, 11U);
  339. }
  340. BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_cname_glue)
  341. {
  342. std::unique_ptr<SyncRes> sr;
  343. initSR(sr, true);
  344. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  345. primeHints();
  346. const DNSName target("powerdns.com.");
  347. const DNSName targetCName1("cname.sub.powerdns.com.");
  348. const DNSName targetCName2("cname2.sub.powerdns.com.");
  349. const ComboAddress targetCName2Addr("192.0.2.42");
  350. testkeysset_t keys;
  351. auto luaconfsCopy = g_luaconfs.getCopy();
  352. luaconfsCopy.dsAnchors.clear();
  353. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  354. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  355. generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  356. g_luaconfs.setState(luaconfsCopy);
  357. size_t queriesCount = 0;
  358. sr->setAsyncCallback([target, targetCName1, targetCName2, targetCName2Addr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  359. queriesCount++;
  360. if (type == QType::DS || type == QType::DNSKEY) {
  361. if (domain == DNSName("sub.powerdns.com")) {
  362. setLWResult(res, 0, true, false, true);
  363. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  364. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  365. addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
  366. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  367. return 1;
  368. }
  369. else {
  370. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  371. }
  372. }
  373. else {
  374. if (isRootServer(ip)) {
  375. setLWResult(res, 0, false, false, true);
  376. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  377. addDS(DNSName("com."), 300, res->d_records, keys);
  378. addRRSIG(keys, res->d_records, DNSName("."), 300);
  379. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  380. return 1;
  381. }
  382. else if (ip == ComboAddress("192.0.2.1:53")) {
  383. setLWResult(res, 0, false, false, true);
  384. if (domain == DNSName("com.")) {
  385. setLWResult(res, 0, true, false, true);
  386. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  387. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  388. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  389. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  390. }
  391. else {
  392. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  393. if (domain == DNSName("powerdns.com.")) {
  394. addDS(DNSName("powerdns.com."), 300, res->d_records, keys);
  395. }
  396. else if (domain == DNSName("sub.powerdns.com")) {
  397. addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
  398. }
  399. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  400. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  401. }
  402. return 1;
  403. }
  404. else if (ip == ComboAddress("192.0.2.2:53")) {
  405. setLWResult(res, 0, true, false, true);
  406. if (type == QType::NS) {
  407. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  408. if (domain == DNSName("powerdns.com.")) {
  409. addRRSIG(keys, res->d_records, domain, 300);
  410. }
  411. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  412. if (domain == DNSName("powerdns.com.")) {
  413. addRRSIG(keys, res->d_records, domain, 300);
  414. }
  415. }
  416. else {
  417. if (domain == DNSName("powerdns.com.")) {
  418. addRecordToLW(res, domain, QType::CNAME, targetCName1.toString());
  419. addRRSIG(keys, res->d_records, domain, 300);
  420. /* add the CNAME target as a glue, with no RRSIG since the sub zone is insecure */
  421. addRecordToLW(res, targetCName1, QType::CNAME, targetCName2.toString());
  422. addRecordToLW(res, targetCName2, QType::A, targetCName2Addr.toString());
  423. }
  424. else if (domain == targetCName1) {
  425. addRecordToLW(res, domain, QType::CNAME, targetCName2.toString());
  426. }
  427. else if (domain == targetCName2) {
  428. addRecordToLW(res, domain, QType::A, targetCName2Addr.toString());
  429. }
  430. }
  431. return 1;
  432. }
  433. }
  434. return 0;
  435. });
  436. vector<DNSRecord> ret;
  437. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  438. BOOST_CHECK_EQUAL(res, RCode::NoError);
  439. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  440. BOOST_REQUIRE_EQUAL(ret.size(), 4U);
  441. BOOST_CHECK_EQUAL(queriesCount, 11U);
  442. /* again, to test the cache */
  443. ret.clear();
  444. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  445. BOOST_CHECK_EQUAL(res, RCode::NoError);
  446. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  447. BOOST_REQUIRE_EQUAL(ret.size(), 4U);
  448. BOOST_CHECK_EQUAL(queriesCount, 11U);
  449. }
  450. BOOST_AUTO_TEST_CASE(test_dnssec_insecure_to_secure_cname)
  451. {
  452. std::unique_ptr<SyncRes> sr;
  453. initSR(sr, true);
  454. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  455. primeHints();
  456. const DNSName target("power-dns.com.");
  457. const DNSName targetCName("powerdns.com.");
  458. const ComboAddress targetCNameAddr("192.0.2.42");
  459. testkeysset_t keys;
  460. auto luaconfsCopy = g_luaconfs.getCopy();
  461. luaconfsCopy.dsAnchors.clear();
  462. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  463. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  464. generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  465. g_luaconfs.setState(luaconfsCopy);
  466. size_t queriesCount = 0;
  467. sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  468. queriesCount++;
  469. if (type == QType::DS) {
  470. if (domain == DNSName("power-dns.com.")) {
  471. setLWResult(res, 0, true, false, true);
  472. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  473. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  474. addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
  475. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  476. return 1;
  477. }
  478. else {
  479. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  480. }
  481. }
  482. else if (type == QType::DNSKEY) {
  483. if (domain == g_rootdnsname || domain == DNSName("com.") || domain == DNSName("powerdns.com.")) {
  484. setLWResult(res, 0, true, false, true);
  485. addDNSKEY(keys, domain, 300, res->d_records);
  486. addRRSIG(keys, res->d_records, domain, 300);
  487. return 1;
  488. }
  489. else {
  490. setLWResult(res, 0, true, false, true);
  491. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  492. return 1;
  493. }
  494. }
  495. else {
  496. if (isRootServer(ip)) {
  497. setLWResult(res, 0, false, false, true);
  498. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  499. addDS(DNSName("com."), 300, res->d_records, keys);
  500. addRRSIG(keys, res->d_records, DNSName("."), 300);
  501. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  502. return 1;
  503. }
  504. else if (ip == ComboAddress("192.0.2.1:53")) {
  505. if (domain == DNSName("com.")) {
  506. setLWResult(res, 0, true, false, true);
  507. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  508. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  509. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  510. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  511. }
  512. else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
  513. setLWResult(res, 0, false, false, true);
  514. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  515. if (domain == targetCName) {
  516. addDS(DNSName("powerdns.com."), 300, res->d_records, keys);
  517. }
  518. else if (domain == target) {
  519. addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
  520. }
  521. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  522. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  523. }
  524. return 1;
  525. }
  526. else if (ip == ComboAddress("192.0.2.2:53")) {
  527. setLWResult(res, 0, true, false, true);
  528. if (type == QType::NS) {
  529. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  530. if (domain == DNSName("powerdns.com.")) {
  531. addRRSIG(keys, res->d_records, domain, 300);
  532. }
  533. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  534. if (domain == DNSName("powerdns.com.")) {
  535. addRRSIG(keys, res->d_records, domain, 300);
  536. }
  537. }
  538. else {
  539. if (domain == target) {
  540. addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
  541. }
  542. else if (domain == targetCName) {
  543. addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
  544. addRRSIG(keys, res->d_records, domain, 300);
  545. }
  546. }
  547. return 1;
  548. }
  549. }
  550. return 0;
  551. });
  552. vector<DNSRecord> ret;
  553. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  554. BOOST_CHECK_EQUAL(res, RCode::NoError);
  555. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  556. BOOST_REQUIRE_EQUAL(ret.size(), 3U);
  557. BOOST_CHECK_EQUAL(queriesCount, 11U);
  558. /* again, to test the cache */
  559. ret.clear();
  560. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  561. BOOST_CHECK_EQUAL(res, RCode::NoError);
  562. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  563. BOOST_REQUIRE_EQUAL(ret.size(), 3U);
  564. BOOST_CHECK_EQUAL(queriesCount, 11U);
  565. }
  566. BOOST_AUTO_TEST_CASE(test_dnssec_bogus_to_secure_cname)
  567. {
  568. std::unique_ptr<SyncRes> sr;
  569. initSR(sr, true);
  570. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  571. primeHints();
  572. const DNSName target("power-dns.com.");
  573. const DNSName targetCName("powerdns.com.");
  574. const ComboAddress targetCNameAddr("192.0.2.42");
  575. testkeysset_t keys;
  576. auto luaconfsCopy = g_luaconfs.getCopy();
  577. luaconfsCopy.dsAnchors.clear();
  578. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  579. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  580. generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  581. generateKeyMaterial(DNSName("power-dns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  582. g_luaconfs.setState(luaconfsCopy);
  583. size_t queriesCount = 0;
  584. sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  585. queriesCount++;
  586. if (type == QType::DS || type == QType::DNSKEY) {
  587. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  588. }
  589. else {
  590. if (isRootServer(ip)) {
  591. setLWResult(res, 0, false, false, true);
  592. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  593. addDS(DNSName("com."), 300, res->d_records, keys);
  594. addRRSIG(keys, res->d_records, DNSName("."), 300);
  595. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  596. return 1;
  597. }
  598. else if (ip == ComboAddress("192.0.2.1:53")) {
  599. if (domain == DNSName("com.")) {
  600. setLWResult(res, 0, true, false, true);
  601. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  602. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  603. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  604. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  605. }
  606. else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
  607. setLWResult(res, 0, false, false, true);
  608. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  609. addDS(DNSName(domain), 300, res->d_records, keys);
  610. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  611. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  612. }
  613. return 1;
  614. }
  615. else if (ip == ComboAddress("192.0.2.2:53")) {
  616. setLWResult(res, 0, true, false, true);
  617. if (type == QType::NS) {
  618. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  619. addRRSIG(keys, res->d_records, domain, 300);
  620. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  621. addRRSIG(keys, res->d_records, domain, 300);
  622. }
  623. else {
  624. if (domain == target) {
  625. addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
  626. /* No RRSIG, leading to bogus */
  627. }
  628. else if (domain == targetCName) {
  629. addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
  630. addRRSIG(keys, res->d_records, domain, 300);
  631. }
  632. }
  633. return 1;
  634. }
  635. }
  636. return 0;
  637. });
  638. vector<DNSRecord> ret;
  639. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  640. BOOST_CHECK_EQUAL(res, RCode::NoError);
  641. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
  642. BOOST_REQUIRE_EQUAL(ret.size(), 3U);
  643. BOOST_CHECK_EQUAL(queriesCount, 11U);
  644. /* again, to test the cache */
  645. ret.clear();
  646. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  647. BOOST_CHECK_EQUAL(res, RCode::NoError);
  648. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
  649. BOOST_REQUIRE_EQUAL(ret.size(), 3U);
  650. BOOST_CHECK_EQUAL(queriesCount, 11U);
  651. }
  652. BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_bogus_cname)
  653. {
  654. std::unique_ptr<SyncRes> sr;
  655. initSR(sr, true);
  656. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  657. primeHints();
  658. const DNSName target("power-dns.com.");
  659. const DNSName targetCName("powerdns.com.");
  660. const ComboAddress targetCNameAddr("192.0.2.42");
  661. testkeysset_t keys;
  662. auto luaconfsCopy = g_luaconfs.getCopy();
  663. luaconfsCopy.dsAnchors.clear();
  664. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  665. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  666. generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  667. generateKeyMaterial(DNSName("power-dns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  668. g_luaconfs.setState(luaconfsCopy);
  669. size_t queriesCount = 0;
  670. sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  671. queriesCount++;
  672. if (type == QType::DS || type == QType::DNSKEY) {
  673. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  674. }
  675. else {
  676. if (isRootServer(ip)) {
  677. setLWResult(res, 0, false, false, true);
  678. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  679. addDS(DNSName("com."), 300, res->d_records, keys);
  680. addRRSIG(keys, res->d_records, DNSName("."), 300);
  681. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  682. return 1;
  683. }
  684. else if (ip == ComboAddress("192.0.2.1:53")) {
  685. if (domain == DNSName("com.")) {
  686. setLWResult(res, 0, true, false, true);
  687. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  688. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  689. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  690. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  691. }
  692. else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
  693. setLWResult(res, 0, false, false, true);
  694. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  695. addDS(DNSName(domain), 300, res->d_records, keys);
  696. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  697. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  698. }
  699. return 1;
  700. }
  701. else if (ip == ComboAddress("192.0.2.2:53")) {
  702. setLWResult(res, 0, true, false, true);
  703. if (type == QType::NS) {
  704. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  705. addRRSIG(keys, res->d_records, domain, 300);
  706. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  707. addRRSIG(keys, res->d_records, domain, 300);
  708. }
  709. else {
  710. if (domain == target) {
  711. addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
  712. addRRSIG(keys, res->d_records, domain, 300);
  713. }
  714. else if (domain == targetCName) {
  715. addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
  716. /* No RRSIG, leading to bogus */
  717. }
  718. }
  719. return 1;
  720. }
  721. }
  722. return 0;
  723. });
  724. vector<DNSRecord> ret;
  725. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  726. BOOST_CHECK_EQUAL(res, RCode::NoError);
  727. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
  728. BOOST_REQUIRE_EQUAL(ret.size(), 3U);
  729. BOOST_CHECK_EQUAL(queriesCount, 11U);
  730. /* again, to test the cache */
  731. ret.clear();
  732. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  733. BOOST_CHECK_EQUAL(res, RCode::NoError);
  734. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
  735. BOOST_REQUIRE_EQUAL(ret.size(), 3U);
  736. BOOST_CHECK_EQUAL(queriesCount, 11U);
  737. }
  738. BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_secure_cname)
  739. {
  740. std::unique_ptr<SyncRes> sr;
  741. initSR(sr, true);
  742. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  743. primeHints();
  744. const DNSName target("power-dns.com.");
  745. const DNSName targetCName("powerdns.com.");
  746. const ComboAddress targetCNameAddr("192.0.2.42");
  747. testkeysset_t keys;
  748. auto luaconfsCopy = g_luaconfs.getCopy();
  749. luaconfsCopy.dsAnchors.clear();
  750. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  751. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  752. generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  753. generateKeyMaterial(DNSName("power-dns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  754. g_luaconfs.setState(luaconfsCopy);
  755. size_t queriesCount = 0;
  756. sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  757. queriesCount++;
  758. if (type == QType::DS || type == QType::DNSKEY) {
  759. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  760. }
  761. else {
  762. if (isRootServer(ip)) {
  763. setLWResult(res, 0, false, false, true);
  764. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  765. addDS(DNSName("com."), 300, res->d_records, keys);
  766. addRRSIG(keys, res->d_records, DNSName("."), 300);
  767. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  768. return 1;
  769. }
  770. else if (ip == ComboAddress("192.0.2.1:53")) {
  771. if (domain == DNSName("com.")) {
  772. setLWResult(res, 0, true, false, true);
  773. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  774. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  775. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  776. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  777. }
  778. else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
  779. setLWResult(res, 0, false, false, true);
  780. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  781. addDS(DNSName(domain), 300, res->d_records, keys);
  782. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  783. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  784. }
  785. return 1;
  786. }
  787. else if (ip == ComboAddress("192.0.2.2:53")) {
  788. setLWResult(res, 0, true, false, true);
  789. if (type == QType::NS) {
  790. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  791. addRRSIG(keys, res->d_records, domain, 300);
  792. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  793. addRRSIG(keys, res->d_records, domain, 300);
  794. }
  795. else {
  796. if (domain == target) {
  797. addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
  798. addRRSIG(keys, res->d_records, domain, 300);
  799. }
  800. else if (domain == targetCName) {
  801. addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
  802. addRRSIG(keys, res->d_records, domain, 300);
  803. }
  804. }
  805. return 1;
  806. }
  807. }
  808. return 0;
  809. });
  810. vector<DNSRecord> ret;
  811. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  812. BOOST_CHECK_EQUAL(res, RCode::NoError);
  813. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
  814. BOOST_REQUIRE_EQUAL(ret.size(), 4U);
  815. BOOST_CHECK_EQUAL(queriesCount, 12U);
  816. /* again, to test the cache */
  817. ret.clear();
  818. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  819. BOOST_CHECK_EQUAL(res, RCode::NoError);
  820. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
  821. BOOST_REQUIRE_EQUAL(ret.size(), 4U);
  822. BOOST_CHECK_EQUAL(queriesCount, 12U);
  823. }
  824. BOOST_AUTO_TEST_CASE(test_dnssec_bogus_to_insecure_cname)
  825. {
  826. std::unique_ptr<SyncRes> sr;
  827. initSR(sr, true);
  828. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  829. primeHints();
  830. const DNSName target("powerdns.com.");
  831. const DNSName targetCName("power-dns.com.");
  832. const ComboAddress targetCNameAddr("192.0.2.42");
  833. testkeysset_t keys;
  834. auto luaconfsCopy = g_luaconfs.getCopy();
  835. luaconfsCopy.dsAnchors.clear();
  836. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  837. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  838. generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  839. generateKeyMaterial(DNSName("power-dns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  840. g_luaconfs.setState(luaconfsCopy);
  841. size_t queriesCount = 0;
  842. sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  843. queriesCount++;
  844. if (type == QType::DS) {
  845. if (domain == DNSName("power-dns.com.")) {
  846. setLWResult(res, 0, true, false, true);
  847. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  848. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  849. addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
  850. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  851. return 1;
  852. }
  853. else {
  854. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  855. }
  856. }
  857. else if (type == QType::DNSKEY) {
  858. if (domain == g_rootdnsname || domain == DNSName("com.") || domain == DNSName("powerdns.com.")) {
  859. setLWResult(res, 0, true, false, true);
  860. addDNSKEY(keys, domain, 300, res->d_records);
  861. addRRSIG(keys, res->d_records, domain, 300);
  862. return 1;
  863. }
  864. else {
  865. setLWResult(res, 0, true, false, true);
  866. addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  867. return 1;
  868. }
  869. }
  870. else {
  871. if (isRootServer(ip)) {
  872. setLWResult(res, 0, false, false, true);
  873. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  874. addDS(DNSName("com."), 300, res->d_records, keys);
  875. addRRSIG(keys, res->d_records, DNSName("."), 300);
  876. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  877. return 1;
  878. }
  879. else if (ip == ComboAddress("192.0.2.1:53")) {
  880. if (domain == DNSName("com.")) {
  881. setLWResult(res, 0, true, false, true);
  882. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  883. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  884. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  885. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  886. }
  887. else if (domain == DNSName("powerdns.com.") || domain == DNSName("power-dns.com.")) {
  888. setLWResult(res, 0, false, false, true);
  889. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  890. if (domain == DNSName("powerdns.com.")) {
  891. addDS(DNSName("powerdns.com."), 300, res->d_records, keys);
  892. }
  893. else if (domain == targetCName) {
  894. addNSECRecordToLW(domain, DNSName("z.power-dns.com."), {QType::NS}, 600, res->d_records);
  895. }
  896. addRRSIG(keys, res->d_records, DNSName("com."), 300);
  897. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  898. }
  899. return 1;
  900. }
  901. else if (ip == ComboAddress("192.0.2.2:53")) {
  902. setLWResult(res, 0, true, false, true);
  903. if (type == QType::NS) {
  904. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  905. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  906. }
  907. else {
  908. if (domain == DNSName("powerdns.com.")) {
  909. addRecordToLW(res, domain, QType::CNAME, targetCName.toString());
  910. /* No RRSIG -> Bogus */
  911. }
  912. else if (domain == targetCName) {
  913. addRecordToLW(res, domain, QType::A, targetCNameAddr.toString());
  914. }
  915. }
  916. return 1;
  917. }
  918. }
  919. return 0;
  920. });
  921. vector<DNSRecord> ret;
  922. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  923. BOOST_CHECK_EQUAL(res, RCode::NoError);
  924. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
  925. /* no RRSIG to show */
  926. BOOST_CHECK_EQUAL(ret.size(), 2U);
  927. BOOST_CHECK_EQUAL(queriesCount, 10U);
  928. /* again, to test the cache */
  929. ret.clear();
  930. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  931. BOOST_CHECK_EQUAL(res, RCode::NoError);
  932. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
  933. BOOST_CHECK_EQUAL(ret.size(), 2U);
  934. BOOST_CHECK_EQUAL(queriesCount, 10U);
  935. }
  936. BOOST_AUTO_TEST_CASE(test_dnssec_insecure_ta)
  937. {
  938. std::unique_ptr<SyncRes> sr;
  939. initSR(sr, true);
  940. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  941. primeHints();
  942. const DNSName target("powerdns.com.");
  943. const ComboAddress targetAddr("192.0.2.42");
  944. testkeysset_t keys;
  945. auto luaconfsCopy = g_luaconfs.getCopy();
  946. luaconfsCopy.dsAnchors.clear();
  947. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  948. /* No key material for .com */
  949. generateKeyMaterial(target, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  950. luaconfsCopy.dsAnchors[target].insert(keys[target].second);
  951. g_luaconfs.setState(luaconfsCopy);
  952. size_t queriesCount = 0;
  953. sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  954. queriesCount++;
  955. if (type == QType::DNSKEY) {
  956. if (domain == g_rootdnsname || domain == DNSName("powerdns.com.")) {
  957. setLWResult(res, 0, true, false, true);
  958. addDNSKEY(keys, domain, 300, res->d_records);
  959. addRRSIG(keys, res->d_records, domain, 300);
  960. return 1;
  961. }
  962. else if (domain == DNSName("com.")) {
  963. setLWResult(res, 0, true, false, true);
  964. addRecordToLW(res, domain, QType::SOA, ". yop. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  965. return 1;
  966. }
  967. }
  968. else {
  969. if (isRootServer(ip)) {
  970. setLWResult(res, 0, false, false, true);
  971. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  972. addNSECRecordToLW(DNSName("com."), DNSName("com."), {QType::NS}, 600, res->d_records);
  973. addRRSIG(keys, res->d_records, DNSName("."), 300);
  974. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  975. return 1;
  976. }
  977. else if (ip == ComboAddress("192.0.2.1:53")) {
  978. if (target == domain) {
  979. setLWResult(res, 0, false, false, true);
  980. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  981. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  982. }
  983. else if (domain == DNSName("com.")) {
  984. setLWResult(res, 0, true, false, true);
  985. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  986. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  987. }
  988. return 1;
  989. }
  990. else if (ip == ComboAddress("192.0.2.2:53")) {
  991. setLWResult(res, 0, true, false, true);
  992. if (type == QType::NS) {
  993. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  994. }
  995. else {
  996. addRecordToLW(res, domain, QType::A, targetAddr.toString(), DNSResourceRecord::ANSWER, 3600);
  997. }
  998. addRRSIG(keys, res->d_records, domain, 300);
  999. return 1;
  1000. }
  1001. }
  1002. return 0;
  1003. });
  1004. vector<DNSRecord> ret;
  1005. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  1006. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1007. /* should be insecure but we have a TA for powerdns.com. */
  1008. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
  1009. /* We got a RRSIG */
  1010. BOOST_REQUIRE_EQUAL(ret.size(), 2U);
  1011. BOOST_CHECK(ret[0].d_type == QType::A);
  1012. BOOST_CHECK_EQUAL(queriesCount, 5U);
  1013. /* again, to test the cache */
  1014. ret.clear();
  1015. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  1016. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1017. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure);
  1018. BOOST_REQUIRE_EQUAL(ret.size(), 2U);
  1019. BOOST_CHECK(ret[0].d_type == QType::A);
  1020. BOOST_CHECK_EQUAL(queriesCount, 5U);
  1021. }
  1022. BOOST_AUTO_TEST_CASE(test_dnssec_insecure_ta_norrsig)
  1023. {
  1024. std::unique_ptr<SyncRes> sr;
  1025. initSR(sr, true);
  1026. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  1027. primeHints();
  1028. const DNSName target("powerdns.com.");
  1029. const ComboAddress targetAddr("192.0.2.42");
  1030. testkeysset_t keys;
  1031. auto luaconfsCopy = g_luaconfs.getCopy();
  1032. luaconfsCopy.dsAnchors.clear();
  1033. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  1034. /* No key material for .com */
  1035. generateKeyMaterial(target, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  1036. luaconfsCopy.dsAnchors[target].insert(keys[target].second);
  1037. g_luaconfs.setState(luaconfsCopy);
  1038. size_t queriesCount = 0;
  1039. sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  1040. queriesCount++;
  1041. if (type == QType::DNSKEY) {
  1042. if (domain == g_rootdnsname || domain == DNSName("powerdns.com.")) {
  1043. setLWResult(res, 0, true, false, true);
  1044. addDNSKEY(keys, domain, 300, res->d_records);
  1045. addRRSIG(keys, res->d_records, domain, 300);
  1046. return 1;
  1047. }
  1048. else if (domain == DNSName("com.")) {
  1049. setLWResult(res, 0, true, false, true);
  1050. addRecordToLW(res, domain, QType::SOA, ". yop. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
  1051. return 1;
  1052. }
  1053. }
  1054. else {
  1055. if (target.isPartOf(domain) && isRootServer(ip)) {
  1056. setLWResult(res, 0, false, false, true);
  1057. addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600);
  1058. addNSECRecordToLW(DNSName("com."), DNSName("com."), {QType::NS}, 600, res->d_records);
  1059. addRRSIG(keys, res->d_records, DNSName("."), 300);
  1060. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  1061. return 1;
  1062. }
  1063. else if (ip == ComboAddress("192.0.2.1:53")) {
  1064. if (target == domain) {
  1065. setLWResult(res, 0, false, false, true);
  1066. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600);
  1067. addRecordToLW(res, "ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600);
  1068. }
  1069. else if (domain == DNSName("com.")) {
  1070. setLWResult(res, 0, true, false, true);
  1071. addRecordToLW(res, domain, QType::NS, "a.gtld-servers.com.");
  1072. addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600);
  1073. }
  1074. return 1;
  1075. }
  1076. else if (domain == target && ip == ComboAddress("192.0.2.2:53")) {
  1077. setLWResult(res, 0, true, false, true);
  1078. if (type == QType::NS) {
  1079. addRecordToLW(res, domain, QType::NS, "ns1.powerdns.com.");
  1080. }
  1081. else {
  1082. addRecordToLW(res, domain, QType::A, targetAddr.toString(), DNSResourceRecord::ANSWER, 3600);
  1083. }
  1084. /* No RRSIG in a now (thanks to TA) Secure zone -> Bogus*/
  1085. return 1;
  1086. }
  1087. }
  1088. return 0;
  1089. });
  1090. vector<DNSRecord> ret;
  1091. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  1092. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1093. /* should be insecure but we have a TA for powerdns.com., but no RRSIG so Bogus */
  1094. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
  1095. /* No RRSIG */
  1096. BOOST_REQUIRE_EQUAL(ret.size(), 1U);
  1097. BOOST_CHECK(ret[0].d_type == QType::A);
  1098. BOOST_CHECK_EQUAL(queriesCount, 4U);
  1099. /* again, to test the cache */
  1100. ret.clear();
  1101. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  1102. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1103. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoRRSIG);
  1104. BOOST_REQUIRE_EQUAL(ret.size(), 1U);
  1105. BOOST_CHECK(ret[0].d_type == QType::A);
  1106. BOOST_CHECK_EQUAL(queriesCount, 4U);
  1107. }
  1108. BOOST_AUTO_TEST_CASE(test_dnssec_nta)
  1109. {
  1110. std::unique_ptr<SyncRes> sr;
  1111. initSR(sr, true);
  1112. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  1113. primeHints();
  1114. const DNSName target(".");
  1115. testkeysset_t keys;
  1116. auto luaconfsCopy = g_luaconfs.getCopy();
  1117. luaconfsCopy.dsAnchors.clear();
  1118. generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  1119. /* Add a NTA for "." */
  1120. luaconfsCopy.negAnchors[g_rootdnsname] = "NTA for Root";
  1121. g_luaconfs.setState(luaconfsCopy);
  1122. size_t queriesCount = 0;
  1123. sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  1124. queriesCount++;
  1125. if (domain == target && type == QType::NS) {
  1126. setLWResult(res, 0, true, false, true);
  1127. char addr[] = "a.root-servers.net.";
  1128. for (char idx = 'a'; idx <= 'm'; idx++) {
  1129. addr[0] = idx;
  1130. addRecordToLW(res, domain, QType::NS, std::string(addr), DNSResourceRecord::ANSWER, 3600);
  1131. }
  1132. addRRSIG(keys, res->d_records, domain, 300);
  1133. addRecordToLW(res, "a.root-servers.net.", QType::A, "198.41.0.4", DNSResourceRecord::ADDITIONAL, 3600);
  1134. addRecordToLW(res, "a.root-servers.net.", QType::AAAA, "2001:503:ba3e::2:30", DNSResourceRecord::ADDITIONAL, 3600);
  1135. return 1;
  1136. }
  1137. else if (domain == target && type == QType::DNSKEY) {
  1138. setLWResult(res, 0, true, false, true);
  1139. /* No DNSKEY */
  1140. return 1;
  1141. }
  1142. return 0;
  1143. });
  1144. vector<DNSRecord> ret;
  1145. int res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
  1146. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1147. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  1148. /* 13 NS + 1 RRSIG */
  1149. BOOST_REQUIRE_EQUAL(ret.size(), 14U);
  1150. BOOST_CHECK_EQUAL(queriesCount, 1U);
  1151. /* again, to test the cache */
  1152. ret.clear();
  1153. res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
  1154. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1155. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  1156. BOOST_REQUIRE_EQUAL(ret.size(), 14U);
  1157. BOOST_CHECK_EQUAL(queriesCount, 1U);
  1158. }
  1159. BOOST_AUTO_TEST_CASE(test_dnssec_no_ta)
  1160. {
  1161. std::unique_ptr<SyncRes> sr;
  1162. initSR(sr, true);
  1163. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  1164. primeHints();
  1165. const DNSName target(".");
  1166. testkeysset_t keys;
  1167. /* Remove the root DS */
  1168. auto luaconfsCopy = g_luaconfs.getCopy();
  1169. luaconfsCopy.dsAnchors.clear();
  1170. g_luaconfs.setState(luaconfsCopy);
  1171. size_t queriesCount = 0;
  1172. sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  1173. queriesCount++;
  1174. if (domain == target && type == QType::NS) {
  1175. setLWResult(res, 0, true, false, true);
  1176. char addr[] = "a.root-servers.net.";
  1177. for (char idx = 'a'; idx <= 'm'; idx++) {
  1178. addr[0] = idx;
  1179. addRecordToLW(res, domain, QType::NS, std::string(addr), DNSResourceRecord::ANSWER, 3600);
  1180. }
  1181. addRecordToLW(res, "a.root-servers.net.", QType::A, "198.41.0.4", DNSResourceRecord::ADDITIONAL, 3600);
  1182. addRecordToLW(res, "a.root-servers.net.", QType::AAAA, "2001:503:ba3e::2:30", DNSResourceRecord::ADDITIONAL, 3600);
  1183. return 1;
  1184. }
  1185. return 0;
  1186. });
  1187. vector<DNSRecord> ret;
  1188. int res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
  1189. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1190. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  1191. /* 13 NS + 0 RRSIG */
  1192. BOOST_REQUIRE_EQUAL(ret.size(), 13U);
  1193. BOOST_CHECK_EQUAL(queriesCount, 1U);
  1194. /* again, to test the cache */
  1195. ret.clear();
  1196. res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
  1197. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1198. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
  1199. BOOST_REQUIRE_EQUAL(ret.size(), 13U);
  1200. BOOST_CHECK_EQUAL(queriesCount, 1U);
  1201. }
  1202. BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nodata)
  1203. {
  1204. std::unique_ptr<SyncRes> sr;
  1205. initSR(sr, true);
  1206. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  1207. primeHints();
  1208. const DNSName target("powerdns.com.");
  1209. testkeysset_t keys;
  1210. auto luaconfsCopy = g_luaconfs.getCopy();
  1211. luaconfsCopy.dsAnchors.clear();
  1212. generateKeyMaterial(DNSName("."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  1213. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  1214. generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  1215. g_luaconfs.setState(luaconfsCopy);
  1216. size_t queriesCount = 0;
  1217. sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  1218. queriesCount++;
  1219. if (type == QType::DS || type == QType::DNSKEY) {
  1220. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  1221. }
  1222. else {
  1223. setLWResult(res, 0, true, false, true);
  1224. return 1;
  1225. }
  1226. return 0;
  1227. });
  1228. vector<DNSRecord> ret;
  1229. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  1230. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1231. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
  1232. BOOST_REQUIRE_EQUAL(ret.size(), 0U);
  1233. /* com|NS, powerdns.com|NS, powerdns.com|A */
  1234. BOOST_CHECK_EQUAL(queriesCount, 3U);
  1235. /* again, to test the cache */
  1236. ret.clear();
  1237. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  1238. BOOST_CHECK_EQUAL(res, RCode::NoError);
  1239. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
  1240. BOOST_REQUIRE_EQUAL(ret.size(), 0U);
  1241. /* we don't store empty results */
  1242. BOOST_CHECK_EQUAL(queriesCount, 4U);
  1243. }
  1244. BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nxdomain)
  1245. {
  1246. std::unique_ptr<SyncRes> sr;
  1247. initSR(sr, true);
  1248. setDNSSECValidation(sr, DNSSECMode::ValidateAll);
  1249. primeHints();
  1250. const DNSName target("powerdns.com.");
  1251. testkeysset_t keys;
  1252. auto luaconfsCopy = g_luaconfs.getCopy();
  1253. luaconfsCopy.dsAnchors.clear();
  1254. generateKeyMaterial(DNSName("."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  1255. generateKeyMaterial(DNSName("com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
  1256. generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
  1257. g_luaconfs.setState(luaconfsCopy);
  1258. size_t queriesCount = 0;
  1259. sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
  1260. queriesCount++;
  1261. if (type == QType::DS || type == QType::DNSKEY) {
  1262. return genericDSAndDNSKEYHandler(res, domain, domain, type, keys);
  1263. }
  1264. else {
  1265. setLWResult(res, RCode::NXDomain, true, false, true);
  1266. return 1;
  1267. }
  1268. return 0;
  1269. });
  1270. vector<DNSRecord> ret;
  1271. int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  1272. BOOST_CHECK_EQUAL(res, RCode::NXDomain);
  1273. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
  1274. BOOST_REQUIRE_EQUAL(ret.size(), 0U);
  1275. /* com|NS, powerdns.com|NS, powerdns.com|A */
  1276. BOOST_CHECK_EQUAL(queriesCount, 3U);
  1277. /* again, to test the cache */
  1278. ret.clear();
  1279. res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
  1280. BOOST_CHECK_EQUAL(res, RCode::NXDomain);
  1281. BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusMissingNegativeIndication);
  1282. BOOST_REQUIRE_EQUAL(ret.size(), 0U);
  1283. /* we don't store empty results */
  1284. BOOST_CHECK_EQUAL(queriesCount, 4U);
  1285. }
  1286. BOOST_AUTO_TEST_SUITE_END()