Skip to content

Instantly share code, notes, and snippets.

@ayufan
Created March 5, 2020 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayufan/c0e827e4d5ae33acecdf60888c34e5e4 to your computer and use it in GitHub Desktop.
Save ayufan/c0e827e4d5ae33acecdf60888c34e5e4 to your computer and use it in GitHub Desktop.
GPG Agent Watcher to show Mac OS notify when SSH sign happens
#!/bin/bash
realpath() {
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}
DETECT=${DETECT:-notify}
LABEL=eu.ayufan.gpg-agent-watcher
TARGET=~/Library/LaunchAgents/$LABEL.plist
GPG_AGENT_CONF=~/.gnupg/gpg-agent.conf
GPG_AGENT_LOG_FILE=~/.gnupg/gpg-agent.log
SELF=$(realpath $0)
verify() {
echo "Verifying gpg-agent config..."
if ! grep -q "^verbose" "$GPG_AGENT_CONF"; then
echo "Missing 'verbose' in '$GPG_AGENT_CONF'"
exit 1
fi
if ! grep -q "^log-file $GPG_AGENT_LOG_FILE" "$GPG_AGENT_CONF"; then
echo "Missing 'log-file $GPG_AGENT_LOG_FILE' in '$GPG_AGENT_CONF'"
exit 1
fi
}
install() {
echo "Installing $0..."
cat <<EOF > $TARGET
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>$LABEL</string>
<key>ProgramArguments</key>
<array>
<string>$SELF</string>
<string>run</string>
</array>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
EOF
launchctl load $TARGET
launchctl start $LABEL
launchctl list $LABEL
}
uninstall() {
echo "Uninstalling $0..."
launchctl stop $LABEL
launchctl unload $TARGET
}
ssh_notify() {
osascript -e 'display notification "Sign requested by SSH" with title "GPG Agent" sound name "Submarine"'
}
gpg_notify() {
osascript -e 'display notification "Your yubikey is waiting for touch!" with title "Yubikey" sound name "Submarine"'
}
ssh_sign_request_gpg_detect() {
gpg --card-status &
PID=$!
# notify after 1s
( sleep 0.25s && gpg_notify ) &
SLEEP_PID=$!
# kill after 10s
( sleep 10s && kill "$PID" ) &
KILL_PID=$!
# wait for GPG, first
wait "$PID"
kill "$PID" "$SLEEP_PID" "$KILL_PID"
}
ssh_sign_request_notify() {
ssh_notify
}
run() {
echo "Running $0..."
tail -n 0 -F "$GPG_AGENT_LOG_FILE" | while read LINE; do
case "$LINE" in
*ssh*sign_request*started*)
ssh_sign_request_$DETECT
;;
esac
done
}
case "$1" in
install)
verify
uninstall
install
;;
uninstall)
uninstall
;;
run)
run
;;
*)
echo "usage: $0 <install|uninstall|run>"
exit 1
;;
esac
@ayufan
Copy link
Author

ayufan commented Mar 5, 2020

I use gpg-agent as ssh-agent, and my gpg keyring also stores all SSH keys, and works with Yubikey.

This makes a very simpler script to watch for gpg-agent log messages to show when the ssh request happens and shows desktop notification, it also does not require any sudo access, but small change in gpg-agent.conf.

mkdir ~/bin
cd ~/bin
wget https://gist.github.com/ayufan/c0e827e4d5ae33acecdf60888c34e5e4/raw/8bd1b69702d5a8e3b6f2e033c37f09629e4f8d71/gpg-agent-watcher.bash
chmod +x gpg-agent-watcher.bash
./gpg-agent-watcher.bash install

And then reboot to make gnupg2 to grab new gpg-agent settings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment