From 48147ab3a80bc8c582486aff0d3b33dd20f685d7 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Fri, 1 Nov 2002 12:55:13 +0000 Subject: [PATCH] Implement access to the SSH agent. This ought to make agent forwarding work as well, of course. [originally from svn r2172] --- unix/uxagentc.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/unix/uxagentc.c b/unix/uxagentc.c index 5eeb0b1f..af56f1b8 100644 --- a/unix/uxagentc.c +++ b/unix/uxagentc.c @@ -4,6 +4,10 @@ #include #include +#include +#include +#include +#include #include "misc.h" #include "puttymem.h" @@ -16,10 +20,77 @@ int agent_exists(void) { - return FALSE; /* FIXME */ + if (getenv("SSH_AUTH_SOCK") != NULL) + return TRUE; + return FALSE; } void agent_query(void *in, int inlen, void **out, int *outlen) { - /* FIXME */ + char *name; + int sock; + struct sockaddr_un addr; + int done; + int retsize, retlen; + char sizebuf[4], *retbuf; + + name = getenv("SSH_AUTH_SOCK"); + if (!name) + goto failure; + + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + perror("socket(PF_UNIX)"); + exit(1); + } + + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, name, sizeof(addr.sun_path)); + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(sock); + goto failure; + } + + for (done = 0; done < inlen ;) { + int ret = write(sock, (char *)in + done, inlen - done); + if (ret <= 0) { + close(sock); + goto failure; + } + done += ret; + } + + retbuf = sizebuf; + retsize = 4; + retlen = 0; + + while (retlen < retsize) { + int ret = read(sock, retbuf + retlen, retsize - retlen); + if (ret <= 0) { + close(sock); + if (retbuf != sizebuf) sfree(retbuf); + goto failure; + } + retlen += ret; + if (retsize == 4 && retlen == 4) { + retsize = GET_32BIT(retbuf); + if (retsize <= 0) { + close(sock); + goto failure; + } + retsize += 4; + assert(retbuf == sizebuf); + retbuf = smalloc(retsize); + memcpy(retbuf, sizebuf, 4); + } + } + + assert(retbuf != sizebuf); + *out = retbuf; + *outlen = retlen; + return; + + failure: + *out = NULL; + *outlen = 0; }