changeset 11:f76c9389e9e0

Mostly done with the listener changeover
author Matt Johnston <matt@ucc.asn.au>
date Thu, 03 Jun 2004 17:22:48 +0000
parents 7f77962de998
children 7a37cff27258
files agentfwd.h dbutil.c dbutil.h svr-agentfwd.c svr-auth.c svr-chansession.c tcpfwd-direct.c tcpfwd-remote.c x11fwd.c x11fwd.h
diffstat 10 files changed, 92 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/agentfwd.h	Thu Jun 03 16:45:53 2004 +0000
+++ b/agentfwd.h	Thu Jun 03 17:22:48 2004 +0000
@@ -30,9 +30,8 @@
 #include "channel.h"
 
 int agentreq(struct ChanSess * chansess);
-int agentaccept(struct ChanSess * chansess);
+void agentsetauth(struct ChanSess *chansess);
 void agentcleanup(struct ChanSess * chansess);
-void agentsetauth(struct ChanSess *chansess);
 void agentset(struct ChanSess *chansess);
 
 #ifdef __hpux
--- a/dbutil.c	Thu Jun 03 16:45:53 2004 +0000
+++ b/dbutil.c	Thu Jun 03 17:22:48 2004 +0000
@@ -158,7 +158,7 @@
 		retstring = host->h_name;
 	}
 
-	return strdup(retstring);
+	return m_strdup(retstring);
 }
 #ifdef DEBUG_TRACE
 void printhex(unsigned char* buf, int len) {
@@ -263,6 +263,16 @@
 
 }
 
+void * m_strdup(const char * str) {
+	char* ret;
+
+	ret = strdup(str);
+	if (ret == NULL) {
+		dropbear_exit("m_strdup failed");
+	}
+	return ret;
+}
+
 void __m_free(void* ptr) {
 	if (ptr != NULL) {
 		free(ptr);
--- a/dbutil.h	Thu Jun 03 16:45:53 2004 +0000
+++ b/dbutil.h	Thu Jun 03 17:22:48 2004 +0000
@@ -51,6 +51,7 @@
 
 int m_close(int fd);
 void * m_malloc(size_t size);
+void * m_strdup(const char * str);
 void * m_realloc(void* ptr, size_t size);
 #define m_free(X) __m_free(X); (X) = NULL;
 void __m_free(void* ptr);
--- a/svr-agentfwd.c	Thu Jun 03 16:45:53 2004 +0000
+++ b/svr-agentfwd.c	Thu Jun 03 17:22:48 2004 +0000
@@ -38,45 +38,52 @@
 #include "packet.h"
 #include "buffer.h"
 #include "random.h"
+#include "listener.h"
 
 #define AGENTDIRPREFIX "/tmp/dropbear-"
 
 static int send_msg_channel_open_agent(int fd);
-static int bindagent(struct ChanSess * chansess);
+static int bindagent(int fd, struct ChanSess * chansess);
+static void agentaccept(struct Listener * listener);
 
 /* Handles client requests to start agent forwarding, sets up listening socket.
  * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
 int agentreq(struct ChanSess * chansess) {
 
-	if (chansess->agentfd != -1) {
+	int fd;
+
+	if (chansess->agentlistener != NULL) {
 		return DROPBEAR_FAILURE;
 	}
 
 	/* create listening socket */
-	chansess->agentfd = socket(PF_UNIX, SOCK_STREAM, 0);
-	if (chansess->agentfd < 0) {
+	fd = socket(PF_UNIX, SOCK_STREAM, 0);
+	if (fd < 0) {
 		goto fail;
 	}
 
 	/* create the unix socket dir and file */
-	if (bindagent(chansess) == DROPBEAR_FAILURE) {
+	if (bindagent(fd, chansess) == DROPBEAR_FAILURE) {
 		return DROPBEAR_FAILURE;
 	}
 
 	/* listen */
-	if (listen(chansess->agentfd, 20) < 0) {
+	if (listen(fd, 20) < 0) {
 		goto fail;
 	}
 
 	/* set non-blocking */
-	if (fcntl(chansess->agentfd, F_SETFL, O_NONBLOCK) < 0) {
+	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
 		goto fail;
 	}
 
-	/* channel.c's channel fd code will handle the socket now */
+	/* pass if off to listener */
+	chansess->agentlistener = new_listener( fd, 0, chansess, 
+								agentaccept, NULL);
 
-	/* set the maxfd so that select() loop will notice it */
-	ses.maxfd = MAX(ses.maxfd, chansess->agentfd);
+	if (chansess->agentlistener == NULL) {
+		goto fail;
+	}
 
 	return DROPBEAR_SUCCESS;
 
@@ -90,16 +97,18 @@
 /* accepts a connection on the forwarded socket and opens a new channel for it
  * back to the client */
 /* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
-int agentaccept(struct ChanSess * chansess) {
+static void agentaccept(struct Listener * listener) {
 
 	int fd;
 
-	fd = accept(chansess->agentfd, NULL, NULL);
+	fd = accept(listener->sock, NULL, NULL);
 	if (fd < 0) {
-		return DROPBEAR_FAILURE;
+		return;
 	}
 
-	return send_msg_channel_open_agent(fd);
+	if (send_msg_channel_open_agent(listener->sock) != DROPBEAR_SUCCESS) {
+		close(fd);
+	}
 
 }
 
@@ -110,7 +119,7 @@
 	char *path = NULL;
 	int len;
 
-	if (chansess->agentfd == -1) {
+	if (chansess->agentlistener == NULL) {
 		return;
 	}
 
@@ -131,46 +140,57 @@
 	gid_t gid;
 	int len;
 
-	if (chansess->agentfd == -1) {
-		return;
-	}
-
-	close(chansess->agentfd);
-
-	/* Remove the dir as the user. That way they can't cause problems except
-	 * for themselves */
-	uid = getuid();
-	gid = getgid();
-	if ((setegid(svr_ses.authstate.pw->pw_gid)) < 0 ||
-		(seteuid(svr_ses.authstate.pw->pw_uid)) < 0) {
-		dropbear_exit("failed to set euid");
+	if (chansess->agentlistener != NULL) {
+		remove_listener(chansess->agentlistener);
+		chansess->agentlistener = NULL;
 	}
 
-	/* 2 for "/" and "\0" */
-	len = strlen(chansess->agentdir) + strlen(chansess->agentfile) + 2;
+	if (chansess->agentfile && chansess->agentdir) {
+
+		/* Remove the dir as the user. That way they can't cause problems except
+		 * for themselves */
+		uid = getuid();
+		gid = getgid();
+		if ((setegid(svr_ses.authstate.pw->pw_gid)) < 0 ||
+			(seteuid(svr_ses.authstate.pw->pw_uid)) < 0) {
+			dropbear_exit("failed to set euid");
+		}
+
+		/* 2 for "/" and "\0" */
+		len = strlen(chansess->agentdir) + strlen(chansess->agentfile) + 2;
 
-	path = m_malloc(len);
-	snprintf(path, len, "%s/%s", chansess->agentdir, chansess->agentfile);
-	unlink(path);
-	m_free(path);
+		path = m_malloc(len);
+		snprintf(path, len, "%s/%s", chansess->agentdir, chansess->agentfile);
+		unlink(path);
+		m_free(path);
+
+		rmdir(chansess->agentdir);
 
-	rmdir(chansess->agentdir);
+		if ((seteuid(uid)) < 0 ||
+			(setegid(gid)) < 0) {
+			dropbear_exit("failed to revert euid");
+		}
 
-	if ((seteuid(uid)) < 0 ||
-		(setegid(gid)) < 0) {
-		dropbear_exit("failed to revert euid");
+		m_free(chansess->agentfile);
+		m_free(chansess->agentdir);
 	}
 
-	m_free(chansess->agentfile);
-	m_free(chansess->agentdir);
+}
 
-}
+static const struct ChanType chan_agent = {
+	0, /* sepfds */
+	"[email protected]",
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 
 /* helper for accepting an agent request */
 static int send_msg_channel_open_agent(int fd) {
 
-	if (send_msg_channel_open_init(fd, CHANNEL_ID_AGENT,
-				"[email protected]") == DROPBEAR_SUCCESS) {
+	if (send_msg_channel_open_init(fd, &chan_agent) == DROPBEAR_SUCCESS) {
 		encrypt_packet();
 		return DROPBEAR_SUCCESS;
 	} else {
@@ -180,7 +200,7 @@
 
 /* helper for creating the agent socket-file
    returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
-static int bindagent(struct ChanSess * chansess) {
+static int bindagent(int fd, struct ChanSess * chansess) {
 
 	struct sockaddr_un addr;
 	unsigned int prefix;
@@ -225,13 +245,13 @@
 	 * between subsequent user processes reusing socket fds (odds are now
 	 * 1/(2^64) */
 	genrandom((unsigned char*)&prefix, sizeof(prefix));
-	snprintf(sockfile, sizeof(sockfile), "auth-%.8x-%d", prefix,
-			chansess->agentfd);
+	snprintf(sockfile, sizeof(sockfile), "auth-%.8x-%d", prefix, fd);
+			
 	snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, sockfile);
 
-	if (bind(chansess->agentfd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
-		chansess->agentdir = strdup(path);
-		chansess->agentfile = strdup(sockfile);
+	if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
+		chansess->agentdir = m_strdup(path);
+		chansess->agentfile = m_strdup(sockfile);
 		ret = DROPBEAR_SUCCESS;
 	}
 
--- a/svr-auth.c	Thu Jun 03 16:45:53 2004 +0000
+++ b/svr-auth.c	Thu Jun 03 17:22:48 2004 +0000
@@ -151,7 +151,7 @@
 		if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
 				strncmp(methodname, AUTH_METHOD_PASSWORD,
 					AUTH_METHOD_PASSWORD_LEN) == 0) {
-			passwordauth(username, userlen);
+			passwordauth();
 			goto out;
 		}
 	}
@@ -162,7 +162,7 @@
 	if (methodlen == AUTH_METHOD_PUBKEY_LEN &&
 			strncmp(methodname, AUTH_METHOD_PUBKEY,
 				AUTH_METHOD_PUBKEY_LEN) == 0) {
-		pubkeyauth(username, userlen);
+		pubkeyauth();
 		goto out;
 	}
 #endif
@@ -200,7 +200,7 @@
 			}
 			authclear();
 			svr_ses.authstate.pw = getpwnam((char*)username);
-			svr_ses.authstate.username = strdup(username);
+			svr_ses.authstate.username = m_strdup(username);
 			m_free(svr_ses.authstate.printableuser);
 	}
 
@@ -214,7 +214,7 @@
 	}
 
 	/* We can set it once we know its a real user */
-	svr_ses.authstate.printableuser = strdup(svr_ses.authstate.pw->pw_name);
+	svr_ses.authstate.printableuser = m_strdup(svr_ses.authstate.pw->pw_name);
 
 	/* check for non-root if desired */
 	if (ses.opts->norootlogin && svr_ses.authstate.pw->pw_uid == 0) {
--- a/svr-chansession.c	Thu Jun 03 16:45:53 2004 +0000
+++ b/svr-chansession.c	Thu Jun 03 17:22:48 2004 +0000
@@ -419,7 +419,7 @@
 		return DROPBEAR_FAILURE;
 	}
 	
-	chansess->tty = (char*)strdup(namebuf);
+	chansess->tty = (char*)m_strdup(namebuf);
 	if (!chansess->tty) {
 		dropbear_exit("out of memory"); /* TODO disconnect */
 	}
@@ -541,7 +541,7 @@
 #ifdef SFTPSERVER_PATH
 			if ((cmdlen == 4) && strncmp(chansess->cmd, "sftp", 4) == 0) {
 				m_free(chansess->cmd);
-				chansess->cmd = strdup(SFTPSERVER_PATH);
+				chansess->cmd = m_strdup(SFTPSERVER_PATH);
 			} else 
 #endif
 			{
--- a/tcpfwd-direct.c	Thu Jun 03 16:45:53 2004 +0000
+++ b/tcpfwd-direct.c	Thu Jun 03 17:22:48 2004 +0000
@@ -9,7 +9,7 @@
 static int newtcp(const char * host, int port);
 
 const struct ChanType chan_tcpdirect = {
-	0, /* sepfds */
+	1, /* sepfds */
 	"direct-tcpip",
 	newtcpdirect, /* init */
 	NULL, /* checkclose */
--- a/tcpfwd-remote.c	Thu Jun 03 16:45:53 2004 +0000
+++ b/tcpfwd-remote.c	Thu Jun 03 17:22:48 2004 +0000
@@ -71,7 +71,7 @@
 }
 
 static const struct ChanType chan_tcpremote = {
-	0, /* sepfds */
+	1, /* sepfds */
 	"forwarded-tcpip",
 	NULL,
 	NULL,
--- a/x11fwd.c	Thu Jun 03 16:45:53 2004 +0000
+++ b/x11fwd.c	Thu Jun 03 17:22:48 2004 +0000
@@ -38,7 +38,6 @@
 #define X11BINDBASE 6010
 
 static void x11accept(struct Listener* listener);
-static void x11cleanup(struct Listener *listener);
 static int bindport(int fd);
 static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr);
 
@@ -167,7 +166,7 @@
 	}
 }
 
-static void x11cleanup(struct Listener *listener) {
+void x11cleanup(struct Listener *listener) {
 
 	struct ChanSess *chansess = (struct ChanSess*)listener->typedata;
 
--- a/x11fwd.h	Thu Jun 03 16:45:53 2004 +0000
+++ b/x11fwd.h	Thu Jun 03 17:22:48 2004 +0000
@@ -31,6 +31,7 @@
 
 int x11req(struct ChanSess * chansess);
 void x11setauth(struct ChanSess *chansess);
+void x11cleanup(struct Listener *listener);
 
 #endif /* DROPBEAR_X11FWD */
 #endif /* _X11FWD_H_ */