Last active
August 31, 2022 06:34
-
-
Save Nimamoh/e2df2ba0a99ef221d8cca360c931e5e6 to your computer and use it in GitHub Desktop.
win-gpg-agent-relay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
GNUPGHOME="$HOME/.gnupg" | |
PIDFILE="$GNUPGHOME/win-gpg-agent-relay.pid" | |
LOGFILE="$GNUPGHOME/win-gpg-agent-relay.log" | |
is_pid_running() { | |
if [[ -z "$1" ]]; then | |
return 1 | |
fi | |
ps -p "$1" >/dev/null | |
return $? | |
} | |
# Log only if verbose mode is active | |
log() { | |
if [[ -n "$VERBOSE" ]]; then | |
# shellcheck disable=SC2068 | |
echo >&2 "$@" | |
fi | |
} | |
# Log | |
info() { | |
# shellcheck disable=SC2068 | |
echo >&2 "$@" | |
} | |
_cleanup() { | |
info "Cleaning up relay to $GNUPGHOME/S.gpg-agent..." | |
if is_pid_running "$SOCAT_GPG_AGENT_PID"; then | |
kill -SIGTERM "$SOCAT_GPG_AGENT_PID" || info "Failed." | |
fi | |
info "Cleaning up relay to $GNUPGHOME/S.gpg-agent.ssh..." | |
if is_pid_running "$SOCAT_GPG_AGENT_SSH_PID"; then | |
kill -SIGTERM "$SOCAT_GPG_AGENT_SSH_PID" || info "Failed." | |
fi | |
} | |
die() { | |
if [[ -n "$1" ]]; then | |
info "$1" | |
fi | |
info "Exiting." | |
exit 1 | |
} | |
usage() { | |
info "Usage: win-gpg-agent-relay [OPTIONS] COMMAND" | |
info "" | |
info " SUMMARY: Relay local GPG sockets to win-gpg-agent's ones in order to integrate WSL2 and host." | |
info "" | |
info " OPTIONS:" | |
info " -h|--help this page" | |
info "" | |
info " -v|--verbose verbose mode" | |
info "" | |
info " --wingpgagent-sockets-windir DIR Directory where win-gpg-agent store its sockets." | |
info " This is a the directory from windows host. ex: 'C:\win-gpg-agent-sockets'" | |
info "" | |
info " --wingpgagent-dir DIR Directory where win-gpg-agent is." | |
info "" | |
info " COMMAND: start, stop foreground" | |
} | |
fg_opts() { | |
FG_OPTS=() | |
# Generate opts for passing it to foreground version | |
if [[ -n "$VERBOSE" ]]; then | |
FG_OPTS+=("-v") | |
fi | |
if [[ -n "$WINGPGAGENT_SOCKETS_WINDIR" ]]; then | |
# shellcheck disable=SC2089 | |
FG_OPTS+=("--wingpgagent-sockets-windir") | |
FG_OPTS+=("$WINGPGAGENT_SOCKETS_WINDIR") | |
fi | |
if [[ -n "$WINGPGAGENT_DIR" ]]; then | |
FG_OPTS+=("--wingpgagent-dir") | |
FG_OPTS+=("$WINGPGAGENT_DIR") | |
fi | |
} | |
main() { | |
POSITIONAL=() | |
VERBOSE="" | |
while (($# > 0)); do | |
case "$1" in | |
-v | --verbose) | |
VERBOSE="ENABLED" | |
shift # shift once since flags have no values | |
;; | |
-h | --help) | |
usage | |
exit 0 | |
;; | |
--wingpgagent-sockets-windir) | |
numOfArgs=1 | |
if (($# < numOfArgs + 1)); then | |
shift $# | |
else | |
WINGPGAGENT_SOCKETS_WINDIR="$2" | |
shift $((numOfArgs + 1)) | |
fi | |
;; | |
--wingpgagent-dir) | |
numOfArgs=1 | |
if (($# < numOfArgs + 1)); then | |
shift $# | |
else | |
WINGPGAGENT_DIR="$2" | |
shift $((numOfArgs + 1)) | |
fi | |
;; | |
*) # unknown flag/switch | |
POSITIONAL+=("$1") | |
shift | |
if [[ "${#POSITIONAL[@]}" -gt 1 ]]; then | |
usage | |
die | |
fi | |
;; | |
esac | |
done | |
set -- "${POSITIONAL[@]}" # restore positional params | |
case "${POSITIONAL[0]}" in | |
start) | |
fg_opts | |
true >"$LOGFILE" | |
# shellcheck disable=SC2086,SC2090 | |
start-stop-daemon \ | |
--start --oknodo \ | |
--pidfile "$PIDFILE" -m \ | |
--output "$LOGFILE" \ | |
--background \ | |
--name bash --startas "$0" ${VERBOSE:+--verbose} -- foreground "${FG_OPTS[@]}" | |
;; | |
stop) | |
start-stop-daemon --pidfile "$PIDFILE" --stop --remove-pidfile ${VERBOSE:+--verbose} | |
;; | |
status) | |
start-stop-daemon --pidfile "$PIDFILE" --status ${VERBOSE:+--verbose} | |
local result=$? | |
case $result in | |
0) info "$0 is running" ;; | |
1 | 3) info "$0 is not running" ;; | |
4) info "$0 unable to determine status" ;; | |
esac | |
return $result | |
;; | |
foreground) | |
relay | |
;; | |
*) | |
usage | |
die | |
;; | |
esac | |
} | |
mult_by_two_and_max() { | |
# outputs max(x * 2, y) | |
# where x is first argument, y the second one | |
local max | |
max=${2:-600} | |
last=${1:-1} | |
curr=$((last * 2)) | |
curr=$((curr > max ? max : curr)) | |
echo "$curr" | |
} | |
sorelay() { | |
# Serve socket at path $1 relaying to windows AF_LINUX socket $2 through sorelay tool | |
# return 0 on successfully setup socat, outputs the PID | |
info "Set up $1 as socket relaying to $2" | |
local pid | |
local exec | |
exec="\'$SORELAY_BIN\' \'$2\'" | |
socat UNIX-LISTEN:"\"$1\"",fork EXEC:"\"$exec\"",nofork 1>/dev/null 2>&1 & | |
pid="$!" | |
# quickly check if socat still running to catch early errors | |
if ! is_pid_running "$pid"; then | |
info "socat $1 failed" | |
return 1 | |
fi | |
echo "$pid" | |
} | |
relay() { | |
trap _cleanup EXIT | |
log "Verbose mode: ON" | |
log "Using win-gpg-agent: $WINGPGAGENT_DIR" | |
log "Using win-gpg-agent sockets in: $WINGPGAGENT_SOCKETS_WINDIR" | |
[[ -z "$WINGPGAGENT_SOCKETS_WINDIR" ]] && usage && die "Please provide directory of win-gpg-agent sockets" | |
[[ -z "$WINGPGAGENT_DIR" ]] && usage && die "Please provide directory of win-gpg-agent" | |
TMPFOLDER=$(mktemp -d) | |
{ [[ -z "$TMPFOLDER" ]] && die "Failed creating a temp folder"; } || log "Temp folder: $TMPFOLDER" | |
cp "$WINGPGAGENT_DIR/sorelay.exe" "$TMPFOLDER/sorelay.exe" || die "Failed to copy sorelay." | |
SORELAY_BIN="$TMPFOLDER/sorelay.exe" | |
GPG_AGENT_SOCK="$WINGPGAGENT_SOCKETS_WINDIR/S.gpg-agent" | |
GPG_AGENT_SSH_SOCK="$WINGPGAGENT_SOCKETS_WINDIR/S.gpg-agent.ssh" | |
info "Killing previously setup gpg agent..." | |
echo "KILLAGENT" | gpg-connect-agent >/dev/null 2>&1 | |
if ! SOCAT_GPG_AGENT_PID=$(sorelay "$HOME/.gnupg/S.gpg-agent" "$GPG_AGENT_SOCK"); then die; fi | |
info "socat running with PID: $SOCAT_GPG_AGENT_PID" | |
if ! SOCAT_GPG_AGENT_SSH_PID=$(sorelay "$HOME/.gnupg/S.gpg-agent.ssh" "$GPG_AGENT_SSH_SOCK"); then die; fi | |
info "socat running with PID: $SOCAT_GPG_AGENT_SSH_PID" | |
while true; do | |
log -n "Polling GPG agent... " | |
gpg-connect-agent /bye >/dev/null 2>&1 || die "Failure communicating with S.gpg-agent." | |
log "OK" | |
log -n "Polling SSH agent..." | |
ssh-add -L >/dev/null 2>&1 || die "Failure communicating with S.gpg-agent.ssh." | |
log "OK" | |
local time_s | |
time_s=$(mult_by_two_and_max "${time_s:-5}" 600) | |
log "Wait $time_s seconds" | |
sleep "$time_s" | |
done | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment