#!/bin/sh
# SecuremeVPN NetworkManager helper. Installed to
# /usr/lib/securemevpn/securemevpn-nm-helper and run as root by the app via
# pkexec (polkit action com.securemevpn.nm-helper: no password for the active
# local desktop user). It only ever touches the one NetworkManager connection
# it is named after.
#
#   securemevpn-nm-helper up <name>    < wg-quick config on stdin
#   securemevpn-nm-helper down <name>
set -eu
PATH=/usr/sbin:/usr/bin:/sbin:/bin
export PATH

cmd="${1:-}"
name="${2:-}"
case "$name" in
  '' | *[!A-Za-z0-9_-]*) echo "invalid connection name" >&2; exit 2 ;;
esac
if [ "${#name}" -gt 15 ]; then echo "invalid connection name" >&2; exit 2; fi
if ! command -v nmcli >/dev/null 2>&1; then
  echo "NetworkManager (nmcli) is required" >&2
  exit 3
fi

case "$cmd" in
  up)
    dir=$(mktemp -d /run/securemevpn.XXXXXX)
    chmod 700 "$dir"
    trap 'rm -rf "$dir"' EXIT
    conf="$dir/$name.conf"
    # Keep plain WireGuard keys only. Anything else (PreUp, PostUp, Table,
    # SaveConfig, ...) is refused: this runs as root.
    head -c 16384 | tr -d '\r' | awk '
      /^[[:space:]]*$/ || /^[[:space:]]*#/ { next }
      /^[[:space:]]*\[(Interface|Peer)\][[:space:]]*$/ { print; next }
      {
        key = $0; sub(/=.*/, "", key); gsub(/[[:space:]]/, "", key)
        if (key ~ /^(PrivateKey|Address|DNS|MTU|ListenPort|PublicKey|PresharedKey|AllowedIPs|Endpoint|PersistentKeepalive)$/) { print; next }
        bad = 1
      }
      END { if (bad) exit 4 }
    ' >"$conf" || { echo "refused: config has unsupported keys" >&2; exit 4; }
    chmod 600 "$conf"
    nmcli connection delete id "$name" >/dev/null 2>&1 || true
    nmcli connection import type wireguard file "$conf" >/dev/null
    nmcli connection modify id "$name" connection.autoconnect no
    nmcli --wait 20 connection up id "$name" >/dev/null
    ;;
  down)
    nmcli connection down id "$name" >/dev/null 2>&1 || true
    nmcli connection delete id "$name" >/dev/null 2>&1 || true
    ;;
  *)
    echo "usage: $0 up|down <name>" >&2
    exit 2
    ;;
esac
