106 lines
3.1 KiB
Bash
106 lines
3.1 KiB
Bash
#!/usr/bin/env bash
|
|
# BastionGuard user-session watcher
|
|
# Monitors suspend/resume and lock/unlock events, then restarts BastionGuard user services.
|
|
|
|
set -u
|
|
|
|
RESTART_SCRIPT="${BG_RESTART_SCRIPT:-/usr/share/BastionGuard/data/scripts/BastionGuard-restart-user-services.sh}"
|
|
DEBOUNCE_SECONDS="${BG_RESTART_DEBOUNCE_SECONDS:-8}"
|
|
STAMP_FILE="${XDG_RUNTIME_DIR:-/tmp}/BastionGuard-user-session-watch.last"
|
|
|
|
log_msg() {
|
|
local msg="$1"
|
|
if command -v systemd-cat >/dev/null 2>&1; then
|
|
printf '%s\n' "$msg" | systemd-cat -t BastionGuard-user-session-watch -p info
|
|
else
|
|
printf '%s\n' "BastionGuard-user-session-watch: $msg" >&2
|
|
fi
|
|
}
|
|
|
|
restart_user_services() {
|
|
local reason="$1"
|
|
local now last
|
|
|
|
now="$(date +%s)"
|
|
last="0"
|
|
if [ -r "$STAMP_FILE" ]; then
|
|
last="$(cat "$STAMP_FILE" 2>/dev/null || printf '0')"
|
|
fi
|
|
|
|
case "$last" in
|
|
''|*[!0-9]*) last="0" ;;
|
|
esac
|
|
|
|
if [ $((now - last)) -lt "$DEBOUNCE_SECONDS" ]; then
|
|
log_msg "skip restart for '$reason' because debounce is active"
|
|
return 0
|
|
fi
|
|
|
|
printf '%s\n' "$now" > "$STAMP_FILE" 2>/dev/null || true
|
|
|
|
if [ ! -x "$RESTART_SCRIPT" ]; then
|
|
log_msg "restart script missing or not executable: $RESTART_SCRIPT"
|
|
return 0
|
|
fi
|
|
|
|
log_msg "restarting BastionGuard user services after: $reason"
|
|
"$RESTART_SCRIPT" --user "$reason" || log_msg "restart script returned a non-zero status for: $reason"
|
|
}
|
|
|
|
monitor_login1_sleep() {
|
|
dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Manager',member='PrepareForSleep'" 2>/dev/null |
|
|
while IFS= read -r line; do
|
|
case "$line" in
|
|
*"boolean false"*) restart_user_services "resume" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
monitor_login1_lock() {
|
|
dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Session'" 2>/dev/null |
|
|
while IFS= read -r line; do
|
|
case "$line" in
|
|
*"member=Lock"*) restart_user_services "session-lock" ;;
|
|
*"member=Unlock"*) restart_user_services "session-unlock" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
monitor_freedesktop_screensaver() {
|
|
dbus-monitor --session "type='signal',interface='org.freedesktop.ScreenSaver'" 2>/dev/null |
|
|
while IFS= read -r line; do
|
|
case "$line" in
|
|
*"member=ActiveChanged"*) restart_user_services "screensaver-active-changed" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
monitor_gnome_screensaver() {
|
|
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" 2>/dev/null |
|
|
while IFS= read -r line; do
|
|
case "$line" in
|
|
*"member=ActiveChanged"*) restart_user_services "gnome-screensaver-active-changed" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
cleanup() {
|
|
trap - INT TERM EXIT
|
|
jobs -p | xargs -r kill 2>/dev/null || true
|
|
}
|
|
trap cleanup INT TERM EXIT
|
|
|
|
if ! command -v dbus-monitor >/dev/null 2>&1; then
|
|
log_msg "dbus-monitor not found; install package 'dbus' or equivalent"
|
|
while :; do sleep 3600; done
|
|
fi
|
|
|
|
log_msg "watcher started"
|
|
|
|
monitor_login1_sleep &
|
|
monitor_login1_lock &
|
|
monitor_freedesktop_screensaver &
|
|
monitor_gnome_screensaver &
|
|
|
|
# Keep the service alive. If a monitor exits, systemd restarts this watcher.
|
|
wait -n
|