Mostly done with the listener changeover

--HG--
extra : convert_revision : 1a4dca8836a2a04a21fb675c718a549a8d445d25
This commit is contained in:
Matt Johnston 2004-06-03 17:22:48 +00:00
parent 444dbb5364
commit 9f369bc42f
10 changed files with 94 additions and 64 deletions

View File

@ -30,9 +30,8 @@
#include "channel.h" #include "channel.h"
int agentreq(struct ChanSess * chansess); int agentreq(struct ChanSess * chansess);
int agentaccept(struct ChanSess * chansess);
void agentcleanup(struct ChanSess * chansess);
void agentsetauth(struct ChanSess *chansess); void agentsetauth(struct ChanSess *chansess);
void agentcleanup(struct ChanSess * chansess);
void agentset(struct ChanSess *chansess); void agentset(struct ChanSess *chansess);
#ifdef __hpux #ifdef __hpux

View File

@ -158,7 +158,7 @@ char* getaddrhostname(struct sockaddr * addr) {
retstring = host->h_name; retstring = host->h_name;
} }
return strdup(retstring); return m_strdup(retstring);
} }
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
void printhex(unsigned char* buf, int len) { void printhex(unsigned char* buf, int len) {
@ -263,6 +263,16 @@ void * m_malloc(size_t size) {
} }
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) { void __m_free(void* ptr) {
if (ptr != NULL) { if (ptr != NULL) {
free(ptr); free(ptr);

View File

@ -51,6 +51,7 @@ int buf_readfile(buffer* buf, const char* filename);
int m_close(int fd); int m_close(int fd);
void * m_malloc(size_t size); void * m_malloc(size_t size);
void * m_strdup(const char * str);
void * m_realloc(void* ptr, size_t size); void * m_realloc(void* ptr, size_t size);
#define m_free(X) __m_free(X); (X) = NULL; #define m_free(X) __m_free(X); (X) = NULL;
void __m_free(void* ptr); void __m_free(void* ptr);

View File

@ -38,45 +38,52 @@
#include "packet.h" #include "packet.h"
#include "buffer.h" #include "buffer.h"
#include "random.h" #include "random.h"
#include "listener.h"
#define AGENTDIRPREFIX "/tmp/dropbear-" #define AGENTDIRPREFIX "/tmp/dropbear-"
static int send_msg_channel_open_agent(int fd); 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. /* Handles client requests to start agent forwarding, sets up listening socket.
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
int agentreq(struct ChanSess * chansess) { int agentreq(struct ChanSess * chansess) {
if (chansess->agentfd != -1) { int fd;
if (chansess->agentlistener != NULL) {
return DROPBEAR_FAILURE; return DROPBEAR_FAILURE;
} }
/* create listening socket */ /* create listening socket */
chansess->agentfd = socket(PF_UNIX, SOCK_STREAM, 0); fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (chansess->agentfd < 0) { if (fd < 0) {
goto fail; goto fail;
} }
/* create the unix socket dir and file */ /* create the unix socket dir and file */
if (bindagent(chansess) == DROPBEAR_FAILURE) { if (bindagent(fd, chansess) == DROPBEAR_FAILURE) {
return DROPBEAR_FAILURE; return DROPBEAR_FAILURE;
} }
/* listen */ /* listen */
if (listen(chansess->agentfd, 20) < 0) { if (listen(fd, 20) < 0) {
goto fail; goto fail;
} }
/* set non-blocking */ /* set non-blocking */
if (fcntl(chansess->agentfd, F_SETFL, O_NONBLOCK) < 0) { if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
goto fail; 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 */ if (chansess->agentlistener == NULL) {
ses.maxfd = MAX(ses.maxfd, chansess->agentfd); goto fail;
}
return DROPBEAR_SUCCESS; return DROPBEAR_SUCCESS;
@ -90,16 +97,18 @@ fail:
/* accepts a connection on the forwarded socket and opens a new channel for it /* accepts a connection on the forwarded socket and opens a new channel for it
* back to the client */ * back to the client */
/* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ /* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
int agentaccept(struct ChanSess * chansess) { static void agentaccept(struct Listener * listener) {
int fd; int fd;
fd = accept(chansess->agentfd, NULL, NULL); fd = accept(listener->sock, NULL, NULL);
if (fd < 0) { 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 @@ void agentset(struct ChanSess * chansess) {
char *path = NULL; char *path = NULL;
int len; int len;
if (chansess->agentfd == -1) { if (chansess->agentlistener == NULL) {
return; return;
} }
@ -131,46 +140,57 @@ void agentcleanup(struct ChanSess * chansess) {
gid_t gid; gid_t gid;
int len; int len;
if (chansess->agentfd == -1) { if (chansess->agentlistener != NULL) {
return; remove_listener(chansess->agentlistener);
chansess->agentlistener = NULL;
} }
close(chansess->agentfd); if (chansess->agentfile && chansess->agentdir) {
/* Remove the dir as the user. That way they can't cause problems except /* Remove the dir as the user. That way they can't cause problems except
* for themselves */ * for themselves */
uid = getuid(); uid = getuid();
gid = getgid(); gid = getgid();
if ((setegid(svr_ses.authstate.pw->pw_gid)) < 0 || if ((setegid(svr_ses.authstate.pw->pw_gid)) < 0 ||
(seteuid(svr_ses.authstate.pw->pw_uid)) < 0) { (seteuid(svr_ses.authstate.pw->pw_uid)) < 0) {
dropbear_exit("failed to set euid"); 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);
rmdir(chansess->agentdir);
if ((seteuid(uid)) < 0 ||
(setegid(gid)) < 0) {
dropbear_exit("failed to revert euid");
}
m_free(chansess->agentfile);
m_free(chansess->agentdir);
} }
/* 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);
rmdir(chansess->agentdir);
if ((seteuid(uid)) < 0 ||
(setegid(gid)) < 0) {
dropbear_exit("failed to revert euid");
}
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 */ /* helper for accepting an agent request */
static int send_msg_channel_open_agent(int fd) { static int send_msg_channel_open_agent(int fd) {
if (send_msg_channel_open_init(fd, CHANNEL_ID_AGENT, if (send_msg_channel_open_init(fd, &chan_agent) == DROPBEAR_SUCCESS) {
"auth-agent@openssh.com") == DROPBEAR_SUCCESS) {
encrypt_packet(); encrypt_packet();
return DROPBEAR_SUCCESS; return DROPBEAR_SUCCESS;
} else { } else {
@ -180,7 +200,7 @@ static int send_msg_channel_open_agent(int fd) {
/* helper for creating the agent socket-file /* helper for creating the agent socket-file
returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
static int bindagent(struct ChanSess * chansess) { static int bindagent(int fd, struct ChanSess * chansess) {
struct sockaddr_un addr; struct sockaddr_un addr;
unsigned int prefix; unsigned int prefix;
@ -225,13 +245,13 @@ bindsocket:
* between subsequent user processes reusing socket fds (odds are now * between subsequent user processes reusing socket fds (odds are now
* 1/(2^64) */ * 1/(2^64) */
genrandom((unsigned char*)&prefix, sizeof(prefix)); genrandom((unsigned char*)&prefix, sizeof(prefix));
snprintf(sockfile, sizeof(sockfile), "auth-%.8x-%d", prefix, snprintf(sockfile, sizeof(sockfile), "auth-%.8x-%d", prefix, fd);
chansess->agentfd);
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, sockfile); snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, sockfile);
if (bind(chansess->agentfd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
chansess->agentdir = strdup(path); chansess->agentdir = m_strdup(path);
chansess->agentfile = strdup(sockfile); chansess->agentfile = m_strdup(sockfile);
ret = DROPBEAR_SUCCESS; ret = DROPBEAR_SUCCESS;
} }

View File

@ -151,7 +151,7 @@ void recv_msg_userauth_request() {
if (methodlen == AUTH_METHOD_PASSWORD_LEN && if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
strncmp(methodname, AUTH_METHOD_PASSWORD, strncmp(methodname, AUTH_METHOD_PASSWORD,
AUTH_METHOD_PASSWORD_LEN) == 0) { AUTH_METHOD_PASSWORD_LEN) == 0) {
passwordauth(username, userlen); passwordauth();
goto out; goto out;
} }
} }
@ -162,7 +162,7 @@ void recv_msg_userauth_request() {
if (methodlen == AUTH_METHOD_PUBKEY_LEN && if (methodlen == AUTH_METHOD_PUBKEY_LEN &&
strncmp(methodname, AUTH_METHOD_PUBKEY, strncmp(methodname, AUTH_METHOD_PUBKEY,
AUTH_METHOD_PUBKEY_LEN) == 0) { AUTH_METHOD_PUBKEY_LEN) == 0) {
pubkeyauth(username, userlen); pubkeyauth();
goto out; goto out;
} }
#endif #endif
@ -200,7 +200,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
} }
authclear(); authclear();
svr_ses.authstate.pw = getpwnam((char*)username); 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); m_free(svr_ses.authstate.printableuser);
} }
@ -214,7 +214,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
} }
/* We can set it once we know its a real user */ /* 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 */ /* check for non-root if desired */
if (ses.opts->norootlogin && svr_ses.authstate.pw->pw_uid == 0) { if (ses.opts->norootlogin && svr_ses.authstate.pw->pw_uid == 0) {

View File

@ -419,7 +419,7 @@ static int sessionpty(struct ChanSess * chansess) {
return DROPBEAR_FAILURE; return DROPBEAR_FAILURE;
} }
chansess->tty = (char*)strdup(namebuf); chansess->tty = (char*)m_strdup(namebuf);
if (!chansess->tty) { if (!chansess->tty) {
dropbear_exit("out of memory"); /* TODO disconnect */ dropbear_exit("out of memory"); /* TODO disconnect */
} }
@ -541,7 +541,7 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
#ifdef SFTPSERVER_PATH #ifdef SFTPSERVER_PATH
if ((cmdlen == 4) && strncmp(chansess->cmd, "sftp", 4) == 0) { if ((cmdlen == 4) && strncmp(chansess->cmd, "sftp", 4) == 0) {
m_free(chansess->cmd); m_free(chansess->cmd);
chansess->cmd = strdup(SFTPSERVER_PATH); chansess->cmd = m_strdup(SFTPSERVER_PATH);
} else } else
#endif #endif
{ {

View File

@ -9,7 +9,7 @@ static int newtcpdirect(struct Channel * channel);
static int newtcp(const char * host, int port); static int newtcp(const char * host, int port);
const struct ChanType chan_tcpdirect = { const struct ChanType chan_tcpdirect = {
0, /* sepfds */ 1, /* sepfds */
"direct-tcpip", "direct-tcpip",
newtcpdirect, /* init */ newtcpdirect, /* init */
NULL, /* checkclose */ NULL, /* checkclose */

View File

@ -71,7 +71,7 @@ out:
} }
static const struct ChanType chan_tcpremote = { static const struct ChanType chan_tcpremote = {
0, /* sepfds */ 1, /* sepfds */
"forwarded-tcpip", "forwarded-tcpip",
NULL, NULL,
NULL, NULL,

View File

@ -38,7 +38,6 @@
#define X11BINDBASE 6010 #define X11BINDBASE 6010
static void x11accept(struct Listener* listener); static void x11accept(struct Listener* listener);
static void x11cleanup(struct Listener *listener);
static int bindport(int fd); static int bindport(int fd);
static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr); static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr);
@ -167,7 +166,7 @@ void x11setauth(struct ChanSess *chansess) {
} }
} }
static void x11cleanup(struct Listener *listener) { void x11cleanup(struct Listener *listener) {
struct ChanSess *chansess = (struct ChanSess*)listener->typedata; struct ChanSess *chansess = (struct ChanSess*)listener->typedata;

View File

@ -31,6 +31,7 @@
int x11req(struct ChanSess * chansess); int x11req(struct ChanSess * chansess);
void x11setauth(struct ChanSess *chansess); void x11setauth(struct ChanSess *chansess);
void x11cleanup(struct Listener *listener);
#endif /* DROPBEAR_X11FWD */ #endif /* DROPBEAR_X11FWD */
#endif /* _X11FWD_H_ */ #endif /* _X11FWD_H_ */