40 std::filesystem::path
policyPath{
"/etc/bastionguard/rootguard.conf"};
48 std::cerr <<
"uso: " << executable
49 <<
" [--policy FILE] [--audit|--enforce]"
50 " [--allow-unsafe-policy] [--check-policy]\n";
56 for (
int index = 1; index < argc; ++index) {
57 const std::string_view argument(argv[index]);
58 if (argument ==
"--policy" && index + 1 < argc) {
60 }
else if (argument ==
"--audit") {
62 }
else if (argument ==
"--enforce") {
64 }
else if (argument ==
"--allow-unsafe-policy") {
66 }
else if (argument ==
"--check-policy") {
70 throw std::invalid_argument(
"argomento non riconosciuto");
91 const std::filesystem::path path{
"/run/bastionguard-rootguard.status"};
92 const std::filesystem::path temporary = path.string() +
".tmp." +
93 std::to_string(::getpid());
94 std::ofstream output(temporary, std::ios::trunc);
103 <<
"auto_block_services="
104 << (effectiveServiceBlocking ?
"true" :
"false") <<
'\n'
105 <<
"block_user_home=" << (policy.
blockUserHome ?
"true" :
"false") <<
'\n';
109 ::chmod(temporary.c_str(), 0644);
110 if (::rename(temporary.c_str(), path.c_str()) != 0)
111 std::filesystem::remove(temporary);
116 const std::filesystem::path path{
"/run/bastionguard-rootguard.policy-view"};
117 const std::filesystem::path temporary = path.string() +
".tmp." +
118 std::to_string(::getpid());
119 std::ofstream output(temporary, std::ios::trunc);
122 output <<
"block_user_home=" << (policy.
blockUserHome ?
"true" :
"false") <<
'\n'
130 output <<
"trusted_application=" << rule.path.string() <<
'\n';
132 output <<
"trusted_executable=" << rule.path.string() <<
'\n';
134 output <<
"denied_executable=" << rule.path.string() <<
'\n';
136 output << (rule.recursive ?
"protected_recursive=" :
"protected_path=")
137 << rule.path.string() <<
'\n';
139 output << (rule.recursive ?
"ignored_recursive=" :
"ignored_path=")
140 << rule.path.string() <<
'\n';
144 ::chmod(temporary.c_str(), 0644);
145 if (::rename(temporary.c_str(), path.c_str()) != 0)
146 std::filesystem::remove(temporary);
164 std::cerr <<
"RootGuard policy: mode=" <<
toString(policy.
mode)
170 <<
" block_user_home=" << (policy.
blockUserHome ?
"true" :
"false")
184int main(
const int argc,
char* argv[])
193 if (options.checkOnly)
202 eventSink.
add(consoleSink);
204 std::unique_ptr<JsonEventSink> jsonSink;
206 if (
const auto parent = policy.
eventLog.parent_path(); !parent.empty())
207 std::filesystem::create_directories(parent);
208 jsonSink = std::make_unique<JsonEventSink>(policy.
eventLog);
209 eventSink.
add(*jsonSink);
212 const auto automaticServiceBlockingEnabled = [](
const Policy& activePolicy) {
213 return activePolicy.autoBlockSystemServices &&
218 eventSink, automaticServiceBlockingEnabled(policy));
224 std::cerr <<
"BastionGuard RootGuard avviato: trusted-app caricati="
229 for (
const auto& warning : report.
warnings)
230 std::cerr <<
"RootGuard policy warning: " << warning <<
'\n';
233 const int result = engine.
pollOnce(250);
235 throw std::runtime_error(
"errore ring buffer: " + std::to_string(result));
241 bool auditEntered =
false;
253 const auto previousEventLog = policy.
eventLog;
254 const auto reloadedReport = engine.
reloadPolicy(reloaded);
255 policy = std::move(reloaded);
257 automaticServiceBlockingEnabled(policy));
260 std::cerr <<
"RootGuard policy ricaricata: trusted-app="
261 << reloadedReport.trustedApplicationsLoaded
263 << reloadedReport.trustedLoaded <<
" denied="
264 << reloadedReport.deniedLoaded <<
" protected="
265 << reloadedReport.protectedLoaded <<
'\n';
266 if (policy.
eventLog != previousEventLog) {
267 std::cerr <<
"nota: una modifica di event_log richiede riavvio\n";
269 }
catch (
const std::exception& error) {
270 std::cerr <<
"ricaricamento policy fallito; "
272 ?
"motore lasciato in audit: "
273 :
"impossibile garantire il passaggio in audit: ")
274 << error.what() <<
'\n';
278 std::filesystem::remove(
"/run/bastionguard-rootguard.status");
279 }
catch (
const std::exception& error) {
280 std::filesystem::remove(
"/run/bastionguard-rootguard.status");
281 std::cerr <<
"RootGuard: " << error.what() <<
'\n';
int main(int argc, char *argv[])
void setAutoBlockSystemServices(bool enabled) noexcept
void add(IEventSink &sink)
static Policy loadFromText(const std::string &content, const std::filesystem::path &source="<memory>")
static std::string read(const std::filesystem::path &path, bool requireSecureOwnership)
PolicyApplyReport reloadPolicy(const Policy &policy)
int pollOnce(int timeoutMilliseconds) noexcept
void runIntegrityCheckIfDue() noexcept
PolicyApplyReport start(const Policy &policy)
Options parseOptions(const int argc, char *argv[])
void handleStopSignal(int) noexcept
bastionguard::rootguard::Policy auditRuntimePolicy(bastionguard::rootguard::Policy policy)
volatile std::sig_atomic_t gStopRequested
void printPolicySummary(const bastionguard::rootguard::Policy &policy)
void printUsage(const char *executable)
void writeRuntimePolicyView(const bastionguard::rootguard::Policy &policy)
void writeRuntimeStatus(const bastionguard::rootguard::Policy &policy)
void handleReloadSignal(int) noexcept
volatile std::sig_atomic_t gReloadRequested
bastionguard::rootguard::Policy loadPolicy(const Options &options)
const char * toString(Mode mode) noexcept
std::filesystem::path policyPath
std::optional< bastionguard::rootguard::Mode > modeOverride
std::size_t protectedLoaded
std::size_t trustedApplicationsLoaded
std::vector< std::string > warnings
std::size_t trustedLoaded
bool detectGlobalMetadataBursts
bool autoBlockSystemServices
std::vector< PolicyPath > trustedExecutables
Action credentialAnomalyAction
std::vector< PolicyPath > deniedExecutables
std::uint32_t metadataBurstThreshold
std::vector< PolicyPath > ignoredPaths
std::uint32_t globalMetadataSampleLimit
std::filesystem::path eventLog
std::uint32_t metadataBurstCooldownMs
Action globalMetadataAction
bool monitorGlobalPrivilegeMetadata
std::vector< PolicyPath > protectedPaths
std::uint32_t metadataBurstWindowMs
std::vector< PolicyPath > trustedApplications