Setting up ssh-agent on Windows XP

Ovidiu Predescu’s Weblog
As you probably know already, ssh-agent is an easy way to enter the passwords for your private SSH keys only once per session. On Linux and Unix systems, when using X-Windows, it is very easy to setup ssh-agent as the parent process of your window manager. In fact most of the Linux distributions start-up the window manager this way.

The way ssh-agent works is by setting up two environment variables, SSH_AUTH_SOCK and SSH_AGENT_PID. The first is used to communicate the location of the Unix socket domain on which ssh-agent is listening for requests. The second is used to identify the Unix process id of ssh-agent, so it can be killed by ssh-add -k.

These environment variables have to communicated to every process that wants to use ssh later on, so ssh can connect to the ssh-agent process and fetch the decrypted private keys. In the Unix parent-child process model, this works just fine. The ssh-agent does the work of creating the Unix socket domain and then forks a child process. In this process it first exports the two environment variables above, then exec the process – the window manager for X-Windows. This way all the processes that inherit from it will have these environment variables available.

On Windows this is not possible, since there is no way to interpose some other process before the window manager. This of course, assumes the same parent-child relationship of processes as in Unix. The alternative is to always start ssh-agent on some well-known socket. Below, I assume you use Cygwin, an excellent free-software Unix emulator for Windows.

There are few things you need to do. First in your Windows home directory (usually c:\Document and Settings\yourusername, make sure you have a .bash_profile that reads:

. ~/.bashrc

Then create a .bashrc file in your home directory, and add to it the following:

export SSH_AUTH_SOCK=/tmp/.ssh-socket

ssh-add -l 2>&1 >/dev/null
if [ $? = 2 ]; then
# Exit status 2 means couldn’t connect to ssh-agent; start one now
ssh-agent -a $SSH_AUTH_SOCK >/tmp/.ssh-script
. /tmp/.ssh-script
echo $SSH_AGENT_PID >/tmp/.ssh-agent-pid
fi

function kill-agent {
pid=`cat /tmp/.ssh-agent-pid`
kill $pid
}

Next, go to the Start menu, “Control Panel” -> “System” -> “Advanced” -> “Environment Variables” and add a new variable SSH_AUTH_SOCK, whose value should be /tmp/.ssh-socket. Hit OK to make the change persistent.

What happens next? The first time you open a bash terminal, an ssh-agent process is going to be automatically created. This process will listen on the Unix socket domain /tmp/.ssh-socket. Run ssh-add at the prompt to enter the password for your private key(s).

Now when you open another terminal, that will share the same ssh-agent process because of the SSH_AUTH_SOCK definition. Running ssh or any other command that uses ssh underneath will work without having to enter the password for your keys.

It will also work if you run a cygwin-ified version of XEmacs. Tramp, CVS or any other Emacs package that uses ssh will work just fine now.

The only requirement is for these programs to be cygwin-ified, otherwise the sharing described above doesn’t work.

One Reply to “Setting up ssh-agent on Windows XP”

  1. Thank you for this helpful tip. It worked well on the first time but kept failing after that. It could not start the agent a second time due of a binding error. I fixed the problem by removing /tmp/.ssh-socket before starting the agent:


    rm -f $SSH_AUTH_SOCK > /dev/nul 2>&1
    ssh-agent -a $SSH_AUTH_SOCK >/tmp/.ssh-script

Leave a Reply