Friday, August 1, 2008

Automate ssh-agent loading and sharing across logins

When the keychain package is not available on a platform I usually use a simple script in my .profile or .bash_profile or .bashrc that loads or reuses an existing ssh-agent.  This allows me to load an ssh key once and use it in any terminal without any additional effort. Like so:

# ssh-agent sharing
if [ -e ~/.ssh-agent ]; then
. ~/.ssh-agent
else
eval $(ssh-agent|tee ~/.ssh-agent)
fi

I tried sprucing it up for Terminal on my iPhone because it starts 4 simultaneous terminals at the same time. My first attempt was a dismal failure. I misguidedly added the following above the previous script:

# ssh-agent sharing - failed multiple concurrent launch attempt
if { ps awx |grep ssh-agent ; } then
if [ -e ~/.ssh-agent ]; then
. ~/.ssh-agent
else
killall ssh-agent
rm ~/.ssh-agent
fi
fi

I ended up finding a relatively simple file locking script:

function my_lockfile ()
{
TEMPFILE="$1.$$"
LOCKFILE="$1.lock"
{ echo $$ > $TEMPFILE ; } &> /dev/null || {
echo "You don't have permission to access `dirname $TEMPFILE`"
return 1
}
ln $TEMPFILE $LOCKFILE >& /dev/null && {
rm -f $TEMPFILE
return 0
}
kill -0 `cat $LOCKFILE` >& /dev/null && {
rm -f $TEMPFILE
return 1
}
echo "Removing stale lock file"
rm -f $LOCKFILE
ln $TEMPFILE $LOCKFILE >& /dev/null && {
rm -f $TEMPFILE
return 0
}
rm -f $TEMPFILE
return 1
}

Which makes it relatively easy to rewrite the script like so:

until my_lockfile ~/.sshagent; do
sleep 1
done

if [ -z "$SSH_AGENT_PID" ]; then
if [ -e ~/.ssh-agent ]; then
. ~/.ssh-agent >& /dev/null
else
eval $(ssh-agent|tee ~/.ssh-agent) >& /dev/null
fi
fi

if ! ps -p "$SSH_AGENT_PID" >& /dev/null; then
eval $(ssh-agent|tee ~/.ssh-agent) >& /dev/null
fi

rm -f ~/.ssh-agent.lock

The import part is the loop at the beginning of the script and the rm at the end.
I could add in a timeout but the lockfile script is pretty good at cleaning up unused lock files. Worst case scenario you can Ctrl-C to break out of the startup script.
If you need help with the basics of using ssh keys and the ssh-agent follow this link:
Automate a Remote Login Using SSH - Webmonkey
Blogged with the Flock Browser

No comments: