# HG changeset patch # User Matt Johnston # Date 1086283368 0 # Node ID f76c9389e9e044fa037452e874bb9bb5c259928c # Parent 7f77962de9987ef152b792d6b69d3f67f2334986 Mostly done with the listener changeover diff -r 7f77962de998 -r f76c9389e9e0 agentfwd.h --- 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 diff -r 7f77962de998 -r f76c9389e9e0 dbutil.c --- 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); diff -r 7f77962de998 -r f76c9389e9e0 dbutil.h --- 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); diff -r 7f77962de998 -r f76c9389e9e0 svr-agentfwd.c --- 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 */ + "auth-agent@openssh.com", + 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, - "auth-agent@openssh.com") == 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; } diff -r 7f77962de998 -r f76c9389e9e0 svr-auth.c --- 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) { diff -r 7f77962de998 -r f76c9389e9e0 svr-chansession.c --- 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 { diff -r 7f77962de998 -r f76c9389e9e0 tcpfwd-direct.c --- 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 */ diff -r 7f77962de998 -r f76c9389e9e0 tcpfwd-remote.c --- 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, diff -r 7f77962de998 -r f76c9389e9e0 x11fwd.c --- 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; diff -r 7f77962de998 -r f76c9389e9e0 x11fwd.h --- 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_ */