auth_srv_unittest.cc 34 KB

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