auth_srv_unittest.cc 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  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 <vector>
  16. #include <boost/shared_ptr.hpp>
  17. #include <gtest/gtest.h>
  18. #include <dns/message.h>
  19. #include <dns/messagerenderer.h>
  20. #include <dns/name.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 <auth/auth_srv.h>
  30. #include <auth/common.h>
  31. #include <auth/statistics.h>
  32. #include <dns/tests/unittest_util.h>
  33. #include <testutils/dnsmessage_test.h>
  34. #include <testutils/srv_test.h>
  35. #include <testutils/portconfig.h>
  36. using namespace std;
  37. using namespace isc::cc;
  38. using namespace isc::dns;
  39. using namespace isc::util;
  40. using namespace isc::dns::rdata;
  41. using namespace isc::data;
  42. using namespace isc::xfr;
  43. using namespace isc::asiodns;
  44. using namespace isc::asiolink;
  45. using namespace isc::testutils;
  46. using namespace isc::server_common::portconfig;
  47. using isc::UnitTestUtil;
  48. namespace {
  49. const char* const CONFIG_TESTDB =
  50. "{\"database_file\": \"" TEST_DATA_DIR "/example.sqlite3\"}";
  51. // The following file must be non existent and must be non"creatable" (see
  52. // the sqlite3 test).
  53. const char* const BADCONFIG_TESTDB =
  54. "{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\"}";
  55. class AuthSrvTest : public SrvTestBase {
  56. protected:
  57. AuthSrvTest() :
  58. dnss_(ios_, NULL, NULL, NULL),
  59. server(true, xfrout),
  60. rrclass(RRClass::IN())
  61. {
  62. server.setDNSService(dnss_);
  63. server.setXfrinSession(&notify_session);
  64. server.setStatisticsSession(&statistics_session);
  65. }
  66. virtual void processMessage() {
  67. server.processMessage(*io_message, parse_message, response_obuffer,
  68. &dnsserv);
  69. }
  70. IOService ios_;
  71. DNSService dnss_;
  72. MockSession statistics_session;
  73. MockXfroutClient xfrout;
  74. AuthSrv server;
  75. const RRClass rrclass;
  76. vector<uint8_t> response_data;
  77. };
  78. // A helper function that builds a response to version.bind/TXT/CH that
  79. // should be identical to the response from our builtin (static) data source
  80. // by default. The resulting wire-format data will be stored in 'data'.
  81. void
  82. createBuiltinVersionResponse(const qid_t qid, vector<uint8_t>& data) {
  83. const Name version_name("version.bind");
  84. Message message(Message::RENDER);
  85. UnitTestUtil::createRequestMessage(message, Opcode::QUERY(),
  86. qid, version_name,
  87. RRClass::CH(), RRType::TXT());
  88. message.setHeaderFlag(Message::HEADERFLAG_QR);
  89. message.setHeaderFlag(Message::HEADERFLAG_AA);
  90. RRsetPtr rrset_version = RRsetPtr(new RRset(version_name, RRClass::CH(),
  91. RRType::TXT(), RRTTL(0)));
  92. rrset_version->addRdata(generic::TXT(PACKAGE_STRING));
  93. message.addRRset(Message::SECTION_ANSWER, rrset_version);
  94. RRsetPtr rrset_version_ns = RRsetPtr(new RRset(version_name, RRClass::CH(),
  95. RRType::NS(), RRTTL(0)));
  96. rrset_version_ns->addRdata(generic::NS(version_name));
  97. message.addRRset(Message::SECTION_AUTHORITY, rrset_version_ns);
  98. OutputBuffer obuffer(0);
  99. MessageRenderer renderer(obuffer);
  100. message.toWire(renderer);
  101. data.clear();
  102. data.assign(static_cast<const uint8_t*>(renderer.getData()),
  103. static_cast<const uint8_t*>(renderer.getData()) +
  104. renderer.getLength());
  105. }
  106. // In the following tests we confirm the response data is rendered in
  107. // wire format in the expected way.
  108. // The most primitive check: checking the result of the processMessage()
  109. // method
  110. TEST_F(AuthSrvTest, builtInQuery) {
  111. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  112. default_qid, Name("version.bind"),
  113. RRClass::CH(), RRType::TXT());
  114. createRequestPacket(request_message, IPPROTO_UDP);
  115. server.processMessage(*io_message, parse_message, response_obuffer,
  116. &dnsserv);
  117. createBuiltinVersionResponse(default_qid, response_data);
  118. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  119. response_obuffer->getData(),
  120. response_obuffer->getLength(),
  121. &response_data[0], response_data.size());
  122. }
  123. // Same test emulating the UDPServer class behavior (defined in libasiolink).
  124. // This is not a good test in that it assumes internal implementation details
  125. // of UDPServer, but we've encountered a regression due to the introduction
  126. // of that class, so we add a test for that case to prevent such a regression
  127. // in future.
  128. // Besides, the generalization of UDPServer is probably too much for the
  129. // authoritative only server in terms of performance, and it's quite likely
  130. // we need to drop it for the authoritative server implementation.
  131. // At that point we can drop this test, too.
  132. TEST_F(AuthSrvTest, builtInQueryViaDNSServer) {
  133. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  134. default_qid, Name("version.bind"),
  135. RRClass::CH(), RRType::TXT());
  136. createRequestPacket(request_message, IPPROTO_UDP);
  137. (*server.getDNSLookupProvider())(*io_message, parse_message,
  138. response_message,
  139. response_obuffer, &dnsserv);
  140. (*server.getDNSAnswerProvider())(*io_message, parse_message,
  141. response_message, response_obuffer);
  142. createBuiltinVersionResponse(default_qid, response_data);
  143. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  144. response_obuffer->getData(),
  145. response_obuffer->getLength(),
  146. &response_data[0], response_data.size());
  147. }
  148. // Same type of test as builtInQueryViaDNSServer but for an error response.
  149. TEST_F(AuthSrvTest, iqueryViaDNSServer) {
  150. createDataFromFile("iquery_fromWire.wire");
  151. (*server.getDNSLookupProvider())(*io_message, parse_message,
  152. response_message,
  153. response_obuffer, &dnsserv);
  154. (*server.getDNSAnswerProvider())(*io_message, parse_message,
  155. response_message, response_obuffer);
  156. UnitTestUtil::readWireData("iquery_response_fromWire.wire",
  157. response_data);
  158. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  159. response_obuffer->getData(),
  160. response_obuffer->getLength(),
  161. &response_data[0], response_data.size());
  162. }
  163. // Unsupported requests. Should result in NOTIMP.
  164. TEST_F(AuthSrvTest, unsupportedRequest) {
  165. unsupportedRequest();
  166. }
  167. // Multiple questions. Should result in FORMERR.
  168. TEST_F(AuthSrvTest, multiQuestion) {
  169. multiQuestion();
  170. }
  171. // Incoming data doesn't even contain the complete header. Must be silently
  172. // dropped.
  173. TEST_F(AuthSrvTest, shortMessage) {
  174. shortMessage();
  175. }
  176. // Response messages. Must be silently dropped, whether it's a valid response
  177. // or malformed or could otherwise cause a protocol error.
  178. TEST_F(AuthSrvTest, response) {
  179. response();
  180. }
  181. // Query with a broken question
  182. TEST_F(AuthSrvTest, shortQuestion) {
  183. shortQuestion();
  184. }
  185. // Query with a broken answer section
  186. TEST_F(AuthSrvTest, shortAnswer) {
  187. shortAnswer();
  188. }
  189. // Query with unsupported version of EDNS.
  190. TEST_F(AuthSrvTest, ednsBadVers) {
  191. ednsBadVers();
  192. }
  193. TEST_F(AuthSrvTest, AXFROverUDP) {
  194. axfrOverUDP();
  195. }
  196. TEST_F(AuthSrvTest, AXFRSuccess) {
  197. EXPECT_FALSE(xfrout.isConnected());
  198. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  199. Name("example.com"), RRClass::IN(),
  200. RRType::AXFR());
  201. createRequestPacket(request_message, IPPROTO_TCP);
  202. // On success, the AXFR query has been passed to a separate process,
  203. // so we shouldn't have to respond.
  204. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  205. EXPECT_FALSE(dnsserv.hasAnswer());
  206. EXPECT_TRUE(xfrout.isConnected());
  207. }
  208. // Try giving the server a TSIG signed request and see it can anwer signed as
  209. // well
  210. TEST_F(AuthSrvTest, TSIGSigned) {
  211. // Prepare key, the client message, etc
  212. const TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  213. TSIGContext context(key);
  214. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  215. Name("version.bind"), RRClass::CH(),
  216. RRType::TXT());
  217. createRequestPacket(request_message, IPPROTO_UDP, &context);
  218. // Run the message through the server
  219. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  220. keyring->add(key);
  221. server.setTSIGKeyRing(&keyring);
  222. server.processMessage(*io_message, parse_message, response_obuffer,
  223. &dnsserv);
  224. // What did we get?
  225. EXPECT_TRUE(dnsserv.hasAnswer());
  226. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  227. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  228. // We need to parse the message ourself, or getTSIGRecord won't work
  229. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  230. Message m(Message::PARSE);
  231. m.fromWire(ib);
  232. const TSIGRecord* tsig = m.getTSIGRecord();
  233. ASSERT_TRUE(tsig != NULL) << "Missing TSIG signature";
  234. TSIGError error(context.verify(tsig, response_obuffer->getData(),
  235. response_obuffer->getLength()));
  236. EXPECT_EQ(TSIGError::NOERROR(), error) <<
  237. "The server signed the response, but it doesn't seem to be valid";
  238. }
  239. // Give the server a signed request, but don't give it the key. It will
  240. // not be able to verify it, returning BADKEY
  241. TEST_F(AuthSrvTest, TSIGSignedBadKey) {
  242. TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  243. TSIGContext context(key);
  244. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  245. Name("version.bind"), RRClass::CH(),
  246. RRType::TXT());
  247. createRequestPacket(request_message, IPPROTO_UDP, &context);
  248. // Process the message, but use a different key there
  249. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  250. server.setTSIGKeyRing(&keyring);
  251. server.processMessage(*io_message, parse_message, response_obuffer,
  252. &dnsserv);
  253. EXPECT_TRUE(dnsserv.hasAnswer());
  254. headerCheck(*parse_message, default_qid, TSIGError::BAD_KEY().toRcode(),
  255. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  256. // We need to parse the message ourself, or getTSIGRecord won't work
  257. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  258. Message m(Message::PARSE);
  259. m.fromWire(ib);
  260. const TSIGRecord* tsig = m.getTSIGRecord();
  261. ASSERT_TRUE(tsig != NULL) <<
  262. "Missing TSIG signature (we should have one even at error)";
  263. EXPECT_EQ(TSIGError::BAD_KEY_CODE, tsig->getRdata().getError());
  264. EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
  265. "It should be unsigned with this error";
  266. }
  267. // Give the server a signed request, but signed by a different key
  268. // (with the same name). It should return BADSIG
  269. TEST_F(AuthSrvTest, TSIGBadSig) {
  270. TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  271. TSIGContext context(key);
  272. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  273. Name("version.bind"), RRClass::CH(),
  274. RRType::TXT());
  275. createRequestPacket(request_message, IPPROTO_UDP, &context);
  276. // Process the message, but use a different key there
  277. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  278. keyring->add(TSIGKey("key:QkFECg==:hmac-sha1"));
  279. server.setTSIGKeyRing(&keyring);
  280. server.processMessage(*io_message, parse_message, response_obuffer,
  281. &dnsserv);
  282. EXPECT_TRUE(dnsserv.hasAnswer());
  283. headerCheck(*parse_message, default_qid, TSIGError::BAD_SIG().toRcode(),
  284. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  285. // We need to parse the message ourself, or getTSIGRecord won't work
  286. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  287. Message m(Message::PARSE);
  288. m.fromWire(ib);
  289. const TSIGRecord* tsig = m.getTSIGRecord();
  290. ASSERT_TRUE(tsig != NULL) <<
  291. "Missing TSIG signature (we should have one even at error)";
  292. EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig->getRdata().getError());
  293. EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
  294. "It should be unsigned with this error";
  295. }
  296. // Give the server a signed unsupported request with a bad signature.
  297. // This checks the server first verifies the signature before anything
  298. // else.
  299. TEST_F(AuthSrvTest, TSIGCheckFirst) {
  300. TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  301. TSIGContext context(key);
  302. // Pass a wrong opcode there. The server shouldn't know what to do
  303. // about it.
  304. UnitTestUtil::createRequestMessage(request_message, Opcode::RESERVED14(),
  305. default_qid, Name("version.bind"),
  306. RRClass::CH(), RRType::TXT());
  307. createRequestPacket(request_message, IPPROTO_UDP, &context);
  308. // Process the message, but use a different key there
  309. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  310. keyring->add(TSIGKey("key:QkFECg==:hmac-sha1"));
  311. server.setTSIGKeyRing(&keyring);
  312. server.processMessage(*io_message, parse_message, response_obuffer,
  313. &dnsserv);
  314. EXPECT_TRUE(dnsserv.hasAnswer());
  315. headerCheck(*parse_message, default_qid, TSIGError::BAD_SIG().toRcode(),
  316. Opcode::RESERVED14().getCode(), QR_FLAG, 0, 0, 0, 0);
  317. // We need to parse the message ourself, or getTSIGRecord won't work
  318. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  319. Message m(Message::PARSE);
  320. m.fromWire(ib);
  321. const TSIGRecord* tsig = m.getTSIGRecord();
  322. ASSERT_TRUE(tsig != NULL) <<
  323. "Missing TSIG signature (we should have one even at error)";
  324. EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig->getRdata().getError());
  325. EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
  326. "It should be unsigned with this error";
  327. }
  328. TEST_F(AuthSrvTest, AXFRConnectFail) {
  329. EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
  330. xfrout.disableConnect();
  331. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  332. Name("example.com"), RRClass::IN(),
  333. RRType::AXFR());
  334. createRequestPacket(request_message, IPPROTO_TCP);
  335. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  336. EXPECT_TRUE(dnsserv.hasAnswer());
  337. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  338. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  339. EXPECT_FALSE(xfrout.isConnected());
  340. }
  341. TEST_F(AuthSrvTest, AXFRSendFail) {
  342. // first send a valid query, making the connection with the xfr process
  343. // open.
  344. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  345. Name("example.com"), RRClass::IN(),
  346. RRType::AXFR());
  347. createRequestPacket(request_message, IPPROTO_TCP);
  348. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  349. EXPECT_TRUE(xfrout.isConnected());
  350. xfrout.disableSend();
  351. parse_message->clear(Message::PARSE);
  352. response_obuffer->clear();
  353. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  354. Name("example.com"), RRClass::IN(),
  355. RRType::AXFR());
  356. createRequestPacket(request_message, IPPROTO_TCP);
  357. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  358. EXPECT_TRUE(dnsserv.hasAnswer());
  359. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  360. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  361. // The connection should have been closed due to the send failure.
  362. EXPECT_FALSE(xfrout.isConnected());
  363. }
  364. TEST_F(AuthSrvTest, AXFRDisconnectFail) {
  365. // In our usage disconnect() shouldn't fail. So we'll see the exception
  366. // should it be thrown.
  367. xfrout.disableSend();
  368. xfrout.disableDisconnect();
  369. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  370. Name("example.com"), RRClass::IN(),
  371. RRType::AXFR());
  372. createRequestPacket(request_message, IPPROTO_TCP);
  373. EXPECT_THROW(server.processMessage(*io_message, parse_message,
  374. response_obuffer, &dnsserv),
  375. XfroutError);
  376. EXPECT_TRUE(xfrout.isConnected());
  377. // XXX: we need to re-enable disconnect. otherwise an exception would be
  378. // thrown via the destructor of the server.
  379. xfrout.enableDisconnect();
  380. }
  381. TEST_F(AuthSrvTest, IXFRConnectFail) {
  382. EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
  383. xfrout.disableConnect();
  384. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  385. Name("example.com"), RRClass::IN(),
  386. RRType::IXFR());
  387. createRequestPacket(request_message, IPPROTO_TCP);
  388. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  389. EXPECT_TRUE(dnsserv.hasAnswer());
  390. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  391. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  392. EXPECT_FALSE(xfrout.isConnected());
  393. }
  394. TEST_F(AuthSrvTest, IXFRSendFail) {
  395. // first send a valid query, making the connection with the xfr process
  396. // open.
  397. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  398. Name("example.com"), RRClass::IN(),
  399. RRType::IXFR());
  400. createRequestPacket(request_message, IPPROTO_TCP);
  401. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  402. EXPECT_TRUE(xfrout.isConnected());
  403. xfrout.disableSend();
  404. parse_message->clear(Message::PARSE);
  405. response_obuffer->clear();
  406. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  407. Name("example.com"), RRClass::IN(),
  408. RRType::IXFR());
  409. createRequestPacket(request_message, IPPROTO_TCP);
  410. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  411. EXPECT_TRUE(dnsserv.hasAnswer());
  412. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  413. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  414. // The connection should have been closed due to the send failure.
  415. EXPECT_FALSE(xfrout.isConnected());
  416. }
  417. TEST_F(AuthSrvTest, IXFRDisconnectFail) {
  418. // In our usage disconnect() shouldn't fail. So we'll see the exception
  419. // should it be thrown.
  420. xfrout.disableSend();
  421. xfrout.disableDisconnect();
  422. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  423. Name("example.com"), RRClass::IN(),
  424. RRType::IXFR());
  425. createRequestPacket(request_message, IPPROTO_TCP);
  426. EXPECT_THROW(server.processMessage(*io_message, parse_message,
  427. response_obuffer, &dnsserv),
  428. XfroutError);
  429. EXPECT_TRUE(xfrout.isConnected());
  430. // XXX: we need to re-enable disconnect. otherwise an exception would be
  431. // thrown via the destructor of the server.
  432. xfrout.enableDisconnect();
  433. }
  434. TEST_F(AuthSrvTest, notify) {
  435. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  436. default_qid, Name("example.com"),
  437. RRClass::IN(), RRType::SOA());
  438. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  439. createRequestPacket(request_message, IPPROTO_UDP);
  440. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  441. EXPECT_TRUE(dnsserv.hasAnswer());
  442. // An internal command message should have been created and sent to an
  443. // external module. Check them.
  444. EXPECT_EQ("Zonemgr", notify_session.getMessageDest());
  445. EXPECT_EQ("notify",
  446. notify_session.getSentMessage()->get("command")->get(0)->stringValue());
  447. ConstElementPtr notify_args =
  448. notify_session.getSentMessage()->get("command")->get(1);
  449. EXPECT_EQ("example.com.", notify_args->get("zone_name")->stringValue());
  450. EXPECT_EQ(DEFAULT_REMOTE_ADDRESS,
  451. notify_args->get("master")->stringValue());
  452. EXPECT_EQ("IN", notify_args->get("zone_class")->stringValue());
  453. // On success, the server should return a response to the notify.
  454. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  455. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  456. // The question must be identical to that of the received notify
  457. ConstQuestionPtr question = *parse_message->beginQuestion();
  458. EXPECT_EQ(Name("example.com"), question->getName());
  459. EXPECT_EQ(RRClass::IN(), question->getClass());
  460. EXPECT_EQ(RRType::SOA(), question->getType());
  461. }
  462. TEST_F(AuthSrvTest, notifyForCHClass) {
  463. // Same as the previous test, but for the CH RRClass.
  464. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  465. default_qid, Name("example.com"),
  466. RRClass::CH(), RRType::SOA());
  467. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  468. createRequestPacket(request_message, IPPROTO_UDP);
  469. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  470. EXPECT_TRUE(dnsserv.hasAnswer());
  471. // Other conditions should be the same, so simply confirm the RR class is
  472. // set correctly.
  473. ConstElementPtr notify_args =
  474. notify_session.getSentMessage()->get("command")->get(1);
  475. EXPECT_EQ("CH", notify_args->get("zone_class")->stringValue());
  476. }
  477. TEST_F(AuthSrvTest, notifyEmptyQuestion) {
  478. request_message.clear(Message::RENDER);
  479. request_message.setOpcode(Opcode::NOTIFY());
  480. request_message.setRcode(Rcode::NOERROR());
  481. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  482. request_message.setQid(default_qid);
  483. request_message.toWire(request_renderer);
  484. createRequestPacket(request_message, IPPROTO_UDP);
  485. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  486. EXPECT_TRUE(dnsserv.hasAnswer());
  487. headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
  488. Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
  489. }
  490. TEST_F(AuthSrvTest, notifyMultiQuestions) {
  491. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  492. default_qid, Name("example.com"),
  493. RRClass::IN(), RRType::SOA());
  494. // add one more SOA question
  495. request_message.addQuestion(Question(Name("example.com"), RRClass::IN(),
  496. RRType::SOA()));
  497. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  498. createRequestPacket(request_message, IPPROTO_UDP);
  499. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  500. EXPECT_TRUE(dnsserv.hasAnswer());
  501. headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
  502. Opcode::NOTIFY().getCode(), QR_FLAG, 2, 0, 0, 0);
  503. }
  504. TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
  505. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  506. default_qid, Name("example.com"),
  507. RRClass::IN(), RRType::NS());
  508. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  509. createRequestPacket(request_message, IPPROTO_UDP);
  510. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  511. EXPECT_TRUE(dnsserv.hasAnswer());
  512. headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
  513. Opcode::NOTIFY().getCode(), QR_FLAG, 1, 0, 0, 0);
  514. }
  515. TEST_F(AuthSrvTest, notifyWithoutAA) {
  516. // implicitly leave the AA bit off. our implementation will accept it.
  517. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  518. default_qid, Name("example.com"),
  519. RRClass::IN(), RRType::SOA());
  520. createRequestPacket(request_message, IPPROTO_UDP);
  521. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  522. EXPECT_TRUE(dnsserv.hasAnswer());
  523. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  524. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  525. }
  526. TEST_F(AuthSrvTest, notifyWithErrorRcode) {
  527. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  528. default_qid, Name("example.com"),
  529. RRClass::IN(), RRType::SOA());
  530. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  531. request_message.setRcode(Rcode::SERVFAIL());
  532. createRequestPacket(request_message, IPPROTO_UDP);
  533. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  534. EXPECT_TRUE(dnsserv.hasAnswer());
  535. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  536. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  537. }
  538. TEST_F(AuthSrvTest, notifyWithoutSession) {
  539. server.setXfrinSession(NULL);
  540. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  541. default_qid, Name("example.com"),
  542. RRClass::IN(), RRType::SOA());
  543. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  544. createRequestPacket(request_message, IPPROTO_UDP);
  545. // we simply ignore the notify and let it be resent if an internal error
  546. // happens.
  547. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  548. EXPECT_FALSE(dnsserv.hasAnswer());
  549. }
  550. TEST_F(AuthSrvTest, notifySendFail) {
  551. notify_session.disableSend();
  552. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  553. default_qid, Name("example.com"),
  554. RRClass::IN(), RRType::SOA());
  555. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  556. createRequestPacket(request_message, IPPROTO_UDP);
  557. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  558. EXPECT_FALSE(dnsserv.hasAnswer());
  559. }
  560. TEST_F(AuthSrvTest, notifyReceiveFail) {
  561. notify_session.disableReceive();
  562. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  563. default_qid, Name("example.com"),
  564. RRClass::IN(), RRType::SOA());
  565. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  566. createRequestPacket(request_message, IPPROTO_UDP);
  567. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  568. EXPECT_FALSE(dnsserv.hasAnswer());
  569. }
  570. TEST_F(AuthSrvTest, notifyWithBogusSessionMessage) {
  571. notify_session.setMessage(Element::fromJSON("{\"foo\": 1}"));
  572. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  573. default_qid, Name("example.com"),
  574. RRClass::IN(), RRType::SOA());
  575. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  576. createRequestPacket(request_message, IPPROTO_UDP);
  577. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  578. EXPECT_FALSE(dnsserv.hasAnswer());
  579. }
  580. TEST_F(AuthSrvTest, notifyWithSessionMessageError) {
  581. notify_session.setMessage(
  582. Element::fromJSON("{\"result\": [1, \"FAIL\"]}"));
  583. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  584. default_qid, Name("example.com"),
  585. RRClass::IN(), RRType::SOA());
  586. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  587. createRequestPacket(request_message, IPPROTO_UDP);
  588. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  589. EXPECT_FALSE(dnsserv.hasAnswer());
  590. }
  591. void
  592. updateConfig(AuthSrv* server, const char* const config_data,
  593. const bool expect_success)
  594. {
  595. ConstElementPtr config_answer =
  596. server->updateConfig(Element::fromJSON(config_data));
  597. EXPECT_EQ(Element::map, config_answer->getType());
  598. EXPECT_TRUE(config_answer->contains("result"));
  599. ConstElementPtr result = config_answer->get("result");
  600. EXPECT_EQ(Element::list, result->getType());
  601. EXPECT_EQ(expect_success ? 0 : 1, result->get(0)->intValue());
  602. }
  603. // Install a Sqlite3 data source with testing data.
  604. TEST_F(AuthSrvTest, updateConfig) {
  605. updateConfig(&server, CONFIG_TESTDB, true);
  606. // query for existent data in the installed data source. The resulting
  607. // response should have the AA flag on, and have an RR in each answer
  608. // and authority section.
  609. createDataFromFile("examplequery_fromWire.wire");
  610. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  611. EXPECT_TRUE(dnsserv.hasAnswer());
  612. headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
  613. QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  614. }
  615. TEST_F(AuthSrvTest, datasourceFail) {
  616. updateConfig(&server, CONFIG_TESTDB, true);
  617. // This query will hit a corrupted entry of the data source (the zoneload
  618. // tool and the data source itself naively accept it). This will result
  619. // in a SERVFAIL response, and the answer and authority sections should
  620. // be empty.
  621. createDataFromFile("badExampleQuery_fromWire.wire");
  622. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  623. EXPECT_TRUE(dnsserv.hasAnswer());
  624. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  625. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  626. }
  627. TEST_F(AuthSrvTest, updateConfigFail) {
  628. // First, load a valid data source.
  629. updateConfig(&server, CONFIG_TESTDB, true);
  630. // Next, try to update it with a non-existent one. This should fail.
  631. updateConfig(&server, BADCONFIG_TESTDB, false);
  632. // The original data source should still exist.
  633. createDataFromFile("examplequery_fromWire.wire");
  634. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  635. EXPECT_TRUE(dnsserv.hasAnswer());
  636. headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
  637. QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  638. }
  639. TEST_F(AuthSrvTest, updateWithInMemoryClient) {
  640. // Test configuring memory data source. Detailed test cases are covered
  641. // in the configuration tests. We only check the AuthSrv interface here.
  642. // By default memory data source isn't enabled
  643. EXPECT_EQ(AuthSrv::InMemoryClientPtr(), server.getInMemoryClient(rrclass));
  644. updateConfig(&server,
  645. "{\"datasources\": [{\"type\": \"memory\"}]}", true);
  646. // after successful configuration, we should have one (with empty zoneset).
  647. ASSERT_NE(AuthSrv::InMemoryClientPtr(), server.getInMemoryClient(rrclass));
  648. EXPECT_EQ(0, server.getInMemoryClient(rrclass)->getZoneCount());
  649. // The memory data source is empty, should return REFUSED rcode.
  650. createDataFromFile("examplequery_fromWire.wire");
  651. server.processMessage(*io_message, parse_message, response_obuffer,
  652. &dnsserv);
  653. EXPECT_TRUE(dnsserv.hasAnswer());
  654. headerCheck(*parse_message, default_qid, Rcode::REFUSED(),
  655. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  656. }
  657. TEST_F(AuthSrvTest, chQueryWithInMemoryClient) {
  658. // Configure memory data source for class IN
  659. updateConfig(&server, "{\"datasources\": "
  660. "[{\"class\": \"IN\", \"type\": \"memory\"}]}", true);
  661. // This shouldn't affect the result of class CH query
  662. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  663. default_qid, Name("version.bind"),
  664. RRClass::CH(), RRType::TXT());
  665. createRequestPacket(request_message, IPPROTO_UDP);
  666. server.processMessage(*io_message, parse_message, response_obuffer,
  667. &dnsserv);
  668. EXPECT_TRUE(dnsserv.hasAnswer());
  669. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  670. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  671. }
  672. TEST_F(AuthSrvTest, cacheSlots) {
  673. // simple check for the get/set operations
  674. server.setCacheSlots(10); // 10 = arbitrary choice
  675. EXPECT_EQ(10, server.getCacheSlots());
  676. // 0 is a valid size
  677. server.setCacheSlots(0);
  678. EXPECT_EQ(00, server.getCacheSlots());
  679. }
  680. // Submit UDP normal query and check query counter
  681. TEST_F(AuthSrvTest, queryCounterUDPNormal) {
  682. // The counter should be initialized to 0.
  683. EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_UDP_QUERY));
  684. // Create UDP message and process.
  685. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  686. default_qid, Name("example.com"),
  687. RRClass::IN(), RRType::NS());
  688. createRequestPacket(request_message, IPPROTO_UDP);
  689. server.processMessage(*io_message, parse_message, response_obuffer,
  690. &dnsserv);
  691. // After processing UDP query, the counter should be 1.
  692. EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_UDP_QUERY));
  693. }
  694. // Submit TCP normal query and check query counter
  695. TEST_F(AuthSrvTest, queryCounterTCPNormal) {
  696. // The counter should be initialized to 0.
  697. EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
  698. // Create TCP message and process.
  699. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  700. default_qid, Name("example.com"),
  701. RRClass::IN(), RRType::NS());
  702. createRequestPacket(request_message, IPPROTO_TCP);
  703. server.processMessage(*io_message, parse_message, response_obuffer,
  704. &dnsserv);
  705. // After processing TCP query, the counter should be 1.
  706. EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
  707. }
  708. // Submit TCP AXFR query and check query counter
  709. TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
  710. // The counter should be initialized to 0.
  711. EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
  712. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  713. Name("example.com"), RRClass::IN(), RRType::AXFR());
  714. createRequestPacket(request_message, IPPROTO_TCP);
  715. // On success, the AXFR query has been passed to a separate process,
  716. // so auth itself shouldn't respond.
  717. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  718. EXPECT_FALSE(dnsserv.hasAnswer());
  719. // After processing TCP AXFR query, the counter should be 1.
  720. EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
  721. }
  722. // Submit TCP IXFR query and check query counter
  723. TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
  724. // The counter should be initialized to 0.
  725. EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
  726. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  727. Name("example.com"), RRClass::IN(), RRType::IXFR());
  728. createRequestPacket(request_message, IPPROTO_TCP);
  729. // On success, the IXFR query has been passed to a separate process,
  730. // so auth itself shouldn't respond.
  731. server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
  732. EXPECT_FALSE(dnsserv.hasAnswer());
  733. // After processing TCP IXFR query, the counter should be 1.
  734. EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
  735. }
  736. // class for queryCounterUnexpected test
  737. // getProtocol() returns IPPROTO_IP
  738. class DummyUnknownSocket : public IOSocket {
  739. public:
  740. DummyUnknownSocket() {}
  741. virtual int getNative() const { return (0); }
  742. virtual int getProtocol() const { return (IPPROTO_IP); }
  743. };
  744. // function for queryCounterUnexpected test
  745. // returns a reference to a static object of DummyUnknownSocket
  746. IOSocket&
  747. getDummyUnknownSocket() {
  748. static DummyUnknownSocket socket;
  749. return (socket);
  750. }
  751. // Submit unexpected type of query and check it throws isc::Unexpected
  752. TEST_F(AuthSrvTest, queryCounterUnexpected) {
  753. // This code isn't exception safe, but we'd rather keep the code
  754. // simpler and more readable as this is only for tests and if it throws
  755. // the program would immediately terminate anyway.
  756. // Create UDP query packet.
  757. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  758. default_qid, Name("example.com"),
  759. RRClass::IN(), RRType::NS());
  760. createRequestPacket(request_message, IPPROTO_UDP);
  761. // Modify the message.
  762. delete io_message;
  763. endpoint = IOEndpoint::create(IPPROTO_UDP,
  764. IOAddress(DEFAULT_REMOTE_ADDRESS), 53210);
  765. io_message = new IOMessage(request_renderer.getData(),
  766. request_renderer.getLength(),
  767. getDummyUnknownSocket(), *endpoint);
  768. EXPECT_THROW(server.processMessage(*io_message, parse_message,
  769. response_obuffer, &dnsserv),
  770. isc::Unexpected);
  771. }
  772. TEST_F(AuthSrvTest, stop) {
  773. // normal case is covered in command_unittest.cc. we should primarily
  774. // test it here, but the current design of the stop test takes time,
  775. // so we consolidate the cases in the command tests.
  776. // If/when the interval timer has finer granularity we'll probably add
  777. // our own tests here, so we keep this empty test case.
  778. }
  779. TEST_F(AuthSrvTest, listenAddresses) {
  780. isc::testutils::portconfig::listenAddresses(server);
  781. }
  782. }