mirror of
https://github.com/clearml/dropbear
synced 2025-03-09 13:30:45 +00:00
Mostly done with the listener changeover
--HG-- extra : convert_revision : 1a4dca8836a2a04a21fb675c718a549a8d445d25
This commit is contained in:
parent
444dbb5364
commit
9f369bc42f
@ -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
|
||||
|
12
dbutil.c
12
dbutil.c
@ -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);
|
||||
|
1
dbutil.h
1
dbutil.h
@ -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);
|
||||
|
122
svr-agentfwd.c
122
svr-agentfwd.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -71,7 +71,7 @@ out:
|
||||
}
|
||||
|
||||
static const struct ChanType chan_tcpremote = {
|
||||
0, /* sepfds */
|
||||
1, /* sepfds */
|
||||
"forwarded-tcpip",
|
||||
NULL,
|
||||
NULL,
|
||||
|
3
x11fwd.c
3
x11fwd.c
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user