Skip to content
API Documentation
BastionGuard™
ActionHelper.cpp File Reference

Go to the source code of this file.

Classes

struct  anonymous_namespace{ActionHelper.cpp}::Options

Namespaces

namespace  anonymous_namespace{ActionHelper.cpp}

Functions

void anonymous_namespace{ActionHelper.cpp}::fail (const std::string &message)
std::uint64_t anonymous_namespace{ActionHelper.cpp}::parseUnsigned (const std::string &value, const char *label, const int base=10)
Options anonymous_namespace{ActionHelper.cpp}::parseOptions (const int argc, char *argv[])
bool anonymous_namespace{ActionHelper.cpp}::pathStartsWith (const fs::path &path, const fs::path &prefix)
fs::path anonymous_namespace{ActionHelper.cpp}::normalizedAbsolute (const fs::path &path)
bool anonymous_namespace{ActionHelper.cpp}::isIgnoredPath (const Policy &policy, const fs::path &requested)
bool anonymous_namespace{ActionHelper.cpp}::isProtectedPath (const Policy &policy, const fs::path &requested)
void anonymous_namespace{ActionHelper.cpp}::requireProtectedPath (const Policy &policy, const fs::path &path)
std::string anonymous_namespace{ActionHelper.cpp}::timestamp ()
void anonymous_namespace{ActionHelper.cpp}::copyString (char *destination, const std::size_t size, const std::string &source)
void anonymous_namespace{ActionHelper.cpp}::logAction (const Policy &policy, const fs::path &path, const std::uint32_t eventType, const std::uint32_t verdict, const struct stat *before=nullptr, const struct stat *after=nullptr)
Policy anonymous_namespace{ActionHelper.cpp}::loadPolicy (const fs::path &path)
std::string anonymous_namespace{ActionHelper.cpp}::trim (std::string value)
void anonymous_namespace{ActionHelper.cpp}::rewriteProtectionPolicy (const fs::path &policyPath, const bool enabled)
std::vector< fs::path > anonymous_namespace{ActionHelper.cpp}::normalizeApplicationEntries (const std::vector< fs::path > &entries, const char *label)
void anonymous_namespace{ActionHelper.cpp}::writePolicyAtomically (const fs::path &policyPath, const std::vector< std::string > &lines, const struct stat &metadata)
void anonymous_namespace{ActionHelper.cpp}::rewriteApplicationRules (const Options &options)
void anonymous_namespace{ActionHelper.cpp}::restoreFile (const Options &options, const Policy &policy)
void anonymous_namespace{ActionHelper.cpp}::quarantineFile (const Options &options, const Policy &policy)
int main (const int argc, char *argv[])

Variables

constexpr const char * anonymous_namespace{ActionHelper.cpp}::kDefaultPolicy = "/etc/bastionguard/rootguard.conf"
constexpr const char * anonymous_namespace{ActionHelper.cpp}::kQuarantineDir = "/var/lib/bastionguard/rootguard/quarantine"

Function Documentation

◆ main()

int main ( const int argc,
char * argv[] )

Definition at line 586 of file ActionHelper.cpp.

587{
588 try {
589 if (::geteuid() != 0)
590 fail("Administrative privileges are required.");
591 const Options options = parseOptions(argc, argv);
592 const Policy policy = loadPolicy(options.policy);
593
594 if (options.command == "set-protection") {
595 if (options.protection != "on" && options.protection != "off")
596 fail("set-protection requires --state on|off.");
597 const bool enabled = options.protection == "on";
598 rewriteProtectionPolicy(options.policy, enabled);
599 const Policy updated = loadPolicy(options.policy);
600 logAction(updated, options.policy, RG_EVENT_PROTECTION_MODE_CHANGED,
602 std::cout << (enabled
603 ? "Immediate blocking enabled for protected system paths; user home remains audit-only."
604 : "Immediate metadata blocking disabled.") << '\n';
605 } else if (options.command == "set-application-rules") {
607 } else if (options.command == "restore") {
608 restoreFile(options, policy);
609 } else if (options.command == "remove") {
610 quarantineFile(options, policy);
611 } else if (options.command == "block-service") {
612 const auto path = normalizedAbsolute(options.path);
613 requireProtectedPath(policy, path);
614 if (const auto target = identifySystemService(path)) {
615 if (target->init == InitSystem::OpenRC || target->init == InitSystem::SysVInit) {
616 struct stat current{};
617 if (!options.device || !options.inode ||
618 ::lstat(path.c_str(), &current) != 0 ||
619 FileIdentityResolver::kernelDeviceNumber(current.st_dev) != *options.device ||
620 static_cast<std::uint64_t>(current.st_ino) != *options.inode) {
621 fail("Refusing to execute an OpenRC/SysV service definition without a matching protected identity.");
622 }
623 }
624 }
625 const auto result = blockSystemService(path);
626 if (!result.success) fail(result.message);
628 std::cout << result.message << '\n';
629 } else if (options.command == "unblock-service") {
630 const auto path = normalizedAbsolute(options.path);
631 requireProtectedPath(policy, path);
632 const auto result = unblockSystemService(path);
633 if (!result.success) fail(result.message);
634 std::cout << result.message << '\n';
635 } else {
636 fail("Unknown action: " + options.command);
637 }
638 return 0;
639 } catch (const std::exception& error) {
640 std::cerr << "RootGuard action: " << error.what() << '\n';
641 return 1;
642 }
643}
static __u64 kernelDeviceNumber(dev_t encodedDevice)
Policy loadPolicy(const fs::path &path)
void fail(const std::string &message)
Options parseOptions(const int argc, char *argv[])
void requireProtectedPath(const Policy &policy, const fs::path &path)
fs::path normalizedAbsolute(const fs::path &path)
void quarantineFile(const Options &options, const Policy &policy)
void rewriteApplicationRules(const Options &options)
void logAction(const Policy &policy, const fs::path &path, const std::uint32_t eventType, const std::uint32_t verdict, const struct stat *before=nullptr, const struct stat *after=nullptr)
void rewriteProtectionPolicy(const fs::path &policyPath, const bool enabled)
void restoreFile(const Options &options, const Policy &policy)
std::optional< ServiceTarget > identifySystemService(const std::filesystem::path &path) noexcept
ServiceActionResult blockSystemService(const std::filesystem::path &path) noexcept
ServiceActionResult unblockSystemService(const std::filesystem::path &path) noexcept
@ RG_EVENT_SERVICE_BLOCKED
@ RG_EVENT_PROTECTION_MODE_CHANGED
@ RG_VERDICT_AUDIT
@ RG_VERDICT_BLOCKED

References bastionguard::rootguard::blockSystemService(), anonymous_namespace{ActionHelper.cpp}::fail(), bastionguard::rootguard::identifySystemService(), bastionguard::rootguard::FileIdentityResolver::kernelDeviceNumber(), anonymous_namespace{ActionHelper.cpp}::loadPolicy(), anonymous_namespace{ActionHelper.cpp}::logAction(), main(), anonymous_namespace{ActionHelper.cpp}::normalizedAbsolute(), bastionguard::rootguard::OpenRC, anonymous_namespace{ActionHelper.cpp}::parseOptions(), anonymous_namespace{ActionHelper.cpp}::quarantineFile(), anonymous_namespace{ActionHelper.cpp}::requireProtectedPath(), anonymous_namespace{ActionHelper.cpp}::restoreFile(), anonymous_namespace{ActionHelper.cpp}::rewriteApplicationRules(), anonymous_namespace{ActionHelper.cpp}::rewriteProtectionPolicy(), RG_EVENT_PROTECTION_MODE_CHANGED, RG_EVENT_SERVICE_BLOCKED, RG_VERDICT_AUDIT, RG_VERDICT_BLOCKED, bastionguard::rootguard::SysVInit, and bastionguard::rootguard::unblockSystemService().