mirror of
https://github.com/clearml/dropbear
synced 2025-03-03 18:52:00 +00:00
merge of 50be59810e462f9f44f55e421227d6aa0b31982b
and 69b007796063cb5f042be7cca2d479e90db869c3 --HG-- extra : convert_revision : 5d0dfaa8c0ee6c728a3b4f0f0855199ba729db83
This commit is contained in:
parent
51a74b4799
commit
69282617fd
@ -341,8 +341,14 @@ static int cli_initchansess(struct Channel *channel) {
|
|||||||
|
|
||||||
|
|
||||||
channel->infd = STDOUT_FILENO;
|
channel->infd = STDOUT_FILENO;
|
||||||
|
setnonblocking(STDOUT_FILENO);
|
||||||
|
|
||||||
channel->outfd = STDIN_FILENO;
|
channel->outfd = STDIN_FILENO;
|
||||||
|
setnonblocking(STDIN_FILENO);
|
||||||
|
|
||||||
channel->errfd = STDERR_FILENO;
|
channel->errfd = STDERR_FILENO;
|
||||||
|
setnonblocking(STDERR_FILENO);
|
||||||
|
|
||||||
channel->extrabuf = cbuf_new(RECV_MAXWINDOW);
|
channel->extrabuf = cbuf_new(RECV_MAXWINDOW);
|
||||||
|
|
||||||
if (cli_opts.wantpty) {
|
if (cli_opts.wantpty) {
|
||||||
|
@ -52,6 +52,10 @@ int main(int argc, char ** argv) {
|
|||||||
TRACE(("user='%s' host='%s' port='%s'", cli_opts.username,
|
TRACE(("user='%s' host='%s' port='%s'", cli_opts.username,
|
||||||
cli_opts.remotehost, cli_opts.remoteport));
|
cli_opts.remotehost, cli_opts.remoteport));
|
||||||
|
|
||||||
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
|
||||||
|
dropbear_exit("signal() error");
|
||||||
|
}
|
||||||
|
|
||||||
sock = connect_remote(cli_opts.remotehost, cli_opts.remoteport,
|
sock = connect_remote(cli_opts.remotehost, cli_opts.remoteport,
|
||||||
0, &error);
|
0, &error);
|
||||||
|
|
||||||
|
@ -192,7 +192,8 @@ void channelio(fd_set *readfd, fd_set *writefd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read from program/pipe stderr */
|
/* read from program/pipe stderr */
|
||||||
if (channel->errfd >= 0 && FD_ISSET(channel->errfd, readfd)) {
|
if (channel->extrabuf == NULL &&
|
||||||
|
channel->errfd >= 0 && FD_ISSET(channel->errfd, readfd)) {
|
||||||
send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR);
|
send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +246,14 @@ void channelio(fd_set *readfd, fd_set *writefd) {
|
|||||||
/* do all the EOF/close type stuff checking for a channel */
|
/* do all the EOF/close type stuff checking for a channel */
|
||||||
static void checkclose(struct Channel *channel) {
|
static void checkclose(struct Channel *channel) {
|
||||||
|
|
||||||
|
TRACE(("checkclose: infd %d, outfd %d, errfd %d, sentclosed %d, recvclosed %d",
|
||||||
|
channel->infd, channel->outfd,
|
||||||
|
channel->errfd, channel->sentclosed, channel->recvclosed));
|
||||||
|
TRACE(("writebuf %d extrabuf %s extrabuf %d",
|
||||||
|
cbuf_getused(channel->writebuf),
|
||||||
|
channel->writebuf,
|
||||||
|
channel->writebuf ? 0 : cbuf_getused(channel->extrabuf)));
|
||||||
|
|
||||||
if (!channel->sentclosed) {
|
if (!channel->sentclosed) {
|
||||||
|
|
||||||
/* check for exited - currently only used for server sessions,
|
/* check for exited - currently only used for server sessions,
|
||||||
@ -257,13 +266,13 @@ static void checkclose(struct Channel *channel) {
|
|||||||
|
|
||||||
if (!channel->senteof
|
if (!channel->senteof
|
||||||
&& channel->outfd == FD_CLOSED
|
&& channel->outfd == FD_CLOSED
|
||||||
&& channel->errfd == FD_CLOSED) {
|
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
|
||||||
send_msg_channel_eof(channel);
|
send_msg_channel_eof(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->infd == FD_CLOSED
|
if (channel->infd == FD_CLOSED
|
||||||
&& channel->outfd == FD_CLOSED
|
&& channel->outfd == FD_CLOSED
|
||||||
&& channel->errfd == FD_CLOSED) {
|
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
|
||||||
send_msg_channel_close(channel);
|
send_msg_channel_close(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -383,9 +392,8 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) {
|
|||||||
if (fd == channel->infd && len == maxlen && channel->recveof) {
|
if (fd == channel->infd && len == maxlen && channel->recveof) {
|
||||||
/* Check if we're closing up */
|
/* Check if we're closing up */
|
||||||
closeinfd(channel);
|
closeinfd(channel);
|
||||||
return;
|
|
||||||
TRACE(("leave writechannel: recveof set"));
|
TRACE(("leave writechannel: recveof set"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Window adjust handling */
|
/* Window adjust handling */
|
||||||
@ -433,7 +441,9 @@ void setchannelfds(fd_set *readfd, fd_set *writefd) {
|
|||||||
|
|
||||||
/* For checking FD status (ie closure etc) - we don't actually
|
/* For checking FD status (ie closure etc) - we don't actually
|
||||||
* read data from infd */
|
* read data from infd */
|
||||||
TRACE(("infd = %d, outfd %d, bufused %d", channel->infd, channel->outfd,
|
TRACE(("infd = %d, outfd %d, errfd %d, bufused %d",
|
||||||
|
channel->infd, channel->outfd,
|
||||||
|
channel->errfd,
|
||||||
cbuf_getused(channel->writebuf) ));
|
cbuf_getused(channel->writebuf) ));
|
||||||
if (channel->infd >= 0 && channel->infd != channel->outfd) {
|
if (channel->infd >= 0 && channel->infd != channel->outfd) {
|
||||||
FD_SET(channel->infd, readfd);
|
FD_SET(channel->infd, readfd);
|
||||||
@ -534,9 +544,8 @@ static void removechannel(struct Channel * channel) {
|
|||||||
* yet (ie they were shutdown etc */
|
* yet (ie they were shutdown etc */
|
||||||
close(channel->infd);
|
close(channel->infd);
|
||||||
close(channel->outfd);
|
close(channel->outfd);
|
||||||
if (channel->errfd >= 0) {
|
close(channel->errfd);
|
||||||
close(channel->errfd);
|
|
||||||
}
|
|
||||||
channel->typedata = NULL;
|
channel->typedata = NULL;
|
||||||
|
|
||||||
deletechannel(channel);
|
deletechannel(channel);
|
||||||
@ -619,16 +628,19 @@ static void send_msg_channel_data(struct Channel *channel, int isextended,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read the data */
|
/* read the data */
|
||||||
|
TRACE(("maxlen %d", maxlen));
|
||||||
buf = buf_new(maxlen);
|
buf = buf_new(maxlen);
|
||||||
|
TRACE(("buf pos %d data %x", buf->pos, buf->data));
|
||||||
len = read(fd, buf_getwriteptr(buf, maxlen), maxlen);
|
len = read(fd, buf_getwriteptr(buf, maxlen), maxlen);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
/* on error/eof, send eof */
|
/* on error/eof, send eof */
|
||||||
if (len == 0 || errno != EINTR) {
|
if (len == 0 || errno != EINTR) {
|
||||||
closeoutfd(channel, fd);
|
closeoutfd(channel, fd);
|
||||||
TRACE(("leave send_msg_channel_data: read err %d", channel->index));
|
|
||||||
}
|
}
|
||||||
buf_free(buf);
|
buf_free(buf);
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
|
TRACE(("leave send_msg_channel_data: read err or EOF for fd %d",
|
||||||
|
channel->index));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buf_incrlen(buf, len);
|
buf_incrlen(buf, len);
|
||||||
@ -714,7 +726,7 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd,
|
|||||||
len -= buflen;
|
len -= buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(channel->recvwindow > datalen);
|
assert(channel->recvwindow >= datalen);
|
||||||
channel->recvwindow -= datalen;
|
channel->recvwindow -= datalen;
|
||||||
assert(channel->recvwindow <= RECV_MAXWINDOW);
|
assert(channel->recvwindow <= RECV_MAXWINDOW);
|
||||||
|
|
||||||
@ -927,10 +939,7 @@ int send_msg_channel_open_init(int fd, const struct ChanType *type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set fd non-blocking */
|
/* set fd non-blocking */
|
||||||
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
|
setnonblocking(fd);
|
||||||
TRACE(("leave send_msg_channel_open_init() - FAILED in fcntl()"));
|
|
||||||
return DROPBEAR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
chan->infd = chan->outfd = fd;
|
chan->infd = chan->outfd = fd;
|
||||||
ses.maxfd = MAX(ses.maxfd, fd);
|
ses.maxfd = MAX(ses.maxfd, fd);
|
||||||
@ -1034,15 +1043,19 @@ static void closechanfd(struct Channel *channel, int fd, int how) {
|
|||||||
closein = closeout = 1;
|
closein = closeout = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closeout && fd == channel->errfd) {
|
|
||||||
channel->errfd = FD_CLOSED;
|
|
||||||
}
|
|
||||||
if (closeout && fd == channel->outfd) {
|
if (closeout && fd == channel->outfd) {
|
||||||
channel->outfd = FD_CLOSED;
|
channel->outfd = FD_CLOSED;
|
||||||
}
|
}
|
||||||
|
if (closeout && (channel->extrabuf == NULL) && (fd == channel->errfd)) {
|
||||||
|
channel->errfd = FD_CLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
if (closein && fd == channel->infd) {
|
if (closein && fd == channel->infd) {
|
||||||
channel->infd = FD_CLOSED;
|
channel->infd = FD_CLOSED;
|
||||||
}
|
}
|
||||||
|
if (closein && (channel->extrabuf != NULL) && (fd == channel->errfd)) {
|
||||||
|
channel->errfd = FD_CLOSED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USING_LISTENERS */
|
#endif /* USING_LISTENERS */
|
||||||
|
10
dbutil.c
10
dbutil.c
@ -595,3 +595,13 @@ void m_burn(void *data, unsigned int len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setnonblocking(int fd) {
|
||||||
|
|
||||||
|
TRACE(("setnonblocking: %d", fd));
|
||||||
|
|
||||||
|
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
|
||||||
|
dropbear_exit("Couldn't set nonblocking");
|
||||||
|
}
|
||||||
|
TRACE(("leave setnonblocking"));
|
||||||
|
}
|
||||||
|
1
dbutil.h
1
dbutil.h
@ -61,6 +61,7 @@ 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);
|
||||||
void m_burn(void* data, unsigned int len);
|
void m_burn(void* data, unsigned int len);
|
||||||
|
void setnonblocking(int fd);
|
||||||
|
|
||||||
/* Used to force mp_ints to be initialised */
|
/* Used to force mp_ints to be initialised */
|
||||||
#define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL}
|
#define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL}
|
||||||
|
8
debug.h
8
debug.h
@ -33,12 +33,13 @@
|
|||||||
* etc. Don't use this normally, it might cause problems */
|
* etc. Don't use this normally, it might cause problems */
|
||||||
/* #define DEBUG_VALGRIND */
|
/* #define DEBUG_VALGRIND */
|
||||||
|
|
||||||
/* Define this to compile in trace debugging printf()s. You'll need to
|
/* Define this to compile in trace debugging printf()s.
|
||||||
* run programs with "-v" to turn this on.
|
* You'll need to run programs with "-v" to turn this on.
|
||||||
|
*
|
||||||
* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
|
* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
|
||||||
* since the printing may not sanitise strings etc. This will add a reasonable
|
* since the printing may not sanitise strings etc. This will add a reasonable
|
||||||
* amount to your executable size. */
|
* amount to your executable size. */
|
||||||
#define DEBUG_TRACE
|
/* #define DEBUG_TRACE */
|
||||||
|
|
||||||
/* All functions writing to the cleartext payload buffer call
|
/* All functions writing to the cleartext payload buffer call
|
||||||
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're
|
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're
|
||||||
@ -49,6 +50,7 @@
|
|||||||
/* Define this, compile with -pg and set GMON_OUT_PREFIX=gmon to get gmon
|
/* Define this, compile with -pg and set GMON_OUT_PREFIX=gmon to get gmon
|
||||||
* output when Dropbear forks. This will allow it gprof to be used.
|
* output when Dropbear forks. This will allow it gprof to be used.
|
||||||
* It's useful to run dropbear -F, so you don't fork as much */
|
* It's useful to run dropbear -F, so you don't fork as much */
|
||||||
|
/* (This is Linux specific) */
|
||||||
/*#define DEBUG_FORKGPROF*/
|
/*#define DEBUG_FORKGPROF*/
|
||||||
|
|
||||||
/* A couple of flags, not usually useful, and mightn't do anything */
|
/* A couple of flags, not usually useful, and mightn't do anything */
|
||||||
|
@ -73,9 +73,7 @@ int agentreq(struct ChanSess * chansess) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set non-blocking */
|
/* set non-blocking */
|
||||||
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
|
setnonblocking(fd);
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pass if off to listener */
|
/* pass if off to listener */
|
||||||
chansess->agentlistener = new_listener( &fd, 1, 0, chansess,
|
chansess->agentlistener = new_listener( &fd, 1, 0, chansess,
|
||||||
|
@ -651,11 +651,10 @@ static int noptycommand(struct Channel *channel, struct ChanSess *chansess) {
|
|||||||
ses.maxfd = MAX(ses.maxfd, channel->outfd);
|
ses.maxfd = MAX(ses.maxfd, channel->outfd);
|
||||||
ses.maxfd = MAX(ses.maxfd, channel->errfd);
|
ses.maxfd = MAX(ses.maxfd, channel->errfd);
|
||||||
|
|
||||||
if ((fcntl(channel->outfd, F_SETFL, O_NONBLOCK) < 0) ||
|
setnonblocking(channel->outfd);
|
||||||
(fcntl(channel->infd, F_SETFL, O_NONBLOCK) < 0) ||
|
setnonblocking(channel->infd);
|
||||||
(fcntl(channel->errfd, F_SETFL, O_NONBLOCK) < 0)) {
|
setnonblocking(channel->errfd);
|
||||||
dropbear_exit("Couldn't set nonblocking");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#undef FDIN
|
#undef FDIN
|
||||||
#undef FDOUT
|
#undef FDOUT
|
||||||
@ -761,9 +760,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {
|
|||||||
/* don't need to set stderr here */
|
/* don't need to set stderr here */
|
||||||
ses.maxfd = MAX(ses.maxfd, chansess->master);
|
ses.maxfd = MAX(ses.maxfd, chansess->master);
|
||||||
|
|
||||||
if (fcntl(chansess->master, F_SETFL, O_NONBLOCK) < 0) {
|
setnonblocking(chansess->master);
|
||||||
dropbear_exit("Couldn't set nonblocking");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +75,7 @@ int x11req(struct ChanSess * chansess) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set non-blocking */
|
/* set non-blocking */
|
||||||
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
|
setnonblocking(fd);
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* listener code will handle the socket now.
|
/* listener code will handle the socket now.
|
||||||
* No cleanup handler needed, since listener_remove only happens
|
* No cleanup handler needed, since listener_remove only happens
|
||||||
|
Loading…
Reference in New Issue
Block a user