Browse Source

- tighten validation on incoming requests. return an response rather than
ignoring requests when an error occurs
- added a framework for auth server unit test with an initial simple test


git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1306 e5f2f494-b856-4b98-b285-d166d9295462

JINMEI Tatuya 15 years ago
parent
commit
87ccb0c631

+ 1 - 0
configure.ac

@@ -223,6 +223,7 @@ AC_CONFIG_FILES([Makefile
                  src/lib/dns/tests/Makefile
                  src/lib/exceptions/Makefile
                  src/lib/auth/Makefile
+                 src/lib/auth/tests/Makefile
                ])
 AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
            src/bin/cmdctl/cmdctl.py

+ 2 - 0
src/bin/auth/Makefile.am

@@ -1,3 +1,5 @@
+SUBDIRS = . tests
+
 AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/ext $(SQLITE_CFLAGS)
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@

+ 36 - 5
src/bin/auth/auth_srv.cc

@@ -24,6 +24,8 @@
 #include <cassert>
 #include <iostream>
 
+#include <exceptions/exceptions.h>
+
 #include <dns/buffer.h>
 #include <dns/messagerenderer.h>
 #include <dns/name.h>
@@ -49,6 +51,7 @@
 
 using namespace std;
 
+using namespace isc;
 using namespace isc::auth;
 using namespace isc::dns;
 using namespace isc::dns::rdata;
@@ -89,6 +92,16 @@ AuthSrv::~AuthSrv() {
     delete impl_;
 }
 
+static void
+makeErrorMessage(Message& message, MessageRenderer& renderer,
+                 const Rcode& rcode)
+{
+    message.makeResponse();
+    message.setRcode(rcode);
+    message.setUDPSize(4096);   // XXX: hardcoding
+    message.toWire(renderer);
+}
+
 int
 AuthSrv::processMessage(InputBuffer& request_buffer,
                         Message& message,
@@ -97,17 +110,35 @@ AuthSrv::processMessage(InputBuffer& request_buffer,
 {
     try {
         message.fromWire(request_buffer);
-    } catch (...) {
-        cerr << "[AuthSrv] parse failed" << endl;
-        return (-1);
-    }
+    } catch (const DNSProtocolError& error) {
+        cerr << "returning protocol error" << endl;
+        makeErrorMessage(message, response_renderer, error.getRcode());
+        return (0);
+    } catch (const Exception& ex) {
+        cerr << "returning servfail" << endl;
+        makeErrorMessage(message, response_renderer, Rcode::SERVFAIL());
+        return (0);
+    } // other exceptions will be handled at a higher layer.
 
     if (verbose_mode) {
         cerr << "[AuthSrv] received a message:\n" << message.toText() << endl;
     }
 
+    //
+    // Incoming Message Validation
+    //
+    // In this implementation, we only support normal queries
+    if (message.getOpcode() != Opcode::QUERY()) {
+        if (verbose_mode) {
+            cerr << "unsupported opcode" << endl;
+        }
+        makeErrorMessage(message, response_renderer, Rcode::NOTIMP());
+        return (0);
+    }
+
     if (message.getRRCount(Section::QUESTION()) != 1) {
-        return (-1);
+        makeErrorMessage(message, response_renderer, Rcode::FORMERR());
+        return (0);
     }
 
     const bool dnssec_ok = message.isDNSSECSupported();

+ 28 - 0
src/bin/auth/tests/Makefile.am

@@ -0,0 +1,28 @@
+AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_builddir)/src/bin -I$(top_srcdir)/ext
+
+CLEANFILES = *.gcno *.gcda
+
+TESTS =
+if HAVE_GTEST
+TESTS += run_unittests
+run_unittests_SOURCES = $(top_srcdir)/src/lib/dns/tests/unittest_util.h
+run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
+run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc
+run_unittests_SOURCES += auth_srv_unittest.cc
+run_unittests_SOURCES += run_unittests.cc
+run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDADD += $(SQLITE_LIBS)
+run_unittests_LDADD +=  $(top_builddir)/src/lib/auth/.libs/libauth.a
+run_unittests_LDADD +=  $(top_builddir)/src/lib/dns/.libs/libdns.a
+run_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.a
+run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.a
+run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
+if HAVE_BOOSTLIB
+run_unittests_LDFLAGS += $(BOOST_LDFLAGS)
+run_unittests_LDADD += $(BOOST_SYSTEM_LIB)
+endif
+endif
+
+noinst_PROGRAMS = $(TESTS)

+ 69 - 0
src/bin/auth/tests/auth_srv_unittest.cc

@@ -0,0 +1,69 @@
+// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// $Id$
+
+#include <gtest/gtest.h>
+
+#include <dns/buffer.h>
+#include <dns/name.h>
+#include <dns/message.h>
+#include <dns/messagerenderer.h>
+#include <dns/rrclass.h>
+#include <dns/rrtype.h>
+
+#include <auth/auth_srv.h>
+
+#include <dns/tests/unittest_util.h>
+
+using isc::UnitTestUtil;
+using namespace std;
+using namespace isc::dns;
+
+namespace {
+class AuthSrvTest : public ::testing::Test {
+protected:
+    AuthSrvTest() : request_message(Message::RENDER),
+                    parse_message(Message::PARSE),
+                    qname("www.example.com"),
+                    qclass(RRClass::IN()), qtype(RRType::A()),
+                    request_obuffer(0), request_renderer(request_obuffer),
+                    response_obuffer(0), response_renderer(response_obuffer)
+    {}
+    AuthSrv server;
+    Message request_message;
+    Message parse_message;
+    Name qname;
+    RRClass qclass;
+    RRType qtype;
+    OutputBuffer request_obuffer;
+    MessageRenderer request_renderer;
+    OutputBuffer response_obuffer;
+    MessageRenderer response_renderer;
+    vector<uint8_t> data;
+};
+
+static void
+createDataFromFile(const char* const datafile, vector<uint8_t>& data) {
+    UnitTestUtil::readWireData(datafile, data);
+    InputBuffer buffer(&data[0], data.size());
+}
+
+TEST_F(AuthSrvTest, ManyQuery) {
+    createDataFromFile("testdata/iquery_fromWire", data);
+    InputBuffer buffer(&data[0], data.size());
+    EXPECT_EQ(0, server.processMessage(buffer, parse_message, response_renderer,
+                                       true, false));
+}
+}

+ 24 - 0
src/bin/auth/tests/run_unittests.cc

@@ -0,0 +1,24 @@
+// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// $Id$
+
+#include <gtest/gtest.h>
+
+int
+main(int argc, char* argv[])
+{
+    ::testing::InitGoogleTest(&argc, argv);
+    return (RUN_ALL_TESTS());
+}

+ 13 - 0
src/bin/auth/tests/testdata/iquery_fromWire

@@ -0,0 +1,13 @@
+###
+### This data file was auto-generated from iquery_fromWire.spec
+###
+
+# Header Section
+# ID=4149 QR=Query Opcode=IQUERY(1) Rcode=NOERROR(0)
+1035 4000
+# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=0
+0001 0000 0000 0000
+
+# Question Section
+# QNAME=example.com. QTYPE=A(1) QCLASS=IN(1)
+076578616d706c6503636f6d00 0001 0001

+ 8 - 0
src/bin/auth/tests/testdata/iquery_fromWire.spec

@@ -0,0 +1,8 @@
+#
+# IQUERY message.
+#
+
+[header]
+opcode: iquery
+[question]
+# use default