Thanks, Arek for the inspiration...
Rather than running another shell process, this is just a function running in the current bash shell. It runs a single awk
command to parse the config file and figure out if it should take the password from a shell variable or from the password written cleartext into the ssh config file (with awk
in an eval
instead of declare
due to issues I hit using declare
).
I tried so many ways of using sshpass
directly in an ssh
config file using ProxyCommand, but nothing seemed to work as expected, except when I could log in to a box via RSA and then I needed to send a password to open my encrypted directory. However, my function below seems to work for me in all cases, even for Cygwin.
# In your .bash_profilefunction ssh(){ host=$1; unset PASSWORD unset PASSVAR eval $(awk "/ *#[Pp]assvar / && inhost { printf \"PASSVAR=%s\",\$2; exit 1 } / *#[Pp]assword / && inhost { printf \"PASSWORD=%s\",\$2; } /^#?[Hh][oO][sS][tT] / && inhost { inhost=0; exit 1 } /^[Hh][oO][sS][tT] $host\$/ { inhost=1 }" ~/.ssh/config) if [[ -z "$PASSWORD" ]] && [[ -z "$PASSVAR" ]]; then /usr/bin/ssh -q $* 2>/dev/null else if [[ -n "$PASSVAR" ]]; then PASSWORD=$(TMP=${!PASSVAR-*};echo ${TMP##*-}) fi /usr/local/bin/sshpass -p"$PASSWORD" /usr/bin/ssh -q $* 2>/dev/null fi}# and setup your passwords (perhaps in .bashrc instead...)MYPASS_ENVVAR=SomePasswordMYPASSWD_FROM_FILE=$(</home/me/.passwd_in_file)
Then a ~/.ssh/config
section looks like this:
Host MyHostname Port 22 Hostname 2.1.2.2 User merrydan #Passvar MYPASS_ENVVAR #Password Some!Password
If a #Passvar
exists in the config section this overrides the #Password
.$MYPASS_ENVVAR
is the environment variable holding your password.
Enjoy!
And something to handle most scp scenarios (not fully fleshed but at least a start...)
function scp(){ host=$(echo $* | perl -pe 's/^.*?([A-Za-z-1-9-]+):.*?$/\1/;'); unset PASSWORD unset PASSVAR eval $(awk "/^#[Pp]assvar / && inhost { printf \"PASSVAR=%s\",\$2; exit 1; } /^ *#[Pp]assword / && inhost { printf \"PASSWORD=%s\",\$2; } /^#?[Hh][oO][sS][tT] / && inhost { inhost=0; exit 1; } /^[Hh][oO][sS][tT] $host\$/ { inhost=1 }" ~/.ssh/config.d/*) if [[ -z "$PASSWORD" ]] && [[ -z "$PASSVAR" ]]; then #echo /usr/bin/scp -3 $* /usr/bin/scp -3 $* || true #echo "SSH Exit Code $?" else if [[ -n "$PASSVAR" ]]; then #PASSWORD=`echo ${!PASSVAR}` PASSWORD=$(TMP=${!PASSVAR-*};echo ${TMP##*-}) fi #echo /usr/local/bin/sshpass -p"$PASSWORD" /usr/bin/scp -3 $* /usr/bin/sshpass -p"$PASSWORD" /usr/bin/scp -3 $* || true #echo "SSHPass Exit Code $?" fi}