mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-01 22:45:18 +00:00
[#1680] added check for execurtable permissions
This commit is contained in:
@@ -4,6 +4,7 @@ AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
|
|||||||
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/run_script -I$(top_srcdir)/src/hooks/dhcp/run_script
|
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/run_script -I$(top_srcdir)/src/hooks/dhcp/run_script
|
||||||
AM_CPPFLAGS += $(BOOST_INCLUDES)
|
AM_CPPFLAGS += $(BOOST_INCLUDES)
|
||||||
AM_CPPFLAGS += -DLIBRUN_SCRIPT_SO=\"$(abs_top_builddir)/src/hooks/dhcp/run_script/.libs/libdhcp_run_script.so\"
|
AM_CPPFLAGS += -DLIBRUN_SCRIPT_SO=\"$(abs_top_builddir)/src/hooks/dhcp/run_script/.libs/libdhcp_run_script.so\"
|
||||||
|
AM_CPPFLAGS += -DRUN_SCRIPT_TEST_SH=\"$(abs_top_builddir)/src/hooks/dhcp/run_script/tests/run_script_test.sh\"
|
||||||
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
|
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
|
||||||
|
|
||||||
AM_CXXFLAGS = $(KEA_CXXFLAGS)
|
AM_CXXFLAGS = $(KEA_CXXFLAGS)
|
||||||
|
@@ -75,7 +75,7 @@ public:
|
|||||||
TEST_F(LibLoadTest, validLoad) {
|
TEST_F(LibLoadTest, validLoad) {
|
||||||
// Prepare parameters for the callout parameters library.
|
// Prepare parameters for the callout parameters library.
|
||||||
ElementPtr params = Element::createMap();
|
ElementPtr params = Element::createMap();
|
||||||
ElementPtr name = Element::create("test_script.sh");
|
ElementPtr name = Element::create(RUN_SCRIPT_TEST_SH);
|
||||||
params->set("name", name);
|
params->set("name", name);
|
||||||
ElementPtr sync = Element::create(false);
|
ElementPtr sync = Element::create(false);
|
||||||
params->set("sync", sync);
|
params->set("sync", sync);
|
||||||
@@ -104,12 +104,16 @@ TEST_F(LibLoadTest, invalidLoad) {
|
|||||||
params->set("name", name);
|
params->set("name", name);
|
||||||
EXPECT_FALSE(loadLibs());
|
EXPECT_FALSE(loadLibs());
|
||||||
|
|
||||||
// Use valid name parameter type but use invalid sync parameter type.
|
// Use invalid name parameter.
|
||||||
name = Element::create("script_name.sh");
|
name = Element::create("script_name.sh");
|
||||||
params->set("name", name);
|
params->set("name", name);
|
||||||
|
EXPECT_FALSE(loadLibs());
|
||||||
|
|
||||||
|
// Use valid name parameter type but use invalid sync parameter type.
|
||||||
|
name = Element::create(RUN_SCRIPT_TEST_SH);
|
||||||
|
params->set("name", name);
|
||||||
ElementPtr sync = Element::create("data");
|
ElementPtr sync = Element::create("data");
|
||||||
params->set("sync", sync);
|
params->set("sync", sync);
|
||||||
|
|
||||||
EXPECT_FALSE(loadLibs());
|
EXPECT_FALSE(loadLibs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,6 +32,15 @@ RunScriptImpl::configure(LibraryHandle& handle) {
|
|||||||
if (name->getType() != Element::string) {
|
if (name->getType() != Element::string) {
|
||||||
isc_throw(InvalidParameter, "The 'name' parameter must be a string");
|
isc_throw(InvalidParameter, "The 'name' parameter must be a string");
|
||||||
}
|
}
|
||||||
|
IOServicePtr io_service(new asiolink::IOService());
|
||||||
|
try {
|
||||||
|
ProcessSpawn process(io_service, name->stringValue());
|
||||||
|
if (!process.checkPermissions()) {
|
||||||
|
isc_throw(InvalidParameter, "The 'name' parameter must point to an executable");
|
||||||
|
}
|
||||||
|
} catch (const isc::Exception& ex) {
|
||||||
|
isc_throw(InvalidParameter, "Invalid 'name' parameter: " << ex.what());
|
||||||
|
}
|
||||||
setName(name->stringValue());
|
setName(name->stringValue());
|
||||||
ConstElementPtr sync = handle.getParameter("sync");
|
ConstElementPtr sync = handle.getParameter("sync");
|
||||||
if (sync) {
|
if (sync) {
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -131,6 +132,12 @@ public:
|
|||||||
/// @param pid A process pid.
|
/// @param pid A process pid.
|
||||||
void clearState(const pid_t pid);
|
void clearState(const pid_t pid);
|
||||||
|
|
||||||
|
/// @brief Check executable permissions.
|
||||||
|
///
|
||||||
|
/// @return true if file has executable permissions, false otherwise.
|
||||||
|
/// @throw ProcessSpawnError if file does not exist.
|
||||||
|
bool checkPermissions() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// @brief Copies the argument specified as a C++ string to the new
|
/// @brief Copies the argument specified as a C++ string to the new
|
||||||
@@ -357,6 +364,18 @@ ProcessSpawn::ProcessSpawn(IOServicePtr io_service,
|
|||||||
: impl_(new ProcessSpawnImpl(io_service, executable, args, vars)) {
|
: impl_(new ProcessSpawnImpl(io_service, executable, args, vars)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ProcessSpawnImpl::checkPermissions() const {
|
||||||
|
struct stat st;
|
||||||
|
if (stat(executable_.c_str(), &st)) {
|
||||||
|
isc_throw(ProcessSpawnError, "File not found: " << executable_);
|
||||||
|
}
|
||||||
|
if (st.st_mode & S_IEXEC) {
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
ProcessSpawn::getCommandLine() const {
|
ProcessSpawn::getCommandLine() const {
|
||||||
return (impl_->getCommandLine());
|
return (impl_->getCommandLine());
|
||||||
@@ -387,5 +406,10 @@ ProcessSpawn::clearState(const pid_t pid) {
|
|||||||
return (impl_->clearState(pid));
|
return (impl_->clearState(pid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ProcessSpawn::checkPermissions() const {
|
||||||
|
return (impl_->checkPermissions());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace asiolink
|
} // namespace asiolink
|
||||||
} // namespace isc
|
} // namespace isc
|
||||||
|
@@ -137,6 +137,12 @@ public:
|
|||||||
/// @param pid A process pid.
|
/// @param pid A process pid.
|
||||||
void clearState(const pid_t pid);
|
void clearState(const pid_t pid);
|
||||||
|
|
||||||
|
/// @brief Check executable permissions.
|
||||||
|
///
|
||||||
|
/// @return true if file has executable permissions, false otherwise.
|
||||||
|
/// @throw ProcessSpawnError if file does not exist.
|
||||||
|
bool checkPermissions() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// @brief A smart pointer to the implementation of this class.
|
/// @brief A smart pointer to the implementation of this class.
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <testutils/gtest_utils.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using namespace isc;
|
using namespace isc;
|
||||||
@@ -343,4 +345,19 @@ TEST_F(ProcessSpawnTest, isRunning) {
|
|||||||
ASSERT_EQ(SIGCHLD, processed_signals_[0]);
|
ASSERT_EQ(SIGCHLD, processed_signals_[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test verifies that the checkPermissions function throws if the file does
|
||||||
|
// not exist and returns true or false if the file is or it is not executable.
|
||||||
|
TEST_F(ProcessSpawnTest, checkPermissions) {
|
||||||
|
ProcessSpawn no_process(io_service_, "no-file");
|
||||||
|
EXPECT_THROW_MSG(no_process.checkPermissions(), ProcessSpawnError,
|
||||||
|
"File not found: no-file");
|
||||||
|
|
||||||
|
std::string name = TEST_SCRIPT_SH;
|
||||||
|
name += ".in";
|
||||||
|
ProcessSpawn invalid_process(io_service_, name);
|
||||||
|
ASSERT_FALSE(invalid_process.checkPermissions());
|
||||||
|
ProcessSpawn process(io_service_, TEST_SCRIPT_SH);
|
||||||
|
ASSERT_TRUE(process.checkPermissions());
|
||||||
|
}
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
Reference in New Issue
Block a user