Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
gpg-agent-relay
#!/usr/bin/env bash
# https://gist.github.com/andsens/2ebd7b46c9712ac205267136dc677ac1
GNUPGHOME="$HOME/.gnupg"
PIDFILE="$GNUPGHOME/gpg-agent-relay.pid"
die() {
# shellcheck disable=SC2059
printf "$1\n" >&2
exit 1
}
main() {
checkdeps socat start-stop-daemon lsof timeout
case $1 in
start)
if ! start-stop-daemon --pidfile "$PIDFILE" --background --notify-await --notify-timeout 5 --make-pidfile --exec "$0" --start -- foreground; then
# shellcheck disable=SC2016
die 'Failed to start. Run `gpg-agent-relay foreground` to see output.'
fi
;;
stop)
start-stop-daemon --pidfile "$PIDFILE" --remove-pidfile --stop ;;
status)
start-stop-daemon --pidfile "$PIDFILE" --status
local result=$?
case $result in
0) printf "gpg-agent-relay is running\n" ;;
1 | 3) printf "gpg-agent-relay is not running\n" ;;
4) printf "unable to determine status\n" ;;
esac
return $result
;;
foreground)
relay ;;
*)
die "Usage:\n gpg-agent-relay start\n gpg-agent-relay stop\n gpg-agent-relay status\n gpg-agent-relay foreground" ;;
esac
}
relay() {
set -e
local winhome
winhome=$(/mnt/c/Windows/System32/cmd.exe /c "<nul set /p=%UserProfile%" 2>/dev/null || true)
local npiperelay="/mnt/c/tools/Utils/npiperelay/npiperelay.exe"
local gpgagentsocket="$GNUPGHOME/S.gpg-agent"
local sshagentsocket="$GNUPGHOME/S.gpg-agent.ssh"
# backslash escaping in socat EXEC doesn't seem to work very well, use forward slashes instead
# windows/npiperelay handle that just fine
local wingpgagentpath="${winhome//\\/\/}/AppData/Roaming/gnupg/S.gpg-agent"
killsocket "$gpgagentsocket"
killsocket "$sshagentsocket"
socat UNIX-LISTEN:"$gpgagentsocket,unlink-close,fork,umask=177" EXEC:"$npiperelay -ep -ei -s -a '$wingpgagentpath'",nofork &
GNUPID=$!
# shellcheck disable=SC2064
trap "kill -TERM $GNUPID" EXIT
socat UNIX-LISTEN:"$sshagentsocket,unlink-close,fork,umask=177" EXEC:"$npiperelay /\/\./\pipe/\ssh-pageant" &
SSHPID=$!
set +e
# shellcheck disable=SC2064
trap "kill -TERM $GNUPID; kill -TERM $SSHPID" EXIT
systemd-notify --ready 2>/dev/null
wait $GNUPID $SSHPID
trap - EXIT
}
killsocket() {
local socketpath=$1
if [[ -e $socketpath ]]; then
local socketpid
if socketpid=$(lsof +E -taU -- "$socketpath"); then
timeout .5s tail --pid=$socketpid -f /dev/null &
local timeoutpid=$!
kill "$socketpid"
if ! wait $timeoutpid; then
die "Timed out waiting for pid $socketpid listening at $socketpath"
fi
else
rm "$socketpath"
fi
fi
}
checkdeps() {
local deps=("$@")
local dep
local out
local ret=0
for dep in "${deps[@]}"; do
if ! out=$(type "$dep" 2>&1); then
printf -- "Dependency %s not found:\n%s\n" "$dep" "$out"
ret=1
fi
done
return $ret
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment