Skip to content

Implement timeout and scheduling logic #759

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
4896aa0
feat: introduce evaluator classes
jr0me Apr 15, 2025
8c22c43
refactor: move implementations to source file
jr0me Apr 15, 2025
9b08bd6
fix: add missing library link
jr0me Apr 15, 2025
87a6756
fix: clang tidy warnings
jr0me Apr 15, 2025
b925bf8
tmp add ruleEvaluator class
jr0me Apr 15, 2025
613cd60
refactor: simplify RuleEvaluator constructor and remove redundant mem…
jr0me Apr 15, 2025
861b2dd
feat: SCAPolicy checks type change
jr0me Apr 15, 2025
f9dc7f6
refactor: update SCAPolicy constructor to accept checks and modify te…
jr0me Apr 15, 2025
91c9826
refactor: enhance SCAPolicy to support continuous running and add tim…
jr0me Apr 15, 2025
e42a05b
refactor: add CheckConditionEvaluator class to handle conditional rul…
jr0me Apr 15, 2025
028d937
refactor: add fromString method to CheckConditionEvaluator for condit…
jr0me Apr 15, 2025
24c8164
refactor: use CheckConditionEvaluator to simplify logic
jr0me Apr 15, 2025
8f7e3d1
refactor: implement Stop method in SCAPolicy and update SecurityConfi…
jr0me Apr 15, 2025
8e832a5
refactor: add ReportCheckResult method to SCAPolicy for handling chec…
jr0me Apr 16, 2025
605fd5e
refactor: update PolicyEvaluationContext to use ConditionType and Pol…
jr0me Apr 17, 2025
ecb4d6e
refactor: implement RuleWithReplacedVariables method in PolicyEvaluat…
jr0me Apr 17, 2025
f126aec
refactor: add ResolvedPaths method to PolicyEvaluationContext for pat…
jr0me Apr 17, 2025
2f6bb1f
refactor: add GetPattern method to PolicyEvaluationContext for patter…
jr0me Apr 17, 2025
61dadc4
refactor: move parsing functions to distinct file
jr0me Apr 21, 2025
7f4296a
feat: add function to parse rule type
jr0me Apr 21, 2025
7bbf374
feat: use map instead of unordered map for variables.
jr0me Apr 21, 2025
653916b
refactor: introduce custom comparator for PolicyVariables to sort by …
jr0me Apr 21, 2025
824a348
feat: add requirements vector to SCAPolicy class
jr0me Apr 21, 2025
db5159f
feat: implement requirement checks in SCAPolicy Run method
jr0me Apr 21, 2025
ba51ece
feat: rule cannot be empty, check in constructor
jr0me Apr 22, 2025
98d401d
refactor: simplify policy context struct
jr0me Apr 22, 2025
caa7a90
refactor: split sca_policy.hpp into header and src
jr0me Apr 22, 2025
fed9872
refactor: split sca_policy_check.hpp into header and src
jr0me Apr 22, 2025
7539af0
fix: add sca_utils.cpp to SCA target
jr0me Apr 22, 2025
1c857f2
refactor: move CheckConditionEvaluator to different file
jr0me Apr 22, 2025
df6d549
fix: clang tidy modernize-pass-by-value warnings
jr0me Apr 22, 2025
921f201
fix: update CheckConditionEvaluator method names to follow naming con…
jr0me Apr 22, 2025
64d0a1b
feat: implement PatternMatches function for advanced pattern matching…
jr0me Apr 23, 2025
3b3f325
feat: get file content and use PatternMatches in FileRuleEvaluator
jr0me Apr 23, 2025
f978a94
fix: remove regex prefix
jr0me Apr 23, 2025
a1efa34
feat: continue CheckFileForContents implementation
jr0me Apr 23, 2025
8a05790
fix: remove placeholder comments from CheckFileExistence method
jr0me Apr 23, 2025
49e8e39
feat: implement EvaluateMinterm function for enhanced pattern and num…
jr0me Apr 23, 2025
ef49c39
feat: enhance DirRuleEvaluator to support pattern matching for direct…
jr0me Apr 23, 2025
8238fd4
feat: extend DirRuleEvaluator constructor to include fileUtils and im…
jr0me Apr 23, 2025
fa92696
feat: implement directory file matching logic in DirRuleEvaluator
jr0me Apr 23, 2025
48570c1
feat: update CheckFileForContents to support 'n:' pattern in addition…
jr0me Apr 23, 2025
6dc1273
feat: enhance CommandRuleEvaluator to support pattern matching for co…
jr0me Apr 23, 2025
000d24f
feat: re introduce os utils for linux running processes
jr0me Apr 24, 2025
30c858f
feat: implement cross-platform OsUtils with process listing functiona…
jr0me Apr 24, 2025
4948653
feat: add OsUtils to CMakeLists and implement process evaluation in P…
jr0me Apr 24, 2025
062e9b8
feat: add boilerplate for Registry rule evaluator
jr0me Apr 24, 2025
7c671ee
feat: implement registry evaluation logic in RegistryRuleEvaluator
jr0me Apr 24, 2025
fdc60d9
feat: add Registry constructor to convert string to HKEY
jr0me Apr 24, 2025
aad02e5
refactor: encapsulate registry existence check in lambda
jr0me Apr 24, 2025
50394c4
fix: remove redundant return statement in CheckFileForContents method
jr0me Apr 24, 2025
b904fce
fix: expose constructor for FileRuleEvaluator
jr0me Apr 24, 2025
85dd6d2
test: add unit tests for FileRuleEvaluator functionality
jr0me Apr 24, 2025
cde93f4
feat: enhance CommandRuleEvaluator with customizable command executio…
jr0me Apr 24, 2025
8dc39ee
feat: add directory_rule_evaluator_test with comprehensive test cases
jr0me Apr 24, 2025
5c53a4f
fix: include <functional> header in sca_policy_check.hpp for proper f…
jr0me Apr 24, 2025
da55f60
feat: enhance ProcessRuleEvaluator to accept a customizable process r…
jr0me Apr 24, 2025
eb3b447
feat: add unit tests for ProcessRuleEvaluator functionality
jr0me Apr 24, 2025
61d7ddd
feat: add pcre2 dependencia and complete pcre2match function in SCA
TomasTurina Apr 24, 2025
2bd1d47
fix: windows compilation issues with testing::Invoke
jr0me Apr 24, 2025
ca80eb6
feat: implement numeric comparison logic in SCA
TomasTurina Apr 25, 2025
4228c87
feat: add detailed documentation for SCA utility functions and enhanc…
jr0me Apr 25, 2025
debdeee
fix: update target_link_libraries in CMakeLists.txt to include delete…
jr0me Apr 25, 2025
32fe9f0
feat: enhance RegistryRuleEvaluator with default functions for regist…
jr0me Apr 25, 2025
d7da424
refactor: remove unused fileSystemWrapper parameter from RegistryRule…
jr0me Apr 25, 2025
ecd694a
feat: add Windows-specific tests for RegistryRuleEvaluator functionality
jr0me Apr 25, 2025
569992d
feat: RuleEvaluatorFactory class added
sdvendramini Apr 25, 2025
4cc9776
feat: PolicyParser class added
sdvendramini Apr 25, 2025
16fbce8
feat: Logic added to parse policy files in SCAPolicyLoader
sdvendramini Apr 25, 2025
d73a86d
fix: correct test case name and expected result for ProcessNotFound test
jr0me Apr 25, 2025
d73edbb
fix: update test case for empty process list to return NotFound inste…
jr0me Apr 25, 2025
6ddafed
refactor: remove unused mock includes from registry_rule_evaluator_test
jr0me Apr 25, 2025
415517d
refactor: remove gmock include from registry_rule_evaluator_test and …
jr0me Apr 25, 2025
f4a7fb4
refactor: remove unused [[maybe_unused]] attributes from CreateOrOpen…
jr0me Apr 25, 2025
018aa63
fix: implement RegistryRuleEvaluator instantiation in CreateEvaluator…
jr0me Apr 25, 2025
fc8dccd
fix: instantiate unique pointers before using them
jr0me Apr 25, 2025
0c992e3
fix: update error logging message for SCA coroutine task
jr0me Apr 25, 2025
be0fa79
refactor: shrink scope of ruleEvaluator
jr0me Apr 25, 2025
89f33d7
fix: "->" in a rule is optional
jr0me Apr 25, 2025
9582ca8
refactor: use structured binding to simplify ctx
jr0me Apr 25, 2025
02a0875
test: add rule creation tests for RuleEvaluatorFactory
jr0me Apr 25, 2025
f2b0e77
fix: momentarily only add support for RegistryRuleEvaluator on Windows
jr0me Apr 25, 2025
20ffef4
fix: remove duplicated logic
jr0me Apr 25, 2025
213bee9
fix: rename variable according to project convention
jr0me Apr 25, 2025
c86ecad
refactor: use stringhelper's Trim function
jr0me Apr 25, 2025
c55f17b
fix: stoi exception from bad regex use
jr0me Apr 25, 2025
51d3ca5
fix: simplify RegistryRuleEvaluator instantiation in CreateEvaluator
jr0me Apr 25, 2025
d44ff78
fix: declare PolicyEvaluationContext as const in CreateEvaluator
jr0me Apr 25, 2025
9f36dc5
fix: remove redundant test for missing value pattern in RegistryRuleE…
jr0me Apr 25, 2025
e86bb19
fix: correct conditional logic in RegistryRuleEvaluator::Evaluate
jr0me Apr 25, 2025
93ae704
fix: remove commented-out test for GetPolicies in ScaPolicyLoaderTest
jr0me Apr 25, 2025
4781264
fix: rename Exec to PipeOpen for clarity in cmdHelper
jr0me Apr 28, 2025
74f541a
feat: add Exec function to cmdHelper for executing commands and captu…
jr0me Apr 28, 2025
1aeecfc
feat: update Exec function to return ExecResult containing StdOut, St…
jr0me Apr 28, 2025
95dd7ab
fix: remove unnecessary environment variable passing in Exec function
jr0me Apr 28, 2025
9f6d70d
fix: initialize members in PolicyEvaluationContext for clarity
jr0me Apr 28, 2025
5f6a9d0
fix: change result variable to const for better clarity in SCAPolicy:…
jr0me Apr 28, 2025
3163c15
fix: enhance file existence checks to include regular file validation…
jr0me Apr 28, 2025
eeb37a0
fix: various small changes
jr0me Apr 29, 2025
63d72ca
fix: improve error handling in Exec function and enhance test cases f…
jr0me Apr 29, 2025
7fa7221
fix: Change Exec implementation
sdvendramini Apr 29, 2025
988fc37
feat: Add logic to implement timeout and scheduling
sdvendramini Apr 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/agent/instance_communicator/src/listener_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace instance_communicator
public:
explicit ListenerWrapper(const boost::asio::any_io_executor& executor);

bool CreateOrOpen([[maybe_unused]] const std::string& runPath, const std::size_t bufferSize) override;
bool CreateOrOpen(const std::string& runPath, const std::size_t bufferSize) override;

boost::asio::awaitable<void> AsyncAccept(boost::system::error_code& ec) override;

Expand Down
1 change: 1 addition & 0 deletions src/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_subdirectory(linuxHelper)
add_subdirectory(logger)
add_subdirectory(mapWrapper)
add_subdirectory(networkHelper)
add_subdirectory(os_utils)
add_subdirectory(pal)
add_subdirectory(pipelineHelper)
add_subdirectory(registryHelper)
Expand Down
4 changes: 3 additions & 1 deletion src/common/cmdHelper/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ cmake_minimum_required(VERSION 3.22)

project(cmd_helper)

find_package(boost_process REQUIRED CONFIG)

include(../../cmake/CommonSettings.cmake)
set_common_settings()

add_library(cmd_helper src/cmdHelper.cpp)

target_include_directories(cmd_helper PUBLIC include)

target_link_libraries(cmd_helper PRIVATE deleter_helper)
target_link_libraries(cmd_helper PRIVATE Logger deleter_helper Boost::process)

include(../../cmake/ConfigureTarget.cmake)
configure_target(cmd_helper)
Expand Down
19 changes: 18 additions & 1 deletion src/common/cmdHelper/include/cmdHelper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,26 @@

namespace Utils
{
struct ExecResult
{
std::string StdOut;
std::string StdErr;
int ExitCode;
};

/// @brief Executes a command
/// @param cmd command
/// @param bufferSize buffer size in bytes
/// @return command output
std::string Exec(const std::string& cmd, const size_t bufferSize = 128);
std::string PipeOpen(const std::string& cmd, const size_t bufferSize = 128);

/// @brief Executes a command and captures its output.
///
/// Runs a command without using a shell, capturing both StdOut and StdErr.
/// The function waits for the process to finish before returning.
///
/// @param cmd The command to execute (no shell features like piping or expansions).
/// @return A ExecResult containing the command's StdOut, StdErr, and ExitCode.
/// @throw boost::process::process_error if the command fails to start.
ExecResult Exec(const std::string& cmd);
} // namespace Utils
82 changes: 77 additions & 5 deletions src/common/cmdHelper/src/cmdHelper.cpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,99 @@
#include "cmdHelper.hpp"
#include <cmdHelper.hpp>

#include <fileSmartDeleter.hpp>
#include <logger.hpp>

#include <boost/process.hpp>

#include "fileSmartDeleter.hpp"
#include <cstdio>
#include <memory>
#include <string>
#include <sstream>
#include <stdexcept>
#include <vector>

namespace
{
std::vector<std::string> TokenizeCommand(const std::string& command)
{
std::vector<std::string> result;
std::istringstream stream(command);
std::string token;
while (stream >> token)
{
result.push_back(token);
}

if (result.empty())
{
throw std::runtime_error("Empty command string");
}

return result;
}

std::string GetStreamOutput(std::istream& stream)
{
std::string line;
std::stringstream output;
while (std::getline(stream, line))
{
output << line << '\n';
}
return output.str();
}
} // namespace

namespace Utils
{
std::string Exec(const std::string& cmd, const size_t bufferSize)
std::string PipeOpen(const std::string& cmd, const size_t bufferSize)
{
const std::unique_ptr<FILE, FileSmartDeleter> file {popen(cmd.c_str(), "r")};
std::vector<char> buffer(bufferSize);
std::string result;

if (file)
{
while (fgets(buffer.data(), static_cast<int>(bufferSize), file.get()))
while (fgets(buffer.data(), static_cast<int>(buffer.size()), file.get()))
{
result += buffer.data();
}
}

return result;
}

ExecResult Exec(const std::string& cmd)
{
try
{
// Tokenize to separate the command and its arguments
const auto args = TokenizeCommand(cmd);
const auto exePath = boost::process::search_path(args[0]);
if (exePath.empty())
{
throw std::runtime_error("Executable not found in PATH: " + args[0]);
}

boost::process::ipstream stdoutStream;
boost::process::ipstream stderrStream;
const std::vector<std::string> execArgs(args.begin() + 1, args.end());

boost::process::child process(exePath,
boost::process::args = execArgs,
boost::process::std_out > stdoutStream,
boost::process::std_err > stderrStream);

const auto output = GetStreamOutput(stdoutStream);
const auto error = GetStreamOutput(stderrStream);
process.wait();

return {.StdOut = output, .StdErr = error, .ExitCode = process.exit_code()};
}
catch (const std::exception& e)
{
return {.StdOut = "", .StdErr = e.what(), .ExitCode = 1};
}

return {.StdOut = "", .StdErr = "", .ExitCode = 1};
}
} // namespace Utils
51 changes: 42 additions & 9 deletions src/common/cmdHelper/tests/cmdHelper_test.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,52 @@
#include "cmdHelper_test.hpp"
#include "cmdHelper.hpp"

void CmdUtilsTest::SetUp() {};
#include <string>

void CmdUtilsTest::TearDown() {};
#ifdef WIN32
TEST_F(CmdUtilsTest, CmdVersion)
const std::string TEST_CMD = "ver";
#else
const std::string TEST_CMD = "uname";
#endif

TEST_F(CmdUtilsTest, PipeOpenCmd)
{
const auto result {Utils::Exec("ver")};
const auto result {Utils::PipeOpen(TEST_CMD)};
EXPECT_FALSE(result.empty());
}
#else
TEST_F(CmdUtilsTest, CmdUname)

TEST_F(CmdUtilsTest, ExecCmd)
{
const auto result {Utils::Exec("uname")};
EXPECT_FALSE(result.empty());
const auto result {Utils::Exec(TEST_CMD)};
EXPECT_FALSE(result.StdOut.empty());
EXPECT_TRUE(result.StdErr.empty());
EXPECT_EQ(result.ExitCode, 0);
}

TEST_F(CmdUtilsTest, ExecInvalidCmd)
{
const auto result {Utils::Exec("invalid_command")};
EXPECT_TRUE(result.StdOut.empty());
EXPECT_FALSE(result.StdErr.empty());
EXPECT_NE(result.ExitCode, 0);
}

TEST_F(CmdUtilsTest, PipeOpenInvalidCmd)
{
const auto result {Utils::PipeOpen("invalid_command")};
EXPECT_TRUE(result.empty());
}

TEST_F(CmdUtilsTest, ExecEmptyCmd)
{
const auto result {Utils::Exec("")};
EXPECT_TRUE(result.StdOut.empty());
EXPECT_FALSE(result.StdErr.empty());
EXPECT_NE(result.ExitCode, 0);
}

TEST_F(CmdUtilsTest, PipeOpenEmptyCmd)
{
const auto result {Utils::PipeOpen("")};
EXPECT_TRUE(result.empty());
}
#endif
3 changes: 0 additions & 3 deletions src/common/cmdHelper/tests/cmdHelper_test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,4 @@ class CmdUtilsTest : public ::testing::Test
protected:
CmdUtilsTest() = default;
virtual ~CmdUtilsTest() = default;

void SetUp() override;
void TearDown() override;
};
6 changes: 3 additions & 3 deletions src/common/data_provider/src/sysInfoMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,10 @@ nlohmann::json SysInfo::getOsInfo() const
};

MacOsParser parser;
parser.parseSwVersion(Utils::Exec("sw_vers"), ret);
parser.parseUname(Utils::Exec("uname -r"), ret);
parser.parseSwVersion(Utils::PipeOpen("sw_vers"), ret);
parser.parseUname(Utils::PipeOpen("uname -r"), ret);

if (!parser.parseSystemProfiler(Utils::Exec("system_profiler SPSoftwareDataType"), ret))
if (!parser.parseSystemProfiler(Utils::PipeOpen("system_profiler SPSoftwareDataType"), ret))
{
ret["os_name"] = "macOS";
}
Expand Down
2 changes: 1 addition & 1 deletion src/common/data_provider/src/sysInfoWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ static std::string GetSerialNumber()
}
else
{
const auto rawData {Utils::Exec("wmic baseboard get SerialNumber")};
const auto rawData {Utils::PipeOpen("wmic baseboard get SerialNumber")};
const auto pos {rawData.find("\r\n")};

if (pos != std::string::npos)
Expand Down
2 changes: 1 addition & 1 deletion src/common/data_provider/src/utilsWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@

std::string UtilsWrapper::exec(const std::string& cmd, const size_t bufferSize)
{
return Utils::Exec(cmd, bufferSize);
return Utils::PipeOpen(cmd, bufferSize);
}
6 changes: 3 additions & 3 deletions src/common/linuxHelper/tests/linuxInfoHelper_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ TEST_F(LinuxInfoHelperTest, getBootTime)
{
const auto btimeNumFromFunc {Utils::getBootTime()};

const auto btimeStr {Utils::Exec("grep 'btime' /proc/stat | awk '{print $2}'")};
const auto btimeStr {Utils::PipeOpen("grep 'btime' /proc/stat | awk '{print $2}'")};
const auto btimeNumFromProc {std::stoull(btimeStr)};

EXPECT_FALSE(btimeNumFromFunc != btimeNumFromProc);
}

TEST_F(LinuxInfoHelperTest, timeTick2unixTime)
{
const auto startTimeStr {Utils::Exec("awk '{print $22}' /proc/1/stat")};
const auto startTimeStr {Utils::PipeOpen("awk '{print $22}' /proc/1/stat")};
const auto startTimeNum {std::stoul(startTimeStr)};
const auto startTimeUnixFunc {Utils::timeTick2unixTime(startTimeNum)};

const auto startTimeUnixCmd {std::stoul(Utils::Exec("LC_ALL=C date -d \"`ps -o lstart -p 1|tail -n 1`\" +%s"))};
const auto startTimeUnixCmd {std::stoul(Utils::PipeOpen("LC_ALL=C date -d \"`ps -o lstart -p 1|tail -n 1`\" +%s"))};

EXPECT_FALSE(startTimeUnixFunc != startTimeUnixCmd);
}
2 changes: 0 additions & 2 deletions src/common/os_utils/.clang-format

This file was deleted.

18 changes: 18 additions & 0 deletions src/common/os_utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
cmake_minimum_required(VERSION 3.22)

project(OsUtils)

include(../../cmake/CommonSettings.cmake)
set_common_settings()

add_library(OsUtils $<$<NOT:$<PLATFORM_ID:Windows>>:src/os_utils_unix.cpp>
$<$<PLATFORM_ID:Windows>:src/os_utils_win.cpp>)
target_include_directories(OsUtils PUBLIC include PRIVATE src)
target_link_libraries(OsUtils PUBLIC FilesystemWrapper PRIVATE Logger deleter_helper)

include(../../cmake/ConfigureTarget.cmake)
configure_target(OsUtils)

if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
19 changes: 19 additions & 0 deletions src/common/os_utils/include/ios_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <string>
#include <vector>

namespace os_utils
{
class IOsUtils
{
public:
/// @brief Virtual destructor for IOsUtils.
/// @note Ensures that any derived classes with their own resources are correctly cleaned up.
virtual ~IOsUtils() = default;

/// @brief Get the list of all running processes.
/// @return A vector of strings containing the names of running processes. Empty if none or error found.
virtual std::vector<std::string> GetRunningProcesses() = 0;
};
} // namespace os_utils
38 changes: 0 additions & 38 deletions src/common/os_utils/include/os_utils.h

This file was deleted.

19 changes: 19 additions & 0 deletions src/common/os_utils/include/os_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <ios_utils.hpp>

#include <string>
#include <vector>

namespace os_utils
{
class OsUtils : public IOsUtils
{
public:
/// @brief Destructor for OsUtils.
~OsUtils() = default;

/// @copydoc IOsUtils::GetRunningProcesses
std::vector<std::string> GetRunningProcesses() override;
};
} // namespace os_utils
Loading