1 /*
2  * This file is part of PowerDNS or dnsdist.
3  * Copyright -- PowerDNS.COM B.V. and its contributors
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * In addition, for the avoidance of any doubt, permission is granted to
10  * link this program with OpenSSL and to (re)distribute the binaries
11  * produced as the result of such linking.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 #define BOOST_TEST_DYN_LINK
23 #define BOOST_TEST_NO_MAIN
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 #include <boost/test/unit_test.hpp>
29 #include <boost/assign/list_of.hpp>
30 
31 #include <boost/tuple/tuple.hpp>
32 #include "pdns/namespaces.hh"
33 #include "pdns/dns.hh"
34 #include "pdns/dnsbackend.hh"
35 #include "pdns/dnspacket.hh"
36 #include "pdns/pdnsexception.hh"
37 #include "pdns/logger.hh"
38 #include "pdns/arguments.hh"
39 #include "pdns/json.hh"
40 #include "pdns/statbag.hh"
41 
42 #include "test-remotebackend-keys.hh"
43 
44 extern DNSBackend* be;
45 
46 BOOST_AUTO_TEST_SUITE(test_remotebackend_so)
47 
BOOST_AUTO_TEST_CASE(test_method_lookup)48 BOOST_AUTO_TEST_CASE(test_method_lookup)
49 {
50   BOOST_TEST_MESSAGE("Testing lookup method");
51   DNSResourceRecord rr;
52   be->lookup(QType(QType::SOA), DNSName("unit.test."));
53   // then try to get()
54   BOOST_CHECK(be->get(rr)); // and this should be TRUE.
55   // then we check rr contains what we expect
56   BOOST_CHECK_EQUAL(rr.qname.toString(), "unit.test.");
57   BOOST_CHECK_MESSAGE(rr.qtype == QType::SOA, "returned qtype was not SOA");
58   BOOST_CHECK_EQUAL(rr.content, "ns.unit.test. hostmaster.unit.test. 1 2 3 4 5");
59   BOOST_CHECK_EQUAL(rr.ttl, 300);
60 }
61 
BOOST_AUTO_TEST_CASE(test_method_lookup_empty)62 BOOST_AUTO_TEST_CASE(test_method_lookup_empty)
63 {
64   BOOST_TEST_MESSAGE("Testing lookup method with empty result");
65   DNSResourceRecord rr;
66   be->lookup(QType(QType::SOA), DNSName("empty.unit.test."));
67   // then try to get()
68   BOOST_CHECK(!be->get(rr)); // and this should be FALSE
69 }
70 
BOOST_AUTO_TEST_CASE(test_method_list)71 BOOST_AUTO_TEST_CASE(test_method_list)
72 {
73   int record_count = 0;
74   DNSResourceRecord rr;
75 
76   BOOST_TEST_MESSAGE("Testing list method");
77   be->list(DNSName("unit.test."), -1);
78   while (be->get(rr))
79     record_count++;
80 
81   BOOST_CHECK_EQUAL(record_count, 5); // number of records our test domain has
82 }
83 
BOOST_AUTO_TEST_CASE(test_method_doesDNSSEC)84 BOOST_AUTO_TEST_CASE(test_method_doesDNSSEC)
85 {
86   BOOST_TEST_MESSAGE("Testing doesDNSSEC method");
87   BOOST_CHECK(be->doesDNSSEC()); // should be true
88 }
89 
BOOST_AUTO_TEST_CASE(test_method_setDomainMetadata)90 BOOST_AUTO_TEST_CASE(test_method_setDomainMetadata)
91 {
92   std::vector<std::string> meta;
93   meta.push_back("VALUE");
94   BOOST_TEST_MESSAGE("Testing setDomainMetadata method");
95   BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."), "TEST", meta));
96 }
97 
BOOST_AUTO_TEST_CASE(test_method_alsoNotifies)98 BOOST_AUTO_TEST_CASE(test_method_alsoNotifies)
99 {
100   BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."), "ALSO-NOTIFY", {"192.0.2.1"}));
101   std::set<std::string> alsoNotifies;
102   BOOST_TEST_MESSAGE("Testing alsoNotifies method");
103   be->alsoNotifies(DNSName("unit.test."), &alsoNotifies);
104   BOOST_CHECK_EQUAL(alsoNotifies.size(), 1);
105   if (alsoNotifies.size() > 0)
106     BOOST_CHECK_EQUAL(alsoNotifies.count("192.0.2.1"), 1);
107   BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."), "ALSO-NOTIFY", std::vector<std::string>()));
108 }
109 
BOOST_AUTO_TEST_CASE(test_method_getDomainMetadata)110 BOOST_AUTO_TEST_CASE(test_method_getDomainMetadata)
111 {
112   std::vector<std::string> meta;
113   BOOST_TEST_MESSAGE("Testing getDomainMetadata method");
114   be->getDomainMetadata(DNSName("unit.test."), "TEST", meta);
115   BOOST_CHECK_EQUAL(meta.size(), 1);
116   // in case we got more than one value, which would be unexpected
117   // but not fatal
118   if (meta.size() > 0)
119     BOOST_CHECK_EQUAL(meta[0], "VALUE");
120 }
121 
BOOST_AUTO_TEST_CASE(test_method_getAllDomainMetadata)122 BOOST_AUTO_TEST_CASE(test_method_getAllDomainMetadata)
123 {
124   std::map<std::string, std::vector<std::string>> meta;
125   BOOST_TEST_MESSAGE("Testing getAllDomainMetadata method");
126   be->getAllDomainMetadata(DNSName("unit.test."), meta);
127   BOOST_CHECK_EQUAL(meta.size(), 1);
128   // in case we got more than one value, which would be unexpected
129   // but not fatal
130   if (meta.size() > 0)
131     BOOST_CHECK_EQUAL(meta["TEST"][0], "VALUE");
132 }
133 
BOOST_AUTO_TEST_CASE(test_method_addDomainKey)134 BOOST_AUTO_TEST_CASE(test_method_addDomainKey)
135 {
136   BOOST_TEST_MESSAGE("Testing addDomainKey method");
137   int64_t id;
138   be->addDomainKey(DNSName("unit.test."), k1, id);
139   BOOST_CHECK_EQUAL(id, 1);
140   be->addDomainKey(DNSName("unit.test."), k2, id);
141   BOOST_CHECK_EQUAL(id, 2);
142 }
143 
BOOST_AUTO_TEST_CASE(test_method_getDomainKeys)144 BOOST_AUTO_TEST_CASE(test_method_getDomainKeys)
145 {
146   std::vector<DNSBackend::KeyData> keys;
147   BOOST_TEST_MESSAGE("Testing getDomainKeys method");
148   // we expect to get two keys
149   be->getDomainKeys(DNSName("unit.test."), keys);
150   BOOST_CHECK_EQUAL(keys.size(), 2);
151   // in case we got more than 2 keys, which would be unexpected
152   // but not fatal
153   if (keys.size() > 1) {
154     // check that we have two keys
155     for (DNSBackend::KeyData& kd : keys) {
156       BOOST_CHECK(kd.id > 0);
157       BOOST_CHECK(kd.flags == 256 || kd.flags == 257);
158       BOOST_CHECK(kd.active == true);
159       BOOST_CHECK(kd.published == true);
160       BOOST_CHECK(kd.content.size() > 500);
161     }
162   }
163 }
164 
BOOST_AUTO_TEST_CASE(test_method_deactivateDomainKey)165 BOOST_AUTO_TEST_CASE(test_method_deactivateDomainKey)
166 {
167   BOOST_TEST_MESSAGE("Testing deactivateDomainKey method");
168   BOOST_CHECK(be->deactivateDomainKey(DNSName("unit.test."), 1));
169 }
170 
BOOST_AUTO_TEST_CASE(test_method_activateDomainKey)171 BOOST_AUTO_TEST_CASE(test_method_activateDomainKey)
172 {
173   BOOST_TEST_MESSAGE("Testing activateDomainKey method");
174   BOOST_CHECK(be->activateDomainKey(DNSName("unit.test."), 1));
175 }
176 
BOOST_AUTO_TEST_CASE(test_method_removeDomainKey)177 BOOST_AUTO_TEST_CASE(test_method_removeDomainKey)
178 {
179   BOOST_CHECK(be->removeDomainKey(DNSName("unit.test."), 2));
180   BOOST_CHECK(be->removeDomainKey(DNSName("unit.test."), 1));
181 }
182 
BOOST_AUTO_TEST_CASE(test_method_getBeforeAndAfterNamesAbsolute)183 BOOST_AUTO_TEST_CASE(test_method_getBeforeAndAfterNamesAbsolute)
184 {
185   DNSName unhashed, before, after;
186   BOOST_TEST_MESSAGE("Testing getBeforeAndAfterNamesAbsolute method");
187 
188   be->getBeforeAndAfterNamesAbsolute(-1, DNSName("middle.unit.test."), unhashed, before, after);
189   BOOST_CHECK_EQUAL(unhashed.toString(), "middle.");
190   BOOST_CHECK_EQUAL(before.toString(), "begin.");
191   BOOST_CHECK_EQUAL(after.toString(), "stop.");
192 }
193 
BOOST_AUTO_TEST_CASE(test_method_setTSIGKey)194 BOOST_AUTO_TEST_CASE(test_method_setTSIGKey)
195 {
196   std::string algorithm, content;
197   BOOST_TEST_MESSAGE("Testing setTSIGKey method");
198   BOOST_CHECK_MESSAGE(be->setTSIGKey(DNSName("unit.test."), DNSName("hmac-md5."), "kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys="), "did not return true");
199 }
200 
BOOST_AUTO_TEST_CASE(test_method_getTSIGKey)201 BOOST_AUTO_TEST_CASE(test_method_getTSIGKey)
202 {
203   DNSName algorithm;
204   std::string content;
205   BOOST_TEST_MESSAGE("Testing getTSIGKey method");
206   be->getTSIGKey(DNSName("unit.test."), &algorithm, &content);
207   BOOST_CHECK_EQUAL(algorithm.toString(), "hmac-md5.");
208   BOOST_CHECK_EQUAL(content, "kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys=");
209 }
210 
BOOST_AUTO_TEST_CASE(test_method_deleteTSIGKey)211 BOOST_AUTO_TEST_CASE(test_method_deleteTSIGKey)
212 {
213   std::string algorithm, content;
214   BOOST_TEST_MESSAGE("Testing deleteTSIGKey method");
215   BOOST_CHECK_MESSAGE(be->deleteTSIGKey(DNSName("unit.test.")), "did not return true");
216 }
217 
BOOST_AUTO_TEST_CASE(test_method_getTSIGKeys)218 BOOST_AUTO_TEST_CASE(test_method_getTSIGKeys)
219 {
220   std::vector<struct TSIGKey> keys;
221   BOOST_TEST_MESSAGE("Testing getTSIGKeys method");
222   be->getTSIGKeys(keys);
223   BOOST_CHECK(keys.size() > 0);
224   if (keys.size() > 0) {
225     BOOST_CHECK_EQUAL(keys[0].name.toString(), "test.");
226     BOOST_CHECK_EQUAL(keys[0].algorithm.toString(), "NULL.");
227     BOOST_CHECK_EQUAL(keys[0].key, "NULL");
228   }
229 }
230 
BOOST_AUTO_TEST_CASE(test_method_setNotified)231 BOOST_AUTO_TEST_CASE(test_method_setNotified)
232 {
233   BOOST_TEST_MESSAGE("Testing setNotified method");
234   be->setNotified(1, 2);
235   BOOST_CHECK(true); // we check this on next step
236 }
237 
BOOST_AUTO_TEST_CASE(test_method_getDomainInfo)238 BOOST_AUTO_TEST_CASE(test_method_getDomainInfo)
239 {
240   DomainInfo di;
241   BOOST_TEST_MESSAGE("Testing getDomainInfo method");
242   be->getDomainInfo(DNSName("unit.test."), di);
243   BOOST_CHECK_EQUAL(di.zone.toString(), "unit.test.");
244   BOOST_CHECK_EQUAL(di.serial, 2);
245   BOOST_CHECK_EQUAL(di.notified_serial, 2);
246   BOOST_CHECK_EQUAL(di.kind, DomainInfo::Native);
247   BOOST_CHECK_EQUAL(di.backend, be);
248 }
249 
BOOST_AUTO_TEST_CASE(test_method_getAllDomains)250 BOOST_AUTO_TEST_CASE(test_method_getAllDomains)
251 {
252   DomainInfo di;
253   BOOST_TEST_MESSAGE("Testing getAllDomains method");
254   vector<DomainInfo> result;
255 
256   be->getAllDomains(&result, true);
257 
258   di = result[0];
259   BOOST_CHECK_EQUAL(di.zone.toString(), "unit.test.");
260   BOOST_CHECK_EQUAL(di.serial, 2);
261   BOOST_CHECK_EQUAL(di.notified_serial, 2);
262   BOOST_CHECK_EQUAL(di.kind, DomainInfo::Native);
263   BOOST_CHECK_EQUAL(di.backend, be);
264 }
265 
BOOST_AUTO_TEST_CASE(test_method_superMasterBackend)266 BOOST_AUTO_TEST_CASE(test_method_superMasterBackend)
267 {
268   DNSResourceRecord rr;
269   std::vector<DNSResourceRecord> nsset;
270   DNSBackend* dbd;
271   BOOST_TEST_MESSAGE("Testing superMasterBackend method");
272 
273   rr.qname = DNSName("example.com.");
274   rr.qtype = QType::NS;
275   rr.qclass = QClass::IN;
276   rr.ttl = 300;
277   rr.content = "ns1.example.com.";
278   nsset.push_back(rr);
279   rr.qname = DNSName("example.com.");
280   rr.qtype = QType::NS;
281   rr.qclass = QClass::IN;
282   rr.ttl = 300;
283   rr.content = "ns2.example.com.";
284   nsset.push_back(rr);
285 
286   BOOST_CHECK(be->superMasterBackend("10.0.0.1", DNSName("example.com."), nsset, NULL, NULL, &dbd));
287 
288   // let's see what we got
289   BOOST_CHECK_EQUAL(dbd, be);
290 }
291 
BOOST_AUTO_TEST_CASE(test_method_createSlaveDomain)292 BOOST_AUTO_TEST_CASE(test_method_createSlaveDomain)
293 {
294   BOOST_TEST_MESSAGE("Testing createSlaveDomain method");
295   BOOST_CHECK(be->createSlaveDomain("10.0.0.1", DNSName("pirate.unit.test."), "", ""));
296 }
297 
BOOST_AUTO_TEST_CASE(test_method_feedRecord)298 BOOST_AUTO_TEST_CASE(test_method_feedRecord)
299 {
300   DNSResourceRecord rr;
301   BOOST_TEST_MESSAGE("Testing feedRecord method");
302   be->startTransaction(DNSName("example.com."), 2);
303   rr.qname = DNSName("example.com.");
304   rr.qtype = QType::SOA;
305   rr.qclass = QClass::IN;
306   rr.ttl = 300;
307   rr.content = "ns1.example.com. hostmaster.example.com. 2013013441 7200 3600 1209600 300";
308   BOOST_CHECK(be->feedRecord(rr, DNSName()));
309   rr.qname = DNSName("replace.example.com.");
310   rr.qtype = QType::A;
311   rr.qclass = QClass::IN;
312   rr.ttl = 300;
313   rr.content = "127.0.0.1";
314   BOOST_CHECK(be->feedRecord(rr, DNSName()));
315   be->commitTransaction();
316 }
317 
BOOST_AUTO_TEST_CASE(test_method_replaceRRSet)318 BOOST_AUTO_TEST_CASE(test_method_replaceRRSet)
319 {
320   be->startTransaction(DNSName("example.com."), 2);
321   DNSResourceRecord rr;
322   std::vector<DNSResourceRecord> rrset;
323   BOOST_TEST_MESSAGE("Testing replaceRRSet method");
324   rr.qname = DNSName("replace.example.com.");
325   rr.qtype = QType::A;
326   rr.qclass = QClass::IN;
327   rr.ttl = 300;
328   rr.content = "1.1.1.1";
329   rrset.push_back(rr);
330   BOOST_CHECK(be->replaceRRSet(2, DNSName("replace.example.com."), QType(QType::A), rrset));
331   be->commitTransaction();
332 }
333 
BOOST_AUTO_TEST_CASE(test_method_feedEnts)334 BOOST_AUTO_TEST_CASE(test_method_feedEnts)
335 {
336   BOOST_TEST_MESSAGE("Testing feedEnts method");
337   be->startTransaction(DNSName("example.com."), 2);
338   map<DNSName, bool> nonterm = boost::assign::map_list_of(DNSName("_udp"), true)(DNSName("_sip._udp"), true);
339   BOOST_CHECK(be->feedEnts(2, nonterm));
340   be->commitTransaction();
341 }
342 
BOOST_AUTO_TEST_CASE(test_method_feedEnts3)343 BOOST_AUTO_TEST_CASE(test_method_feedEnts3)
344 {
345   BOOST_TEST_MESSAGE("Testing feedEnts3 method");
346   be->startTransaction(DNSName("example.com"), 2);
347   NSEC3PARAMRecordContent ns3prc;
348   ns3prc.d_iterations = 1;
349   ns3prc.d_salt = "\u00aa\u00bb\u00cc\u00dd";
350   map<DNSName, bool> nonterm = boost::assign::map_list_of(DNSName("_udp"), true)(DNSName("_sip._udp"), true);
351   BOOST_CHECK(be->feedEnts3(2, DNSName("example.com."), nonterm, ns3prc, 0));
352   be->commitTransaction();
353 }
354 
BOOST_AUTO_TEST_CASE(test_method_abortTransaction)355 BOOST_AUTO_TEST_CASE(test_method_abortTransaction)
356 {
357   BOOST_TEST_MESSAGE("Testing abortTransaction method");
358   be->startTransaction(DNSName("example.com."), 2);
359   BOOST_CHECK(be->abortTransaction());
360 }
361 
BOOST_AUTO_TEST_CASE(test_method_directBackendCmd)362 BOOST_AUTO_TEST_CASE(test_method_directBackendCmd)
363 {
364   BOOST_TEST_MESSAGE("Testing directBackendCmd method");
365   BOOST_CHECK_EQUAL(be->directBackendCmd("PING 1234"), "PING 1234");
366 }
367 
BOOST_AUTO_TEST_CASE(test_method_getUpdatedMasters)368 BOOST_AUTO_TEST_CASE(test_method_getUpdatedMasters)
369 {
370   DomainInfo di;
371   BOOST_TEST_MESSAGE("Testing getUpdatedMasters method");
372   vector<DomainInfo> result;
373 
374   be->getUpdatedMasters(&result);
375 
376   BOOST_CHECK(result.size() > 0);
377 
378   di = result[0];
379   BOOST_CHECK_EQUAL(di.zone.toString(), "master.test.");
380   BOOST_CHECK_EQUAL(di.serial, 2);
381   BOOST_CHECK_EQUAL(di.notified_serial, 2);
382   BOOST_CHECK_EQUAL(di.kind, DomainInfo::Master);
383   BOOST_CHECK_EQUAL(di.backend, be);
384 }
385 
386 BOOST_AUTO_TEST_SUITE_END();
387