BastionGuard Ransomware Alert Service (D-Bus + GTK Modal UI)

1. Overview

This module implements a dedicated ransomware alert service for BastionGuard. It provides a session D-Bus endpoint that other components can call to display an infection alert UI to the user. The service is composed of:

  • AlertWindow – a GTK4 (gtkmm) modal dialog that presents detection details and response actions
  • AlertApp – a D-Bus-registered GTK application that receives alert requests, queues them, and shows dialogs sequentially

The design ensures that multiple detections do not spawn multiple overlapping dialogs. Instead, detections are queued and presented one at a time, with an optional “pending” counter shown to the user.


2. D-Bus Interface

2.1 Interface Definition

The service exposes a session-bus interface:

org.BastionGuard.Ransomware.Alert

with a single method:

ShowAlert(string file, string family)

Introspection is provided inline via a static XML definition:

  • Object path: /org/BastionGuard/ransomware/alert
  • Interface: org.BastionGuard.Ransomware.Alert
  • Method: ShowAlert (two input strings)

2.2 Bus Name Acquisition

After registering the object, the service requests a well-known name from the session bus:

org.BastionGuard.Ransomware.Alert

The request is performed via a synchronous call to:

  • Service: org.freedesktop.DBus
  • Method: RequestName

This step ensures stable discovery for clients that need to invoke alerts reliably.


3. Application Architecture

3.1 AlertApp (Service Container)

AlertApp owns the GTK application instance and the runtime state required to process incoming requests:

  • Glib::RefPtr<Gtk::Application> app – application container (ID: org.BastionGuard.ransomware.alert)
  • std::queue<pair<string,string>> queue – FIFO queue of pending (file, family) alerts
  • AlertWindow* current_window – pointer to the currently displayed dialog (if any)

The constructor calls app->hold() to prevent the GTK application from exiting when no window is currently open. This is critical because D-Bus requests may arrive at any time during the session.


3.2 Method Dispatch: on_method_call()

Incoming D-Bus requests are handled via a Gio::DBus::InterfaceVTable bound to:

AlertApp::on_method_call(...)

For ShowAlert:

  1. Extract file and family from the input variant container
  2. Push them into the internal FIFO queue
  3. Return immediately to the caller (non-blocking UX)
  4. If no alert window is currently active, call show_next()

This yields a resilient service behavior where alert submission is fast and UI presentation is serialized.


4. Alert Queue Management

4.1 show_next()

The show_next() method enforces “single dialog at a time” semantics:

  • If a window is open (current_window != nullptr) → no action
  • If the queue is empty → no action
  • Otherwise:
    1. Pop the next (file, family) item
    2. Create a new AlertWindow with pending = queue.size()
    3. Add the window to the Gtk::Application
    4. Wire signals for Ignore-All and Close
    5. Present the dialog

4.2 Ignore-All Semantics

If the user selects “Ignore All” in the dialog, signal_ignore_all is emitted and handled by clearing the queue via swap with an empty queue:

  • Prevents alert storms
  • Ensures the current window closes without immediately showing the next queued alert

4.3 Close Semantics and Next Alert

When the current window closes, the close-request handler:

  • Sets current_window back to nullptr
  • Calls show_next() to display the next queued detection (if any)

This provides a deterministic FIFO alert workflow.


5. AlertWindow UI (Modal Infection Dialog)

5.1 Purpose

AlertWindow is a GTK4 modal dialog that provides immediate response actions to a detected infection. It is similar in structure to the real-time ransomware alert dialog but is packaged here as a standalone class inside the service implementation.


5.2 Layout and Styling

  • Window title intentionally empty (set_title(""))
  • Default size: 620 × 240
  • Non-resizable
  • Modal
  • CSS classes: app-dialog, main-window, app-window
  • Loads BastionGuard.css via resource() and installs provider at application priority

5.3 Header Bar

A custom headerbar (custom-headerbar) is used with a close button icon loaded from:

resource("icon-close.png")

Pressing the close button triggers close() (no remediation action is applied).


5.4 Content and Pending Indicator

The dialog displays:

  • Localized title: “infection detected”
  • Message string containing family and file
  • Status icon:
    • true.png for OK / Clean / None
    • false.png otherwise
  • Optional pending label: “%1 others pending…” when pending > 0

Icons are loaded from a fixed system directory:

/usr/share/BastionGuard/data/icons/

5.5 Response Actions

The dialog exposes three user actions:

  • Quarantine (styled as btn-danger) – calls Quarantine::move(filePath)
  • Ignore (styled as btn-success) – closes the window
  • Ignore All (styled as btn-warning) – emits signal_ignore_all and closes

Quarantine results are logged to stdout/stderr for operational traceability.


6. Localization Bootstrap (lang.conf + gettext)

Before GTK initialization, the module loads language environment overrides from:

~/.config/BastionGuard/lang.conf

The loader:

  • Parses key/value pairs of the form KEY=VALUE
  • Ignores blank lines and comments
  • Sets environment variables via setenv() before locale initialization

After loading:

  • setlocale(LC_ALL, "") applies the selected locale
  • gettext is initialized with:
    • bindtextdomain("BastionGuard", LOCALEDIR)
    • bind_textdomain_codeset("BastionGuard", "UTF-8")
    • textdomain("BastionGuard")

This guarantees that all UI strings and logs emitted via _() use the configured locale.


7. Security and Operational Considerations

  • Separation of concerns: a dedicated alert service prevents the main scanner/daemon from needing complex UI logic.
  • Session bus scope: alerts are exposed on the session bus; only session-local clients can invoke them.
  • Alert storm mitigation: FIFO queueing and “Ignore All” prevent UI spam and reduce user fatigue.
  • Blocking UX: modality is appropriate for high-severity incidents, but it can interrupt workflows; the queue design minimizes overlap while preserving urgency.
  • Resource and asset assumptions: icons and CSS must be present at runtime; missing assets degrade UX but should not crash the service.
  • Quarantine permissions: Quarantine::move() depends on filesystem permissions and quarantine policy; failures are logged and surfaced only via logs in this module.

In summary, the BastionGuard Ransomware Alert Service is a D-Bus-driven GTK application that receives infection notifications, serializes them through a queue, and presents a consistent modal response UI to the user, including direct quarantine integration and robust localization bootstrap support.