diff --git a/agentfwd.h b/agentfwd.h
index 592822007072620c589e4748ae44767fdbe111ee..8575b0c85d63dea4429f5e971da2ddb53a94dc7e 100644
--- a/agentfwd.h
+++ b/agentfwd.h
@@ -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 f2d903a5e4cfd2a7da3d728c4d608714f5250808..b47a6ccfcb984fd3cbc1cb8aaa5952fa6f9e5f62 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 b314edc4bfc87dc573e9e1ac6cf9acd649e2140d..b7ecd553bbf3c92f289653e7f9431fe3088bda66 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) {
diff --git a/dbutil.c b/dbutil.c
index 59ffcbe2f9a22592bebd82c8dfcea9e41f79e6af..73302e065f81916fa2b939a102c0d38d37e13afd 100644
--- a/dbutil.c
+++ b/dbutil.c
@@ -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
diff --git a/debug.h b/debug.h
index b8c2a575aa38599f65afc98f68fcfaef10eb329f..a9cc0bd71f684f8c1a06d20f69a90befff94629a 100644
--- a/debug.h
+++ b/debug.h
@@ -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
diff --git a/session.h b/session.h
index a3f72201f3348146bc27ee38e37828603417a4e1..5a4569e39902e111240d3ea8ce6356294faf021a 100644
--- a/session.h
+++ b/session.h
@@ -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,