2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 22:15:23 +00:00

[#3831] Checkpoint: code done, UTs to be updated

This commit is contained in:
Francis Dupont
2025-05-15 20:25:24 +02:00
parent 0e25831cf8
commit 01dc6e538c
9 changed files with 79 additions and 20 deletions

View File

@@ -532,6 +532,12 @@ An example command invocation looks like this:
} }
} }
.. note::
As of Kea 2.7.9, the config file file may only be written to the same
directory as the config file used when starting Kea (passed as a ``-c``
argument).
.. isccmd:: leases-reclaim .. isccmd:: leases-reclaim
.. _command-leases-reclaim: .. _command-leases-reclaim:

View File

@@ -290,11 +290,18 @@ ControlledDhcpv4Srv::commandConfigWriteHandler(const string&,
// filename parameter was not specified, so let's use whatever we remember // filename parameter was not specified, so let's use whatever we remember
// from the command-line // from the command-line
filename = getConfigFile(); filename = getConfigFile();
} if (filename.empty()) {
return (createAnswer(CONTROL_RESULT_ERROR, "Unable to determine filename."
if (filename.empty()) { "Please specify filename explicitly."));
return (createAnswer(CONTROL_RESULT_ERROR, "Unable to determine filename." }
"Please specify filename explicitly.")); } else {
try {
checkWriteConfigFile(filename);
} catch (const isc::Exception& ex) {
return (createAnswer(CONTROL_RESULT_ERROR,
string("not allowed to write config into ") +
filename));
}
} }
// Ok, it's time to write the file. // Ok, it's time to write the file.

View File

@@ -179,9 +179,9 @@ private:
/// current configuration to disk. This command takes one optional /// current configuration to disk. This command takes one optional
/// parameter called filename. If specified, the current configuration /// parameter called filename. If specified, the current configuration
/// will be written to that file. If not specified, the file used during /// 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 /// Kea start-up will be used. To avoid any exploits, the target
/// always relative and .. is not allowed in the filename. This is /// directory must be the same as a security measure against
/// a security measure against exploiting file writes remotely. /// exploiting file writes remotely.
/// ///
/// @param command (ignored) /// @param command (ignored)
/// @param args may contain optional string argument filename /// @param args may contain optional string argument filename

View File

@@ -293,11 +293,18 @@ ControlledDhcpv6Srv::commandConfigWriteHandler(const string&,
// filename parameter was not specified, so let's use whatever we remember // filename parameter was not specified, so let's use whatever we remember
// from the command-line // from the command-line
filename = getConfigFile(); filename = getConfigFile();
} if (filename.empty()) {
return (createAnswer(CONTROL_RESULT_ERROR, "Unable to determine filename."
if (filename.empty()) { "Please specify filename explicitly."));
return (createAnswer(CONTROL_RESULT_ERROR, "Unable to determine filename." }
"Please specify filename explicitly.")); } else {
try {
checkWriteConfigFile(filename);
} catch (const isc::Exception& ex) {
return (createAnswer(CONTROL_RESULT_ERROR,
string("not allowed to write config into ") +
filename));
}
} }
// Ok, it's time to write the file. // Ok, it's time to write the file.

View File

@@ -179,9 +179,9 @@ private:
/// current configuration to disk. This command takes one optional /// current configuration to disk. This command takes one optional
/// parameter called filename. If specified, the current configuration /// parameter called filename. If specified, the current configuration
/// will be written to that file. If not specified, the file used during /// 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 /// Kea start-up will be used. To avoid any exploits, the target
/// always relative and .. is not allowed in the filename. This is /// directory must be the same as a security measure against
/// a security measure against exploiting file writes remotely. /// exploiting file writes remotely.
/// ///
/// @param command (ignored) /// @param command (ignored)
/// @param args may contain optional string argument filename /// @param args may contain optional string argument filename

View File

@@ -508,13 +508,21 @@ DControllerBase::configWriteHandler(const std::string&,
"Unable to determine filename." "Unable to determine filename."
"Please specify filename explicitly.")); "Please specify filename explicitly."));
} }
} else {
try {
checkWriteConfigFile(filename);
} catch (const isc::Exception& ex) {
return (createAnswer(CONTROL_RESULT_ERROR,
std::string("not allowed to write config into ") +
filename));
}
} }
// Ok, it's time to write the file. // Ok, it's time to write the file.
size_t size = 0; size_t size = 0;
ElementPtr cfg = process_->getCfgMgr()->getContext()->toElement();
try { try {
ElementPtr cfg = process_->getCfgMgr()->getContext()->toElement();
size = writeConfigFile(filename, cfg); size = writeConfigFile(filename, cfg);
} catch (const isc::Exception& ex) { } catch (const isc::Exception& ex) {
return (createAnswer(CONTROL_RESULT_ERROR, return (createAnswer(CONTROL_RESULT_ERROR,

View File

@@ -283,9 +283,9 @@ public:
/// current configuration to disk. This command takes one optional /// current configuration to disk. This command takes one optional
/// parameter called filename. If specified, the current configuration /// parameter called filename. If specified, the current configuration
/// will be written to that file. If not specified, the file used during /// 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 /// Kea start-up will be used. To avoid any exploits, the target
/// always relative and .. is not allowed in the filename. This is /// directory must be the same as a security measure against
/// a security measure against exploiting file writes remotely. /// exploiting file writes remotely.
/// ///
/// @param command (ignored) /// @param command (ignored)
/// @param args may contain optional string argument filename /// @param args may contain optional string argument filename

View File

@@ -125,6 +125,28 @@ Daemon::checkConfigFile() const {
} }
} }
void
Daemon::checkWriteConfigFile(std::string& file) {
Path path(file);
// from checkConfigFile().
if (path.stem().empty()) {
isc_throw(isc::BadValue, "config file:" << file
<< " is missing file name");
}
Path current(config_file_);
if (current.parentPath() == path.parentPath()) {
// Same paths!
return;
}
if (path.parentPath().empty()) {
// Note the current path can't be empty here.
file = current.parentPath() + "/" + file;
return;
}
isc_throw(isc::BadValue, "file " << file << " must be in the same "
<< "directory as the config file (" << config_file_ << "'");
}
std::string std::string
Daemon::getProcName() { Daemon::getProcName() {
return (proc_name_); return (proc_name_);

View File

@@ -139,6 +139,15 @@ public:
/// @throw BadValue when the configuration file name is bad. /// @throw BadValue when the configuration file name is bad.
void checkConfigFile() const; void checkConfigFile() const;
/// @brief Checks the to-be-written configuration file name.
///
/// @note As a side effect prepend the current config file path
/// when the name does not contain a slash.
///
/// @param[in][out] file Reference to the TBW configuration file name.
/// @throw BadValue when not in the same directory.
void checkWriteConfigFile(std::string& file);
/// @brief Writes current configuration to specified file /// @brief Writes current configuration to specified file
/// ///
/// This method writes the current configuration to specified file. /// This method writes the current configuration to specified file.