1. Overview
The RootGuardPage.cpp implementation builds BastionGuard’s complete RootGuard GTKmm interface. It transforms asynchronous snapshots into service status, incident cards, event history, rule editors, and carefully rate-limited alerts while ensuring recovery actions are offered only when the event contains sufficient protected identity and path information.
The file integrates the following components, APIs, or runtime concepts:
- RootGuardClient – one-second refreshes, service actions, policy edits, restore, and quarantine
- RootGuardEvent – event classification, formatting, fingerprinting, and service-path detection
- GTKmm / Glib – stacks, switchers, popovers, dialogs, idle callbacks, timers, and i18n
- rootguard_shared.h – reason flags used for burst and baseline-state presentation
2. Page Layout and Navigation
The page starts with a RootGuard header and four status tiles: Service, Mode, Init system, and PID. A top-level Gtk::StackSwitcher selects four pages:
- Overview – immediate protection, system/home scope, and daemon lifecycle controls
- Incidents – unresolved observations and actionable incidents
- Events – recent formatted event history with optional trusted-event filtering
- Application rules – nested editors for trusted applications, privilege-trusted executables, and blocked executables
3. Immediate Protection and Service Controls
The Overview page explains that immediate blocking applies to protected system metadata while user-home enforcement is normally delegated to Anti-Ransomware. The protection switch is disabled while a change is in progress and delegates the state change to Client::set_immediate_protection().
Start, stop, policy reload, restart, and manual refresh buttons update the status message immediately, then enqueue the corresponding asynchronous client action.
4. Automatic Refresh
A Glib::signal_timeout().connect_seconds() callback refreshes RootGuard every 1 second. The client coalesces duplicate pending refresh requests, so this high-frequency UI timer does not create an unbounded worker backlog.
5. Path Provenance and Recovery Eligibility
Helper functions translate path-resolution provenance into explicit UI text: protected baseline, process FD, process CWD, kernel exact, LSM exact, or basename-only.
Restore is disabled when there is no protected rule, no exact path, a replaced baseline identity, or a missing protected object. Quarantine is likewise limited to protected incidents with an exact existing path. Basename-only records receive a transparency notice instead of guessed actions.
6. Incident Rendering
render_incidents() traverses recent events newest-first, tracks closure records such as file-restored, file-quarantined, and integrity-restored, suppresses duplicates/dismissed incidents, and displays at most 60 unresolved items.
Each row shows a severity-sensitive title, detailed process/path/identity metadata, recovery guidance, and only the actions valid for that exact event. Audit observations never expose Restore or Quarantine because RootGuard did not block or alter the original operation.
7. Event History
render_events() writes up to 150 newest records into a monospaced Gtk::TextView via format_event(). Trusted events are displayed by default but can be hidden locally without waiting for a new daemon snapshot.
8. Application Rule Editors
Each editor validates that entered rules are absolute paths and suppresses duplicates. Collected values are sorted and deduplicated before saving.
The “Add installed desktop/browser defaults” action probes a curated list of common GNOME, KDE, XFCE, Cinnamon, MATE, Firefox, Chromium, Chrome, Brave, and Vivaldi executables; only installed regular executable files are added, and canonicalized paths are preferred.
The save operation prevents a path from being both trusted and denied, marks the UI as saving, and delegates validation/persistence/restart to the client and privileged action helper.
9. Snapshot Synchronization
on_snapshot() updates service status and action sensitivity, mirrors effective protection into the switch without recursively triggering a user action, reconciles rule-save completion, refreshes rule lists when safe, and chooses an explanatory page status based on running/audit/enforcement state.
10. Alert Selection and Noise Control
Only actionable incidents enter popup consideration. The initial historical snapshot never generates popups. Event fingerprints and per-path keys prevent duplicates, while service-block failures can bypass path deduplication so containment failure remains visible.
The page never builds a popup backlog: protected-rule incidents and service events receive priority. Global metadata bursts are much quieter and are limited to one popup every 15 minutes; complete history still remains in Incidents and Events.
11. Alert Window and Incident Response
The alert window presents the exact affected object, path-resolution method, target and actor identities, process hierarchy, EUID/mode/ownership transitions, verdict, reason flags, and burst size when applicable.
Service-definition incidents receive dedicated containment messaging. When valid, Restore calls the client to restore protected metadata and unmask a service; Quarantine requests removal from the original path into RootGuard quarantine. Closing or acknowledging an alert records its fingerprint as dismissed.
12. Destruction and Deferred Cleanup
The destructor disables the atomic lifetime flag, disconnects client/timer signals, clears queued alerts, and hides/resets the current popup. Deferred Glib::signal_idle() cleanup checks the shared lifetime flag before touching page state.
13. Runtime and Security Considerations
- No unsafe path guessing: path-based recovery is disabled unless the event carries an absolute path.
- Audit-mode integrity: audit observations are acknowledgement-only; the UI does not pretend an operation was blocked.
- Popup rate limiting: global metadata bursts cannot produce a notification storm.
- Rule conflict prevention: the UI rejects executables present in both trusted and denied sets before invoking the helper.
- Asynchronous UI: service and privileged operations are delegated to the client worker instead of blocking GTK.
