Update Module (UpdatePage)

1. Overview

The Update module provides an interface for maintaining BastionGuard’s antivirus signatures and third-party detection assets. It supports:

  • Manual ClamAV update via freshclam (executed with elevated privileges)
  • Freshclam system service management (clamav-freshclam.service)
  • Additional signature sources configured by the user (downloaded via curl)
  • SaneSecurity database updates (mirror sync using rsync, then selective install into /var/lib/clamav)
  • Optional automated SaneSecurity updates through a systemd timer (bastionguard-sanesecurity.timer)

The UI is implemented as a GTKmm (GTK4) page and is designed to remain responsive by delegating update execution to background threads while marshaling UI output updates back onto the GTK main loop.


2. User Interface Structure

2.1 Update Output Console

The module provides a log console based on:

  • Gtk::TextView outputView in monospace mode
  • Gtk::TextBuffer buffer as the backing store

The console is placed inside a Gtk::ScrolledWindow with expandable behavior, allowing long update logs to be inspected easily.


2.2 Manual Update Button

The main action is exposed through:

  • updateButton labeled Aggiorna firme (freshclam)

When pressed, it invokes onUpdateClicked(), disables itself for the duration of the update, and prints structured progress messages to the output console.


2.3 Freshclam Service Switch

The module includes management for the automatic ClamAV updater service:

  • serviceSwitch – a toggle bound to the status of clamav-freshclam.service

Initial state is determined by:

systemctl is-active clamav-freshclam.service

When toggled, the module applies the change via:

pkexec systemctl enable --now clamav-freshclam.service
pkexec systemctl disable --now clamav-freshclam.service

2.4 SaneSecurity Auto-Update Switch (Timer)

The module exposes optional automation of SaneSecurity updates through a systemd timer:

  • saneAutoSwitch – enables/disables bastionguard-sanesecurity.timer

Initial state is read using:

systemctl is-enabled bastionguard-sanesecurity.timer

When toggled, the timer is applied using:

pkexec systemctl enable --now bastionguard-sanesecurity.timer
pkexec systemctl disable --now bastionguard-sanesecurity.timer

2.5 Additional Update Sources

The module allows the user to define external signature sources beyond the default ClamAV update channels. The UI provides:

  • addSourceButton – adds a new source entry section
  • saveSourcesButton – persists the configured sources to user configuration storage
  • sourcesBox – a vertical container holding the source sections

Each source is presented as a collapsible accordion-like section with:

  • Source name entry
  • Source URL entry
  • Authentication requirement toggle
  • Username entry
  • Password entry (stored securely using libsecret)
  • Buttons for Test connection, Save source, and Delete source

3. Configuration and Secret Storage

3.1 Sources Configuration File

Additional sources are persisted in the user configuration directory:

~/.config/BastionGuard/sources.conf

Each source is serialized on a single line using a pipe delimiter:

  • name | url | requires_auth (0/1) | username

The module loads this configuration at startup via loadSources() and reconstructs the corresponding UI rows by calling createSourceRow().


3.2 Password Storage with libsecret

When authentication is enabled for a source, the password is stored and retrieved via libsecret using a dedicated schema:

  • Schema name: org.BastionGuard.source
  • Attribute key: secret_key

Passwords are stored using:

secret_password_store_sync(...)

and retrieved using:

secret_password_lookup_sync(...)

The lookup key format is:

BastionGuard:<source_name>

4. Threading and Workflow

4.1 Manual Update Execution

The manual update path is executed by onUpdateClicked() inside a background thread to avoid blocking the UI. The sequence is:

  1. Log start message and disable updateButton
  2. Stop the automatic service: pkexec systemctl stop clamav-freshclam.service
  3. Run a manual update: pkexec freshclam
  4. Restart the automatic service: pkexec systemctl start clamav-freshclam.service
  5. Download signatures from additional configured sources (updateFromExtraSources())
  6. Run SaneSecurity update workflow (updateSaneSecurity())
  7. Reload the ClamAV daemon configuration: pkexec systemctl reload clamav-daemon.service
  8. Re-enable updateButton and log completion

Because GTK widgets must be updated only from the main loop, all log writes use a main-thread dispatch pattern:

Glib::signal_idle().connect_once(...)

The module also provides logSafe() as a wrapper for this behavior.


4.2 Additional Sources Download Workflow

Extra sources are downloaded using curl into the ClamAV database directory:

/var/lib/clamav

Execution flow:

  • The module extracts configured sources from the UI
  • A worker thread iterates each source and runs:
    • Unauthenticated: curl -f -O --output-dir /var/lib/clamav <url>
    • Authenticated: curl -f -u "<user>:<password>" -O --output-dir /var/lib/clamav <url>

Connection tests use an HTTP HEAD request and print the HTTP response code, allowing the user to validate credentials and connectivity before relying on the source for production updates.


4.3 SaneSecurity Update Workflow

SaneSecurity updates are performed via a safe mirror sync model. The workflow uses a temporary directory:

/var/lib/clamav/sanesecurity.tmp

Steps:

  1. Create a clean temporary directory (elevated): pkexec sh -c 'rm -rf /var/lib/clamav/sanesecurity.tmp && mkdir -p /var/lib/clamav/sanesecurity.tmp'
  2. Sync the remote mirror into the temp directory: pkexec rsync -av --delete rsync://rsync.sanesecurity.net/sanesecurity /var/lib/clamav/sanesecurity.tmp/
  3. Install only relevant file types into /var/lib/clamav (selective copy), including:
    • *.ndb, *.hdb, *.ldb
    • *.yar, *.yara
    • *.ign2, *.txt
  4. Remove the temporary directory

This approach minimizes interference with official ClamAV databases while still enabling enhanced coverage through supplementary signatures.


5. Runtime and Security Considerations

  • Privilege model: system modifications are executed using pkexec to request administrative authorization only when required.
  • Non-blocking UI: update operations run in background threads; output is marshaled back to GTK safely via Glib::signal_idle().
  • Secret handling: source passwords are stored in the system keyring using libsecret, not in plaintext configuration files.
  • Operational safety: SaneSecurity updates are staged in a temporary directory before selective installation into /var/lib/clamav.
  • Service interoperability: after updating signatures, the module attempts to reload clamav-daemon.service so the daemon can pick up changes without requiring a full restart.