mirror of
https://github.com/clearml/dropbear
synced 2025-03-09 21:41:07 +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"
|
#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
|
||||||
|
12
dbutil.c
12
dbutil.c
@ -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);
|
||||||
|
1
dbutil.h
1
dbutil.h
@ -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);
|
||||||
|
122
svr-agentfwd.c
122
svr-agentfwd.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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 */
|
||||||
|
@ -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,
|
||||||
|
3
x11fwd.c
3
x11fwd.c
@ -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;
|
||||||
|
|
||||||
|
1
x11fwd.h
1
x11fwd.h
@ -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_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user