1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00
putty-source/unix/uxagentc.c
Simon Tatham d36a4c3685 Introduced wrapper macros snew(), snewn() and sresize() for the
malloc functions, which automatically cast to the same type they're
allocating the size of. Should prevent any future errors involving
mallocing the size of the wrong structure type, and will also make
life easier if we ever need to turn the PuTTY core code from real C
into C++-friendly C. I haven't touched the Mac frontend in this
checkin because I couldn't compile or test it.

[originally from svn r3014]
2003-03-29 16:14:26 +00:00

97 lines
1.9 KiB
C

/*
* SSH agent client code.
*/
#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"
#define GET_32BIT(cp) \
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
((unsigned long)(unsigned char)(cp)[1] << 16) | \
((unsigned long)(unsigned char)(cp)[2] << 8) | \
((unsigned long)(unsigned char)(cp)[3]))
int agent_exists(void)
{
if (getenv("SSH_AUTH_SOCK") != NULL)
return TRUE;
return FALSE;
}
void agent_query(void *in, int inlen, void **out, int *outlen)
{
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 = snewn(retsize, char);
memcpy(retbuf, sizebuf, 4);
}
}
assert(retbuf != sizebuf);
*out = retbuf;
*outlen = retlen;
return;
failure:
*out = NULL;
*outlen = 0;
}