|
@@ -16,6 +16,10 @@
|
|
|
|
|
|
#include <algorithm>
|
|
#include <algorithm>
|
|
#include <vector>
|
|
#include <vector>
|
|
|
|
+#include <string>
|
|
|
|
+
|
|
|
|
+#include <boost/scoped_ptr.hpp>
|
|
|
|
+#include <boost/shared_ptr.hpp>
|
|
|
|
|
|
#include <exceptions/exceptions.h>
|
|
#include <exceptions/exceptions.h>
|
|
|
|
|
|
@@ -25,11 +29,14 @@
|
|
#include <acl/check.h>
|
|
#include <acl/check.h>
|
|
#include <acl/ip_check.h>
|
|
#include <acl/ip_check.h>
|
|
|
|
|
|
|
|
+#include "sockaddr.h"
|
|
|
|
+
|
|
#include <gtest/gtest.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
using namespace std;
|
|
using namespace std;
|
|
|
|
+using boost::scoped_ptr;
|
|
using namespace isc::data;
|
|
using namespace isc::data;
|
|
-using namespace isc::acl::dns;
|
|
|
|
|
|
+using namespace isc::acl;
|
|
using isc::acl::LoaderError;
|
|
using isc::acl::LoaderError;
|
|
|
|
|
|
namespace {
|
|
namespace {
|
|
@@ -38,9 +45,9 @@ namespace {
|
|
// time and the returned value can be used to anything. It is not much of a
|
|
// time and the returned value can be used to anything. It is not much of a
|
|
// test, but the getLoader is not much of a function.
|
|
// test, but the getLoader is not much of a function.
|
|
TEST(DNSACL, getLoader) {
|
|
TEST(DNSACL, getLoader) {
|
|
- RequestLoader* l(&getLoader());
|
|
|
|
|
|
+ dns::RequestLoader* l(&dns::getLoader());
|
|
ASSERT_TRUE(l != NULL);
|
|
ASSERT_TRUE(l != NULL);
|
|
- EXPECT_EQ(l, &getLoader());
|
|
|
|
|
|
+ EXPECT_EQ(l, &dns::getLoader());
|
|
EXPECT_NO_THROW(l->load(Element::fromJSON("[{\"action\": \"DROP\"}]")));
|
|
EXPECT_NO_THROW(l->load(Element::fromJSON("[{\"action\": \"DROP\"}]")));
|
|
|
|
|
|
// Test check rules registered by default, i.e. RequestCheck
|
|
// Test check rules registered by default, i.e. RequestCheck
|
|
@@ -50,9 +57,9 @@ TEST(DNSACL, getLoader) {
|
|
|
|
|
|
class RequestCheckCreatorTest : public ::testing::Test {
|
|
class RequestCheckCreatorTest : public ::testing::Test {
|
|
protected:
|
|
protected:
|
|
- internal::RequestCheckCreator creator_;
|
|
|
|
|
|
+ dns::internal::RequestCheckCreator creator_;
|
|
|
|
|
|
- typedef boost::shared_ptr<const RequestCheck> ConstRequestCheckPtr;
|
|
|
|
|
|
+ typedef boost::shared_ptr<const dns::RequestCheck> ConstRequestCheckPtr;
|
|
ConstRequestCheckPtr check_;
|
|
ConstRequestCheckPtr check_;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -70,9 +77,9 @@ TEST_F(RequestCheckCreatorTest, allowListAbbreviation) {
|
|
// are done in the tests for IPCheck.
|
|
// are done in the tests for IPCheck.
|
|
TEST_F(RequestCheckCreatorTest, createIPv4Check) {
|
|
TEST_F(RequestCheckCreatorTest, createIPv4Check) {
|
|
check_ = creator_.create("from", Element::fromJSON("\"192.0.2.1\""),
|
|
check_ = creator_.create("from", Element::fromJSON("\"192.0.2.1\""),
|
|
- getLoader());
|
|
|
|
- const internal::RequestIPCheck& ipcheck_ =
|
|
|
|
- dynamic_cast<const internal::RequestIPCheck&>(*check_);
|
|
|
|
|
|
+ dns::getLoader());
|
|
|
|
+ const dns::internal::RequestIPCheck& ipcheck_ =
|
|
|
|
+ dynamic_cast<const dns::internal::RequestIPCheck&>(*check_);
|
|
EXPECT_EQ(AF_INET, ipcheck_.getFamily());
|
|
EXPECT_EQ(AF_INET, ipcheck_.getFamily());
|
|
EXPECT_EQ(32, ipcheck_.getPrefixlen());
|
|
EXPECT_EQ(32, ipcheck_.getPrefixlen());
|
|
const vector<uint8_t> check_address(ipcheck_.getAddress());
|
|
const vector<uint8_t> check_address(ipcheck_.getAddress());
|
|
@@ -85,9 +92,9 @@ TEST_F(RequestCheckCreatorTest, createIPv4Check) {
|
|
TEST_F(RequestCheckCreatorTest, createIPv6Check) {
|
|
TEST_F(RequestCheckCreatorTest, createIPv6Check) {
|
|
check_ = creator_.create("from",
|
|
check_ = creator_.create("from",
|
|
Element::fromJSON("\"2001:db8::5300/120\""),
|
|
Element::fromJSON("\"2001:db8::5300/120\""),
|
|
- getLoader());
|
|
|
|
- const internal::RequestIPCheck& ipcheck_ =
|
|
|
|
- dynamic_cast<const internal::RequestIPCheck&>(*check_);
|
|
|
|
|
|
+ dns::getLoader());
|
|
|
|
+ const dns::internal::RequestIPCheck& ipcheck_ =
|
|
|
|
+ dynamic_cast<const dns::internal::RequestIPCheck&>(*check_);
|
|
EXPECT_EQ(AF_INET6, ipcheck_.getFamily());
|
|
EXPECT_EQ(AF_INET6, ipcheck_.getFamily());
|
|
EXPECT_EQ(120, ipcheck_.getPrefixlen());
|
|
EXPECT_EQ(120, ipcheck_.getPrefixlen());
|
|
const vector<uint8_t> check_address(ipcheck_.getAddress());
|
|
const vector<uint8_t> check_address(ipcheck_.getAddress());
|
|
@@ -102,22 +109,79 @@ TEST_F(RequestCheckCreatorTest, createIPv6Check) {
|
|
TEST_F(RequestCheckCreatorTest, badCreate) {
|
|
TEST_F(RequestCheckCreatorTest, badCreate) {
|
|
// Invalid name
|
|
// Invalid name
|
|
EXPECT_THROW(creator_.create("bad", Element::fromJSON("\"192.0.2.1\""),
|
|
EXPECT_THROW(creator_.create("bad", Element::fromJSON("\"192.0.2.1\""),
|
|
- getLoader()), LoaderError);
|
|
|
|
|
|
+ dns::getLoader()), LoaderError);
|
|
|
|
|
|
// Invalid type of parameter
|
|
// Invalid type of parameter
|
|
- EXPECT_THROW(creator_.create("from", Element::fromJSON("4"), getLoader()),
|
|
|
|
|
|
+ EXPECT_THROW(creator_.create("from", Element::fromJSON("4"),
|
|
|
|
+ dns::getLoader()),
|
|
isc::data::TypeError);
|
|
isc::data::TypeError);
|
|
- EXPECT_THROW(creator_.create("from", Element::fromJSON("[]"), getLoader()),
|
|
|
|
|
|
+ EXPECT_THROW(creator_.create("from", Element::fromJSON("[]"),
|
|
|
|
+ dns::getLoader()),
|
|
isc::data::TypeError);
|
|
isc::data::TypeError);
|
|
|
|
|
|
// Syntax error for IPCheck
|
|
// Syntax error for IPCheck
|
|
EXPECT_THROW(creator_.create("from", Element::fromJSON("\"bad\""),
|
|
EXPECT_THROW(creator_.create("from", Element::fromJSON("\"bad\""),
|
|
- getLoader()),
|
|
|
|
|
|
+ dns::getLoader()),
|
|
isc::InvalidParameter);
|
|
isc::InvalidParameter);
|
|
|
|
|
|
// NULL pointer
|
|
// NULL pointer
|
|
- EXPECT_THROW(creator_.create("from", ConstElementPtr(), getLoader()),
|
|
|
|
|
|
+ EXPECT_THROW(creator_.create("from", ConstElementPtr(), dns::getLoader()),
|
|
LoaderError);
|
|
LoaderError);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+class RequestCheckTest : public ::testing::Test {
|
|
|
|
+protected:
|
|
|
|
+ typedef boost::shared_ptr<const dns::RequestCheck> ConstRequestCheckPtr;
|
|
|
|
+
|
|
|
|
+ // A helper shortcut to create a single IP check for the given prefix.
|
|
|
|
+ ConstRequestCheckPtr createIPCheck(const string& prefix) {
|
|
|
|
+ return (creator_.create("from", Element::fromJSON(
|
|
|
|
+ string("\"") + prefix + string("\"")),
|
|
|
|
+ dns::getLoader()));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // create a one time request context for a specific test. Note that
|
|
|
|
+ // getSockaddr() uses a static storage, so it cannot be called more than
|
|
|
|
+ // once in a single test.
|
|
|
|
+ const dns::RequestContext& getRequest4() {
|
|
|
|
+ ipaddr.reset(new IPAddress(tests::getSockAddr("192.0.2.1")));
|
|
|
|
+ request.reset(new dns::RequestContext(*ipaddr));
|
|
|
|
+ return (*request);
|
|
|
|
+ }
|
|
|
|
+ const dns::RequestContext& getRequest6() {
|
|
|
|
+ ipaddr.reset(new IPAddress(tests::getSockAddr("2001:db8::1")));
|
|
|
|
+ request.reset(new dns::RequestContext(*ipaddr));
|
|
|
|
+ return (*request);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+private:
|
|
|
|
+ scoped_ptr<IPAddress> ipaddr;
|
|
|
|
+ scoped_ptr<dns::RequestContext> request;
|
|
|
|
+ dns::internal::RequestCheckCreator creator_;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+TEST_F(RequestCheckTest, checkIPv4) {
|
|
|
|
+ // Exact match
|
|
|
|
+ EXPECT_TRUE(createIPCheck("192.0.2.1")->matches(getRequest4()));
|
|
|
|
+ // Exact match (negative)
|
|
|
|
+ EXPECT_FALSE(createIPCheck("192.0.2.53")->matches(getRequest4()));
|
|
|
|
+ // Prefix match
|
|
|
|
+ EXPECT_TRUE(createIPCheck("192.0.2.0/24")->matches(getRequest4()));
|
|
|
|
+ // Prefix match (negative)
|
|
|
|
+ EXPECT_FALSE(createIPCheck("192.0.1.0/24")->matches(getRequest4()));
|
|
|
|
+ // Address family mismatch (the first 4 bytes of the IPv6 address has the
|
|
|
|
+ // same binary representation as the client's IPv4 address, which
|
|
|
|
+ // shouldn't confuse the match logic)
|
|
|
|
+ EXPECT_FALSE(createIPCheck("c000:0201::")->matches(getRequest4()));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(RequestCheckTest, checkIPv6) {
|
|
|
|
+ // The following are a set of tests of the same concept as checkIPv4
|
|
|
|
+ EXPECT_TRUE(createIPCheck("2001:db8::1")->matches(getRequest6()));
|
|
|
|
+ EXPECT_FALSE(createIPCheck("2001:db8::53")->matches(getRequest6()));
|
|
|
|
+ EXPECT_TRUE(createIPCheck("2001:db8::/64")->matches(getRequest6()));
|
|
|
|
+ EXPECT_FALSE(createIPCheck("2001:db8:1::/64")->matches(getRequest6()));
|
|
|
|
+ EXPECT_FALSE(createIPCheck("32.1.13.184")->matches(getRequest6()));
|
|
|
|
+}
|
|
|
|
+
|
|
}
|
|
}
|