diff --git a/Makefile.in b/Makefile.in
index 4c8441f3c193d1d8522466d66286fd5282575647..efd9e571449aa97364cd0859684faef7a4589315 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -29,7 +29,8 @@ SVROBJS=svr-kex.o svr-algo.o svr-auth.o sshpty.o \
 
 CLIOBJS=cli-algo.o cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \
 		cli-session.o cli-service.o cli-runopts.o cli-chansession.o \
-		cli-authpubkey.o cli-tcpfwd.o cli-channel.o cli-authinteract.o
+		cli-authpubkey.o cli-tcpfwd.o cli-channel.o cli-authinteract.o \
+		cli-agentfwd.o
 
 CLISVROBJS=common-session.o packet.o common-algo.o common-kex.o \
 			common-channel.o common-chansession.o termcodes.o loginrec.o \
diff --git a/agentfwd.h b/agentfwd.h
index 3684455455b731f38a17ba08c885566e6f60dc4e..592822007072620c589e4748ae44767fdbe111ee 100644
--- a/agentfwd.h
+++ b/agentfwd.h
@@ -23,11 +23,11 @@
  * SOFTWARE. */
 #ifndef _AGENTFWD_H_
 #define _AGENTFWD_H_
-#ifndef DISABLE_AGENTFWD
 
 #include "includes.h"
 #include "chansession.h"
 #include "channel.h"
+#include "auth.h"
 
 /* An agent reply can be reasonably large, as it can
  * contain a list of all public keys held by the agent.
@@ -39,14 +39,13 @@ void agentsetauth(struct ChanSess *chansess);
 void agentcleanup(struct ChanSess * chansess);
 void agentset(struct ChanSess *chansess);
 
-SignKeyList * load_agent_keys();
+void load_agent_keys();
 
 #ifdef __hpux
 #define seteuid(a)       setresuid(-1, (a), -1)
 #define setegid(a)       setresgid(-1, (a), -1)
 #endif
 
-extern const struct ChanSess chan_cli_agent;
+extern const struct ChanType cli_chan_agent;
 
-#endif /* DROPBEAR_AGENTFWD */
 #endif /* _AGENTFWD_H_ */
diff --git a/auth.h b/auth.h
index 55efeefcb034be83c3263845b3e2af7714216af6..a35416c7739a9f71ba5e7303f51173493f9ef119 100644
--- a/auth.h
+++ b/auth.h
@@ -26,6 +26,7 @@
 #define _AUTH_H_
 
 #include "includes.h"
+#include "signkey.h"
 #include "chansession.h"
 
 void svr_authinitialise();
@@ -124,8 +125,10 @@ struct AuthState {
 };
 
 /* Sources for signing keys */
-#define SIGNKEY_SOURCE_RAW_FILE 1
-#define SIGNKEY_SOURCE_AGENT 21
+typedef enum {
+	SIGNKEY_SOURCE_RAW_FILE,
+	SIGNKEY_SOURCE_AGENT,
+} signkey_source;
 
 struct SignKeyList;
 /* A singly linked list of signing keys */
@@ -134,7 +137,7 @@ struct SignKeyList {
 	sign_key *key;
 	int type; /* The type of key */
 	struct SignKeyList *next;
-	int source;
+	signkey_source source;
 	char *filename;
 	/* the buffer? for encrypted keys, so we can later get
 	 * the private key portion */
diff --git a/channel.h b/channel.h
index 46f023eae4796ad3653d719e49348f40f96ba01b..5c63226b2549772992ac83e6be12aad4db8b445c 100644
--- a/channel.h
+++ b/channel.h
@@ -58,7 +58,7 @@ struct Channel {
 	unsigned int recvmaxpacket, transmaxpacket;
 	void* typedata; /* a pointer to type specific data */
 	int writefd; /* read from wire, written to insecure side */
-	int readfd; /* read from insecure size, written to wire */
+	int readfd; /* read from insecure side, written to wire */
 	int errfd; /* used like writefd or readfd, depending if it's client or server.
 				  Doesn't exactly belong here, but is cleaner here */
 	circbuffer *writebuf; /* data from the wire, for local consumption */
diff --git a/chansession.h b/chansession.h
index 4513b1a78a98586272817f93d665175fea04209b..8d8e173631100723047032a04e0ad47a7fa0f99f 100644
--- a/chansession.h
+++ b/chansession.h
@@ -60,7 +60,7 @@ struct ChanSess {
 	unsigned char x11singleconn;
 #endif
 
-#ifndef DISABLE_AGENTFWD
+#ifdef ENABLE_SVR_AGENTFWD
 	struct Listener * agentlistener;
 	char * agentfile;
 	char * agentdir;
diff --git a/cli-agentfwd.c b/cli-agentfwd.c
index f0fe38584403a9519b41142e698ac09277ad2faa..f2d903a5e4cfd2a7da3d728c4d608714f5250808 100644
--- a/cli-agentfwd.c
+++ b/cli-agentfwd.c
@@ -47,7 +47,7 @@
 
 static int new_agent_chan(struct Channel * channel);
 
-const struct ChanType chan_cli_agent = {
+const struct ChanType cli_chan_agent = {
 	0, /* sepfds */
 	"auth-agent@openssh.com",
 	new_agent_chan,
@@ -85,8 +85,8 @@ static int new_agent_chan(struct Channel * channel) {
 
 	ses.maxfd = MAX(ses.maxfd, fd);
 
-	channel->infd = fd;
-	channel->outfd = fd;
+	channel->readfd = fd;
+	channel->writefd = fd;
 
 	// success
 	return 0;
@@ -151,7 +151,7 @@ out:
 	return inbuf;
 }
 
-static SignKeyList * agent_get_key_list(int fd)
+static struct SignKeyList * agent_get_key_list(int fd)
 {
 	buffer * inbuf = NULL;
 	unsigned int num = 0;
@@ -183,7 +183,7 @@ static SignKeyList * agent_get_key_list(int fd)
 	num = buf_getint(inbuf);
 	for (i = 0; i < num; i++) {
 		sign_key * pubkey = NULL;
-		char key_type = DROPBEAR_SIGNKEY_ANY;
+		int key_type = DROPBEAR_SIGNKEY_ANY;
 		struct SignKeyList *nextkey = NULL;
 
 		nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList));
@@ -218,16 +218,15 @@ out:
 	return retkey;
 }
 
-/* return DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
-SignKeyList * load_agent_keys()
+void load_agent_keys()
 {
 
-	SignKeyList * ret_list;
+	struct SignKeyList * ret_list;
 	int fd;
 	fd = connect_agent();
 	if (fd < 0) {
 		dropbear_log(LOG_INFO, "Failed to connect to agent");
-		return NULL;
+		return;
 	}
 
 	ret_list =  agent_get_key_list(fd);
diff --git a/cli-authpubkey.c b/cli-authpubkey.c
index 20277a1ae3a941e6320376efbf8b860fb1bd5e76..b314edc4bfc87dc573e9e1ac6cf9acd649e2140d 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.pubkeys == NULL && 
+	if (cli_opts.privkeys == NULL && 
 			cli_opts.agent_fwd &&
 			!cli_opts.agent_keys_loaded) {
 		/* get the list of available keys from the agent */
-		load_agent_keys(&cli_opts.pubkeys);
+		load_agent_keys(&cli_opts.privkeys);
 	}
 
 	if (cli_opts.privkeys != NULL) {
diff --git a/cli-session.c b/cli-session.c
index 4aa2366b1b9f6b4f1352282540f325fff8a30055..f9b372b280a3302e5e6f4870ec62f7362d56392b 100644
--- a/cli-session.c
+++ b/cli-session.c
@@ -35,6 +35,7 @@
 #include "service.h"
 #include "runopts.h"
 #include "chansession.h"
+#include "agentfwd.h"
 
 static void cli_remoteclosed();
 static void cli_sessionloop();
diff --git a/dbutil.c b/dbutil.c
index 0680b7554e9d6c4d9d3d283c91cf56c72d1a92b6..59ffcbe2f9a22592bebd82c8dfcea9e41f79e6af 100644
--- a/dbutil.c
+++ b/dbutil.c
@@ -295,19 +295,16 @@ int dropbear_listen(const char* address, const char* port,
 	return nsock;
 }
 
-/* Connect to a given unix socket. The socket is not non-blocking */
+/* Connect to a given unix socket. The socket is blocking */
 #ifdef ENABLE_CONNECT_UNIX
-int connect_unix(const char* addr)
-{
+int connect_unix(const char* addr) {
 	struct sockaddr_un egdsock;
 	int fd = -1;
 
 	memset((void*)&egdsock, 0x0, sizeof(egdsock));
 	egdsock.sun_family = AF_UNIX;
 	strlcpy(egdsock.sun_path, addr, sizeof(egdsock.sun_path));
-
 	fd = socket(PF_UNIX, SOCK_STREAM, 0);
-
 	return fd;
 }
 #endif
diff --git a/session.h b/session.h
index 5a4569e39902e111240d3ea8ce6356294faf021a..a3f72201f3348146bc27ee38e37828603417a4e1 100644
--- a/session.h
+++ b/session.h
@@ -215,6 +215,17 @@ 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,
diff --git a/sysoptions.h b/sysoptions.h
index 2de118408eb7258cd272a2f49a10c9e43f472314..28e146ca4b8ec24085826581c28d6d894c765a2f 100644
--- a/sysoptions.h
+++ b/sysoptions.h
@@ -146,10 +146,6 @@
 #define DISABLE_X11FWD
 #endif
 
-#ifndef ENABLE_AGENTFWD
-#define DISABLE_AGENTFWD
-#endif
-
 #if defined(ENABLE_CLI_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD)
 #define ENABLE_CLI_ANYTCPFWD 
 #endif
@@ -160,7 +156,7 @@
 
 #if defined(ENABLE_CLI_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD) || \
 	defined(ENABLE_SVR_REMOTETCPFWD) || defined(ENABLE_SVR_LOCALTCPFWD) || \
-	defined(ENABLE_AGENTFWD) || defined(ENABLE_X11FWD)
+	defined(ENABLE_SVR_AGENTFWD) || defined(ENABLE_X11FWD)
 #define USING_LISTENERS
 #endif
 
@@ -168,6 +164,10 @@
 #define ENABLE_CLI_MULTIHOP
 #endif
 
+#if defined(ENABLE_CLI_AGENTFWD) || defined(DROPBEAR_PRNGD_SOCKET)
+#define ENABLE_CONNECT_UNIX
+#endif
+
 #if defined(DROPBEAR_CLIENT) || defined(ENABLE_SVR_PUBKEY_AUTH)
 #define DROPBEAR_KEY_LINES /* ie we're using authorized_keys or known_hosts */
 #endif