-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgssh
More file actions
executable file
·100 lines (91 loc) · 3.8 KB
/
gssh
File metadata and controls
executable file
·100 lines (91 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/bin/bash
set -e
# Allow config from outer environment if set, otherwise initalize to 0
GSSH_DEBUG="${GSSH_DEBUG:-0}"
GSSH_SILENT="${GSSH_SILENT:-0}"
GSSH_ENVWORKAROUND="${GSSH_ENVWORKAROUND:-0}"
for ARG in "$@"; do
shift
case $ARG in
--gssh-debug)
GSSH_DEBUG=1 ;;
--gssh-silent)
GSSH_SILENT=1 ;;
--envfix)
GSSH_ENVWORKAROUND=1;;
*)
set -- "$@" "$ARG" ;;
esac
done
# Right hand side is equivalent to gpgconf --list-dirs agent-socket in newer versions of gpg
# export SSH_AUTH_SOCK="$(gpgconf --list-dirs | awk -F: '$1=="agent-socket" {print $2}')"
if [ -z "$SSH_CONNECTION" ]; then
LOCAL_SOCK="$(gpgconf --list-dirs | awk -F: '$1=="agent-extra-socket" {print $2}')"
if [ -z "$GPG_PUBKEY" ]; then
if gpg --card-status 2>&1 > /dev/null; then
# Yubikey, smartcards, etc.
GPG_KEYID=$(gpg --card-status --with-colons | grep "^fpr:" | awk -F: '{print $2}')
else
# Standard GPG default key
GPG_KEYID="$(gpgconf --list-options gpg | awk -F: '$1 == "default-key" {print $10}')"
fi
if [ -z "$GPG_KEYID" ]; then
echo "Could not determine you gpg signing key id."
echo "Connect yubikey/smartcard; or set GPG_PUBKEY."
echo
exit 1
fi
GPG_PUBKEY=$(gpg --armor --export "$GPG_KEYID")
fi
else
# This Allows chaining gpg forwarding
LOCAL_SOCK="$(gpgconf --list-dirs | awk -F: '$1=="agent-socket" {print $2}')"
fi
if [ "$GSSH_DEBUG" = "1" ]; then
echo "GPG_KEYID: $GPG_KEYID"
echo
echo "$GPG_PUBKEY" | gpg --show-keys
fi
# Smuggle the PUBKEY, KEYID and a randomized tmp directory name for the socket via
# pretend LC_* variables since ssh transfer them over by default
export LC_GSSH_PUBKEY="$GPG_PUBKEY"
export LC_GSSH_KEYID="$GPG_KEYID"
export LC_GSSH_SOCKET="$(mktemp -u)"
# While we are at it, why not simplify the setup on the remote machine by providing a script
# that can be run via eval to set up the config on the remote side?
export LC_GSSH_CONFIG="cat > ~/.gssh-gpg-wrap <<EOF
#!/bin/bash
if [ -z \"\\\$LC_GSSH_SOCKET\" -o -z \"\\\$LC_GSSH_PUBKEY\" -o -z \"\\\$LC_GSSH_KEYID\" ]; then
exec gpg \"\\\$@\"
exit 0
fi
GPGVER=\\\$(gpg --version | head -n 1 | sed \"s/gpg (GnuPG) //\")
if [ \"\\\${GPGVER%.*}\" == \"2.0\" ]; then
echo \"GPG forwarding does not work on gpg 2.0.x; 2.1.x or newer required\" >&2
exit 1
fi
export GNUPGHOME=\\\$(mktemp -d \".gnupg-tmp-XXXXXXXXXX\" -p ~/)
export GNUPGHOME_SUFFIX=\\\${GNUPGHOME#~/.gnupg-tmp-}
trap \"rm -rf -- ~/\\\".gnupg-tmp-\\\${GNUPGHOME_SUFFIX}\\\"\" EXIT
gpgconf --change-options gpg <<< \"default-key:0:\\\"\\\$LC_GSSH_KEYID\"
gpg --import <<<\"\\\$LC_GSSH_PUBKEY\"
AGENT_SOCKET=\"\\\$(gpgconf --list-dirs | awk -F: \"\\\\\\\$1==\\\"agent-socket\\\" {print \\\\\\\$2}\")\"
if [ -n \"\\\$AGENT_SOCKET\" ]; then
ln -sf \"\\\$LC_GSSH_SOCKET\" \"\\\$AGENT_SOCKET\"
fi
gpg \"\\\$@\"
EOF
chmod +x ~/.gssh-gpg-wrap
git config --global gpg.program ~/.gssh-gpg-wrap
git config --global commit.gpgsign true
"
if [ "$GSSH_SILENT" != "1" ]; then
echo "## Notice: to set up git signatures on the remote side, execute: eval \"\$LC_GSSH_CONFIG\"" >&2
echo "## If you want the gpg command itself to forward, add alias gpg=~/.gssh-gpg-wrap to your init scripts." >&2
fi
if [ "$GSSH_ENVWORKAROUND" != "1" ]; then
exec ssh -A -R "$LC_GSSH_SOCKET":"$LOCAL_SOCK" "$@"
else
[ "$GSSH_SILENT" != "1" ] && echo "## Notice: applying workaround for transfering environment variables to remote side; this may supress the motd welcome message."
exec ssh -t -A -R "$LC_GSSH_SOCKET":"$LOCAL_SOCK" "$@" "export LC_GSSH_SOCKET='$LC_GSSH_SOCKET'; export LC_GSSH_PUBKEY='$LC_GSSH_PUBKEY'; export LC_GSSH_KEYID='$LC_GSSH_KEYID'; export LC_GSSH_CONFIG='$LC_GSSH_CONFIG'; bash -l"
fi