#!/usr/bin/env bash set -euo pipefail # mvlog-authorized-notify.sh - forced-command wrapper for a web-server SSH key. # Install in worker user's authorized_keys as: # command="/home/hbrain/source/movmaker/hooks/mvlog-authorized-notify.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAA... comment # # The wrapper only allows a very small set of commands originating from the web server: # python3 /home/hbrain/source/movmaker/mvlog_worker.py --notify-job [--host ] [--remote-root ] # It validates the job token (simple filename-safe characters) and restricts remote-root to the configured path. WORKER_MVLOG_PATH="/home/hbrain/source/movmaker/mvlog_worker.py" ALLOWED_REMOTE_ROOT="/var/www/html/mvlog" cmd="${SSH_ORIGINAL_COMMAND:-}" # Expected parts regex; allow quoted or unquoted simple tokens for job/host/root escaped_path=$(printf '%s' "$WORKER_MVLOG_PATH" | sed 's/[\/&]/\\&/g') regex="^python3[[:space:]]+${escaped_path}[[:space:]]+--notify-job[[:space:]]+'?([A-Za-z0-9._-]+)'?([[:space:]]+--host[[:space:]]+'?([^'[:space:]]+)'?)?([[:space:]]+--remote-root[[:space:]]+'?([^'[:space:]]+)'?)?.*$" if [[ $cmd =~ $regex ]]; then job="${BASH_REMATCH[1]}" host="${BASH_REMATCH[3]:-}" remote_root="${BASH_REMATCH[5]:-}" # Validate simple job token again if ! [[ $job =~ ^[A-Za-z0-9._-]+$ ]]; then echo "invalid job token" >&2 exit 1 fi if [ -n "$remote_root" ] && [ "$remote_root" != "$ALLOWED_REMOTE_ROOT" ]; then echo "remote_root not allowed" >&2 exit 1 fi # Run the notify command with validated pieces. If host omitted, use local hostname. if [ -n "$host" ]; then exec python3 "$WORKER_MVLOG_PATH" --notify-job "$job" --host "$host" --remote-root "$ALLOWED_REMOTE_ROOT" else exec python3 "$WORKER_MVLOG_PATH" --notify-job "$job" --host "$(hostname -f)" --remote-root "$ALLOWED_REMOTE_ROOT" fi fi echo "Unauthorized SSH_ORIGINAL_COMMAND" >&2 exit 2