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"
int agentreq(struct ChanSess * chansess);
int agentaccept(struct ChanSess * chansess);
void agentcleanup(struct ChanSess * chansess);
void agentsetauth(struct ChanSess *chansess);
void agentcleanup(struct ChanSess * chansess);
void agentset(struct ChanSess *chansess);
#ifdef __hpux

View File

@ -158,7 +158,7 @@ char* getaddrhostname(struct sockaddr * addr) {
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_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) {
if (ptr != NULL) {
free(ptr);

View File

@ -51,6 +51,7 @@ int buf_readfile(buffer* buf, const char* filename);
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);

View File

@ -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 @@ fail:
/* 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 @@ void agentset(struct ChanSess * chansess) {
char *path = NULL;
int len;
if (chansess->agentfd == -1) {
if (chansess->agentlistener == NULL) {
return;
}
@ -131,46 +140,57 @@ void agentcleanup(struct ChanSess * chansess) {
gid_t gid;
int len;
if (chansess->agentfd == -1) {
return;
if (chansess->agentlistener != NULL) {
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
* 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");
/* 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);
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 */
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 @@ static int send_msg_channel_open_agent(int fd) {
/* 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 @@ bindsocket:
* 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;
}

View File

@ -151,7 +151,7 @@ void recv_msg_userauth_request() {
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 @@ void recv_msg_userauth_request() {
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 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
}
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 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
}
/* 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) {

View File

@ -419,7 +419,7 @@ static int sessionpty(struct ChanSess * chansess) {
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 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
#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
{

View File

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

View File

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

View File

@ -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 @@ void x11setauth(struct ChanSess *chansess) {
}
}
static void x11cleanup(struct Listener *listener) {
void x11cleanup(struct Listener *listener) {
struct ChanSess *chansess = (struct ChanSess*)listener->typedata;

View File

@ -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_ */