#!/usr/bin/env bash # ssh-touch-notify: an SSH_ASKPASS program for ssh without a terminal. # # For a security-key touch, ssh runs askpass with SSH_ASKPASS_PROMPT=none # and kills it once the touch is done: show a desktop notification for that # long. Real prompts (a PIN, a passphrase, a host-key question) go to a # graphical askpass if there is one (DEVKIT_SSH_ASKPASS, or a known one); # otherwise fail, so ssh fails instead of hanging. set -euo pipefail prompt="${1:-}" if [ "${SSH_ASKPASS_PROMPT:-}" != none ]; then for p in "${DEVKIT_SSH_ASKPASS:-}" ksshaskpass ssh-askpass /usr/lib/ssh/ssh-askpass \ /usr/libexec/openssh/ssh-askpass /usr/libexec/ssh-askpass; do [ -n "$p" ] || continue p="$(command -v "$p" || true)" [ -n "$p" ] && [ "$p" != "$(command -v "$0" || echo "$0")" ] && exec "$p" "$@" done echo "ssh-touch-notify: no askpass to answer \"$prompt\"; run it in a terminal (or set DEVKIT_SSH_ASKPASS)" >&2 exit 1 fi title="SSH: touch your security key" body="${DEVKIT_SSH_HOST:+$DEVKIT_SSH_HOST: }$prompt" id="" sleeper="" done_() { [ -z "$sleeper" ] || kill "$sleeper" 2>/dev/null || true if [ -n "$id" ] && command -v gdbus >/dev/null; then gdbus call --session --dest org.freedesktop.Notifications \ --object-path /org/freedesktop/Notifications \ --method org.freedesktop.Notifications.CloseNotification "$id" >/dev/null 2>&1 || true fi exit 0 } trap done_ TERM INT HUP if command -v notify-send >/dev/null; then id="$(notify-send -p -u critical -a ssh -i security-high "$title" "$body" 2>/dev/null || true)" elif command -v osascript >/dev/null; then osascript -e 'on run argv' -e 'display notification (item 2 of argv) with title (item 1 of argv)' \ -e 'end run' "$title" "$body" >/dev/null 2>&1 || true fi # ssh kills us when the touch is done; give up after the key's own timeout. sleep 60 & sleeper=$! wait "$sleeper" || true done_