auth_srv_unittest.cc 75 KB

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