auth_srv_unittest.cc 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <config.h>
  15. #include <util/io/sockaddr_util.h>
  16. #include <util/memory_segment_local.h>
  17. #include <dns/message.h>
  18. #include <dns/messagerenderer.h>
  19. #include <dns/name.h>
  20. #include <dns/opcode.h>
  21. #include <dns/rrclass.h>
  22. #include <dns/rrtype.h>
  23. #include <dns/rrttl.h>
  24. #include <dns/rdataclass.h>
  25. #include <dns/tsig.h>
  26. #include <server_common/portconfig.h>
  27. #include <server_common/keyring.h>
  28. #include <datasrc/memory_datasrc.h>
  29. #include <datasrc/client_list.h>
  30. #include <auth/auth_srv.h>
  31. #include <auth/command.h>
  32. #include <auth/common.h>
  33. #include <auth/statistics.h>
  34. #include <auth/statistics_items.h>
  35. #include <auth/datasrc_configurator.h>
  36. #include <util/unittests/mock_socketsession.h>
  37. #include <dns/tests/unittest_util.h>
  38. #include <testutils/dnsmessage_test.h>
  39. #include <testutils/srv_test.h>
  40. #include <testutils/mockups.h>
  41. #include <testutils/portconfig.h>
  42. #include <testutils/socket_request.h>
  43. #include <gtest/gtest.h>
  44. #include <boost/lexical_cast.hpp>
  45. #include <boost/shared_ptr.hpp>
  46. #include <boost/scoped_ptr.hpp>
  47. #include <boost/foreach.hpp>
  48. #include <vector>
  49. #include <sys/types.h>
  50. #include <sys/socket.h>
  51. #include <netdb.h>
  52. using namespace std;
  53. using namespace isc::cc;
  54. using namespace isc::dns;
  55. using namespace isc::util;
  56. using namespace isc::util::io::internal;
  57. using namespace isc::util::unittests;
  58. using namespace isc::dns::rdata;
  59. using namespace isc::data;
  60. using namespace isc::xfr;
  61. using namespace isc::asiodns;
  62. using namespace isc::asiolink;
  63. using namespace isc::testutils;
  64. using namespace isc::server_common::portconfig;
  65. using isc::UnitTestUtil;
  66. using boost::scoped_ptr;
  67. using isc::auth::statistics::Counters;
  68. namespace {
  69. const char* const CONFIG_TESTDB =
  70. "{\"database_file\": \"" TEST_DATA_DIR "/example.sqlite3\"}";
  71. // The following file must be non existent and must be non"creatable" (see
  72. // the sqlite3 test).
  73. const char* const BADCONFIG_TESTDB =
  74. "{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\"}";
  75. const char* const STATIC_DSRC_FILE = DSRC_DIR "/static.zone";
  76. // This is a configuration that uses the in-memory data source containing
  77. // a signed example zone.
  78. const char* const CONFIG_INMEMORY_EXAMPLE = TEST_DATA_DIR "/rfc5155-example.zone.signed";
  79. class AuthSrvTest : public SrvTestBase {
  80. protected:
  81. AuthSrvTest() :
  82. dnss_(),
  83. server(xfrout, ddns_forwarder),
  84. // The empty string is expected value of the parameter of
  85. // requestSocket, not the app_name (there's no fallback, it checks
  86. // the empty string is passed).
  87. sock_requestor_(dnss_, address_store_, 53210, "")
  88. {
  89. server.setDNSService(dnss_);
  90. server.setXfrinSession(&notify_session);
  91. server.createDDNSForwarder();
  92. }
  93. ~AuthSrvTest() {
  94. server.destroyDDNSForwarder();
  95. }
  96. virtual void processMessage() {
  97. // If processMessage has been called before, parse_message needs
  98. // to be reset. If it hasn't, there's no harm in doing so
  99. parse_message->clear(Message::PARSE);
  100. server.processMessage(*io_message, *parse_message, *response_obuffer,
  101. &dnsserv);
  102. }
  103. // Helper for checking Rcode statistic counters;
  104. // Checks for one specific Rcode statistics counter value
  105. void checkRcodeCounter(const std::string& rcode_name, const int rcode_value,
  106. const int expected_value) const
  107. {
  108. EXPECT_EQ(expected_value, rcode_value) <<
  109. "Expected Rcode count for " << rcode_name <<
  110. " " << expected_value << ", was: " <<
  111. rcode_value;
  112. }
  113. // Checks whether all Rcode counters are set to zero
  114. void checkAllRcodeCountersZero() const {
  115. // with checking NOERROR == 0 and the others are 0
  116. checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 0);
  117. }
  118. // Checks whether all Rcode counters are set to zero except the given
  119. // rcode (it is checked to be set to 'value')
  120. void checkAllRcodeCountersZeroExcept(const Rcode& rcode, int value) const {
  121. std::string target_rcode_name = rcode.toText();
  122. std::transform(target_rcode_name.begin(), target_rcode_name.end(),
  123. target_rcode_name.begin(), ::tolower);
  124. const std::map<std::string, ConstElementPtr>
  125. stats_map(server.getStatistics()->get("zones")->get("_SERVER_")->
  126. get("rcode")->mapValue());
  127. for (std::map<std::string, ConstElementPtr>::const_iterator
  128. i = stats_map.begin(), e = stats_map.end();
  129. i != e;
  130. ++i)
  131. {
  132. if (i->first.compare(target_rcode_name) == 0) {
  133. checkRcodeCounter(i->first, i->second->intValue(), value);
  134. } else {
  135. checkRcodeCounter(i->first, i->second->intValue(), 0);
  136. }
  137. }
  138. }
  139. // Convenience method for tests that expect to return SERVFAIL
  140. // It calls processMessage, checks if there is an answer, and
  141. // check the header for default SERVFAIL data
  142. void processAndCheckSERVFAIL() {
  143. processMessage();
  144. EXPECT_TRUE(dnsserv.hasAnswer());
  145. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  146. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  147. }
  148. // Convenient shortcut of creating a simple request and having the
  149. // server process it.
  150. void createAndSendRequest(RRType req_type, Opcode opcode = Opcode::QUERY(),
  151. const Name& req_name = Name("example.com"),
  152. RRClass req_class = RRClass::IN(),
  153. int protocol = IPPROTO_UDP,
  154. const char* const remote_address =
  155. DEFAULT_REMOTE_ADDRESS,
  156. uint16_t remote_port = DEFAULT_REMOTE_PORT)
  157. {
  158. UnitTestUtil::createRequestMessage(request_message, opcode,
  159. default_qid, req_name,
  160. req_class, req_type);
  161. createRequestPacket(request_message, protocol, NULL,
  162. remote_address, remote_port);
  163. parse_message->clear(Message::PARSE);
  164. server.processMessage(*io_message, *parse_message, *response_obuffer,
  165. &dnsserv);
  166. }
  167. MockDNSService dnss_;
  168. MockXfroutClient xfrout;
  169. MockSocketSessionForwarder ddns_forwarder;
  170. AuthSrv server;
  171. vector<uint8_t> response_data;
  172. AddressList address_store_;
  173. TestSocketRequestor sock_requestor_;
  174. };
  175. // A helper function that builds a response to version.bind/TXT/CH that
  176. // should be identical to the response from our builtin (static) data source
  177. // by default. The resulting wire-format data will be stored in 'data'.
  178. void
  179. createBuiltinVersionResponse(const qid_t qid, vector<uint8_t>& data) {
  180. const Name version_name("VERSION.BIND.");
  181. const Name apex_name("BIND.");
  182. Message message(Message::RENDER);
  183. UnitTestUtil::createRequestMessage(message, Opcode::QUERY(),
  184. qid, version_name,
  185. RRClass::CH(), RRType::TXT());
  186. message.setHeaderFlag(Message::HEADERFLAG_QR);
  187. message.setHeaderFlag(Message::HEADERFLAG_AA);
  188. RRsetPtr rrset_version = RRsetPtr(new RRset(version_name, RRClass::CH(),
  189. RRType::TXT(), RRTTL(0)));
  190. rrset_version->addRdata(generic::TXT(PACKAGE_STRING));
  191. message.addRRset(Message::SECTION_ANSWER, rrset_version);
  192. RRsetPtr rrset_version_ns = RRsetPtr(new RRset(apex_name, RRClass::CH(),
  193. RRType::NS(), RRTTL(0)));
  194. rrset_version_ns->addRdata(generic::NS(apex_name));
  195. message.addRRset(Message::SECTION_AUTHORITY, rrset_version_ns);
  196. MessageRenderer renderer;
  197. message.toWire(renderer);
  198. data.clear();
  199. data.assign(static_cast<const uint8_t*>(renderer.getData()),
  200. static_cast<const uint8_t*>(renderer.getData()) +
  201. renderer.getLength());
  202. }
  203. // Check if the item has expected value.
  204. // Before reading the item, check the item exists.
  205. void
  206. expectCounterItem(ConstElementPtr stats,
  207. const std::string& item, const int expected) {
  208. ConstElementPtr value(Element::create(0));
  209. ASSERT_TRUE(stats->find(item, value)) << " Item: " << item;
  210. value = stats->find(item);
  211. EXPECT_EQ(expected, value->intValue()) << " Item: " << item;
  212. }
  213. // We did not configure any client lists. Therefore it should be REFUSED
  214. TEST_F(AuthSrvTest, noClientList) {
  215. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  216. default_qid, Name("version.bind"),
  217. RRClass::CH(), RRType::TXT());
  218. createRequestPacket(request_message, IPPROTO_UDP);
  219. server.processMessage(*io_message, *parse_message, *response_obuffer,
  220. &dnsserv);
  221. EXPECT_TRUE(dnsserv.hasAnswer());
  222. headerCheck(*parse_message, default_qid, Rcode::REFUSED(),
  223. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  224. }
  225. // Unsupported requests. Should result in NOTIMP.
  226. TEST_F(AuthSrvTest, unsupportedRequest) {
  227. unsupportedRequest();
  228. // unsupportedRequest tries 13 different opcodes
  229. checkAllRcodeCountersZeroExcept(Rcode::NOTIMP(), 13);
  230. }
  231. // Multiple questions. Should result in FORMERR.
  232. TEST_F(AuthSrvTest, multiQuestion) {
  233. multiQuestion();
  234. checkAllRcodeCountersZeroExcept(Rcode::FORMERR(), 1);
  235. }
  236. // Incoming data doesn't even contain the complete header. Must be silently
  237. // dropped.
  238. TEST_F(AuthSrvTest, shortMessage) {
  239. shortMessage();
  240. checkAllRcodeCountersZero();
  241. }
  242. // Response messages. Must be silently dropped, whether it's a valid response
  243. // or malformed or could otherwise cause a protocol error.
  244. TEST_F(AuthSrvTest, response) {
  245. response();
  246. checkAllRcodeCountersZero();
  247. }
  248. // Query with a broken question
  249. TEST_F(AuthSrvTest, shortQuestion) {
  250. shortQuestion();
  251. checkAllRcodeCountersZeroExcept(Rcode::FORMERR(), 1);
  252. }
  253. // Query with a broken answer section
  254. TEST_F(AuthSrvTest, shortAnswer) {
  255. shortAnswer();
  256. checkAllRcodeCountersZeroExcept(Rcode::FORMERR(), 1);
  257. }
  258. // Query with unsupported version of EDNS.
  259. TEST_F(AuthSrvTest, ednsBadVers) {
  260. ednsBadVers();
  261. checkAllRcodeCountersZeroExcept(Rcode::BADVERS(), 1);
  262. }
  263. TEST_F(AuthSrvTest, AXFROverUDP) {
  264. axfrOverUDP();
  265. }
  266. TEST_F(AuthSrvTest, AXFRSuccess) {
  267. EXPECT_FALSE(xfrout.isConnected());
  268. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  269. Name("example.com"), RRClass::IN(),
  270. RRType::AXFR());
  271. createRequestPacket(request_message, IPPROTO_TCP);
  272. // On success, the AXFR query has been passed to a separate process,
  273. // so we shouldn't have to respond.
  274. server.processMessage(*io_message, *parse_message, *response_obuffer,
  275. &dnsserv);
  276. EXPECT_FALSE(dnsserv.hasAnswer());
  277. EXPECT_TRUE(xfrout.isConnected());
  278. checkAllRcodeCountersZero();
  279. }
  280. // Give the server a signed request, but don't give it the key. It will
  281. // not be able to verify it, returning BADKEY
  282. TEST_F(AuthSrvTest, TSIGSignedBadKey) {
  283. TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  284. TSIGContext context(key);
  285. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  286. Name("version.bind"), RRClass::CH(),
  287. RRType::TXT());
  288. createRequestPacket(request_message, IPPROTO_UDP, &context);
  289. // Process the message, but use a different key there
  290. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  291. server.setTSIGKeyRing(&keyring);
  292. server.processMessage(*io_message, *parse_message, *response_obuffer,
  293. &dnsserv);
  294. EXPECT_TRUE(dnsserv.hasAnswer());
  295. headerCheck(*parse_message, default_qid, TSIGError::BAD_KEY().toRcode(),
  296. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  297. // We need to parse the message ourself, or getTSIGRecord won't work
  298. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  299. Message m(Message::PARSE);
  300. m.fromWire(ib);
  301. const TSIGRecord* tsig = m.getTSIGRecord();
  302. ASSERT_TRUE(tsig != NULL) <<
  303. "Missing TSIG signature (we should have one even at error)";
  304. EXPECT_EQ(TSIGError::BAD_KEY_CODE, tsig->getRdata().getError());
  305. EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
  306. "It should be unsigned with this error";
  307. checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
  308. }
  309. // Give the server a signed request, but signed by a different key
  310. // (with the same name). It should return BADSIG
  311. TEST_F(AuthSrvTest, TSIGBadSig) {
  312. TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  313. TSIGContext context(key);
  314. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  315. Name("version.bind"), RRClass::CH(),
  316. RRType::TXT());
  317. createRequestPacket(request_message, IPPROTO_UDP, &context);
  318. // Process the message, but use a different key there
  319. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  320. keyring->add(TSIGKey("key:QkFECg==:hmac-sha1"));
  321. server.setTSIGKeyRing(&keyring);
  322. server.processMessage(*io_message, *parse_message, *response_obuffer,
  323. &dnsserv);
  324. EXPECT_TRUE(dnsserv.hasAnswer());
  325. headerCheck(*parse_message, default_qid, TSIGError::BAD_SIG().toRcode(),
  326. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  327. // We need to parse the message ourself, or getTSIGRecord won't work
  328. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  329. Message m(Message::PARSE);
  330. m.fromWire(ib);
  331. const TSIGRecord* tsig = m.getTSIGRecord();
  332. ASSERT_TRUE(tsig != NULL) <<
  333. "Missing TSIG signature (we should have one even at error)";
  334. EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig->getRdata().getError());
  335. EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
  336. "It should be unsigned with this error";
  337. checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
  338. }
  339. // Give the server a signed unsupported request with a bad signature.
  340. // This checks the server first verifies the signature before anything
  341. // else.
  342. TEST_F(AuthSrvTest, TSIGCheckFirst) {
  343. TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  344. TSIGContext context(key);
  345. // Pass a wrong opcode there. The server shouldn't know what to do
  346. // about it.
  347. UnitTestUtil::createRequestMessage(request_message, Opcode::RESERVED14(),
  348. default_qid, Name("version.bind"),
  349. RRClass::CH(), RRType::TXT());
  350. createRequestPacket(request_message, IPPROTO_UDP, &context);
  351. // Process the message, but use a different key there
  352. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  353. keyring->add(TSIGKey("key:QkFECg==:hmac-sha1"));
  354. server.setTSIGKeyRing(&keyring);
  355. server.processMessage(*io_message, *parse_message, *response_obuffer,
  356. &dnsserv);
  357. EXPECT_TRUE(dnsserv.hasAnswer());
  358. headerCheck(*parse_message, default_qid, TSIGError::BAD_SIG().toRcode(),
  359. Opcode::RESERVED14().getCode(), QR_FLAG, 0, 0, 0, 0);
  360. // We need to parse the message ourself, or getTSIGRecord won't work
  361. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  362. Message m(Message::PARSE);
  363. m.fromWire(ib);
  364. const TSIGRecord* tsig = m.getTSIGRecord();
  365. ASSERT_TRUE(tsig != NULL) <<
  366. "Missing TSIG signature (we should have one even at error)";
  367. EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig->getRdata().getError());
  368. EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
  369. "It should be unsigned with this error";
  370. // TSIG should have failed, and so the per opcode counter shouldn't be
  371. // incremented.
  372. ConstElementPtr stats = server.getStatistics();
  373. expectCounterItem(stats->get("zones")->get("_SERVER_")->get("opcode"),
  374. "other", 0);
  375. checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
  376. }
  377. TEST_F(AuthSrvTest, AXFRConnectFail) {
  378. EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
  379. xfrout.disableConnect();
  380. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  381. Name("example.com"), RRClass::IN(),
  382. RRType::AXFR());
  383. createRequestPacket(request_message, IPPROTO_TCP);
  384. server.processMessage(*io_message, *parse_message, *response_obuffer,
  385. &dnsserv);
  386. EXPECT_TRUE(dnsserv.hasAnswer());
  387. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  388. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  389. EXPECT_FALSE(xfrout.isConnected());
  390. }
  391. TEST_F(AuthSrvTest, AXFRSendFail) {
  392. // first send a valid query, making the connection with the xfr process
  393. // open.
  394. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  395. Name("example.com"), RRClass::IN(),
  396. RRType::AXFR());
  397. createRequestPacket(request_message, IPPROTO_TCP);
  398. server.processMessage(*io_message, *parse_message, *response_obuffer,
  399. &dnsserv);
  400. EXPECT_TRUE(xfrout.isConnected());
  401. xfrout.disableSend();
  402. parse_message->clear(Message::PARSE);
  403. response_obuffer->clear();
  404. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  405. Name("example.com"), RRClass::IN(),
  406. RRType::AXFR());
  407. createRequestPacket(request_message, IPPROTO_TCP);
  408. server.processMessage(*io_message, *parse_message, *response_obuffer,
  409. &dnsserv);
  410. EXPECT_TRUE(dnsserv.hasAnswer());
  411. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  412. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  413. // The connection should have been closed due to the send failure.
  414. EXPECT_FALSE(xfrout.isConnected());
  415. }
  416. TEST_F(AuthSrvTest, AXFRDisconnectFail) {
  417. // In our usage disconnect() shouldn't fail. But even if it does,
  418. // it should not disrupt service (so processMessage should have caught it)
  419. xfrout.disableSend();
  420. xfrout.disableDisconnect();
  421. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  422. Name("example.com"), RRClass::IN(),
  423. RRType::AXFR());
  424. createRequestPacket(request_message, IPPROTO_TCP);
  425. EXPECT_NO_THROW(server.processMessage(*io_message, *parse_message,
  426. *response_obuffer, &dnsserv));
  427. // Since the disconnect failed, we should still be 'connected'
  428. EXPECT_TRUE(xfrout.isConnected());
  429. // XXX: we need to re-enable disconnect. otherwise an exception would be
  430. // thrown via the destructor of the server.
  431. xfrout.enableDisconnect();
  432. }
  433. TEST_F(AuthSrvTest, IXFRConnectFail) {
  434. EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
  435. xfrout.disableConnect();
  436. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  437. Name("example.com"), RRClass::IN(),
  438. RRType::IXFR());
  439. createRequestPacket(request_message, IPPROTO_TCP);
  440. server.processMessage(*io_message, *parse_message, *response_obuffer,
  441. &dnsserv);
  442. EXPECT_TRUE(dnsserv.hasAnswer());
  443. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  444. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  445. EXPECT_FALSE(xfrout.isConnected());
  446. }
  447. TEST_F(AuthSrvTest, IXFRSendFail) {
  448. // first send a valid query, making the connection with the xfr process
  449. // open.
  450. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  451. Name("example.com"), RRClass::IN(),
  452. RRType::IXFR());
  453. createRequestPacket(request_message, IPPROTO_TCP);
  454. server.processMessage(*io_message, *parse_message, *response_obuffer,
  455. &dnsserv);
  456. EXPECT_TRUE(xfrout.isConnected());
  457. xfrout.disableSend();
  458. parse_message->clear(Message::PARSE);
  459. response_obuffer->clear();
  460. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  461. Name("example.com"), RRClass::IN(),
  462. RRType::IXFR());
  463. createRequestPacket(request_message, IPPROTO_TCP);
  464. server.processMessage(*io_message, *parse_message, *response_obuffer,
  465. &dnsserv);
  466. EXPECT_TRUE(dnsserv.hasAnswer());
  467. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  468. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  469. // The connection should have been closed due to the send failure.
  470. EXPECT_FALSE(xfrout.isConnected());
  471. }
  472. TEST_F(AuthSrvTest, IXFRDisconnectFail) {
  473. // In our usage disconnect() shouldn't fail, but even if it does,
  474. // procesMessage() should catch it.
  475. xfrout.disableSend();
  476. xfrout.disableDisconnect();
  477. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  478. Name("example.com"), RRClass::IN(),
  479. RRType::IXFR());
  480. createRequestPacket(request_message, IPPROTO_TCP);
  481. EXPECT_NO_THROW(server.processMessage(*io_message, *parse_message,
  482. *response_obuffer, &dnsserv));
  483. EXPECT_TRUE(xfrout.isConnected());
  484. // XXX: we need to re-enable disconnect. otherwise an exception would be
  485. // thrown via the destructor of the server.
  486. xfrout.enableDisconnect();
  487. }
  488. TEST_F(AuthSrvTest, notify) {
  489. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  490. default_qid, Name("example.com"),
  491. RRClass::IN(), RRType::SOA());
  492. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  493. createRequestPacket(request_message, IPPROTO_UDP);
  494. server.processMessage(*io_message, *parse_message, *response_obuffer,
  495. &dnsserv);
  496. EXPECT_TRUE(dnsserv.hasAnswer());
  497. // An internal command message should have been created and sent to an
  498. // external module. Check them.
  499. EXPECT_EQ("Zonemgr", notify_session.getMessageDest());
  500. EXPECT_EQ("notify",
  501. notify_session.getSentMessage()->get("command")->get(0)->stringValue());
  502. ConstElementPtr notify_args =
  503. notify_session.getSentMessage()->get("command")->get(1);
  504. EXPECT_EQ("example.com.", notify_args->get("zone_name")->stringValue());
  505. EXPECT_EQ(DEFAULT_REMOTE_ADDRESS,
  506. notify_args->get("master")->stringValue());
  507. EXPECT_EQ("IN", notify_args->get("zone_class")->stringValue());
  508. // On success, the server should return a response to the notify.
  509. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  510. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  511. // The question must be identical to that of the received notify
  512. ConstQuestionPtr question = *parse_message->beginQuestion();
  513. EXPECT_EQ(Name("example.com"), question->getName());
  514. EXPECT_EQ(RRClass::IN(), question->getClass());
  515. EXPECT_EQ(RRType::SOA(), question->getType());
  516. checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 1);
  517. }
  518. TEST_F(AuthSrvTest, notifyForCHClass) {
  519. // Same as the previous test, but for the CH RRClass.
  520. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  521. default_qid, Name("example.com"),
  522. RRClass::CH(), RRType::SOA());
  523. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  524. createRequestPacket(request_message, IPPROTO_UDP);
  525. server.processMessage(*io_message, *parse_message, *response_obuffer,
  526. &dnsserv);
  527. EXPECT_TRUE(dnsserv.hasAnswer());
  528. // Other conditions should be the same, so simply confirm the RR class is
  529. // set correctly.
  530. ConstElementPtr notify_args =
  531. notify_session.getSentMessage()->get("command")->get(1);
  532. EXPECT_EQ("CH", notify_args->get("zone_class")->stringValue());
  533. }
  534. TEST_F(AuthSrvTest, notifyEmptyQuestion) {
  535. request_message.clear(Message::RENDER);
  536. request_message.setOpcode(Opcode::NOTIFY());
  537. request_message.setRcode(Rcode::NOERROR());
  538. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  539. request_message.setQid(default_qid);
  540. request_message.toWire(request_renderer);
  541. createRequestPacket(request_message, IPPROTO_UDP);
  542. server.processMessage(*io_message, *parse_message, *response_obuffer,
  543. &dnsserv);
  544. EXPECT_TRUE(dnsserv.hasAnswer());
  545. headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
  546. Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
  547. }
  548. TEST_F(AuthSrvTest, notifyMultiQuestions) {
  549. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  550. default_qid, Name("example.com"),
  551. RRClass::IN(), RRType::SOA());
  552. // add one more SOA question
  553. request_message.addQuestion(Question(Name("example.com"), RRClass::IN(),
  554. RRType::SOA()));
  555. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  556. createRequestPacket(request_message, IPPROTO_UDP);
  557. server.processMessage(*io_message, *parse_message, *response_obuffer,
  558. &dnsserv);
  559. EXPECT_TRUE(dnsserv.hasAnswer());
  560. headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
  561. Opcode::NOTIFY().getCode(), QR_FLAG, 2, 0, 0, 0);
  562. }
  563. TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
  564. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  565. default_qid, Name("example.com"),
  566. RRClass::IN(), RRType::NS());
  567. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  568. createRequestPacket(request_message, IPPROTO_UDP);
  569. server.processMessage(*io_message, *parse_message, *response_obuffer,
  570. &dnsserv);
  571. EXPECT_TRUE(dnsserv.hasAnswer());
  572. headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
  573. Opcode::NOTIFY().getCode(), QR_FLAG, 1, 0, 0, 0);
  574. }
  575. TEST_F(AuthSrvTest, notifyWithoutAA) {
  576. // implicitly leave the AA bit off. our implementation will accept it.
  577. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  578. default_qid, Name("example.com"),
  579. RRClass::IN(), RRType::SOA());
  580. createRequestPacket(request_message, IPPROTO_UDP);
  581. server.processMessage(*io_message, *parse_message, *response_obuffer,
  582. &dnsserv);
  583. EXPECT_TRUE(dnsserv.hasAnswer());
  584. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  585. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  586. }
  587. TEST_F(AuthSrvTest, notifyWithErrorRcode) {
  588. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  589. default_qid, Name("example.com"),
  590. RRClass::IN(), RRType::SOA());
  591. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  592. request_message.setRcode(Rcode::SERVFAIL());
  593. createRequestPacket(request_message, IPPROTO_UDP);
  594. server.processMessage(*io_message, *parse_message, *response_obuffer,
  595. &dnsserv);
  596. EXPECT_TRUE(dnsserv.hasAnswer());
  597. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  598. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  599. }
  600. TEST_F(AuthSrvTest, notifyWithoutSession) {
  601. server.setXfrinSession(NULL);
  602. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  603. default_qid, Name("example.com"),
  604. RRClass::IN(), RRType::SOA());
  605. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  606. createRequestPacket(request_message, IPPROTO_UDP);
  607. // we simply ignore the notify and let it be resent if an internal error
  608. // happens.
  609. server.processMessage(*io_message, *parse_message, *response_obuffer,
  610. &dnsserv);
  611. EXPECT_FALSE(dnsserv.hasAnswer());
  612. }
  613. TEST_F(AuthSrvTest, notifySendFail) {
  614. notify_session.disableSend();
  615. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  616. default_qid, Name("example.com"),
  617. RRClass::IN(), RRType::SOA());
  618. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  619. createRequestPacket(request_message, IPPROTO_UDP);
  620. server.processMessage(*io_message, *parse_message, *response_obuffer,
  621. &dnsserv);
  622. EXPECT_FALSE(dnsserv.hasAnswer());
  623. }
  624. TEST_F(AuthSrvTest, notifyReceiveFail) {
  625. notify_session.disableReceive();
  626. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  627. default_qid, Name("example.com"),
  628. RRClass::IN(), RRType::SOA());
  629. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  630. createRequestPacket(request_message, IPPROTO_UDP);
  631. server.processMessage(*io_message, *parse_message, *response_obuffer,
  632. &dnsserv);
  633. EXPECT_FALSE(dnsserv.hasAnswer());
  634. }
  635. TEST_F(AuthSrvTest, notifyWithBogusSessionMessage) {
  636. notify_session.setMessage(Element::fromJSON("{\"foo\": 1}"));
  637. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  638. default_qid, Name("example.com"),
  639. RRClass::IN(), RRType::SOA());
  640. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  641. createRequestPacket(request_message, IPPROTO_UDP);
  642. server.processMessage(*io_message, *parse_message, *response_obuffer,
  643. &dnsserv);
  644. EXPECT_FALSE(dnsserv.hasAnswer());
  645. }
  646. TEST_F(AuthSrvTest, notifyWithSessionMessageError) {
  647. notify_session.setMessage(
  648. Element::fromJSON("{\"result\": [1, \"FAIL\"]}"));
  649. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  650. default_qid, Name("example.com"),
  651. RRClass::IN(), RRType::SOA());
  652. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  653. createRequestPacket(request_message, IPPROTO_UDP);
  654. server.processMessage(*io_message, *parse_message, *response_obuffer,
  655. &dnsserv);
  656. EXPECT_FALSE(dnsserv.hasAnswer());
  657. }
  658. void
  659. updateDatabase(AuthSrv* server, const char* params) {
  660. const ConstElementPtr config(Element::fromJSON("{"
  661. "\"IN\": [{"
  662. " \"type\": \"sqlite3\","
  663. " \"params\": " + string(params) +
  664. "}]}"));
  665. DataSourceConfigurator::testReconfigure(server, config);
  666. }
  667. void
  668. updateInMemory(AuthSrv* server, const char* origin, const char* filename) {
  669. const ConstElementPtr config(Element::fromJSON("{"
  670. "\"IN\": [{"
  671. " \"type\": \"MasterFiles\","
  672. " \"params\": {"
  673. " \"" + string(origin) + "\": \"" + string(filename) + "\""
  674. " },"
  675. " \"cache-enable\": true"
  676. "}],"
  677. "\"CH\": [{"
  678. " \"type\": \"static\","
  679. " \"params\": \"" + string(STATIC_DSRC_FILE) + "\""
  680. "}]}"));
  681. DataSourceConfigurator::testReconfigure(server, config);
  682. }
  683. void
  684. updateBuiltin(AuthSrv* server) {
  685. const ConstElementPtr config(Element::fromJSON("{"
  686. "\"CH\": [{"
  687. " \"type\": \"static\","
  688. " \"params\": \"" + string(STATIC_DSRC_FILE) + "\""
  689. "}]}"));
  690. DataSourceConfigurator::testReconfigure(server, config);
  691. }
  692. // Try giving the server a TSIG signed request and see it can anwer signed as
  693. // well
  694. #ifdef USE_STATIC_LINK
  695. TEST_F(AuthSrvTest, DISABLED_TSIGSigned) { // Needs builtin
  696. #else
  697. TEST_F(AuthSrvTest, TSIGSigned) {
  698. #endif
  699. // Prepare key, the client message, etc
  700. updateBuiltin(&server);
  701. const TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  702. TSIGContext context(key);
  703. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  704. Name("VERSION.BIND."), RRClass::CH(),
  705. RRType::TXT());
  706. createRequestPacket(request_message, IPPROTO_UDP, &context);
  707. // Run the message through the server
  708. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  709. keyring->add(key);
  710. server.setTSIGKeyRing(&keyring);
  711. server.processMessage(*io_message, *parse_message, *response_obuffer,
  712. &dnsserv);
  713. // What did we get?
  714. EXPECT_TRUE(dnsserv.hasAnswer());
  715. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  716. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  717. // We need to parse the message ourself, or getTSIGRecord won't work
  718. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  719. Message m(Message::PARSE);
  720. m.fromWire(ib);
  721. const TSIGRecord* tsig = m.getTSIGRecord();
  722. ASSERT_TRUE(tsig != NULL) << "Missing TSIG signature";
  723. TSIGError error(context.verify(tsig, response_obuffer->getData(),
  724. response_obuffer->getLength()));
  725. EXPECT_EQ(TSIGError::NOERROR(), error) <<
  726. "The server signed the response, but it doesn't seem to be valid";
  727. checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 1);
  728. }
  729. // Same test emulating the UDPServer class behavior (defined in libasiolink).
  730. // This is not a good test in that it assumes internal implementation details
  731. // of UDPServer, but we've encountered a regression due to the introduction
  732. // of that class, so we add a test for that case to prevent such a regression
  733. // in future.
  734. // Besides, the generalization of UDPServer is probably too much for the
  735. // authoritative only server in terms of performance, and it's quite likely
  736. // we need to drop it for the authoritative server implementation.
  737. // At that point we can drop this test, too.
  738. #ifdef USE_STATIC_LINK
  739. TEST_F(AuthSrvTest, DISABLED_builtInQueryViaDNSServer) {
  740. #else
  741. TEST_F(AuthSrvTest, builtInQueryViaDNSServer) {
  742. #endif
  743. updateBuiltin(&server);
  744. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  745. default_qid, Name("VERSION.BIND."),
  746. RRClass::CH(), RRType::TXT());
  747. createRequestPacket(request_message, IPPROTO_UDP);
  748. (*server.getDNSLookupProvider())(*io_message, parse_message,
  749. response_message,
  750. response_obuffer, &dnsserv);
  751. (*server.getDNSAnswerProvider())(*io_message, parse_message,
  752. response_message, response_obuffer);
  753. createBuiltinVersionResponse(default_qid, response_data);
  754. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  755. response_obuffer->getData(),
  756. response_obuffer->getLength(),
  757. &response_data[0], response_data.size());
  758. // After it has been run, the message should be cleared
  759. EXPECT_EQ(0, parse_message->getRRCount(Message::SECTION_QUESTION));
  760. }
  761. // In the following tests we confirm the response data is rendered in
  762. // wire format in the expected way.
  763. // The most primitive check: checking the result of the processMessage()
  764. // method
  765. #ifdef USE_STATIC_LINK
  766. TEST_F(AuthSrvTest, DISABLED_builtInQuery) {
  767. #else
  768. TEST_F(AuthSrvTest, builtInQuery) {
  769. #endif
  770. updateBuiltin(&server);
  771. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  772. default_qid, Name("VERSION.BIND."),
  773. RRClass::CH(), RRType::TXT());
  774. createRequestPacket(request_message, IPPROTO_UDP);
  775. server.processMessage(*io_message, *parse_message, *response_obuffer,
  776. &dnsserv);
  777. createBuiltinVersionResponse(default_qid, response_data);
  778. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  779. response_obuffer->getData(),
  780. response_obuffer->getLength(),
  781. &response_data[0], response_data.size());
  782. checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 1);
  783. }
  784. // Same type of test as builtInQueryViaDNSServer but for an error response.
  785. #ifdef USE_STATIC_LINK
  786. TEST_F(AuthSrvTest, DISABLED_iqueryViaDNSServer) { // Needs builtin
  787. #else
  788. TEST_F(AuthSrvTest, iqueryViaDNSServer) { // Needs builtin
  789. #endif
  790. updateBuiltin(&server);
  791. createDataFromFile("iquery_fromWire.wire");
  792. (*server.getDNSLookupProvider())(*io_message, parse_message,
  793. response_message,
  794. response_obuffer, &dnsserv);
  795. (*server.getDNSAnswerProvider())(*io_message, parse_message,
  796. response_message, response_obuffer);
  797. UnitTestUtil::readWireData("iquery_response_fromWire.wire",
  798. response_data);
  799. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  800. response_obuffer->getData(),
  801. response_obuffer->getLength(),
  802. &response_data[0], response_data.size());
  803. }
  804. // Install a Sqlite3 data source with testing data.
  805. #ifdef USE_STATIC_LINK
  806. TEST_F(AuthSrvTest, DISABLED_updateConfig) {
  807. #else
  808. TEST_F(AuthSrvTest, updateConfig) {
  809. #endif
  810. updateDatabase(&server, CONFIG_TESTDB);
  811. // query for existent data in the installed data source. The resulting
  812. // response should have the AA flag on, and have an RR in each answer
  813. // and authority section.
  814. createDataFromFile("examplequery_fromWire.wire");
  815. server.processMessage(*io_message, *parse_message, *response_obuffer,
  816. &dnsserv);
  817. EXPECT_TRUE(dnsserv.hasAnswer());
  818. headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
  819. QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  820. }
  821. #ifdef USE_STATIC_LINK
  822. TEST_F(AuthSrvTest, DISABLED_datasourceFail) {
  823. #else
  824. TEST_F(AuthSrvTest, datasourceFail) {
  825. #endif
  826. updateDatabase(&server, CONFIG_TESTDB);
  827. // This query will hit a corrupted entry of the data source (the zoneload
  828. // tool and the data source itself naively accept it). This will result
  829. // in a SERVFAIL response, and the answer and authority sections should
  830. // be empty.
  831. createDataFromFile("badExampleQuery_fromWire.wire");
  832. server.processMessage(*io_message, *parse_message, *response_obuffer,
  833. &dnsserv);
  834. EXPECT_TRUE(dnsserv.hasAnswer());
  835. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  836. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  837. }
  838. #ifdef USE_STATIC_LINK
  839. TEST_F(AuthSrvTest, DISABLED_updateConfigFail) {
  840. #else
  841. TEST_F(AuthSrvTest, updateConfigFail) {
  842. #endif
  843. // First, load a valid data source.
  844. updateDatabase(&server, CONFIG_TESTDB);
  845. // Next, try to update it with a non-existent one. This should fail.
  846. EXPECT_THROW(updateDatabase(&server, BADCONFIG_TESTDB),
  847. isc::datasrc::DataSourceError);
  848. // The original data source should still exist.
  849. createDataFromFile("examplequery_fromWire.wire");
  850. server.processMessage(*io_message, *parse_message, *response_obuffer,
  851. &dnsserv);
  852. EXPECT_TRUE(dnsserv.hasAnswer());
  853. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  854. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  855. }
  856. TEST_F(AuthSrvTest, updateWithInMemoryClient) {
  857. // Test configuring memory data source. Detailed test cases are covered
  858. // in the configuration tests. We only check the AuthSrv interface here.
  859. // Create an empty in-memory
  860. const ConstElementPtr config(Element::fromJSON("{"
  861. "\"IN\": [{"
  862. " \"type\": \"MasterFiles\","
  863. " \"params\": {},"
  864. " \"cache-enable\": true"
  865. "}]}"));
  866. DataSourceConfigurator::testReconfigure(&server, config);
  867. // after successful configuration, we should have one (with empty zoneset).
  868. // The memory data source is empty, should return REFUSED rcode.
  869. createDataFromFile("examplequery_fromWire.wire");
  870. server.processMessage(*io_message, *parse_message, *response_obuffer,
  871. &dnsserv);
  872. EXPECT_TRUE(dnsserv.hasAnswer());
  873. headerCheck(*parse_message, default_qid, Rcode::REFUSED(),
  874. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  875. }
  876. #ifdef USE_STATIC_LINK
  877. TEST_F(AuthSrvTest, DISABLED_queryWithInMemoryClientNoDNSSEC) {
  878. #else
  879. TEST_F(AuthSrvTest, queryWithInMemoryClientNoDNSSEC) {
  880. #endif
  881. // In this example, we do simple check that query is handled from the
  882. // query handler class, and confirm it returns no error and a non empty
  883. // answer section. Detailed examination on the response content
  884. // for various types of queries are tested in the query tests.
  885. updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
  886. createDataFromFile("nsec3query_nodnssec_fromWire.wire");
  887. server.processMessage(*io_message, *parse_message, *response_obuffer,
  888. &dnsserv);
  889. EXPECT_TRUE(dnsserv.hasAnswer());
  890. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  891. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 2, 1);
  892. }
  893. #ifdef USE_STATIC_LINK
  894. TEST_F(AuthSrvTest, DISABLED_queryWithInMemoryClientDNSSEC) {
  895. #else
  896. TEST_F(AuthSrvTest, queryWithInMemoryClientDNSSEC) {
  897. #endif
  898. // Similar to the previous test, but the query has the DO bit on.
  899. // The response should contain RRSIGs, and should have more RRs than
  900. // the previous case.
  901. updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
  902. createDataFromFile("nsec3query_fromWire.wire");
  903. server.processMessage(*io_message, *parse_message, *response_obuffer,
  904. &dnsserv);
  905. EXPECT_TRUE(dnsserv.hasAnswer());
  906. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  907. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 2, 3, 3);
  908. }
  909. TEST_F(AuthSrvTest,
  910. #ifdef USE_STATIC_LINK
  911. DISABLED_chQueryWithInMemoryClient
  912. #else
  913. chQueryWithInMemoryClient
  914. #endif
  915. )
  916. {
  917. // Set up the in-memory
  918. updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
  919. // This shouldn't affect the result of class CH query
  920. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  921. default_qid, Name("VERSION.BIND."),
  922. RRClass::CH(), RRType::TXT());
  923. createRequestPacket(request_message, IPPROTO_UDP);
  924. server.processMessage(*io_message, *parse_message, *response_obuffer,
  925. &dnsserv);
  926. EXPECT_TRUE(dnsserv.hasAnswer());
  927. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  928. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  929. }
  930. // Submit UDP normal query and check query counter
  931. TEST_F(AuthSrvTest, queryCounterUDPNormal) {
  932. // The counters should be initialized to 0.
  933. ConstElementPtr stats_init = server.getStatistics()->
  934. get("zones")->get("_SERVER_");
  935. expectCounterItem(stats_init->get("request"), "udp", 0);
  936. expectCounterItem(stats_init->get("request"), "tcp", 0);
  937. expectCounterItem(stats_init->get("opcode"), "query", 0);
  938. expectCounterItem(stats_init->get("rcode"), "refused", 0);
  939. // Create UDP message and process.
  940. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  941. default_qid, Name("example.com"),
  942. RRClass::IN(), RRType::NS());
  943. createRequestPacket(request_message, IPPROTO_UDP);
  944. server.processMessage(*io_message, *parse_message, *response_obuffer,
  945. &dnsserv);
  946. // After processing the UDP query, these counters should be incremented:
  947. // request.udp, opcode.query, rcode.refused
  948. // and these counters should not be incremented:
  949. // request.tcp
  950. ConstElementPtr stats_after = server.getStatistics()->
  951. get("zones")->get("_SERVER_");
  952. expectCounterItem(stats_after->get("request"), "udp", 1);
  953. expectCounterItem(stats_after->get("request"), "tcp", 0);
  954. expectCounterItem(stats_after->get("opcode"), "query", 1);
  955. expectCounterItem(stats_after->get("rcode"), "refused", 1);
  956. }
  957. // Submit TCP normal query and check query counter
  958. TEST_F(AuthSrvTest, queryCounterTCPNormal) {
  959. // The counters should be initialized to 0.
  960. ConstElementPtr stats_init = server.getStatistics()->
  961. get("zones")->get("_SERVER_");
  962. expectCounterItem(stats_init->get("request"), "udp", 0);
  963. expectCounterItem(stats_init->get("request"), "tcp", 0);
  964. expectCounterItem(stats_init->get("opcode"), "query", 0);
  965. expectCounterItem(stats_init->get("rcode"), "refused", 0);
  966. // Create TCP message and process.
  967. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  968. default_qid, Name("example.com"),
  969. RRClass::IN(), RRType::NS());
  970. createRequestPacket(request_message, IPPROTO_TCP);
  971. server.processMessage(*io_message, *parse_message, *response_obuffer,
  972. &dnsserv);
  973. // After processing the TCP query, these counters should be incremented:
  974. // request.tcp, opcode.query, rcode.refused, response
  975. // and these counters should not be incremented:
  976. // request.udp
  977. ConstElementPtr stats_after = server.getStatistics()->
  978. get("zones")->get("_SERVER_");
  979. expectCounterItem(stats_after->get("request"), "udp", 0);
  980. expectCounterItem(stats_after->get("request"), "tcp", 1);
  981. expectCounterItem(stats_after->get("opcode"), "query", 1);
  982. expectCounterItem(stats_after->get("rcode"), "refused", 1);
  983. }
  984. // Submit TCP AXFR query and check query counter
  985. TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
  986. // The counters should be initialized to 0.
  987. ConstElementPtr stats_init = server.getStatistics()->
  988. get("zones")->get("_SERVER_");
  989. expectCounterItem(stats_init->get("request"), "udp", 0);
  990. expectCounterItem(stats_init->get("request"), "tcp", 0);
  991. expectCounterItem(stats_init->get("opcode"), "query", 0);
  992. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  993. Name("example.com"), RRClass::IN(), RRType::AXFR());
  994. createRequestPacket(request_message, IPPROTO_TCP);
  995. // On success, the AXFR query has been passed to a separate process,
  996. // so auth itself shouldn't respond.
  997. server.processMessage(*io_message, *parse_message, *response_obuffer,
  998. &dnsserv);
  999. EXPECT_FALSE(dnsserv.hasAnswer());
  1000. // After processing the TCP AXFR query, these counters should be
  1001. // incremented:
  1002. // request.tcp, opcode.query
  1003. // and these counters should not be incremented:
  1004. // request.udp, response
  1005. ConstElementPtr stats_after = server.getStatistics()->
  1006. get("zones")->get("_SERVER_");
  1007. expectCounterItem(stats_after->get("request"), "udp", 0);
  1008. expectCounterItem(stats_after->get("request"), "tcp", 1);
  1009. expectCounterItem(stats_after->get("opcode"), "query", 1);
  1010. }
  1011. // Submit TCP IXFR query and check query counter
  1012. TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
  1013. // The counters should be initialized to 0.
  1014. ConstElementPtr stats_init = server.getStatistics()->
  1015. get("zones")->get("_SERVER_");
  1016. expectCounterItem(stats_init->get("request"), "udp", 0);
  1017. expectCounterItem(stats_init->get("request"), "tcp", 0);
  1018. expectCounterItem(stats_init->get("opcode"), "query", 0);
  1019. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  1020. Name("example.com"), RRClass::IN(), RRType::IXFR());
  1021. createRequestPacket(request_message, IPPROTO_TCP);
  1022. // On success, the IXFR query has been passed to a separate process,
  1023. // so auth itself shouldn't respond.
  1024. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1025. &dnsserv);
  1026. EXPECT_FALSE(dnsserv.hasAnswer());
  1027. // After processing the TCP IXFR query, these counters should be
  1028. // incremented:
  1029. // request.tcp, opcode.query
  1030. // and these counters should not be incremented:
  1031. // request.udp, response
  1032. ConstElementPtr stats_after = server.getStatistics()->
  1033. get("zones")->get("_SERVER_");
  1034. expectCounterItem(stats_after->get("request"), "udp", 0);
  1035. expectCounterItem(stats_after->get("request"), "tcp", 1);
  1036. expectCounterItem(stats_after->get("opcode"), "query", 1);
  1037. }
  1038. TEST_F(AuthSrvTest, queryCounterOpcodes) {
  1039. int other_expected = 0;
  1040. for (int i = 0; i < 16; ++i) {
  1041. std::string item_name;
  1042. int expected;
  1043. if (isc::auth::statistics::opcode_to_qrcounter[i] ==
  1044. isc::auth::statistics::QR_OPCODE_OTHER) {
  1045. item_name = "OTHER";
  1046. other_expected += i + 1;
  1047. expected = other_expected;
  1048. } else {
  1049. item_name = Opcode(i).toText();
  1050. expected = i + 1;
  1051. }
  1052. std::transform(item_name.begin(), item_name.end(), item_name.begin(),
  1053. ::tolower);
  1054. // The counter should be initialized to expected value.
  1055. expectCounterItem(server.getStatistics()->
  1056. get("zones")->get("_SERVER_")->get("opcode"),
  1057. item_name, expected - (i + 1));
  1058. // For each possible opcode, create a request message and send it
  1059. UnitTestUtil::createRequestMessage(request_message, Opcode(i),
  1060. default_qid, Name("example.com"),
  1061. RRClass::IN(), RRType::NS());
  1062. createRequestPacket(request_message, IPPROTO_UDP);
  1063. // "send" the request N-th times where N is i + 1 for i-th code.
  1064. // we intentionally use different values for each code
  1065. for (int j = 0; j <= i; ++j) {
  1066. parse_message->clear(Message::PARSE);
  1067. server.processMessage(*io_message, *parse_message,
  1068. *response_obuffer,
  1069. &dnsserv);
  1070. }
  1071. // Confirm the counter.
  1072. expectCounterItem(server.getStatistics()->
  1073. get("zones")->get("_SERVER_")->get("opcode"),
  1074. item_name, expected);
  1075. }
  1076. }
  1077. // class for queryCounterUnexpected test
  1078. // getProtocol() returns IPPROTO_IP
  1079. class DummyUnknownSocket : public IOSocket {
  1080. public:
  1081. DummyUnknownSocket() {}
  1082. virtual int getNative() const { return (0); }
  1083. virtual int getProtocol() const { return (IPPROTO_IP); }
  1084. };
  1085. // function for queryCounterUnexpected test
  1086. // returns a reference to a static object of DummyUnknownSocket
  1087. IOSocket&
  1088. getDummyUnknownSocket() {
  1089. static DummyUnknownSocket socket;
  1090. return (socket);
  1091. }
  1092. // Submit unexpected type of query and check it is ignored
  1093. TEST_F(AuthSrvTest, queryCounterUnexpected) {
  1094. // This code isn't exception safe, but we'd rather keep the code
  1095. // simpler and more readable as this is only for tests
  1096. // Create UDP query packet.
  1097. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1098. default_qid, Name("example.com"),
  1099. RRClass::IN(), RRType::NS());
  1100. createRequestPacket(request_message, IPPROTO_UDP);
  1101. // Modify the message.
  1102. delete io_message;
  1103. endpoint = IOEndpoint::create(IPPROTO_UDP,
  1104. IOAddress(DEFAULT_REMOTE_ADDRESS), 53210);
  1105. io_message = new IOMessage(request_renderer.getData(),
  1106. request_renderer.getLength(),
  1107. getDummyUnknownSocket(), *endpoint);
  1108. EXPECT_FALSE(dnsserv.hasAnswer());
  1109. }
  1110. TEST_F(AuthSrvTest, stop) {
  1111. // normal case is covered in command_unittest.cc. we should primarily
  1112. // test it here, but the current design of the stop test takes time,
  1113. // so we consolidate the cases in the command tests.
  1114. // If/when the interval timer has finer granularity we'll probably add
  1115. // our own tests here, so we keep this empty test case.
  1116. }
  1117. TEST_F(AuthSrvTest, listenAddresses) {
  1118. isc::testutils::portconfig::listenAddresses(server);
  1119. // Check it requests the correct addresses
  1120. const char* tokens[] = {
  1121. "TCP:127.0.0.1:53210:1",
  1122. "UDP:127.0.0.1:53210:2",
  1123. "TCP:::1:53210:3",
  1124. "UDP:::1:53210:4",
  1125. NULL
  1126. };
  1127. sock_requestor_.checkTokens(tokens, sock_requestor_.given_tokens_,
  1128. "Given tokens");
  1129. // It returns back to empty set of addresses afterwards, so
  1130. // they should be released
  1131. sock_requestor_.checkTokens(tokens, sock_requestor_.released_tokens_,
  1132. "Released tokens");
  1133. }
  1134. TEST_F(AuthSrvTest, processNormalQuery_reuseRenderer1) {
  1135. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1136. default_qid, Name("example.com"),
  1137. RRClass::IN(), RRType::NS());
  1138. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  1139. createRequestPacket(request_message, IPPROTO_UDP);
  1140. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1141. &dnsserv);
  1142. EXPECT_NE(request_message.getRcode(), parse_message->getRcode());
  1143. }
  1144. TEST_F(AuthSrvTest, processNormalQuery_reuseRenderer2) {
  1145. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1146. default_qid, Name("example.com"),
  1147. RRClass::IN(), RRType::SOA());
  1148. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  1149. createRequestPacket(request_message, IPPROTO_UDP);
  1150. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1151. &dnsserv);
  1152. ConstQuestionPtr question = *parse_message->beginQuestion();
  1153. EXPECT_STRNE(question->getType().toText().c_str(),
  1154. RRType::NS().toText().c_str());
  1155. }
  1156. //
  1157. // Tests for catching exceptions in various stages of the query processing
  1158. //
  1159. // These tests work by defining two proxy classes, that act as an in-memory
  1160. // client by default, but can throw exceptions at various points.
  1161. //
  1162. namespace {
  1163. /// The possible methods to throw in, either in FakeClient or
  1164. /// FakeZoneFinder
  1165. enum ThrowWhen {
  1166. THROW_NEVER,
  1167. THROW_AT_FIND_ZONE,
  1168. THROW_AT_GET_ORIGIN,
  1169. THROW_AT_GET_CLASS,
  1170. THROW_AT_FIND,
  1171. THROW_AT_FIND_ALL,
  1172. THROW_AT_FIND_NSEC3
  1173. };
  1174. /// convenience function to check whether and what to throw
  1175. void
  1176. checkThrow(ThrowWhen method, ThrowWhen throw_at, bool isc_exception) {
  1177. if (method == throw_at) {
  1178. if (isc_exception) {
  1179. isc_throw(isc::Exception, "foo");
  1180. } else {
  1181. throw std::exception();
  1182. }
  1183. }
  1184. }
  1185. /// \brief proxy class for the ZoneFinder returned by the Client
  1186. /// proxied by FakeClient
  1187. ///
  1188. /// See the documentation for FakeClient for more information,
  1189. /// all methods simply check whether they should throw, and if not, call
  1190. /// their proxied equivalent.
  1191. class FakeZoneFinder : public isc::datasrc::ZoneFinder {
  1192. public:
  1193. FakeZoneFinder(isc::datasrc::ZoneFinderPtr zone_finder,
  1194. ThrowWhen throw_when, bool isc_exception,
  1195. ConstRRsetPtr fake_rrset) :
  1196. real_zone_finder_(zone_finder),
  1197. throw_when_(throw_when),
  1198. isc_exception_(isc_exception),
  1199. fake_rrset_(fake_rrset)
  1200. {}
  1201. virtual isc::dns::Name
  1202. getOrigin() const {
  1203. checkThrow(THROW_AT_GET_ORIGIN, throw_when_, isc_exception_);
  1204. return (real_zone_finder_->getOrigin());
  1205. }
  1206. virtual isc::dns::RRClass
  1207. getClass() const {
  1208. checkThrow(THROW_AT_GET_CLASS, throw_when_, isc_exception_);
  1209. return (real_zone_finder_->getClass());
  1210. }
  1211. virtual isc::datasrc::ZoneFinderContextPtr
  1212. find(const isc::dns::Name& name,
  1213. const isc::dns::RRType& type,
  1214. isc::datasrc::ZoneFinder::FindOptions options)
  1215. {
  1216. using namespace isc::datasrc;
  1217. checkThrow(THROW_AT_FIND, throw_when_, isc_exception_);
  1218. // If faked RRset was specified on construction and it matches the
  1219. // query, return it instead of searching the real data source.
  1220. if (fake_rrset_ && fake_rrset_->getName() == name &&
  1221. fake_rrset_->getType() == type)
  1222. {
  1223. return (ZoneFinderContextPtr(new ZoneFinder::Context(
  1224. *this, options,
  1225. ResultContext(SUCCESS,
  1226. fake_rrset_))));
  1227. }
  1228. return (real_zone_finder_->find(name, type, options));
  1229. }
  1230. virtual isc::datasrc::ZoneFinderContextPtr
  1231. findAll(const isc::dns::Name& name,
  1232. std::vector<isc::dns::ConstRRsetPtr> &target,
  1233. const FindOptions options = FIND_DEFAULT)
  1234. {
  1235. checkThrow(THROW_AT_FIND_ALL, throw_when_, isc_exception_);
  1236. return (real_zone_finder_->findAll(name, target, options));
  1237. }
  1238. virtual FindNSEC3Result
  1239. findNSEC3(const isc::dns::Name& name, bool recursive) {
  1240. checkThrow(THROW_AT_FIND_NSEC3, throw_when_, isc_exception_);
  1241. return (real_zone_finder_->findNSEC3(name, recursive));
  1242. }
  1243. private:
  1244. isc::datasrc::ZoneFinderPtr real_zone_finder_;
  1245. ThrowWhen throw_when_;
  1246. bool isc_exception_;
  1247. ConstRRsetPtr fake_rrset_;
  1248. };
  1249. /// \brief Proxy FakeClient that can throw exceptions at specified times
  1250. ///
  1251. /// Currently it is used as an 'InMemoryClient' using setInMemoryClient,
  1252. /// but it is in effect a general datasource client.
  1253. class FakeClient : public isc::datasrc::DataSourceClient {
  1254. public:
  1255. /// \brief Create a proxy memory client
  1256. ///
  1257. /// \param real_client The real (in-memory) client to proxy
  1258. /// \param throw_when if set to any value other than never, that is
  1259. /// the method that will throw an exception (either in this
  1260. /// class or the related FakeZoneFinder)
  1261. /// \param isc_exception if true, throw isc::Exception, otherwise,
  1262. /// throw std::exception
  1263. /// \param fake_rrset If non NULL, it will be used as an answer to
  1264. /// find() for that name and type.
  1265. FakeClient(const DataSourceClient* real_client,
  1266. ThrowWhen throw_when, bool isc_exception,
  1267. ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
  1268. real_client_ptr_(real_client),
  1269. throw_when_(throw_when),
  1270. isc_exception_(isc_exception),
  1271. fake_rrset_(fake_rrset)
  1272. {}
  1273. /// \brief proxy call for findZone
  1274. ///
  1275. /// if this instance was constructed with throw_when set to find_zone,
  1276. /// this method will throw. Otherwise, it will return a FakeZoneFinder
  1277. /// instance which will throw at the method specified at the
  1278. /// construction of this instance.
  1279. virtual FindResult
  1280. findZone(const isc::dns::Name& name) const {
  1281. checkThrow(THROW_AT_FIND_ZONE, throw_when_, isc_exception_);
  1282. const FindResult result =
  1283. real_client_ptr_->findZone(name);
  1284. return (FindResult(result.code, isc::datasrc::ZoneFinderPtr(
  1285. new FakeZoneFinder(result.zone_finder,
  1286. throw_when_,
  1287. isc_exception_,
  1288. fake_rrset_))));
  1289. }
  1290. isc::datasrc::ZoneUpdaterPtr
  1291. getUpdater(const isc::dns::Name&, bool, bool) const {
  1292. isc_throw(isc::NotImplemented,
  1293. "Update attempt on in fake data source");
  1294. }
  1295. std::pair<isc::datasrc::ZoneJournalReader::Result,
  1296. isc::datasrc::ZoneJournalReaderPtr>
  1297. getJournalReader(const isc::dns::Name&, uint32_t, uint32_t) const {
  1298. isc_throw(isc::NotImplemented, "Journaling isn't supported for "
  1299. "fake data source");
  1300. }
  1301. private:
  1302. const DataSourceClient* real_client_ptr_;
  1303. ThrowWhen throw_when_;
  1304. bool isc_exception_;
  1305. ConstRRsetPtr fake_rrset_;
  1306. };
  1307. class FakeList : public isc::datasrc::ConfigurableClientList {
  1308. public:
  1309. /// \brief Creates a fake list for the given in-memory client
  1310. ///
  1311. /// It will create a FakeClient for each client in the original list,
  1312. /// with the given arguments, which is used when searching for the
  1313. /// corresponding data source.
  1314. FakeList(const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1315. real_list, ThrowWhen throw_when, bool isc_exception,
  1316. ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
  1317. ConfigurableClientList(RRClass::IN()),
  1318. real_(real_list)
  1319. {
  1320. BOOST_FOREACH(const DataSourceInfo& info, real_->getDataSources()) {
  1321. const isc::datasrc::DataSourceClientPtr
  1322. client(new FakeClient(info.data_src_client_ != NULL ?
  1323. info.data_src_client_ :
  1324. info.getCacheClient(),
  1325. throw_when, isc_exception, fake_rrset));
  1326. clients_.push_back(client);
  1327. data_sources_.push_back(
  1328. DataSourceInfo(client.get(),
  1329. isc::datasrc::DataSourceClientContainerPtr(),
  1330. false, RRClass::IN(), mem_sgmt_));
  1331. }
  1332. }
  1333. private:
  1334. const boost::shared_ptr<isc::datasrc::ConfigurableClientList> real_;
  1335. vector<isc::datasrc::DataSourceClientPtr> clients_;
  1336. MemorySegmentLocal mem_sgmt_;
  1337. };
  1338. } // end anonymous namespace for throwing proxy classes
  1339. // Test for the tests
  1340. //
  1341. // Set the proxies to never throw, this should have the same result as
  1342. // queryWithInMemoryClientNoDNSSEC, and serves to test the two proxy classes
  1343. TEST_F(AuthSrvTest,
  1344. #ifdef USE_STATIC_LINK
  1345. DISABLED_queryWithInMemoryClientProxy
  1346. #else
  1347. queryWithInMemoryClientProxy
  1348. #endif
  1349. )
  1350. {
  1351. // Set real inmem client to proxy
  1352. updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
  1353. boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1354. list(new FakeList(server.getClientList(RRClass::IN()), THROW_NEVER,
  1355. false));
  1356. server.setClientList(RRClass::IN(), list);
  1357. createDataFromFile("nsec3query_nodnssec_fromWire.wire");
  1358. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1359. &dnsserv);
  1360. EXPECT_TRUE(dnsserv.hasAnswer());
  1361. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  1362. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 2, 1);
  1363. }
  1364. // Convenience function for the rest of the tests, set up a proxy
  1365. // to throw in the given method
  1366. // If isc_exception is true, it will throw isc::Exception, otherwise
  1367. // it will throw std::exception
  1368. // If non null rrset is given, it will be passed to the proxy so it can
  1369. // return some faked response.
  1370. void
  1371. setupThrow(AuthSrv* server, ThrowWhen throw_when, bool isc_exception,
  1372. ConstRRsetPtr rrset = ConstRRsetPtr())
  1373. {
  1374. updateInMemory(server, "example.", CONFIG_INMEMORY_EXAMPLE);
  1375. boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1376. list(new FakeList(server->getClientList(RRClass::IN()), throw_when,
  1377. isc_exception, rrset));
  1378. server->setClientList(RRClass::IN(), list);
  1379. }
  1380. TEST_F(AuthSrvTest,
  1381. #ifdef USE_STATIC_LINK
  1382. DISABLED_queryWithThrowingProxyServfails
  1383. #else
  1384. queryWithThrowingProxyServfails
  1385. #endif
  1386. )
  1387. {
  1388. // Test the common cases, all of which should simply return SERVFAIL
  1389. // Use THROW_NEVER as end marker
  1390. ThrowWhen throws[] = { THROW_AT_FIND_ZONE,
  1391. THROW_AT_GET_ORIGIN,
  1392. THROW_AT_FIND,
  1393. THROW_AT_FIND_NSEC3,
  1394. THROW_NEVER };
  1395. UnitTestUtil::createDNSSECRequestMessage(request_message, opcode,
  1396. default_qid, Name("foo.example."),
  1397. RRClass::IN(), RRType::TXT());
  1398. for (ThrowWhen* when(throws); *when != THROW_NEVER; ++when) {
  1399. createRequestPacket(request_message, IPPROTO_UDP);
  1400. setupThrow(&server, *when, true);
  1401. processAndCheckSERVFAIL();
  1402. // To be sure, check same for non-isc-exceptions
  1403. createRequestPacket(request_message, IPPROTO_UDP);
  1404. setupThrow(&server, *when, false);
  1405. processAndCheckSERVFAIL();
  1406. }
  1407. }
  1408. // Throw isc::Exception in getClass(). (Currently?) getClass is not called
  1409. // in the processMessage path, so this should result in a normal answer
  1410. TEST_F(AuthSrvTest,
  1411. #ifdef USE_STATIC_LINK
  1412. DISABLED_queryWithInMemoryClientProxyGetClass
  1413. #else
  1414. queryWithInMemoryClientProxyGetClass
  1415. #endif
  1416. )
  1417. {
  1418. createDataFromFile("nsec3query_nodnssec_fromWire.wire");
  1419. setupThrow(&server, THROW_AT_GET_CLASS, true);
  1420. // getClass is not called so it should just answer
  1421. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1422. &dnsserv);
  1423. EXPECT_TRUE(dnsserv.hasAnswer());
  1424. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  1425. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 2, 1);
  1426. }
  1427. TEST_F(AuthSrvTest,
  1428. #ifdef USE_STATIC_LINK
  1429. DISABLED_queryWithThrowingInToWire
  1430. #else
  1431. queryWithThrowingInToWire
  1432. #endif
  1433. )
  1434. {
  1435. // Set up a faked data source. It will return an empty RRset for the
  1436. // query.
  1437. ConstRRsetPtr empty_rrset(new RRset(Name("foo.example"),
  1438. RRClass::IN(), RRType::TXT(),
  1439. RRTTL(0)));
  1440. setupThrow(&server, THROW_NEVER, true, empty_rrset);
  1441. // Repeat the query processing two times. Due to the faked RRset,
  1442. // toWire() should throw, and it should result in SERVFAIL.
  1443. OutputBufferPtr orig_buffer;
  1444. for (int i = 0; i < 2; ++i) {
  1445. UnitTestUtil::createDNSSECRequestMessage(request_message, opcode,
  1446. default_qid,
  1447. Name("foo.example."),
  1448. RRClass::IN(), RRType::TXT());
  1449. createRequestPacket(request_message, IPPROTO_UDP);
  1450. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1451. &dnsserv);
  1452. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  1453. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  1454. // Make a backup of the original buffer for latest tests and replace
  1455. // it with a new one
  1456. if (!orig_buffer) {
  1457. orig_buffer = response_obuffer;
  1458. response_obuffer.reset(new OutputBuffer(0));
  1459. }
  1460. request_message.clear(Message::RENDER);
  1461. parse_message->clear(Message::PARSE);
  1462. }
  1463. // Now check if the original buffer is intact
  1464. parse_message->clear(Message::PARSE);
  1465. InputBuffer ibuffer(orig_buffer->getData(), orig_buffer->getLength());
  1466. parse_message->fromWire(ibuffer);
  1467. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  1468. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  1469. }
  1470. //
  1471. // DDNS related tests
  1472. //
  1473. // Helper subroutine to check if the given socket address has the expected
  1474. // address and port. It depends on specific output of getnameinfo() (while
  1475. // there can be multiple textual representation of the same address) but
  1476. // in practice it should be reliable.
  1477. void
  1478. checkAddrPort(const struct sockaddr& actual_sa,
  1479. const string& expected_addr, uint16_t expected_port)
  1480. {
  1481. char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
  1482. const int error = getnameinfo(&actual_sa, getSALength(actual_sa), hbuf,
  1483. sizeof(hbuf), sbuf, sizeof(sbuf),
  1484. NI_NUMERICHOST | NI_NUMERICSERV);
  1485. if (error != 0) {
  1486. isc_throw(isc::Unexpected, "getnameinfo failed: " <<
  1487. gai_strerror(error));
  1488. }
  1489. EXPECT_EQ(expected_addr, hbuf);
  1490. EXPECT_EQ(boost::lexical_cast<string>(expected_port), sbuf);
  1491. }
  1492. TEST_F(AuthSrvTest, DDNSForward) {
  1493. EXPECT_FALSE(ddns_forwarder.isConnected());
  1494. // Repeat sending an update request 4 times, differing some network
  1495. // parameters: UDP/IPv4, TCP/IPv4, UDP/IPv6, TCP/IPv6, in this order.
  1496. // By doing that we can also confirm the forwarder connection will be
  1497. // established exactly once, and kept established.
  1498. for (size_t i = 0; i < 4; ++i) {
  1499. // Use different names for some different cases
  1500. const Name zone_name = Name(i < 2 ? "example.com" : "example.org");
  1501. const socklen_t family = (i < 2) ? AF_INET : AF_INET6;
  1502. const char* const remote_addr =
  1503. (family == AF_INET) ? "192.0.2.1" : "2001:db8::1";
  1504. const uint16_t remote_port =
  1505. (family == AF_INET) ? 53214 : 53216;
  1506. const int protocol = ((i % 2) == 0) ? IPPROTO_UDP : IPPROTO_TCP;
  1507. createAndSendRequest(RRType::SOA(), Opcode::UPDATE(), zone_name,
  1508. RRClass::IN(), protocol, remote_addr,
  1509. remote_port);
  1510. EXPECT_FALSE(dnsserv.hasAnswer());
  1511. EXPECT_TRUE(ddns_forwarder.isConnected());
  1512. // Examine the pushed data (note: currently "local end" has a dummy
  1513. // value equal to remote)
  1514. EXPECT_EQ(family, ddns_forwarder.getPushedFamily());
  1515. const int expected_type =
  1516. (protocol == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
  1517. EXPECT_EQ(expected_type, ddns_forwarder.getPushedType());
  1518. EXPECT_EQ(protocol, ddns_forwarder.getPushedProtocol());
  1519. checkAddrPort(ddns_forwarder.getPushedRemoteend(),
  1520. remote_addr, remote_port);
  1521. checkAddrPort(ddns_forwarder.getPushedLocalend(),
  1522. remote_addr, remote_port);
  1523. EXPECT_EQ(io_message->getDataSize(),
  1524. ddns_forwarder.getPushedData().size());
  1525. EXPECT_EQ(0, memcmp(io_message->getData(),
  1526. &ddns_forwarder.getPushedData()[0],
  1527. ddns_forwarder.getPushedData().size()));
  1528. }
  1529. }
  1530. TEST_F(AuthSrvTest, DDNSForwardConnectFail) {
  1531. // make connect attempt fail. It should result in SERVFAIL. Note that
  1532. // the question (zone) section should be cleared for opcode of update.
  1533. ddns_forwarder.disableConnect();
  1534. createAndSendRequest(RRType::SOA(), Opcode::UPDATE());
  1535. EXPECT_TRUE(dnsserv.hasAnswer());
  1536. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  1537. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1538. EXPECT_FALSE(ddns_forwarder.isConnected());
  1539. // Now make connect okay again. Despite the previous failure the new
  1540. // connection should now be established.
  1541. ddns_forwarder.enableConnect();
  1542. createAndSendRequest(RRType::SOA(), Opcode::UPDATE());
  1543. EXPECT_FALSE(dnsserv.hasAnswer());
  1544. EXPECT_TRUE(ddns_forwarder.isConnected());
  1545. }
  1546. TEST_F(AuthSrvTest, DDNSForwardPushFail) {
  1547. // Make first request succeed, which will establish the connection.
  1548. EXPECT_FALSE(ddns_forwarder.isConnected());
  1549. createAndSendRequest(RRType::SOA(), Opcode::UPDATE());
  1550. EXPECT_TRUE(ddns_forwarder.isConnected());
  1551. // make connect attempt fail. It should result in SERVFAIL. The
  1552. // connection should be closed. Use IPv6 address for varying log output.
  1553. ddns_forwarder.disablePush();
  1554. createAndSendRequest(RRType::SOA(), Opcode::UPDATE(), Name("example.com"),
  1555. RRClass::IN(), IPPROTO_UDP, "2001:db8::2");
  1556. EXPECT_TRUE(dnsserv.hasAnswer());
  1557. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  1558. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1559. EXPECT_FALSE(ddns_forwarder.isConnected());
  1560. // Allow push again. Connection will be reopened, and the request will
  1561. // be forwarded successfully.
  1562. ddns_forwarder.enablePush();
  1563. createAndSendRequest(RRType::SOA(), Opcode::UPDATE());
  1564. EXPECT_FALSE(dnsserv.hasAnswer());
  1565. EXPECT_TRUE(ddns_forwarder.isConnected());
  1566. }
  1567. TEST_F(AuthSrvTest, DDNSForwardClose) {
  1568. scoped_ptr<AuthSrv> tmp_server(new AuthSrv(xfrout, ddns_forwarder));
  1569. tmp_server->createDDNSForwarder();
  1570. UnitTestUtil::createRequestMessage(request_message, Opcode::UPDATE(),
  1571. default_qid, Name("example.com"),
  1572. RRClass::IN(), RRType::SOA());
  1573. createRequestPacket(request_message, IPPROTO_UDP);
  1574. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1575. &dnsserv);
  1576. EXPECT_FALSE(dnsserv.hasAnswer());
  1577. EXPECT_TRUE(ddns_forwarder.isConnected());
  1578. // Destroy the server. The forwarder should close the connection.
  1579. tmp_server.reset();
  1580. EXPECT_FALSE(ddns_forwarder.isConnected());
  1581. }
  1582. namespace {
  1583. // Send a basic command without arguments, and check the response has
  1584. // result code 0
  1585. void sendSimpleCommand(AuthSrv& server, const std::string& command) {
  1586. ConstElementPtr response = execAuthServerCommand(server, command,
  1587. ConstElementPtr());
  1588. int command_result = -1;
  1589. isc::config::parseAnswer(command_result, response);
  1590. EXPECT_EQ(0, command_result);
  1591. }
  1592. } // end anonymous namespace
  1593. TEST_F(AuthSrvTest, DDNSForwardCreateDestroy) {
  1594. // Test that AuthSrv returns NOTIMP before ddns forwarder is created,
  1595. // that the ddns_forwarder is connected when the 'start_ddns_forwarder'
  1596. // command has been sent, and that it is no longer connected and auth
  1597. // returns NOTIMP after the stop_ddns_forwarding command is sent.
  1598. scoped_ptr<AuthSrv> tmp_server(new AuthSrv(xfrout, ddns_forwarder));
  1599. // Prepare update message to send
  1600. UnitTestUtil::createRequestMessage(request_message, Opcode::UPDATE(),
  1601. default_qid, Name("example.com"),
  1602. RRClass::IN(), RRType::SOA());
  1603. createRequestPacket(request_message, IPPROTO_UDP);
  1604. // before creating forwarder. isConnected() should be false and
  1605. // rcode to UPDATE should be NOTIMP
  1606. parse_message->clear(Message::PARSE);
  1607. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1608. &dnsserv);
  1609. EXPECT_FALSE(ddns_forwarder.isConnected());
  1610. EXPECT_TRUE(dnsserv.hasAnswer());
  1611. headerCheck(*parse_message, default_qid, Rcode::NOTIMP(),
  1612. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1613. // now create forwarder
  1614. sendSimpleCommand(*tmp_server, "start_ddns_forwarder");
  1615. // our mock does not respond, and since auth is supposed to send it on,
  1616. // there should now be no result when an UPDATE is sent
  1617. parse_message->clear(Message::PARSE);
  1618. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1619. &dnsserv);
  1620. EXPECT_FALSE(dnsserv.hasAnswer());
  1621. EXPECT_TRUE(ddns_forwarder.isConnected());
  1622. // If we send a start again, the connection should be recreated,
  1623. // visible because isConnected() reports false until an actual message
  1624. // has been forwarded
  1625. sendSimpleCommand(*tmp_server, "start_ddns_forwarder");
  1626. EXPECT_FALSE(ddns_forwarder.isConnected());
  1627. parse_message->clear(Message::PARSE);
  1628. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1629. &dnsserv);
  1630. EXPECT_FALSE(dnsserv.hasAnswer());
  1631. EXPECT_TRUE(ddns_forwarder.isConnected());
  1632. // Now tell it to stop forwarder, should respond with NOTIMP again
  1633. sendSimpleCommand(*tmp_server, "stop_ddns_forwarder");
  1634. parse_message->clear(Message::PARSE);
  1635. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1636. &dnsserv);
  1637. EXPECT_FALSE(ddns_forwarder.isConnected());
  1638. EXPECT_TRUE(dnsserv.hasAnswer());
  1639. headerCheck(*parse_message, default_qid, Rcode::NOTIMP(),
  1640. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1641. // Sending stop again should make no difference
  1642. sendSimpleCommand(*tmp_server, "stop_ddns_forwarder");
  1643. parse_message->clear(Message::PARSE);
  1644. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1645. &dnsserv);
  1646. EXPECT_FALSE(ddns_forwarder.isConnected());
  1647. EXPECT_TRUE(dnsserv.hasAnswer());
  1648. headerCheck(*parse_message, default_qid, Rcode::NOTIMP(),
  1649. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1650. }
  1651. // Check the client list accessors
  1652. TEST_F(AuthSrvTest, clientList) {
  1653. // The lists don't exist. Therefore, the list of RRClasses is empty.
  1654. // We also have no IN list.
  1655. EXPECT_TRUE(server.getClientListClasses().empty());
  1656. EXPECT_EQ(boost::shared_ptr<const isc::datasrc::ClientList>(),
  1657. server.getClientList(RRClass::IN()));
  1658. // Put something in.
  1659. const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1660. list(new isc::datasrc::ConfigurableClientList(RRClass::IN()));
  1661. const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1662. list2(new isc::datasrc::ConfigurableClientList(RRClass::CH()));
  1663. server.setClientList(RRClass::IN(), list);
  1664. server.setClientList(RRClass::CH(), list2);
  1665. // There are two things in the list and they are IN and CH
  1666. vector<RRClass> classes(server.getClientListClasses());
  1667. ASSERT_EQ(2, classes.size());
  1668. EXPECT_EQ(RRClass::IN(), classes[0]);
  1669. EXPECT_EQ(RRClass::CH(), classes[1]);
  1670. // And the lists can be retrieved.
  1671. EXPECT_EQ(list, server.getClientList(RRClass::IN()));
  1672. EXPECT_EQ(list2, server.getClientList(RRClass::CH()));
  1673. // Remove one of them
  1674. server.setClientList(RRClass::CH(),
  1675. boost::shared_ptr<isc::datasrc::ConfigurableClientList>());
  1676. // This really got deleted, including the class.
  1677. classes = server.getClientListClasses();
  1678. ASSERT_EQ(1, classes.size());
  1679. EXPECT_EQ(RRClass::IN(), classes[0]);
  1680. EXPECT_EQ(list, server.getClientList(RRClass::IN()));
  1681. }
  1682. }