diff options
Diffstat (limited to 'src/lib/process')
-rw-r--r-- | src/lib/process/d_controller.cc | 119 | ||||
-rw-r--r-- | src/lib/process/d_controller.h | 41 | ||||
-rw-r--r-- | src/lib/process/d_process.h | 9 | ||||
-rw-r--r-- | src/lib/process/testutils/d_test_stubs.cc | 42 | ||||
-rw-r--r-- | src/lib/process/testutils/d_test_stubs.h | 44 |
5 files changed, 169 insertions, 86 deletions
diff --git a/src/lib/process/d_controller.cc b/src/lib/process/d_controller.cc index 974e178392..5b112d4331 100644 --- a/src/lib/process/d_controller.cc +++ b/src/lib/process/d_controller.cc @@ -406,6 +406,125 @@ DControllerBase::checkConfig(ConstElementPtr new_config) { } ConstElementPtr +DControllerBase::configGetHandler(const std::string&, + ConstElementPtr /*args*/) { + ConstElementPtr config = process_->getCfgMgr()->getContext()->toElement(); + + return (createAnswer(COMMAND_SUCCESS, config)); +} + +ConstElementPtr +DControllerBase::configWriteHandler(const std::string&, + ConstElementPtr args) { + std::string filename; + + if (args) { + if (args->getType() != Element::map) { + return (createAnswer(COMMAND_ERROR, "Argument must be a map")); + } + ConstElementPtr filename_param = args->get("filename"); + if (filename_param) { + if (filename_param->getType() != Element::string) { + return (createAnswer(COMMAND_ERROR, + "passed parameter 'filename' " + "is not a string")); + } + filename = filename_param->stringValue(); + } + } + + if (filename.empty()) { + // filename parameter was not specified, so let's use + // whatever we remember + filename = getConfigFile(); + if (filename.empty()) { + return (createAnswer(COMMAND_ERROR, + "Unable to determine filename." + "Please specify filename explicitly.")); + } + } + + // Now do the sanity checks on the filename + if (filename.find("..") != std::string::npos) { + // Trying to escape the directory.. nope. + return (createAnswer(COMMAND_ERROR, + "Using '..' in filename is not allowed.")); + } + + if (filename.find("\\") != std::string::npos) { + // Trying to inject escapes (possibly to inject quotes and something + // nasty afterward) + return (createAnswer(COMMAND_ERROR, + "Using \\ in filename is not allowed.")); + } + + if (filename[0] == '/') { + // Absolute paths are not allowed. + return (createAnswer(COMMAND_ERROR, + "Absolute path in filename is not allowed.")); + } + + // Ok, it's time to write the file. + size_t size = 0; + try { + size = writeConfigFile(filename); + } catch (const isc::Exception& ex) { + return (createAnswer(COMMAND_ERROR, + std::string("Error during write-config:") + + ex.what())); + } + if (size == 0) { + return (createAnswer(COMMAND_ERROR, + "Error writing configuration to " + filename)); + } + + // Ok, it's time to return the successful response. + ElementPtr params = Element::createMap(); + params->set("size", Element::create(static_cast<long long>(size))); + params->set("filename", Element::create(filename)); + + return (createAnswer(CONTROL_RESULT_SUCCESS, "Configuration written to " + + filename + " successful", params)); +} + +ConstElementPtr +DControllerBase::configTestHandler(const std::string&, ConstElementPtr args) { + const int status_code = CONTROL_RESULT_SUCCESS; // 1 indicates an error + ConstElementPtr dhcp4; + std::string message; + + // Command arguments are expected to be: + // { "Dhcp4": { ... }, "Logging": { ... } } + // The Lnogging component is technically optional. If it's not supplied + // logging will revert to default logging. + if (!args) { + message = "Missing mandatory 'arguments' parameter."; + } else { + dhcp4 = args->get("Dhcp4"); + if (!dhcp4) { + message = "Missing mandatory 'Dhcp4' parameter."; + } else if (dhcp4->getType() != Element::map) { + message = "'Dhcp4' parameter expected to be a map."; + } + } + + if (!message.empty()) { + // Something is amiss with arguments, return a failure response. + ConstElementPtr result = isc::config::createAnswer(status_code, + message); + return (result); + } + + // We are starting the configuration process so we should remove any + // staging configuration that has been created during previous + // configuration attempts. + isc::dhcp::CfgMgr::instance().rollback(); + + // Now we check the server proper. + return (checkConfig(dhcp4)); +} + +ConstElementPtr DControllerBase::versionGetHandler(const std::string&, ConstElementPtr args) { ConstElementPtr answer; diff --git a/src/lib/process/d_controller.h b/src/lib/process/d_controller.h index f4b536202b..c7c3aa11fe 100644 --- a/src/lib/process/d_controller.h +++ b/src/lib/process/d_controller.h @@ -256,6 +256,47 @@ public: buildReportHandler(const std::string& command, isc::data::ConstElementPtr args); + /// @brief handler for config-get command + /// + /// This method handles the config-get command, which retrieves + /// the current configuration and returns it in response. + /// + /// @param command (ignored) + /// @param args (ignored) + /// @return current configuration wrapped in a response + isc::data::ConstElementPtr + configGetHandler(const std::string& command, + isc::data::ConstElementPtr args); + + /// @brief handler for config-write command + /// + /// This handle processes write-config comamnd, which writes the + /// current configuration to disk. This command takes one optional + /// parameter called filename. If specified, the current configuration + /// will be written to that file. If not specified, the file used during + /// Kea start-up will be used. To avoid any exploits, the path is + /// always relative and .. is not allowed in the filename. This is + /// a security measure against exploiting file writes remotely. + /// + /// @param command (ignored) + /// @param args may contain optional string argument filename + /// @return status of the configuration file write + isc::data::ConstElementPtr + configWriteHandler(const std::string& command, + isc::data::ConstElementPtr args); + + /// @brief handler for config-test command + /// + /// This method handles the config-test command, which checks + /// configuration specified in args parameter. + /// + /// @param command (ignored) + /// @param args configuration to be checked. + /// @return status of the command + isc::data::ConstElementPtr + configTestHandler(const std::string& command, + isc::data::ConstElementPtr args); + /// @brief handler for 'shutdown' command /// /// This method handles shutdown command. It initiates the shutdown procedure diff --git a/src/lib/process/d_process.h b/src/lib/process/d_process.h index 0ab13133d5..d7c58d9f02 100644 --- a/src/lib/process/d_process.h +++ b/src/lib/process/d_process.h @@ -31,6 +31,15 @@ static const std::string VERSION_GET_COMMAND("version-get"); /// @brief String value for the build-report command. static const std::string BUILD_REPORT_COMMAND("build-report"); +/// @brief String value for the config-get command. +static const std::string CONFIG_GET_COMMAND("config-get"); + +/// @brief String value for the config-write command. +static const std::string CONFIG_WRITE_COMMAND("config-write"); + +/// @brief String value for the config-test command. +static const std::string CONFIG_TEST_COMMAND("config-test"); + /// @brief String value for the shutdown command. static const std::string SHUT_DOWN_COMMAND("shutdown"); diff --git a/src/lib/process/testutils/d_test_stubs.cc b/src/lib/process/testutils/d_test_stubs.cc index 8bff0f2acc..d265232161 100644 --- a/src/lib/process/testutils/d_test_stubs.cc +++ b/src/lib/process/testutils/d_test_stubs.cc @@ -19,9 +19,6 @@ namespace process { // Initialize the static failure flag. SimFailure::FailureType SimFailure::failure_type_ = SimFailure::ftNoFailure; -// Define custom process command supported by DStubProcess. -const char* DStubProcess::stub_proc_command_("cool_proc_cmd"); - DStubProcess::DStubProcess(const char* name, asiolink::IOServicePtr io_service) : DProcessBase(name, io_service, DCfgMgrBasePtr(new DStubCfgMgr())) { }; @@ -77,32 +74,11 @@ DStubProcess::configure(isc::data::ConstElementPtr config_set, bool check_only) return (getCfgMgr()->parseConfig(config_set, check_only)); } -isc::data::ConstElementPtr -DStubProcess::command(const std::string& command, - isc::data::ConstElementPtr /* args */) { - isc::data::ConstElementPtr answer; - if (SimFailure::shouldFailOn(SimFailure::ftProcessCommand)) { - // Simulates a process command execution failure. - answer = isc::config::createAnswer(COMMAND_ERROR, - "SimFailure::ftProcessCommand"); - } else if (command.compare(stub_proc_command_) == 0) { - answer = isc::config::createAnswer(COMMAND_SUCCESS, "Command accepted"); - } else { - answer = isc::config::createAnswer(COMMAND_INVALID, - "Unrecognized command:" + command); - } - - return (answer); -} - DStubProcess::~DStubProcess() { }; //************************** DStubController ************************* -// Define custom controller command supported by DStubController. -const char* DStubController::stub_ctl_command_("spiffy"); - // Define custom command line option command supported by DStubController. const char* DStubController::stub_option_x_ = "x"; @@ -162,24 +138,6 @@ DProcessBase* DStubController::createProcess() { return (new DStubProcess(getAppName().c_str(), getIOService())); } -isc::data::ConstElementPtr -DStubController::customControllerCommand(const std::string& command, - isc::data::ConstElementPtr /* args */) { - isc::data::ConstElementPtr answer; - if (SimFailure::shouldFailOn(SimFailure::ftControllerCommand)) { - // Simulates command failing to execute. - answer = isc::config::createAnswer(COMMAND_ERROR, - "SimFailure::ftControllerCommand"); - } else if (command.compare(stub_ctl_command_) == 0) { - answer = isc::config::createAnswer(COMMAND_SUCCESS, "Command accepted"); - } else { - answer = isc::config::createAnswer(COMMAND_INVALID, - "Unrecognized command:" + command); - } - - return (answer); -} - const std::string DStubController::getCustomOpts() const { // Return the "list" of custom options supported by DStubController. return (std::string(stub_option_x_)); diff --git a/src/lib/process/testutils/d_test_stubs.h b/src/lib/process/testutils/d_test_stubs.h index 09c2298787..334adac7bf 100644 --- a/src/lib/process/testutils/d_test_stubs.h +++ b/src/lib/process/testutils/d_test_stubs.h @@ -45,8 +45,6 @@ public: ftCreateProcessNull, ftProcessInit, ftProcessConfigure, - ftControllerCommand, - ftProcessCommand, ftProcessShutdown, ftElementBuild, ftElementCommit, @@ -104,9 +102,6 @@ public: class DStubProcess : public DProcessBase { public: - /// @brief Static constant that defines a custom process command string. - static const char* stub_proc_command_; - /// @brief Constructor /// /// @param name name is a text label for the process. Generally used @@ -152,24 +147,6 @@ public: virtual isc::data::ConstElementPtr configure(isc::data::ConstElementPtr config_set, bool check_only); - /// @brief Executes the given command. - /// - /// This implementation will recognizes one "custom" process command, - /// stub_proc_command_. It will fail if SimFailure is set to - /// ftProcessCommand. - /// - /// @param command is a string label representing the command to execute. - /// @param args is a set of arguments (if any) required for the given - /// command. - /// @return an Element that contains the results of command composed - /// of an integer status value and a string explanation of the outcome. - /// The status value is: - /// COMMAND_SUCCESS if the command is recognized and executes successfully. - /// COMMAND_ERROR if the command is recognized but fails to execute. - /// COMMAND_INVALID if the command is not recognized. - virtual isc::data::ConstElementPtr command(const std::string& command, - isc::data::ConstElementPtr args); - /// @brief Returns configuration summary in the textual format. /// /// @return Always an empty string. @@ -198,10 +175,6 @@ public: /// @return returns a pointer reference to the singleton instance. static DControllerBasePtr& instance(); - /// @brief Defines a custom controller command string. This is a - /// custom command supported by DStubController. - static const char* stub_ctl_command_; - /// @brief Defines a custom command line option supported by /// DStubController. static const char* stub_option_x_; @@ -266,23 +239,6 @@ protected: /// ftCreateProcessException. virtual DProcessBase* createProcess(); - /// @brief Executes custom controller commands are supported by - /// DStubController. This implementation supports one custom controller - /// command, stub_ctl_command_. It will fail if SimFailure is set - /// to ftControllerCommand. - /// - /// @param command is a string label representing the command to execute. - /// @param args is a set of arguments (if any) required for the given - /// command. - /// @return an Element that contains the results of command composed - /// of an integer status value and a string explanation of the outcome. - /// The status value is: - /// COMMAND_SUCCESS if the command is recognized and executes successfully. - /// COMMAND_ERROR if the command is recognized but fails to execute. - /// COMMAND_INVALID if the command is not recognized. - virtual isc::data::ConstElementPtr customControllerCommand( - const std::string& command, isc::data::ConstElementPtr args); - /// @brief Provides a string of the additional command line options /// supported by DStubController. DStubController supports one /// addition option, stub_option_x_. |