#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;
}