ssh-agent in Cygwin?

Corinna Vinschen vinschen at redhat.com
Fri Dec 18 20:54:07 EST 2009


On Dec 17 15:09, Peter Stuge wrote:
> Corinna Vinschen wrote:
> > > > I don't quite understand the question.  Cygwin's ssh-agent is
> > > > working just like on other platforms, using AF_UNIX sockets.
> > > 
> > > Ok! Are those sockets somehow reachable from native win32?
> > 
> > No.  Why is that necesary?  libssh2 should be usable within the Cygwin
> > POSIX layer without using any native Win32 functions.
> 
> Yes, but I'm thinking of the case where a win32 app is using libssh2
> and there is an ssh-agent in Cygwin. If not too difficult, it would
> be nice to make that too work. (win32 app+pageant and cygwin
> app+cygwin ssh-agent should work already, this is another case.)

Well, that *might* be possible, but it's very tricky for the Win32
application.  You only have the information available in the environment
if the Win32 process is running in the same process tree in which the
ssh-agent has been started.  The ssh-agent is started like this in
Cygwin (as on other POSIX systems):

  $ eval `ssh-agent`
  $ env | grep SSH
  SSH_AUTH_SOCK=/tmp/ssh-WUoLQ1057/agent.1057
  SSH_AGENT_PID=1058

So you have a POSIX path to the auth socket.  You have to convert it now
to a Win32 path.  The easiest way is to find and call the cygpath
application, for instance:

  $ cygpath -wa `echo $SSH_AUTH_SOCK`
  C:\cygwin\tmp\ssh-WUoLQ1057\agent.1057

Alternatively you have to find the cygwin1.dll, load it dynamically, and
call the cygwin_conv_path() function:
http://cygwin.com/1.7/cygwin-api/func-cygwin-conv-path.html

For the Cygwin API the file is a socket, but for the Win32 API it's just
a file.  Windows has no concept of AF_UNIX/AF_LOCAL sockets, so they are
implemented as ordinary AF_INET sockets with pure local binding, and the
socket file contains the information for Cygwin how to connect to them.
For security purposes it's only readable by the creator of the socket,
usually.

When you got the Win32 path, just open the file using Win32 calls and
read the content.  It looks similar to this:

  !<socket >53795 s F0E9D75D-2AD3C2BA-2EF88B65-6B26688A\0

- "!<socket >" is just a cookie for Cygwin to identify this file as a
  socket file.
- "53795" is the AF_INET port number.
- "s" means it's a SOCK_STREAM type socket (alternatively "d" for
  SOCK_DGRAM).

The remainder is a hex magic number which constitute a block of 4 32 bit
values in host byte order.

Now...

- Create an AF_INET/SOCK_STREAM socket and connect it to the ssh-agent
  listening on 127.0.0.1:53795.
- Convert the magic number into a 4*32 bit block of data in host byte
  order and send it to the agent.
- Call read on the socket and wait for the reply.  If your magic number
  was incorrect, the listener will disconnect.  Otherwise it replies
  with the same magic number block of 4*32 byte.
- Now send a second packet with your credentials.  It's just a block
  of three 32 bit values in host byte order:

    uint32_t pid;
    uint32_t uid;
    uint32_t gid;

  Then read the same block from the socket.  This information is
  returned in Cygwin in calls to getpeereid.

- Still here?  Congrats.  You have established the AF_UNIX socket
  connection to the ssh-agent authentication socket.

If you have further questions, we should better move this discussion
over to the cygwin mailing list (cygwin AT cygwin DOT com).  The Cygwin
libssh2 package maintainer might be interested in this as well.


HTH,
Corinna

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat


More information about the openssh-unix-dev mailing list