diff options
-rw-r--r-- | agentfwd.h | 2 | ||||
-rw-r--r-- | cli-agentfwd.c | 41 | ||||
-rw-r--r-- | cli-authpubkey.c | 4 | ||||
-rw-r--r-- | dbutil.c | 19 | ||||
-rw-r--r-- | debug.h | 2 | ||||
-rw-r--r-- | session.h | 11 |
6 files changed, 40 insertions, 39 deletions
@@ -39,7 +39,7 @@ void agentsetauth(struct ChanSess *chansess); void agentcleanup(struct ChanSess * chansess); void agentset(struct ChanSess *chansess); -void load_agent_keys(); +void load_agent_keys(struct SignKeyList * ret_list); #ifdef __hpux #define seteuid(a) setresuid(-1, (a), -1) diff --git a/cli-agentfwd.c b/cli-agentfwd.c index f2d903a..b47a6cc 100644 --- a/cli-agentfwd.c +++ b/cli-agentfwd.c @@ -94,13 +94,14 @@ static int new_agent_chan(struct Channel * channel) { /* Sends a request to the agent, returning a newly allocated buffer * with the response */ +/* This function will block waiting for a response - it will + * only be used by client authentication (not for forwarded requests) + * won't cause problems for interactivity. */ /* Packet format (from draft-ylonen) 4 bytes Length, msb first. Does not include length itself. 1 byte Packet type. The value 255 is reserved for future extensions. data Any data, depending on packet type. Encoding as in the ssh packet - protocol. - - In this case, data is always empty + protocol. */ static buffer * agent_request(int fd, unsigned char type) { @@ -113,16 +114,17 @@ static buffer * agent_request(int fd, unsigned char type) { buf_putint(payload, 1); buf_putbyte(payload, type); + buf_setpos(payload, 0); ret = atomicio(write, fd, buf_getptr(payload, payload->len), payload->len); if ((size_t)ret != payload->len) { - TRACE(("write failed for agent_request")) + TRACE(("write failed fd %d for agent_request, %s", fd, strerror(errno))) goto out; } buf_free(payload); payload = NULL; - + TRACE(("Wrote out bytes for agent_request")) /* Now we read the response */ inbuf = buf_new(4); ret = atomicio(read, fd, buf_getwriteptr(inbuf, 4), 4); @@ -130,19 +132,27 @@ static buffer * agent_request(int fd, unsigned char type) { TRACE(("read of length failed for agent_request")) goto out; } + buf_setpos(inbuf, 0); + buf_setlen(inbuf, ret); readlen = buf_getint(inbuf); if (readlen > MAX_AGENT_REPLY) { TRACE(("agent reply is too big")); goto out; } + + TRACE(("agent_request readlen is %d", readlen)) buf_resize(inbuf, readlen); + buf_setpos(inbuf, 0); ret = atomicio(read, fd, buf_getwriteptr(inbuf, readlen), readlen); if ((size_t)ret != readlen) { TRACE(("read of data failed for agent_request")) goto out; } + buf_incrwritepos(inbuf, readlen); + buf_setpos(inbuf, 0); + TRACE(("agent_request success, length %d", readlen)) out: if (payload) @@ -151,17 +161,18 @@ out: return inbuf; } -static struct SignKeyList * agent_get_key_list(int fd) +static void agent_get_key_list(int fd, struct SignKeyList * ret_list) { buffer * inbuf = NULL; unsigned int num = 0; unsigned char packet_type; unsigned int i; - struct SignKeyList *retkey = NULL, *key = NULL; + struct SignKeyList *key = NULL; int ret; inbuf = agent_request(fd, SSH2_AGENTC_REQUEST_IDENTITIES); if (!inbuf) { + TRACE(("agent_request returned no identities")) goto out; } @@ -187,11 +198,8 @@ static struct SignKeyList * agent_get_key_list(int fd) struct SignKeyList *nextkey = NULL; nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList)); - if (key) - key->next = nextkey; - else - retkey = nextkey; - key = nextkey; + ret_list->next = nextkey; + ret_list = nextkey; pubkey = new_sign_key(); ret = buf_get_pub_key(inbuf, pubkey, &key_type); @@ -214,14 +222,11 @@ out: buf_free(inbuf); inbuf = NULL; } - - return retkey; } -void load_agent_keys() +/* Returned keys are appended to ret_list */ +void load_agent_keys(struct SignKeyList * ret_list) { - - struct SignKeyList * ret_list; int fd; fd = connect_agent(); if (fd < 0) { @@ -229,7 +234,7 @@ void load_agent_keys() return; } - ret_list = agent_get_key_list(fd); + agent_get_key_list(fd, ret_list); close(fd); } diff --git a/cli-authpubkey.c b/cli-authpubkey.c index b314edc..b7ecd55 100644 --- a/cli-authpubkey.c +++ b/cli-authpubkey.c @@ -174,11 +174,11 @@ int cli_auth_pubkey() { TRACE(("enter cli_auth_pubkey")) - if (cli_opts.privkeys == NULL && - cli_opts.agent_fwd && + if (cli_opts.agent_fwd && !cli_opts.agent_keys_loaded) { /* get the list of available keys from the agent */ load_agent_keys(&cli_opts.privkeys); + cli_opts.agent_keys_loaded = 1; } if (cli_opts.privkeys != NULL) { @@ -297,14 +297,22 @@ int dropbear_listen(const char* address, const char* port, /* Connect to a given unix socket. The socket is blocking */ #ifdef ENABLE_CONNECT_UNIX -int connect_unix(const char* addr) { - struct sockaddr_un egdsock; +int connect_unix(const char* path) { + struct sockaddr_un addr; int fd = -1; - memset((void*)&egdsock, 0x0, sizeof(egdsock)); - egdsock.sun_family = AF_UNIX; - strlcpy(egdsock.sun_path, addr, sizeof(egdsock.sun_path)); + memset((void*)&addr, 0x0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + TRACE(("Failed to open unix socket")) + return -1; + } + if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + TRACE(("Failed to connect to '%s' socket", path)) + return -1; + } return fd; } #endif @@ -574,7 +582,6 @@ unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) { } return retstring; - } /* Get the hostname corresponding to the address addr. On failure, the IP @@ -39,7 +39,7 @@ * Caution: Don't use this in an unfriendly environment (ie unfirewalled), * since the printing may not sanitise strings etc. This will add a reasonable * amount to your executable size. */ -/*#define DEBUG_TRACE*/ +#define DEBUG_TRACE /* All functions writing to the cleartext payload buffer call * CHECKCLEARTOWRITE() before writing. This is only really useful if you're @@ -215,17 +215,6 @@ struct serversession { }; -struct protocol { - int sock; /* read/write with this */ - buffer * readbuf; /* Pending input data, should read a packet's worth */ - struct Queue writequeue; /* A queue of output buffers to send */ - void (*process)(); /* To be called after reading */ - size_t (*bytes_to_read)(); - void * state; /* protocol specific */ - void (*protocol_closed)(); /* to be run when the sock gets closed */ - void (*loop_handler)(); /* to run at end of each loop */ -}; - typedef enum { KEX_NOTHING, KEXINIT_RCVD, |