2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 05:27:55 +00:00

[3186] Initial classes in DHCP user check hook library

Adds new source tree branch, bind10/src/hooks, for maintaining
custom hooks libraries.  Adds bare bones implementation of UserRegistry
for use in custom DHCP hooks library.
This commit is contained in:
Thomas Markwalder 2013-10-11 14:10:06 -04:00
parent b080f05c59
commit f0edd52c24
18 changed files with 1159 additions and 0 deletions

View File

@ -1288,6 +1288,10 @@ AC_CONFIG_FILES([Makefile
src/bin/usermgr/Makefile
src/bin/usermgr/tests/Makefile
src/bin/tests/Makefile
src/hooks/Makefile
src/hooks/dhcp/Makefile
src/hooks/dhcp/user_chk/Makefile
src/hooks/dhcp/user_chk/tests/Makefile
src/lib/Makefile
src/lib/asiolink/Makefile
src/lib/asiolink/tests/Makefile

View File

@ -1,4 +1,6 @@
SUBDIRS = lib bin
# hooks lib could be a configurable switch
SUBDIRS += hooks
EXTRA_DIST = \
cppcheck-suppress.lst \

1
src/hooks/Makefile.am Normal file
View File

@ -0,0 +1 @@
SUBDIRS = dhcp

View File

@ -0,0 +1 @@
SUBDIRS = user_chk

View File

@ -0,0 +1,59 @@
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
# Some versions of GCC warn about some versions of Boost regarding
# missing initializer for members in its posix_time.
# https://svn.boost.org/trac/boost/ticket/3477
# But older GCC compilers don't have the flag.
AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
# Define rule to build logging source files from message file
# hooks_messages.h hooks_messages.cc: s-messages
# s-messages: hooks_messages.mes
# $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/hooks/hooks_messages.mes
# touch $@
# Tell automake that the message files are built as part of the build process
# (so that they are built before the main library is built).
# BUILT_SOURCES = hooks_messages.h hooks_messages.cc
BUILT_SOURCES =
# Ensure that the message file is included in the distribution
EXTRA_DIST =
# Get rid of generated message files on a clean
# CLEANFILES = *.gcno *.gcda hooks_messages.h hooks_messages.cc s-messages
CLEANFILES = *.gcno *.gcda
lib_LTLIBRARIES = libdhcp_user_chk.la
libdhcp_user_chk_la_SOURCES =
libdhcp_user_chk_la_SOURCES += load_unload.cc
libdhcp_user_chk_la_SOURCES += user.cc user.h
libdhcp_user_chk_la_SOURCES += user_data_source.cc user_data_source.h
libdhcp_user_chk_la_SOURCES += user_registry.cc user_registry.h
libdhcp_user_chk_la_SOURCES += version.cc
#nodist_libdhcp_user_chk_la_SOURCES = hooks_messages.cc hooks_messages.h
nodist_libdhcp_user_chk_la_SOURCES =
libdhcp_user_chk_la_CXXFLAGS = $(AM_CXXFLAGS)
libdhcp_user_chk_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
libdhcp_user_chk_la_LDFLAGS = $(AM_LDFLAGS)
libdhcp_user_chk_la_LDFLAGS += -avoid-version -export-dynamic -module
libdhcp_user_chk_la_LIBADD =
libdhcp_user_chk_la_LIBADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
libdhcp_user_chk_la_LIBADD += $(top_builddir)/src/lib/log/libb10-log.la
libdhcp_user_chk_la_LIBADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
libdhcp_user_chk_la_LIBADD += $(top_builddir)/src/lib/util/libb10-util.la
libdhcp_user_chk_la_LIBADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
if USE_CLANGPP
# Disable unused parameter warning caused by some of the
# Boost headers when compiling with clang.
libdhcp_user_chk_la_CXXFLAGS += -Wno-unused-parameter
endif

View File

@ -0,0 +1,32 @@
// Copyright (C) 2013 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.
// load_unload.cc
#include <hooks/hooks.h>
using namespace isc::hooks;
extern "C" {
int load(LibraryHandle&) {
// @todo instantiate registry here
return (0);
}
int unload() {
// @todo destruct registry here
return (0);
}
}

View File

@ -0,0 +1,62 @@
SUBDIRS = .
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/user_chk
AM_CPPFLAGS += $(BOOST_INCLUDES) $(BOTAN_INCLUDES)
AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/hooks/dhcp/user_chk/tests\"
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
AM_CXXFLAGS = $(B10_CXXFLAGS)
# Some versions of GCC warn about some versions of Boost regarding
# missing initializer for members in its posix_time.
# https://svn.boost.org/trac/boost/ticket/3477
# But older GCC compilers don't have the flag.
AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
USER_CHK_LIB = $(top_builddir)/src/hooks/dhcp/user_chk/libdhcp_user_chk.la
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
CLEANFILES = *.gcno *.gcda
TESTS_ENVIRONMENT = \
$(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
TESTS =
if HAVE_GTEST
TESTS += libdhcp_user_chk_unittests
libdhcp_user_chk_unittests_SOURCES =
libdhcp_user_chk_unittests_SOURCES += ../user.cc ../user.h
libdhcp_user_chk_unittests_SOURCES += ../user_data_source.cc ../user_data_source.h
libdhcp_user_chk_unittests_SOURCES += ../user_registry.cc ../user_registry.h
libdhcp_user_chk_unittests_SOURCES += run_unittests.cc
libdhcp_user_chk_unittests_SOURCES += userid_unittests.cc
libdhcp_user_chk_unittests_SOURCES += user_unittests.cc
libdhcp_user_chk_unittests_SOURCES += user_registry_unittests.cc
libdhcp_user_chk_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
libdhcp_user_chk_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
libdhcp_user_chk_unittests_CXXFLAGS = $(AM_CXXFLAGS)
if USE_CLANGPP
# This is to workaround unused variables tcout and tcerr in
# log4cplus's streams.h and unused parameters from some of the
# Boost headers.
libdhcp_user_chk_unittests_CXXFLAGS += -Wno-unused-parameter
endif
libdhcp_user_chk_unittests_LDADD = $(top_builddir)/src/lib/log/libb10-log.la
libdhcp_user_chk_unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
libdhcp_user_chk_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
libdhcp_user_chk_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
#libdhcp_user_chk_unittests_LDADD += $(top_builddir)/src/hooks/dhcp/user_chk/libdhcp_user_chk.la
libdhcp_user_chk_unittests_LDADD += ${BOTAN_LIBS} ${BOTAN_RPATH}
libdhcp_user_chk_unittests_LDADD += $(GTEST_LDADD)
endif
noinst_PROGRAMS = $(TESTS)

View File

@ -0,0 +1,27 @@
// Copyright (C) 2013 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.
#include <log/logger_support.h>
#include <gtest/gtest.h>
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
isc::log::initLogger();
int result = RUN_ALL_TESTS();
return (result);
}

View File

@ -0,0 +1,133 @@
// Copyright (C) 2013 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.
#include <dhcp/hwaddr.h>
#include <exceptions/exceptions.h>
#include <user_registry.h>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <gtest/gtest.h>
using namespace std;
namespace {
TEST(UserRegistry, constructor) {
UserRegistryPtr reg;
ASSERT_NO_THROW(reg.reset(new UserRegistry()));
}
TEST(UserRegistry, userBasics) {
UserRegistryPtr reg;
ASSERT_NO_THROW(reg.reset(new UserRegistry()));
UserIdPtr id, id2;
// Make user ids.
ASSERT_NO_THROW(id.reset(new UserId(UserId::HW_ADDRESS, "01010101")));
ASSERT_NO_THROW(id2.reset(new UserId(UserId::HW_ADDRESS, "02020202")));
UserPtr user, user2;
// Verify that a blank user cannot be added.
ASSERT_THROW(reg->addUser(user), isc::BadValue);
// Make new users.
ASSERT_NO_THROW(user.reset(new User(*id)));
ASSERT_NO_THROW(user2.reset(new User(*id)));
// Add first user.
ASSERT_NO_THROW(reg->addUser(user));
// Verify user added can be found.
UserPtr found_user;
ASSERT_NO_THROW(found_user = reg->findUser(*id));
EXPECT_TRUE(found_user);
EXPECT_EQ(*id, found_user->getUserId());
// Verify user not added cannot be found.
ASSERT_NO_THROW(found_user = reg->findUser(*id2));
EXPECT_FALSE(found_user);
// Verfiy user can no longer be found.
ASSERT_NO_THROW(reg->removeUser(*id));
ASSERT_NO_THROW(found_user = reg->findUser(*id));
EXPECT_FALSE(found_user);
}
TEST(UserRegistry, findByHWAddr) {
UserRegistryPtr reg;
ASSERT_NO_THROW(reg.reset(new UserRegistry()));
// Make a user.
UserPtr user;
ASSERT_NO_THROW(user.reset(new User(UserId::HW_ADDRESS, "01010101")));
// Verify user can be added.
ASSERT_NO_THROW(reg->addUser(user));
// Make a HWAddr instance using the same id value.
isc::dhcp::HWAddr hwaddr(user->getUserId().getId(),
isc::dhcp::HTYPE_ETHER);
// Verify user can be found by HWAddr.
UserPtr found_user;
ASSERT_NO_THROW(found_user = reg->findUser(hwaddr));
EXPECT_TRUE(found_user);
EXPECT_EQ(user->getUserId(), found_user->getUserId());
}
TEST(UserRegistry, findByDUID) {
UserRegistryPtr reg;
ASSERT_NO_THROW(reg.reset(new UserRegistry()));
// Make a user.
UserPtr user;
ASSERT_NO_THROW(user.reset(new User(UserId::DUID, "01010101")));
// Verify user can be added.
ASSERT_NO_THROW(reg->addUser(user));
// Make a HWAddr instance using the same id value.
isc::dhcp::DUID duid(user->getUserId().getId());
// Verify user can be found by HWAddr.
UserPtr found_user;
ASSERT_NO_THROW(found_user = reg->findUser(duid));
EXPECT_TRUE(found_user);
EXPECT_EQ(user->getUserId(), found_user->getUserId());
}
TEST(UserRegistry, findByClientId) {
UserRegistryPtr reg;
ASSERT_NO_THROW(reg.reset(new UserRegistry()));
// Make a user.
UserPtr user;
ASSERT_NO_THROW(user.reset(new User(UserId::CLIENT_ID, "01010101")));
// Verify user can be added.
ASSERT_NO_THROW(reg->addUser(user));
// Make a HWAddr instance using the same id value.
isc::dhcp::ClientId client_id(user->getUserId().getId());
// Verify user can be found by HWAddr.
UserPtr found_user;
ASSERT_NO_THROW(found_user = reg->findUser(client_id));
EXPECT_TRUE(found_user);
EXPECT_EQ(user->getUserId(), found_user->getUserId());
}
} // end of anonymous namespace

View File

@ -0,0 +1,72 @@
// Copyright (C) 2013 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.
#include <exceptions/exceptions.h>
#include <user.h>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <gtest/gtest.h>
using namespace std;
namespace {
TEST(UserTest, construction) {
std::string test_address("01FF02AC030B0709");
UserIdPtr id;
ASSERT_NO_THROW(id.reset(new UserId(UserId::HW_ADDRESS, test_address)));
UserPtr user;
// Verify construction from a UserId.
ASSERT_NO_THROW(user.reset(new User(*id)));
// Verify construction from a type and an address vector.
ASSERT_NO_THROW(user.reset(new User(UserId::HW_ADDRESS, id->getId())));
ASSERT_NO_THROW(user.reset(new User(UserId::DUID, id->getId())));
ASSERT_NO_THROW(user.reset(new User(UserId::CLIENT_ID, id->getId())));
// Verify construction from a type and an address string.
ASSERT_NO_THROW(user.reset(new User(UserId::HW_ADDRESS, test_address)));
ASSERT_NO_THROW(user.reset(new User(UserId::DUID, test_address)));
ASSERT_NO_THROW(user.reset(new User(UserId::CLIENT_ID, test_address)));
}
TEST(UserTest, properties) {
UserPtr user;
ASSERT_NO_THROW(user.reset(new User(UserId::DUID, "01020304050607")));
std::string value = "";
EXPECT_NO_THROW(user->setProperty("one","1"));
EXPECT_NO_THROW(value = user->getProperty("one"));
EXPECT_EQ(value, "1");
EXPECT_NO_THROW(user->setProperty("one","1.0"));
EXPECT_NO_THROW(value = user->getProperty("one"));
EXPECT_EQ(value, "1.0");
EXPECT_NO_THROW(user->delProperty("one"));
EXPECT_NO_THROW(value = user->getProperty("one"));
EXPECT_TRUE(value.empty());
EXPECT_THROW(user->setProperty("", "blah"), isc::BadValue);
EXPECT_NO_THROW(user->setProperty("one", ""));
EXPECT_NO_THROW(value = user->getProperty("one"));
EXPECT_TRUE(value.empty());
}
} // end of anonymous namespace

View File

@ -0,0 +1,165 @@
// Copyright (C) 2013 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.
#include <exceptions/exceptions.h>
#include <user.h>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <gtest/gtest.h>
using namespace std;
namespace {
TEST(UserIdTest, invalidConstructors) {
// Verify that constructor does not allow empty id vector.
std::vector<uint8_t> empty_bytes;
ASSERT_THROW(UserId(UserId::HW_ADDRESS, empty_bytes), isc::BadValue);
ASSERT_THROW(UserId(UserId::DUID, empty_bytes), isc::BadValue);
ASSERT_THROW(UserId(UserId::CLIENT_ID, empty_bytes), isc::BadValue);
// Verify that constructor does not allow empty id string.
ASSERT_THROW(UserId(UserId::HW_ADDRESS, ""), isc::BadValue);
ASSERT_THROW(UserId(UserId::DUID, ""), isc::BadValue);
ASSERT_THROW(UserId(UserId::CLIENT_ID, ""), isc::BadValue);
}
TEST(UserIdTest, hwAddress_type) {
EXPECT_EQ(std::string(UserId::HW_ADDRESS_STR),
UserId::lookupTypeStr(UserId::HW_ADDRESS));
EXPECT_EQ(UserId::HW_ADDRESS,
UserId::lookupType(UserId::HW_ADDRESS_STR));
uint8_t tmp[] = { 0x01, 0xFF, 0x02, 0xAC, 0x03, 0x0B, 0x07, 0x08 };
std::vector<uint8_t> bytes(tmp, tmp + (sizeof(tmp)/sizeof(uint8_t)));
UserIdPtr id;
ASSERT_NO_THROW(id.reset(new UserId(UserId::HW_ADDRESS, bytes)));
EXPECT_EQ(id->getType(), UserId::HW_ADDRESS);
EXPECT_EQ(bytes, id->getId());
// Verify a == b;
UserIdPtr id2;
ASSERT_NO_THROW(id2.reset(new UserId(UserId::HW_ADDRESS, id->toText())));
EXPECT_TRUE(*id == *id2);
EXPECT_FALSE(*id != *id2);
EXPECT_FALSE(*id < *id2);
// Verify a < b;
ASSERT_NO_THROW(id2.reset(new UserId(UserId::HW_ADDRESS,
"01FF02AC030B0709")));
EXPECT_FALSE(*id == *id2);
EXPECT_TRUE(*id != *id2);
EXPECT_TRUE(*id < *id2);
// Verify a > b;
ASSERT_NO_THROW(id2.reset(new UserId(UserId::HW_ADDRESS,
"01FF02AC030B0707")));
EXPECT_FALSE(*id == *id2);
EXPECT_TRUE(*id != *id2);
EXPECT_FALSE(*id < *id2);
}
TEST(UserIdTest, duid_type) {
EXPECT_EQ(std::string(UserId::DUID_STR),
UserId::lookupTypeStr(UserId::DUID));
EXPECT_EQ(UserId::DUID,
UserId::lookupType(UserId::DUID_STR));
uint8_t tmp[] = { 0x01, 0xFF, 0x02, 0xAC, 0x03, 0x0B, 0x07, 0x08 };
std::vector<uint8_t> bytes(tmp, tmp + (sizeof(tmp)/sizeof(uint8_t)));
UserIdPtr id;
ASSERT_NO_THROW(id.reset(new UserId(UserId::DUID, bytes)));
EXPECT_EQ(id->getType(), UserId::DUID);
EXPECT_EQ(bytes, id->getId());
// Verify a == b;
UserIdPtr id2;
ASSERT_NO_THROW(id2.reset(new UserId(UserId::DUID, id->toText())));
EXPECT_TRUE(*id == *id2);
EXPECT_FALSE(*id != *id2);
EXPECT_FALSE(*id < *id2);
// Verify a < b;
ASSERT_NO_THROW(id2.reset(new UserId(UserId::DUID, "01FF02AC030B0709")));
EXPECT_FALSE(*id == *id2);
EXPECT_TRUE(*id != *id2);
EXPECT_TRUE(*id < *id2);
// Verify a > b;
ASSERT_NO_THROW(id2.reset(new UserId(UserId::DUID, "01FF02AC030B0707")));
EXPECT_FALSE(*id == *id2);
EXPECT_TRUE(*id != *id2);
EXPECT_FALSE(*id < *id2);
}
TEST(UserIdTest, client_id_type) {
EXPECT_EQ(std::string(UserId::CLIENT_ID_STR),
UserId::lookupTypeStr(UserId::CLIENT_ID));
EXPECT_EQ(UserId::CLIENT_ID,
UserId::lookupType(UserId::CLIENT_ID_STR));
uint8_t tmp[] = { 0x01, 0xFF, 0x02, 0xAC, 0x03, 0x0B, 0x07, 0x08 };
std::vector<uint8_t> bytes(tmp, tmp + (sizeof(tmp)/sizeof(uint8_t)));
UserIdPtr id;
ASSERT_NO_THROW(id.reset(new UserId(UserId::CLIENT_ID, bytes)));
EXPECT_EQ(id->getType(), UserId::CLIENT_ID);
EXPECT_EQ(bytes, id->getId());
// Verify a == b;
UserIdPtr id2;
ASSERT_NO_THROW(id2.reset(new UserId(UserId::CLIENT_ID, id->toText())));
EXPECT_TRUE(*id == *id2);
EXPECT_FALSE(*id != *id2);
EXPECT_FALSE(*id < *id2);
// Verify a < b;
ASSERT_NO_THROW(id2.reset(new UserId(UserId::CLIENT_ID,
"01FF02AC030B0709")));
EXPECT_FALSE(*id == *id2);
EXPECT_TRUE(*id != *id2);
EXPECT_TRUE(*id < *id2);
// Verify a > b;
ASSERT_NO_THROW(id2.reset(new UserId(UserId::CLIENT_ID,
"01FF02AC030B0707")));
EXPECT_FALSE(*id == *id2);
EXPECT_TRUE(*id != *id2);
EXPECT_FALSE(*id < *id2);
}
TEST(UserIdTest, type_compare) {
UserIdPtr hw, duid, client;
ASSERT_NO_THROW(hw.reset(new UserId(UserId::HW_ADDRESS,
"01FF02AC030B0709")));
ASSERT_NO_THROW(duid.reset(new UserId(UserId::DUID,
"01FF02AC030B0709")));
ASSERT_NO_THROW(client.reset(new UserId(UserId::CLIENT_ID,
"01FF02AC030B0709")));
// Verify that UserIdType influences logical comparators.
EXPECT_NE(*hw, *duid);
EXPECT_NE(*hw , *client);
EXPECT_NE(*duid, *client);
}
} // end of anonymous namespace

View File

@ -0,0 +1,226 @@
// Copyright (C) 2013 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.
#include <dhcp/hwaddr.h>
#include <dhcp/duid.h>
#include <exceptions/exceptions.h>
#include <user.h>
#include <iomanip>
#include <sstream>
//********************************* UserId ******************************
const char* UserId::HW_ADDRESS_STR = "HW_ADDR";
const char* UserId::DUID_STR = "DUID";
const char* UserId::CLIENT_ID_STR = "CLIENT_ID";
UserId::UserId(UserIdType id_type, const std::vector<uint8_t>& id)
: id_type_(id_type), id_(id) {
if (id.size() == 0) {
isc_throw(isc::BadValue, "UserId id may not be blank");
}
}
UserId::UserId(UserIdType id_type, const std::string & id_str) :
id_type_(id_type) {
if (id_str.empty()) {
isc_throw(isc::BadValue, "UserId id string may not be blank");
}
// logic to convert id_str etc...
// input str is expected to be 2-digits per bytes, no delims
std::vector<uint8_t> addr_bytes;
decodeHex(id_str, addr_bytes);
// Attempt to instantiate the appropriate id class to leverage validation.
switch (id_type) {
case HW_ADDRESS: {
isc::dhcp::HWAddr hwaddr(addr_bytes, isc::dhcp::HTYPE_ETHER);
break;
}
case CLIENT_ID: {
isc::dhcp::ClientId client_id(addr_bytes);
break;
}
case DUID: {
isc::dhcp::DUID duid(addr_bytes);
break;
}
default:
isc_throw (isc::BadValue, "Invalid id_type: " << id_type);
break;
}
// It's a valid id.
id_ = addr_bytes;
}
UserId::~UserId() {
}
const std::vector<uint8_t>&
UserId::getId() const {
return (id_);
}
UserId::UserIdType
UserId::getType() const {
return (id_type_);
}
std::string
UserId::toText(char delim_char) const {
std::stringstream tmp;
tmp << std::hex;
bool delim = false;
for (std::vector<uint8_t>::const_iterator it = id_.begin();
it != id_.end(); ++it) {
if (delim_char && delim) {
tmp << delim_char;
}
tmp << std::setw(2) << std::setfill('0')
<< static_cast<unsigned int>(*it);
delim = true;
}
return (tmp.str());
}
bool
UserId::operator ==(const UserId & other) const {
return ((this->id_type_ == other.id_type_) && (this->id_ == other.id_));
}
bool
UserId::operator !=(const UserId & other) const {
return (!(*this == other));
}
bool
UserId::operator <(const UserId & other) const {
return ((this->id_type_ == other.id_type_) && (this->id_ < other.id_));
}
void
UserId::decodeHex(const std::string& input, std::vector<uint8_t>& bytes)
const {
int len = input.size();
if ((len % 2) != 0) {
isc_throw (isc::BadValue,
"input string must be event number of digits: "
<< input);
}
for (int i = 0; i < len / 2; i++) {
unsigned int tmp;
if (sscanf (&input[i*2], "%02x", &tmp) != 1) {
isc_throw (isc::BadValue,
"input string contains invalid characters: "
<< input);
}
bytes.push_back(static_cast<uint8_t>(tmp));
}
}
std::string
UserId::lookupTypeStr(UserIdType type) {
const char* tmp = NULL;
switch (type) {
case HW_ADDRESS:
tmp = HW_ADDRESS_STR;
break;
case DUID:
tmp = DUID_STR;
break;
case CLIENT_ID:
tmp = CLIENT_ID_STR;
break;
default:
isc_throw(isc::BadValue, "Invalid UserIdType:" << type);
break;
}
return (std::string(tmp));
}
UserId::UserIdType
UserId::lookupType(const std::string& type_str) {
if (type_str == HW_ADDRESS_STR) {
return (HW_ADDRESS);
} else if (type_str == DUID_STR) {
return (DUID);
} else if (type_str == CLIENT_ID_STR) {
return (CLIENT_ID);
}
isc_throw(isc::BadValue, "Invalid UserIdType string:" << type_str);
}
std::ostream&
operator<<(std::ostream& os, const UserId& user_id) {
std::string tmp = UserId::lookupTypeStr(user_id.getType());
os << tmp << "=" << user_id.toText();
return (os);
}
//********************************* User ******************************
User::User(const UserId& user_id) : user_id_(user_id) {
}
User::User(UserId::UserIdType id_type, const std::vector<uint8_t>& id)
: user_id_(id_type, id) {
}
User::User(UserId::UserIdType id_type, const std::string& id_str)
: user_id_(id_type, id_str) {
}
User::~User() {
}
void User::setProperty(const std::string& name, const std::string& value) {
if (name.empty()) {
isc_throw (isc::BadValue, "User property name cannot be blank");
}
properties_[name]=value;
}
std::string
User::getProperty(const std::string& name) const {
PropertyMap::const_iterator it = properties_.find(name);
if (it != properties_.end()) {
return ((*it).second);
}
return ("");
}
void
User::delProperty(const std::string & name) {
PropertyMap::iterator it = properties_.find(name);
if (it != properties_.end()) {
properties_.erase(it);
}
}
const UserId&
User::getUserId() const {
return (user_id_);
}

View File

@ -0,0 +1,109 @@
// Copyright (C) 2013 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.
#ifndef _USER_H
#define _USER_H
#include <boost/shared_ptr.hpp>
#include <vector>
#include <map>
class UserId {
public:
enum UserIdType {
HW_ADDRESS,
DUID,
CLIENT_ID
};
static const char* HW_ADDRESS_STR;
static const char* DUID_STR;
static const char* CLIENT_ID_STR;
UserId(UserIdType id_type, const std::vector<uint8_t>& id);
UserId(UserIdType id_type, const std::string& id_str);
~UserId();
/// @brief Returns a const reference to the actual id value
const std::vector<uint8_t>& getId() const;
/// @brief Returns the UserIdType
UserIdType getType() const;
/// @brief Returns textual representation of a id (e.g. 00:01:02:03:ff)
std::string toText(char delim_char=0x0) const;
/// @brief Compares two UserIds for equality
bool operator ==(const UserId & other) const;
/// @brief Compares two UserIds for inequality
bool operator !=(const UserId & other) const;
/// @brief Performs less than comparision of two UserIds
bool operator <(const UserId & other) const;
static std::string lookupTypeStr(UserIdType type);
static UserIdType lookupType(const std::string& type_str);
private:
void decodeHex(const std::string& input, std::vector<uint8_t>& bytes) const;
/// @brief The type of id value
UserIdType id_type_;
/// @brief The id value
std::vector<uint8_t> id_;
};
std::ostream&
operator<<(std::ostream& os, const UserId& user_id);
typedef boost::shared_ptr<UserId> UserIdPtr;
typedef std::map<std::string, std::string> PropertyMap;
class User {
public:
User(const UserId & user_id);
User(UserId::UserIdType id_type, const std::vector<uint8_t>& id);
User(UserId::UserIdType id_type, const std::string& id_str);
~User();
void setProperty(const std::string& name, const std::string& value);
std::string getProperty(const std::string& name) const;
void delProperty(const std::string& name);
const UserId& getUserId() const;
private:
UserId user_id_;
PropertyMap properties_;
};
typedef boost::shared_ptr<User> UserPtr;
#endif

View File

@ -0,0 +1,49 @@
// Copyright (C) 2013 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.
#include <user_data_source.h>
UserDataSource::UserDataSource() {
}
UserDataSource::~UserDataSource() {
if (open_flag_) {
close();
}
}
void
UserDataSource::open() {
open_flag_ = false;
}
UserPtr
UserDataSource::readNextUser() {
return (UserPtr());
}
void
UserDataSource::close() {
open_flag_ = false;
}
bool
UserDataSource::isOpen() const {
return open_flag_;
}
void
UserDataSource::setOpenFlag(bool value) {
open_flag_ = value;
}

View File

@ -0,0 +1,42 @@
// Copyright (C) 2013 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.
#ifndef _USER_DATA_SOURCE_H
#define _USER_DATA_SOURCE_H
#include <user.h>
class UserDataSource {
public:
UserDataSource();
~UserDataSource();
void open();
UserPtr readNextUser();
void close();
bool isOpen() const;
void setOpenFlag(bool value);
private:
bool open_flag_;
};
typedef boost::shared_ptr<UserDataSource> UserDataSourcePtr;
#endif

View File

@ -0,0 +1,89 @@
// Copyright (C) 2013 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.
#include <user_registry.h>
#include <user.h>
UserRegistry::UserRegistry() {
}
UserRegistry::~UserRegistry(){
}
void
UserRegistry::addUser(UserPtr& user) {
if (!user) {
isc_throw (isc::BadValue, "UserRegistry cannot add blank user");
}
if (findUser(user->getUserId())) {
isc_throw (isc::BadValue, "Duplicate User!");
}
users_[user->getUserId()] = user;
}
const UserPtr&
UserRegistry::findUser(const UserId& id) const {
static UserPtr empty;
UserMap::const_iterator it = users_.find(id);
if (it != users_.end()) {
return ((*it).second);
}
return empty;
}
void
UserRegistry::removeUser(const UserId& id) {
static UserPtr empty;
UserMap::iterator it = users_.find(id);
if (it != users_.end()) {
users_.erase(it);
}
}
const UserPtr&
UserRegistry::findUser(const isc::dhcp::HWAddr& hwaddr) const {
UserId id(UserId::HW_ADDRESS, hwaddr.hwaddr_);
return (findUser(id));
}
const UserPtr&
UserRegistry::findUser(const isc::dhcp::ClientId& client_id) const {
UserId id(UserId::CLIENT_ID, client_id.getClientId());
return (findUser(id));
}
const UserPtr&
UserRegistry::findUser(const isc::dhcp::DUID& duid) const {
UserId id(UserId::DUID, duid.getDuid());
return (findUser(id));
}
void UserRegistry::refresh() {
}
void UserRegistry::clearall() {
users_.clear();
}
void UserRegistry::setSource(UserDataSourcePtr& source) {
source_ = source;
}
const UserDataSourcePtr& UserRegistry::getSource() {
return (source_);
}

View File

@ -0,0 +1,62 @@
// Copyright (C) 2013 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.
#ifndef _USER_REGISTRY_H
#define _USER_REGISTRY_H
#include <dhcp/hwaddr.h>
#include <dhcp/duid.h>
#include <user.h>
#include <user_data_source.h>
#include <string>
using namespace std;
typedef std::map<UserId,UserPtr> UserMap;
class UserRegistry {
public:
UserRegistry();
~UserRegistry();
void addUser(UserPtr& user);
const UserPtr& findUser(const UserId& id) const;
void removeUser(const UserId& id);
const UserPtr& findUser(const isc::dhcp::HWAddr& hwaddr) const;
const UserPtr& findUser(const isc::dhcp::ClientId& client_id) const;
const UserPtr& findUser(const isc::dhcp::DUID& duid) const;
void refresh();
void clearall();
const UserDataSourcePtr& getSource();
void setSource(UserDataSourcePtr& source);
private:
UserMap users_;
UserDataSourcePtr source_;
};
typedef boost::shared_ptr<UserRegistry> UserRegistryPtr;
#endif

View File

@ -0,0 +1,24 @@
// Copyright (C) 2013 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.
// version.cc
#include <hooks/hooks.h>
extern "C" {
int version() {
return (BIND10_HOOKS_VERSION);
}
}