#!/usr/bin/env bash set -euo pipefail ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" MANAGER="$ROOT/data/init/common/bastionguard-service" # No root privileges and no live systemd required: invalid units must be # rejected before the backend invokes systemctl/rc-service. for unit in ssh.service NetworkManager.service systemd-logind.service BastionGuard-evil.service \ "nginx.service;touch /tmp/bastionguard-bad"; do set +e msg="$(sh "$MANAGER" --system restart "$unit" 2>&1)" rc=$? set -e [[ $rc -eq 64 ]] || { echo "Unexpected system unit rejection status $rc for $unit" >&2; exit 1; } done # A valid unit must pass the permission check, even when service management # cannot be executed in the container (non-systemd rootfs). set +e sh "$MANAGER" --system reload dnsmasq.service >/dev/null 2>&1 rc=$? set -e [[ $rc -ne 64 ]] || { echo 'dnsmasq rejected unexpectedly' >&2; exit 1; } # Guard user-mode command rejects invalid CLI options. set +e sh "$MANAGER" --user restart --bad-option >/dev/null 2>&1 rc=$? set -e [[ $rc -ne 0 ]] || { echo 'user unit accepted invalid options' >&2; exit 1; } # Mock an ordinary desktop session: its restart must only address user units. FAKE_DIR="$(mktemp -d /tmp/bastionguard-systemctl-test-XXXXXX)" trap 'rm -rf "$FAKE_DIR"' EXIT cat > "$FAKE_DIR/systemctl" <<'SH' #!/bin/sh printf '%s\n' "$*" >> "$BG_SYSTEMCTL_LOG" exit 0 SH chmod +x "$FAKE_DIR/systemctl" BG_SYSTEMCTL_LOG="$FAKE_DIR/calls" PATH="$FAKE_DIR:$PATH" \ bash "$ROOT/data/scripts/BastionGuard-restart-user-services.sh" --user resume [[ -s "$FAKE_DIR/calls" ]] || { echo 'user-mode restart produced no calls' >&2; exit 1; } if grep -Ev '^--user ' "$FAKE_DIR/calls" >/dev/null; then echo 'user-mode restart invoked a system-level systemctl command' >&2; exit 1 fi if grep -Eq 'phishing-scanner|usbd|ransomware-realtime\.service|user-session-watch' "$FAKE_DIR/calls"; then echo 'user-mode restart touched a system or self-watcher unit' >&2; exit 1 fi if grep -RE '(^|[^A-Za-z0-9_])popen[[:space:]]*\(' "$ROOT/src" --include='*.cpp' --include='*.hpp'; then echo 'unsafe popen call remains in C++ source' >&2; exit 1 fi # Sanity-check unit files without treating missing installed binaries as a # packaging syntax error. if command -v systemd-analyze >/dev/null 2>&1; then output="$(systemd-analyze verify "$ROOT/data/service/BastionGuard-ransomware-scanner.service" \ "$ROOT/data/service/BastionGuard-phishing-scanner.service" 2>&1 || true)" if grep -Eqi 'has a bad unit file setting|Unknown lvalue|Missing .* section|Unbalanced quoting' <<<"$output"; then echo "$output" >&2; exit 1 fi fi echo 'service manager systemd allowlist and unit syntax: OK'