// Fetch the TLS context.
auto tls_context = config_->getThisServerConfig()->getTlsContext();
- // Instantiate the listener.
- listener_.reset(new CmdHttpListener(server_address, my_url.getPort(),
- listener_threads, tls_context));
+ // Set the HTTP basic authentication.
+ HttpAuthConfigPtr auth_config;
+ // Wrong type: BasicHttpAuthPtr vs BasicHttpAuthConfigPtr
+ // auth_config = config_->getThisServerConfig()->getBasicAuth();
+
// Set the command filter when enabled.
+ std::unordered_set<std::string> command_accept_list;
if (config_->getRestrictCommands()) {
if (server_type == HAServerType::DHCPv4) {
- CmdResponseCreator::command_accept_list_ =
- CommandCreator::ha_commands4_;
+ command_accept_list = CommandCreator::ha_commands4_;
} else {
- CmdResponseCreator::command_accept_list_ =
- CommandCreator::ha_commands6_;
+ command_accept_list = CommandCreator::ha_commands6_;
}
}
+
+ // Instantiate the listener.
+ listener_.reset(new CmdHttpListener(server_address,
+ my_url.getPort(),
+ listener_threads,
+ tls_context,
+ auth_config,
+ command_accept_list));
}
}
HAMtServiceTest()
: HATest() {
MultiThreadingMgr::instance().setMode(true);
- CmdResponseCreator::command_accept_list_.clear();
}
/// @brief Destructor.
~HAMtServiceTest() {
io_service_->stopAndPoll();
MultiThreadingMgr::instance().setMode(false);
- CmdResponseCreator::command_accept_list_.clear();
}
/// @brief Callback function invoke upon test timeout.
// Multi-threading should be enabled.
ASSERT_TRUE(ha_config->get()->getEnableMultiThreading());
+ // Authentication is disabled.
+ ASSERT_TRUE(service->listener_);
+ EXPECT_FALSE(service->listener_->getAuthConfig());
+
// Command filtering is enabled.
- EXPECT_FALSE(CmdResponseCreator::command_accept_list_.empty());
+ EXPECT_FALSE(service->listener_->getCommandAcceptList().empty());
// Now we'll start, pause, resume and stop a few times.
for (int i = 0; i < 3; ++i) {
using namespace isc::data;
using namespace isc::http;
using namespace isc::util;
+using namespace std;
namespace isc {
namespace config {
CmdHttpListener::CmdHttpListener(const IOAddress& address, const uint16_t port,
const uint16_t thread_pool_size /* = 1 */,
- TlsContextPtr context /* = () */)
+ TlsContextPtr context /* = () */,
+ HttpAuthConfigPtr http_auth_config /* = () */,
+ unordered_set<string> command_accept_list /* = {} */)
: address_(address), port_(port), thread_io_service_(), http_listener_(),
thread_pool_size_(thread_pool_size), thread_pool_(),
- tls_context_(context) {
+ tls_context_(context), http_auth_config_(http_auth_config),
+ command_accept_list_(command_accept_list) {
}
CmdHttpListener::~CmdHttpListener() {
// Create the response creator factory first. It will be used to
// generate response creators. Each response creator will be
// used to generate the answer to specific request.
- HttpResponseCreatorFactoryPtr rcf(new CmdResponseCreatorFactory());
+ HttpResponseCreatorFactoryPtr
+ rcf(new CmdResponseCreatorFactory(http_auth_config_,
+ command_accept_list_));
// Create the HTTP listener. It will open up a TCP socket and be
// prepared to accept incoming connections.
#include <asiolink/io_address.h>
#include <asiolink/io_service.h>
#include <asiolink/io_service_thread_pool.h>
+#include <http/auth_config.h>
#include <http/listener.h>
#include <thread>
#include <vector>
/// @brief Constructor
CmdHttpListener(const asiolink::IOAddress& address, const uint16_t port,
const uint16_t thread_pool_size = 1,
- asiolink::TlsContextPtr context = asiolink::TlsContextPtr());
+ asiolink::TlsContextPtr context = asiolink::TlsContextPtr(),
+ http::HttpAuthConfigPtr http_auth_config = http::HttpAuthConfigPtr(),
+ std::unordered_set<std::string> command_accept_list = {});
/// @brief Destructor
virtual ~CmdHttpListener();
return (thread_io_service_);
}
+ /// @brief Fetches the authentication configuration.
+ ///
+ /// @return the authentication configuration.
+ http::HttpAuthConfigPtr getAuthConfig() const {
+ return (http_auth_config_);
+ }
+
+ /// @brief Fetches the command accept list.
+ ///
+ /// @return the command accept list.
+ std::unordered_set<std::string> getCommandAcceptList() const {
+ return (command_accept_list_);
+ }
+
private:
/// @brief IP address on which to listen.
isc::asiolink::IOAddress address_;
/// @brief The TLS context.
asiolink::TlsContextPtr tls_context_;
+
+ /// @brief The server current authentication configuration.
+ http::HttpAuthConfigPtr http_auth_config_;
+
+ /// @brief The server command accept list.
+ std::unordered_set<std::string> command_accept_list_;
};
/// @brief Defines a shared pointer to CmdHttpListener.
namespace isc {
namespace config {
-HttpAuthConfigPtr CmdResponseCreator::http_auth_config_;
-
-unordered_set<string> CmdResponseCreator::command_accept_list_;
-
bool CmdResponseCreator::EMULATE_AGENT_RESPONSE = true;
HttpRequestPtr
class CmdResponseCreator : public http::HttpResponseCreator {
public:
+ /// @brief Constructor.
+ ///
+ /// @param http_auth_config Authentication configuration.
+ /// @param command_accept_list Command accept list.
+ CmdResponseCreator(http::HttpAuthConfigPtr http_auth_config,
+ std::unordered_set<std::string> command_accept_list) :
+ http::HttpResponseCreator(), http_auth_config_(http_auth_config),
+ command_accept_list_(command_accept_list) {
+ }
+
+ /// @brief virtual destructor.
+ virtual ~CmdResponseCreator() = default;
+
/// @brief Create a new request.
///
/// This method creates a bare instance of the @ref
const data::ConstElementPtr& body,
const std::unordered_set<std::string>& accept);
- /// @brief The server current authentication configuration.
- ///
- /// Default to the empty HttpAuthConfigPtr.
- ///
- /// @note: This is currently not used, except in unit-tests. For the time being,
- /// we postponed writing the corresponding code in the HA, so http_auth_config_
- /// is left to its empty default value.
- static http::HttpAuthConfigPtr http_auth_config_;
+ /// @brief The emulate agent response flag.
+ static bool EMULATE_AGENT_RESPONSE;
- /// @brief The server command accept list.
+ /// @brief Fetches the authentication configuration.
///
- /// Default to the empty list which means to accept everything.
- static std::unordered_set<std::string> command_accept_list_;
+ /// @return the authentication configuration.
+ http::HttpAuthConfigPtr getAuthConfig() const {
+ return (http_auth_config_);
+ }
- /// @brief The emulate agent response flag.
- static bool EMULATE_AGENT_RESPONSE;
+ /// @brief Fetches the command accept list.
+ ///
+ /// @return the command accept list.
+ std::unordered_set<std::string> getCommandAcceptList() const {
+ return (command_accept_list_);
+ }
private:
/// @return Pointer to an object representing HTTP response.
virtual http::HttpResponsePtr
createDynamicHttpResponse(http::HttpRequestPtr request);
+
+ /// @brief The server current authentication configuration.
+ http::HttpAuthConfigPtr http_auth_config_;
+
+ /// @brief The server command accept list.
+ std::unordered_set<std::string> command_accept_list_;
};
/// @brief Pointer to the @ref CmdResponseCreator.
///
/// Creates sole instance of the @ref CmdResponseCreator object
/// returned by the @ref CmdResponseCreatorFactory::create.
- CmdResponseCreatorFactory() : sole_creator_(new CmdResponseCreator) {
+ ///
+ /// @param http_auth_config Authentication configuration.
+ /// @param command_accept_list Command accept list.
+ CmdResponseCreatorFactory(http::HttpAuthConfigPtr http_auth_config,
+ std::unordered_set<std::string> command_accept_list)
+ : sole_creator_(new CmdResponseCreator(http_auth_config,
+ command_accept_list)) {
}
/// @brief Returns an instance of the @ref CmdResponseCreator which
#include <gtest/gtest.h>
using namespace isc::config;
+using namespace isc::http;
+using namespace std;
namespace {
// the create() method.
TEST(CmdResponseCreatorFactory, createDefault) {
// Create the factory.
- CmdResponseCreatorFactory factory;
+ HttpAuthConfigPtr http_auth_config;
+ unordered_set<string> command_accept_list;
+ CmdResponseCreatorFactory factory(http_auth_config, command_accept_list);
// Create a response creator.
CmdResponseCreatorPtr response1;
EXPECT_TRUE(CmdResponseCreator::EMULATE_AGENT_RESPONSE);
// Authorization configuration should be an empty pointer.
- EXPECT_FALSE(CmdResponseCreator::http_auth_config_);
+ EXPECT_FALSE(response1->getAuthConfig());
// By default all commands are accepted.
- EXPECT_TRUE(CmdResponseCreator::command_accept_list_.empty());
+ EXPECT_TRUE(response1->getCommandAcceptList().empty());
// Invoke create() again.
CmdResponseCreatorPtr response2;
// be turned off.
TEST(CmdResponseCreatorFactory, createAgentEmulationDisabled) {
// Instantiate the factory.
- CmdResponseCreatorFactory factory;
+ HttpAuthConfigPtr http_auth_config;
+ unordered_set<string> command_accept_list;
+ CmdResponseCreatorFactory factory(http_auth_config, command_accept_list);
// Disable agent emulation.
CmdResponseCreator::EMULATE_AGENT_RESPONSE = false;
EXPECT_FALSE(CmdResponseCreator::EMULATE_AGENT_RESPONSE);
// Authorization configuration should be an empty pointer.
- EXPECT_FALSE(CmdResponseCreator::http_auth_config_);
+ EXPECT_FALSE(response->getAuthConfig());
// By default all commands are accepted.
- EXPECT_TRUE(CmdResponseCreator::command_accept_list_.empty());
+ EXPECT_TRUE(response->getCommandAcceptList().empty());
}
} // end of anonymous namespace
config::CommandMgr::instance().
registerCommand("foo", std::bind(&CmdResponseCreatorTest::fooCommandHandler,
this, ph::_1, ph::_2));
- // Clear class variables.
- CmdResponseCreator::http_auth_config_.reset();
- CmdResponseCreator::command_accept_list_.clear();
}
/// @brief Destructor.
/// Removes registered commands from the command manager.
virtual ~CmdResponseCreatorTest() {
config::CommandMgr::instance().deregisterAll();
- CmdResponseCreator::http_auth_config_.reset();
- CmdResponseCreator::command_accept_list_.clear();
}
/// @brief SetUp function that wraps call to initCreator.
/// @brief Creates a new CmdResponseCreator and new HttpRequest.
///
/// @param emulate_agent_flag enables/disables agent response emulation
+ /// @param http_auth_config authentication configuration.
+ /// @param command_accept_list command accept list.
/// in the CmdResponsCreator.
- void initCreator(bool emulate_agent_flag = true) {
- response_creator_.reset(new CmdResponseCreator);
+ void initCreator(bool emulate_agent_flag = true,
+ HttpAuthConfigPtr http_auth_config = HttpAuthConfigPtr(),
+ unordered_set<string> command_accept_list = {}) {
CmdResponseCreator::EMULATE_AGENT_RESPONSE = emulate_agent_flag;
+ response_creator_.reset(new CmdResponseCreator(http_auth_config,
+ command_accept_list));
request_ = response_creator_->createNewHttpRequest();
ASSERT_TRUE(request_) << "initCreator failed to create request";
}
// This test verifies basic HTTP authentication - reject case.
// Empty case was handled in createDynamicHttpResponseNoEmulation.
TEST_F(CmdResponseCreatorTest, basicAuthReject) {
- initCreator(false);
+ // Create basic HTTP authentication configuration.
+ BasicHttpAuthConfigPtr basic(new BasicHttpAuthConfig);
+ ASSERT_TRUE(basic);
+ EXPECT_NO_THROW(basic->add("test", "", "123\xa3", ""));
+
+ initCreator(false, basic);
setBasicContext(request_);
// Body: "foo" command has been registered in the test fixture constructor.
// All requests must be finalized before they can be processed.
ASSERT_NO_THROW(request_->finalize());
- // Create basic HTTP authentication configuration.
- CmdResponseCreator::http_auth_config_.reset(new BasicHttpAuthConfig());
- BasicHttpAuthConfigPtr basic =
- boost::dynamic_pointer_cast<BasicHttpAuthConfig>(
- CmdResponseCreator::http_auth_config_);
- ASSERT_TRUE(basic);
- EXPECT_NO_THROW(basic->add("test", "", "123\xa3", ""));
-
// Create response from the request.
HttpResponsePtr response;
ASSERT_NO_THROW(response = response_creator_->createHttpResponse(request_));
// This test verifies basic HTTP authentication - accept case.
// Empty case was handled in createDynamicHttpResponseNoEmulation.
TEST_F(CmdResponseCreatorTest, basicAuthAccept) {
- initCreator(false);
+ // Create basic HTTP authentication configuration.
+ BasicHttpAuthConfigPtr basic(new BasicHttpAuthConfig);
+ ASSERT_TRUE(basic);
+ EXPECT_NO_THROW(basic->add("test", "", "123\xa3", ""));
+
+ initCreator(false, basic);
setBasicContext(request_);
// Body: "foo" command has been registered in the test fixture constructor.
// All requests must be finalized before they can be processed.
ASSERT_NO_THROW(request_->finalize());
- // Create basic HTTP authentication configuration.
- CmdResponseCreator::http_auth_config_.reset(new BasicHttpAuthConfig());
- BasicHttpAuthConfigPtr basic =
- boost::dynamic_pointer_cast<BasicHttpAuthConfig>(
- CmdResponseCreator::http_auth_config_);
- ASSERT_TRUE(basic);
- EXPECT_NO_THROW(basic->add("test", "", "123\xa3", ""));
-
// Create response from the request.
HttpResponsePtr response;
ASSERT_NO_THROW(response = response_creator_->createHttpResponse(request_));
// This test verifies command filtering at the HTTP level - reject case.
TEST_F(CmdResponseCreatorTest, filterCommandReject) {
- initCreator(false);
+ // Add foo in the access list.
+ unordered_set<string> accept;
+ accept.insert("foo");
+ initCreator(false, 0, accept);
setBasicContext(request_);
// For the log message...
request_->setRemote("127.0.0.1");
// All requests must be finalized before they can be processed.
ASSERT_NO_THROW(request_->finalize());
- // Add foo in the access list.
- CmdResponseCreator::command_accept_list_.insert("foo");
-
// Create response from the request.
HttpResponsePtr response;
ASSERT_NO_THROW(response = response_creator_->createHttpResponse(request_));
// This test verifies command filtering at the HTTP level - accept case.
TEST_F(CmdResponseCreatorTest, filterCommandAccept) {
- initCreator(false);
+ // Add foo in the access list.
+ unordered_set<string> accept;
+ accept.insert("foo");
+ initCreator(false, 0, accept);
setBasicContext(request_);
// Body: "foo" command has been registered in the test fixture constructor.
// All requests must be finalized before they can be processed.
ASSERT_NO_THROW(request_->finalize());
- // Add foo in the access list.
- CmdResponseCreator::command_accept_list_.insert("foo");
-
// Create response from the request.
HttpResponsePtr response;
ASSERT_NO_THROW(response = response_creator_->createHttpResponse(request_));
/// @brief Test timeout (ms).
const long TEST_TIMEOUT = 10000;
-/// @brief Test fixture class for @ref CmdHttpListener.
+/// @brief Test fixture class for @ref HttpCommandMgr.
class HttpCommandMgrTest : public ::testing::Test {
public: