Replace ChanType.sepfds with Channel.bidir_fd

This handles the case where a svrchansess has separate FDs
for nopty, but a single FD for pty mode.

The use of sepfds was also previously incorrect for X11 and
agent forwarding
This commit is contained in:
Matt Johnston 2021-10-11 15:42:14 +08:00
parent 8e6f73e879
commit f17400e738
9 changed files with 13 additions and 15 deletions

View File

@ -60,6 +60,9 @@ struct Channel {
int readfd; /* read from insecure side, written to wire */ int readfd; /* read from insecure side, written to wire */
int errfd; /* used like writefd or readfd, depending if it's client or server. int errfd; /* used like writefd or readfd, depending if it's client or server.
Doesn't exactly belong here, but is cleaner here */ Doesn't exactly belong here, but is cleaner here */
int bidir_fd; /* a boolean indicating that writefd/readfd are the same
file descriptor (bidirectional), such as a network socket or PTY.
That is handled differently when closing FDs */
circbuffer *writebuf; /* data from the wire, for local consumption. Can be circbuffer *writebuf; /* data from the wire, for local consumption. Can be
initially NULL */ initially NULL */
circbuffer *extrabuf; /* extended-data for the program - used like writebuf circbuffer *extrabuf; /* extended-data for the program - used like writebuf
@ -87,7 +90,6 @@ struct Channel {
struct ChanType { struct ChanType {
int sepfds; /* Whether this channel has separate pipes for in/out or not */
const char *name; const char *name;
/* Sets up the channel */ /* Sets up the channel */
int (*inithandler)(struct Channel*); int (*inithandler)(struct Channel*);

View File

@ -47,7 +47,6 @@
static int new_agent_chan(struct Channel * channel); static int new_agent_chan(struct Channel * channel);
const struct ChanType cli_chan_agent = { const struct ChanType cli_chan_agent = {
0, /* sepfds */
"auth-agent@openssh.com", "auth-agent@openssh.com",
new_agent_chan, new_agent_chan,
NULL, NULL,
@ -94,6 +93,7 @@ static int new_agent_chan(struct Channel * channel) {
channel->readfd = fd; channel->readfd = fd;
channel->writefd = fd; channel->writefd = fd;
channel->bidir_fd = 1;
return 0; return 0;
} }

View File

@ -46,7 +46,6 @@ static int cli_init_netcat(struct Channel *channel);
static void cli_tty_setup(void); static void cli_tty_setup(void);
const struct ChanType clichansess = { const struct ChanType clichansess = {
0, /* sepfds */
"session", /* name */ "session", /* name */
cli_initchansess, /* inithandler */ cli_initchansess, /* inithandler */
NULL, /* checkclosehandler */ NULL, /* checkclosehandler */
@ -344,6 +343,7 @@ static int cli_init_stdpipe_sess(struct Channel *channel) {
setnonblocking(STDERR_FILENO); setnonblocking(STDERR_FILENO);
channel->extrabuf = cbuf_new(opts.recv_window); channel->extrabuf = cbuf_new(opts.recv_window);
channel->bidir_fd = 0;
return 0; return 0;
} }
@ -383,7 +383,6 @@ static int cli_initchansess(struct Channel *channel) {
#if DROPBEAR_CLI_NETCAT #if DROPBEAR_CLI_NETCAT
static const struct ChanType cli_chan_netcat = { static const struct ChanType cli_chan_netcat = {
0, /* sepfds */
"direct-tcpip", "direct-tcpip",
cli_init_netcat, /* inithandler */ cli_init_netcat, /* inithandler */
NULL, NULL,

View File

@ -35,7 +35,6 @@
static int newtcpforwarded(struct Channel * channel); static int newtcpforwarded(struct Channel * channel);
const struct ChanType cli_chan_tcpremote = { const struct ChanType cli_chan_tcpremote = {
1, /* sepfds */
"forwarded-tcpip", "forwarded-tcpip",
newtcpforwarded, newtcpforwarded,
NULL, NULL,
@ -51,7 +50,6 @@ static int cli_localtcp(const char* listenaddr,
const char* remoteaddr, const char* remoteaddr,
unsigned int remoteport); unsigned int remoteport);
static const struct ChanType cli_chan_tcplocal = { static const struct ChanType cli_chan_tcplocal = {
1, /* sepfds */
"direct-tcpip", "direct-tcpip",
tcp_prio_inithandler, tcp_prio_inithandler,
NULL, NULL,

View File

@ -339,6 +339,7 @@ void channel_connect_done(int result, int sock, void* user_data, const char* err
if (result == DROPBEAR_SUCCESS) if (result == DROPBEAR_SUCCESS)
{ {
channel->readfd = channel->writefd = sock; channel->readfd = channel->writefd = sock;
channel->bidir_fd = 1;
channel->conn_pending = NULL; channel->conn_pending = NULL;
send_msg_channel_open_confirmation(channel, channel->recvwindow, send_msg_channel_open_confirmation(channel, channel->recvwindow,
channel->recvmaxpacket); channel->recvmaxpacket);
@ -1039,7 +1040,7 @@ static void close_chan_fd(struct Channel *channel, int fd, int how) {
int closein = 0, closeout = 0; int closein = 0, closeout = 0;
if (channel->type->sepfds) { if (channel->bidir_fd) {
TRACE(("SHUTDOWN(%d, %d)", fd, how)) TRACE(("SHUTDOWN(%d, %d)", fd, how))
shutdown(fd, how); shutdown(fd, how);
if (how == 0) { if (how == 0) {
@ -1069,7 +1070,7 @@ static void close_chan_fd(struct Channel *channel, int fd, int how) {
/* if we called shutdown on it and all references are gone, then we /* if we called shutdown on it and all references are gone, then we
* need to close() it to stop it lingering */ * need to close() it to stop it lingering */
if (channel->type->sepfds && channel->readfd == FD_CLOSED if (channel->bidir_fd && channel->readfd == FD_CLOSED
&& channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) { && channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) {
TRACE(("CLOSE (finally) of %d", fd)) TRACE(("CLOSE (finally) of %d", fd))
m_close(fd); m_close(fd);
@ -1102,6 +1103,7 @@ int send_msg_channel_open_init(int fd, const struct ChanType *type) {
chan->writefd = chan->readfd = fd; chan->writefd = chan->readfd = fd;
ses.maxfd = MAX(ses.maxfd, fd); ses.maxfd = MAX(ses.maxfd, fd);
chan->bidir_fd = 1;
chan->await_open = 1; chan->await_open = 1;

View File

@ -186,7 +186,6 @@ void svr_agentcleanup(struct ChanSess * chansess) {
} }
static const struct ChanType chan_svr_agent = { static const struct ChanType chan_svr_agent = {
0, /* sepfds */
"auth-agent@openssh.com", "auth-agent@openssh.com",
NULL, NULL,
NULL, NULL,

View File

@ -64,7 +64,6 @@ static void send_msg_chansess_exitsignal(const struct Channel * channel,
static void get_termmodes(const struct ChanSess *chansess); static void get_termmodes(const struct ChanSess *chansess);
const struct ChanType svrchansess = { const struct ChanType svrchansess = {
0, /* sepfds */
"session", /* name */ "session", /* name */
newchansess, /* inithandler */ newchansess, /* inithandler */
sesscheckclose, /* checkclosehandler */ sesscheckclose, /* checkclosehandler */
@ -769,6 +768,7 @@ static int noptycommand(struct Channel *channel, struct ChanSess *chansess) {
ses.maxfd = MAX(ses.maxfd, channel->writefd); ses.maxfd = MAX(ses.maxfd, channel->writefd);
ses.maxfd = MAX(ses.maxfd, channel->readfd); ses.maxfd = MAX(ses.maxfd, channel->readfd);
ses.maxfd = MAX(ses.maxfd, channel->errfd); ses.maxfd = MAX(ses.maxfd, channel->errfd);
channel->bidir_fd = 0;
addchildpid(chansess, chansess->pid); addchildpid(chansess, chansess->pid);
@ -895,6 +895,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {
channel->readfd = chansess->master; channel->readfd = chansess->master;
/* 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);
channel->bidir_fd = 1;
setnonblocking(chansess->master); setnonblocking(chansess->master);

View File

@ -59,7 +59,6 @@ static int newtcpdirect(struct Channel * channel);
#if DROPBEAR_SVR_REMOTETCPFWD #if DROPBEAR_SVR_REMOTETCPFWD
static const struct ChanType svr_chan_tcpremote = { static const struct ChanType svr_chan_tcpremote = {
1, /* sepfds */
"forwarded-tcpip", "forwarded-tcpip",
tcp_prio_inithandler, tcp_prio_inithandler,
NULL, NULL,
@ -241,7 +240,6 @@ out:
#if DROPBEAR_SVR_LOCALTCPFWD #if DROPBEAR_SVR_LOCALTCPFWD
const struct ChanType svr_chan_tcpdirect = { const struct ChanType svr_chan_tcpdirect = {
1, /* sepfds */
"direct-tcpip", "direct-tcpip",
newtcpdirect, /* init */ newtcpdirect, /* init */
NULL, /* checkclose */ NULL, /* checkclose */

View File

@ -211,7 +211,6 @@ static int x11_inithandler(struct Channel *channel) {
} }
static const struct ChanType chan_x11 = { static const struct ChanType chan_x11 = {
0, /* sepfds */
"x11", "x11",
x11_inithandler, /* inithandler */ x11_inithandler, /* inithandler */
NULL, /* checkclose */ NULL, /* checkclose */