-
Notifications
You must be signed in to change notification settings - Fork 0
/
sshwrap
executable file
·154 lines (131 loc) · 3.51 KB
/
sshwrap
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#! /usr/bin/env bash
# Wrapper for SSH the constructs ~/.ssh/config.
#
# To use this:
# - create ~/.sshwraprc
# - in $PATH before the real ssh link to this script with the name `ssh`
# and `scp`
#
# Yes, SSH version >= 7.3p1 have the Include directive, but some machines
# I use don't have that version. Also, SunOS SSH doesn't have Include.
#
# Include would make something like this possible:
#
# Include ~/.ssh/config_head
# Include ~/.ssh/config_fi
#
# # `Host' matches the TO host not the host we're initiating from.
# # The following includes the external config only when on my laptop.
# Match exec "test %L = gazorpazorp"
# Include ~/.ssh/config_external
#
# Match exec "test %L != gazorpazorp"
# Include ~/.ssh/config_internal
set -ueE -o pipefail
prog="$(basename "$0")"
function errordie {
[ "${*-}" ] && echo "Error: ${prog}: $*" 1>&2
exit 1
}
if [ "$(uname -s)" = "SunOS" ]; then
egrep=egrep
else
egrep="grep -E"
fi
rc="$HOME/.sshwraprc"
[ -f "$rc" ] || errordie "$rc does not exist"
# shellcheck disable=SC1090
source "$rc"
# shellcheck disable=SC2154
[ ${#__sshwrap_config_files[@]} -gt 0 ] ||
errordie "__sshwrap_config_files not defined by $rc"
function executable_p {
if [ -x "$1" ]; then
echo "$1"
return 0
else
return 1
fi
}
# this will be either ssh or scp
app=$(basename "${BASH_SOURCE[0]}")
if realsxx=$(executable_p "/opt/local/bin/${app}"); then
: # macOS Mac Ports
elif realsxx=$(executable_p "/usr/local/bin/${app}"); then
: # macOS Homebrew
elif realsxx=$(executable_p "/opt/homebrew/bin/${app}"); then
: # macOS Homebrew on M1/Big Sur
elif realsxx=$(executable_p "/usr/bin/${app}"); then
:
elif realsxx=$(executable_p "/bin/${app}"); then
:
else
realsxx=
fi
[ "$realsxx" ] || errordie "cannot find ${app} binary"
p="$HOME/.ssh"
rebuild=
if [ "${__sshwraprc_force_update-}" ]; then
rebuild="__sshwraprc_force_update non-null"
elif [ ! -f "$p/config" ]; then
rebuild="config does not exist"
else
for config in "$rc" "${__sshwrap_config_files[@]}"; do
if [ "$config" -nt "$p/config" ]; then
rebuild="$config newer than $p/config"
break
fi
done
fi
lockfile="/tmp/${prog}.lock"
function exit_cleanup {
/bin/rm -f "$lockfile"
}
function err_report {
echo "Error on line $(caller)" 1>&2
}
trap err_report ERR
trap exit_cleanup EXIT
# thor/thunder don't have lockfile
if ! type -p lockfile &> /dev/null; then
function lockfile {
:
}
fi
if [ "$rebuild" ]; then
echo "Updating $p/config: reason: $rebuild" 1>&2
if [ "$(uname -s)" = "SunOS" ]; then
cpp=/usr/lib/cpp
else
cpp=cpp
fi
# lock to update $p/config
i=0
while true; do
if ! lockfile -r 0 "$lockfile"; then
if [ $i -gt 4 ]; then
errordie "lockfile $lockfile busy could not update $p/config"
fi
i=$(( i + 1 ))
fi
# got lock file, get out of here
break
done
echo " configs: ${__sshwrap_config_files[*]}" 1>&2
# shellcheck disable=SC2001
host=$(sed -e 's/\..*$//' <<< "$HOSTNAME")
cat "${__sshwrap_config_files[@]}" | \
$egrep -v '^\s*#' | \
sed -e 's/^!/#/g' | \
$cpp -undef "-D__host_$host" | \
$egrep -v '^#' > "$p/config"
rm -f "$lockfile"
fi
# new BASH versions set HOSTNAME, it turns out
if [[ $HOSTNAME =~ (tenner|teller|relay) ]]; then
# SSH too old there
addkeys=
else
addkeys="-o AddKeysToAgent=yes"
fi
exec $realsxx $addkeys "$@"