Overview
The Anti-Ransomware module is implemented by the AntiRansomwarePage class. This module provides two complementary capabilities:
- Manual scanning of a selected file or directory using YARA rules (local static detection)
- Real-time event visibility by tailing a dedicated daemon log file and rendering relevant security events in the UI
Threat notifications are propagated via D-Bus using the BastionGuard alert interface, with a local GTK dialog used as a fallback when D-Bus is unavailable.
User Interface Structure
Header
The page uses a security-themed header bar consistent with other protection modules. The header is built using a horizontal Gtk::Box with the CSS class secure-headerbar, containing a centered label with the CSS class secure-header-title.
Displayed title:
Anti-Ransomware
Action Buttons
The module exposes four primary actions (buttons) in a single horizontal toolbar:
btnChooseFile– selects a file target (manual scan)btnChooseFolder– selects a directory target (manual scan)btnScan– executes the manual scan workflowbtnTest– sends a test alert to validate the notification path
Button labels (as defined in code):
📄 Scegli file
📂 Scegli cartella
🧪 Scansiona
🔔 Test notifica
Log Viewer
The module renders an operational log area used for both manual scan output and real-time event lines. It is implemented using:
Gtk::TextBuffer(textBuffer)Gtk::TextView(textView)Gtk::ScrolledWindowwith a minimum height of 250px
The log view is read-only and word-wrapped.
Initialization Sequence
When AntiRansomwarePage is constructed, it performs the following high-level steps:
- Builds the UI layout (header, toolbar, log viewer)
- Registers button signal handlers
- Appends a “ready” line to the log
- Initializes and loads YARA rules via
loadYaraRules() - Starts the real-time log reader thread via
startRealtimeLogReader()
Initial log line:
🔐 Anti-Ransomware pronto.
Manual Scan Workflow (YARA)
Target Selection
The user selects a scan target into selectedPath using standard GTK file chooser dialogs:
AntiRansomwarePage::onChooseFile()usesGtk::FileChooserDialogwith actionOPENAntiRansomwarePage::onChooseFolder()usesGtk::FileChooserDialogwith actionSELECT_FOLDER
On successful selection, the path is logged:
📄 File selezionato: <path>📂 Cartella selezionata: <path>
Scan Dispatch Logic
Manual scanning is started by AntiRansomwarePage::onManualScan(). It validates selectedPath and dispatches based on filesystem type:
- If
selectedPathis a regular file:runYaraOnPath(selectedPath) - If
selectedPathis a directory:scanDirectoryRecursively(selectedPath) - Otherwise: logs an invalid path message
Directory scanning enumerates files recursively using:
std::filesystem::recursive_directory_iterator(root)
YARA Engine Initialization and Rule Loading
The module initializes YARA during rule load:
yr_initialize()
yr_compiler_create(&yaraCompiler)
Rules are loaded from the fixed directory:
/usr/share/BastionGuard/data/yara
All files with extensions .yar or .yara are compiled using:
yr_compiler_add_file(yaraCompiler, f, nullptr, file.path().c_str())
After compilation, the ruleset is produced using:
yr_compiler_get_rules(yaraCompiler, &yaraRules)
If the directory does not exist, the module logs that no rules are available and does not perform YARA scans.
YARA Scan Execution
Each file is scanned using:
yr_rules_scan_file(yaraRules, path.c_str(), 0, yara_callback_gui, this, 0)
The scan logs the file being scanned:
🔍 Scansione: <path>
If YARA returns an error (non ERROR_SUCCESS), the error code is logged.
YARA Match Callback and Alert Triggering
YARA matches for manual scans are delivered via the callback:
static int yara_callback_gui(...)
When a rule matches (CALLBACK_MSG_RULE_MATCHING):
- The rule identifier is extracted from
rule->identifier - If empty, the rule namespace (
rule->ns->name) is used as a fallback identifier - A match line is appended to the GUI log
- An alert is raised using
AntiRansomwarePage::sendAlert(selectedPath, rule_name)
Alerting Mechanism (D-Bus + GUI Fallback)
Alerts are emitted via the session D-Bus interface:
Service: org.BastionGuard.Ransomware.Alert
Path: /org/BastionGuard/ransomware/alert
Interface: org.BastionGuard.Ransomware.Alert
Method: ShowAlert(file, ruleName)
The alert call is constructed as a tuple containing:
file(string path)ruleName(YARA rule identifier or event label)
If D-Bus fails, the module falls back to a modal warning dialog:
Gtk::MessageDialog- Type:
Gtk::MessageType::WARNING - Buttons:
Gtk::ButtonsType::OK
Test Alert Function
The notification pipeline can be validated using the “test alert” button, which invokes:
AntiRansomwarePage::onTestAlert()
sendAlert("/tmp/testfile", "TestRule")
This action does not perform scanning; it exists solely to verify that the D-Bus/GUI alert presentation path is functional.
Real-Time Log Reader (Daemon Visibility)
Purpose
In addition to manual scans, the page provides visibility into events generated by the Anti-Ransomware realtime daemon by tailing a log file and surfacing only relevant lines (match and alert signals).
Log File Source
The log reader tails:
/var/log/BastionGuard/antiransom_inotify.log
Threading Model
The log reader runs in a dedicated background thread started by startRealtimeLogReader(). The thread:
- Opens the logfile
- Seeks to end-of-file (tail behavior)
- Polls for new lines every ~200ms when no new data is available
- Marshals each new log line back to the GTK main loop using
Glib::signal_idle().connect_once()
Important: UI updates are scheduled on the GTK main thread to preserve thread safety.
Lifecycle and Shutdown
The log reader is controlled by logThreadRunning. In the destructor (~AntiRansomwarePage()):
logThreadRunningis set to false- The thread is joined if joinable
- YARA resources are released using
yr_rules_destroy()andyr_compiler_destroy()
Log Line Parser (Real-Time Daemon Events)
Real-time log lines are processed by AntiRansomwarePage::processLogLine(const std::string& line), which intentionally extracts only security-relevant events.
1. Daemon “MATCH” Events
If a line contains the substring:
MATCH →
the parser extracts the rule name from the remainder of the line and logs:
⚠ MATCH realtime: <rule>
2. Daemon “Alert sent” Events
If a line contains:
Alert inviato:
the parser expects the format:
Alert inviato: <file> | <rule>
After trimming whitespace, the UI logs:
🚨 ALERT realtime: <rule> → <file>
All other log lines are ignored.
Design and Security Considerations
- Manual scan uses YARA: local static analysis is performed entirely offline using rules deployed under
/usr/share/BastionGuard/data/yara. - Centralized alert channel: both manual YARA matches and realtime daemon outcomes can be surfaced consistently through the same D-Bus alert interface.
- Thread-safe GUI updates: background log reading never updates GTK widgets directly; all UI writes are marshaled via
Glib::signal_idle(). - Controlled parsing: the realtime log parser intentionally ignores non-critical lines, reducing UI noise and avoiding misleading output.
- Graceful degradation: if D-Bus is not available, alerts fall back to a local warning dialog.
Key Files, Paths, and Interfaces
- YARA rules directory:
/usr/share/BastionGuard/data/yara - Realtime daemon log:
/var/log/BastionGuard/antiransom_inotify.log - D-Bus alert interface:
org.BastionGuard.Ransomware.Alert
/org/BastionGuard/ransomware/alert
org.BastionGuard.Ransomware.Alert
Method: ShowAlert(file, ruleName)