зеркало из https://github.com/github/putty.git
97 строки
1.9 KiB
C
97 строки
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 = smalloc(retsize);
|
|
memcpy(retbuf, sizebuf, 4);
|
|
}
|
|
}
|
|
|
|
assert(retbuf != sizebuf);
|
|
*out = retbuf;
|
|
*outlen = retlen;
|
|
return;
|
|
|
|
failure:
|
|
*out = NULL;
|
|
*outlen = 0;
|
|
}
|