Secure Browser Launcher (BankGui)

1. Overview

The Secure Browser Launcher (internally implemented as BankGuiWindow and shipped as the standalone application org.BastionGuard.bankgui) is a core component of BastionGuard responsible for launching a hardened “Secure Browser” session for banking and checkout workflows.

This module provides a minimal GTK4 (gtkmm) user interface where the user supplies a target bank URL (or identifier), then spawns an external sandboxed helper process (BastionGuard-bankopener) to open the URL in the Secure Browser environment.

Key goals:

  • Isolation by design: the UI does not embed a browser; it only launches a sandboxed browser session via a dedicated helper
  • Internationalization-ready: locale configuration is loaded early and gettext is initialized before UI execution
  • Consistent UX styling: global styling is injected via load_style() and a custom HeaderBar
  • Lifecycle control: best-effort termination of the sandbox process on close/cancel

2. Application Structure

2.1 Standalone Core Module

The launcher is a standalone binary with its own GTK application ID:

org.BastionGuard.bankgui

The application owns a single main window (BankGuiWindow) and terminates after the launched sandbox session ends, or when the user closes/cancels the dialog.


2.2 UI Composition

The window layout uses a two-column structure:

  • Sidebar – branded panel with an embedded logo loaded from application resources and the “BastionGuard” label
  • Main content area – URL entry field and action buttons

The interface is deliberately simplified:

  • Single Gtk::Entry with placeholder text (https://www.miabanca.it)
  • Cancel button (terminates/cleans up and closes window)
  • Open in Secure Browser button (spawns sandbox process)

3. HeaderBar and Window Controls

The module implements a custom GTK4 header bar via build_headerbar():

  • Title widget centered: BastionGuard Secure Browser
  • Custom right-side buttons using resource icons:
    • icon-minimize.png
    • icon-close.png

Window buttons are wired to:

  • Minimize – hides the window (guarded with GTKMM_CHECK_VERSION(4,10,0))
  • Close – terminates the sandbox process (best effort) and hides the window

4. Secure Browser Launch Workflow

4.1 Input Validation

When the user clicks “Open in Secure Browser”, on_open_clicked() performs a minimal validation:

  • Rejects empty input
  • Displays a warning dialog using Gtk::MessageDialog

This module does not perform full URL parsing; the helper binary is responsible for handling canonicalization, allowlisting, and sandbox policy enforcement.


4.2 Subprocess Execution

On valid input, the launcher spawns the external helper:

BastionGuard-bankopener <url>

Process execution is handled via Gio::Subprocess:

  • The window is disabled via set_sensitive(false) during launch
  • The subprocess is created with Gio::Subprocess::Flags::NONE
  • Completion is handled asynchronously using wait_check_async()

When the subprocess terminates, the callback on_sandbox_finished() hides the launcher window.


5. Sandbox Termination Strategy

5.1 Close / Cancel Behavior

The sandbox lifecycle is managed via terminate_sandbox() and is invoked on:

  • Cancel button click
  • Close button click
  • Window close request (on_close_request())

5.2 Best-effort PID Lookup and SIGTERM

Because the helper process is launched indirectly and may spawn additional processes, termination uses a best-effort approach:

  1. Constructs a lookup string matching the launch command: pgrep -f "BastionGuard-bankopener <url>"
  2. Executes the lookup via popen()
  3. Reads the PID string (first match)
  4. Sends SIGTERM to the resolved PID

This approach prioritizes usability and cleanup but relies on process command-line matching; the helper should be designed to manage its own process tree and ensure sandbox termination is complete.


6. Localization and Language Configuration

6.1 Early Locale Injection (lang.conf)

Before initializing setlocale() and gettext, the module attempts to load user language overrides from:

~/.config/BastionGuard/lang.conf

The loader load_lang_conf():

  • Parses key/value pairs in the form KEY=VALUE
  • Ignores empty lines and comment lines starting with #
  • Applies entries via setenv(key, val, 1) (overwrite enabled)

Typical keys include LANG, LC_ALL, and LANGUAGE (depending on upstream configuration policy).


6.2 gettext Initialization

Localization is initialized after environment injection:

  • std::setlocale(LC_ALL, "")
  • bindtextdomain("BastionGuard", LOCALEDIR)
  • bind_textdomain_codeset("BastionGuard", "UTF-8")
  • textdomain("BastionGuard")

The module logs whether lang.conf was applied or if the system locale is used. This ensures that _() calls are safe and consistent before GTK initialization.


7. Styling and Resource Integration

The module loads a shared UI theme via:

load_style();

Brand assets are retrieved through the resource() helper to support relocatable installation layouts:

  • logo-sidebar.png
  • icon-minimize.png
  • icon-close.png

If assets cannot be loaded, failures are logged to stderr and the UI continues without hard failure.


8. Runtime and Security Considerations

  • Privilege model: the launcher itself operates without elevated privileges.
  • Trust boundary: URL validation and sandbox enforcement are intentionally delegated to BastionGuard-bankopener.
  • Process management: subprocess completion is handled asynchronously; termination uses best-effort PID discovery via pgrep -f.
  • UI responsiveness: the window is disabled during launch to avoid repeated spawns.
  • Localization correctness: language overrides are applied before gettext initialization to prevent mixed-locale UI output.
  • Operational robustness: missing icons or logo resources do not crash the application; errors are logged and execution continues.

In summary, this module acts as the core entry point for the Secure Browser user experience, providing a clean and localized launcher UI while delegating sandbox browsing enforcement to a dedicated helper process.