Implement access to the SSH agent. This ought to make agent
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 1 Nov 2002 12:55:13 +0000 (12:55 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 1 Nov 2002 12:55:13 +0000 (12:55 +0000)
forwarding work as well, of course.

git-svn-id: svn://svn.tartarus.org/sgt/putty@2172 cda61777-01e9-0310-a592-d414129be87e

unix/uxagentc.c

index 5eeb0b1..af56f1b 100644 (file)
@@ -4,6 +4,10 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 
 #include "misc.h"
 #include "puttymem.h"
 
 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;
 }