changeset 1829:a7cc3332d8ab

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
author Matt Johnston <matt@ucc.asn.au>
date Mon, 11 Oct 2021 15:42:14 +0800
parents 3f0ac6bc58a1
children c32976db772f
files channel.h cli-agentfwd.c cli-chansession.c cli-tcpfwd.c common-channel.c svr-agentfwd.c svr-chansession.c svr-tcpfwd.c svr-x11fwd.c
diffstat 9 files changed, 13 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/channel.h	Mon Oct 11 15:16:54 2021 +0800
+++ b/channel.h	Mon Oct 11 15:42:14 2021 +0800
@@ -60,6 +60,9 @@
 	int readfd; /* read from insecure side, written to wire */
 	int errfd; /* used like writefd or readfd, depending if it's client or server.
 				  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
 							 initially NULL */
 	circbuffer *extrabuf; /* extended-data for the program - used like writebuf
@@ -87,7 +90,6 @@
 
 struct ChanType {
 
-	int sepfds; /* Whether this channel has separate pipes for in/out or not */
 	const char *name;
 	/* Sets up the channel */
 	int (*inithandler)(struct Channel*);
--- a/cli-agentfwd.c	Mon Oct 11 15:16:54 2021 +0800
+++ b/cli-agentfwd.c	Mon Oct 11 15:42:14 2021 +0800
@@ -47,7 +47,6 @@
 static int new_agent_chan(struct Channel * channel);
 
 const struct ChanType cli_chan_agent = {
-	0, /* sepfds */
 	"[email protected]",
 	new_agent_chan,
 	NULL,
@@ -94,6 +93,7 @@
 
 	channel->readfd = fd;
 	channel->writefd = fd;
+	channel->bidir_fd = 1;
 
 	return 0;
 }
--- a/cli-chansession.c	Mon Oct 11 15:16:54 2021 +0800
+++ b/cli-chansession.c	Mon Oct 11 15:42:14 2021 +0800
@@ -46,7 +46,6 @@
 static void cli_tty_setup(void);
 
 const struct ChanType clichansess = {
-	0, /* sepfds */
 	"session", /* name */
 	cli_initchansess, /* inithandler */
 	NULL, /* checkclosehandler */
@@ -344,6 +343,7 @@
 	setnonblocking(STDERR_FILENO);
 
 	channel->extrabuf = cbuf_new(opts.recv_window);
+	channel->bidir_fd = 0;
 	return 0;
 }
 
@@ -383,7 +383,6 @@
 #if DROPBEAR_CLI_NETCAT
 
 static const struct ChanType cli_chan_netcat = {
-	0, /* sepfds */
 	"direct-tcpip",
 	cli_init_netcat, /* inithandler */
 	NULL,
--- a/cli-tcpfwd.c	Mon Oct 11 15:16:54 2021 +0800
+++ b/cli-tcpfwd.c	Mon Oct 11 15:42:14 2021 +0800
@@ -35,7 +35,6 @@
 static int newtcpforwarded(struct Channel * channel);
 
 const struct ChanType cli_chan_tcpremote = {
-	1, /* sepfds */
 	"forwarded-tcpip",
 	newtcpforwarded,
 	NULL,
@@ -51,7 +50,6 @@
 		const char* remoteaddr,
 		unsigned int remoteport);
 static const struct ChanType cli_chan_tcplocal = {
-	1, /* sepfds */
 	"direct-tcpip",
 	tcp_prio_inithandler,
 	NULL,
@@ -275,10 +273,10 @@
 	}
 
 	channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
-	
+
 	snprintf(portstring, sizeof(portstring), "%u", fwd->connectport);
 	channel->conn_pending = connect_remote(fwd->connectaddr, portstring, channel_connect_done, channel, NULL, NULL);
-	
+
 	err = SSH_OPEN_IN_PROGRESS;
 
 out:
--- a/common-channel.c	Mon Oct 11 15:16:54 2021 +0800
+++ b/common-channel.c	Mon Oct 11 15:42:14 2021 +0800
@@ -339,6 +339,7 @@
 	if (result == DROPBEAR_SUCCESS)
 	{
 		channel->readfd = channel->writefd = sock;
+		channel->bidir_fd = 1;
 		channel->conn_pending = NULL;
 		send_msg_channel_open_confirmation(channel, channel->recvwindow,
 				channel->recvmaxpacket);
@@ -1039,7 +1040,7 @@
 
 	int closein = 0, closeout = 0;
 
-	if (channel->type->sepfds) {
+	if (channel->bidir_fd) {
 		TRACE(("SHUTDOWN(%d, %d)", fd, how))
 		shutdown(fd, how);
 		if (how == 0) {
@@ -1069,7 +1070,7 @@
 
 	/* if we called shutdown on it and all references are gone, then we 
 	 * 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) {
 		TRACE(("CLOSE (finally) of %d", fd))
 		m_close(fd);
@@ -1102,6 +1103,7 @@
 
 	chan->writefd = chan->readfd = fd;
 	ses.maxfd = MAX(ses.maxfd, fd);
+	chan->bidir_fd = 1;
 
 	chan->await_open = 1;
 
--- a/svr-agentfwd.c	Mon Oct 11 15:16:54 2021 +0800
+++ b/svr-agentfwd.c	Mon Oct 11 15:42:14 2021 +0800
@@ -186,7 +186,6 @@
 }
 
 static const struct ChanType chan_svr_agent = {
-	0, /* sepfds */
 	"[email protected]",
 	NULL,
 	NULL,
--- a/svr-chansession.c	Mon Oct 11 15:16:54 2021 +0800
+++ b/svr-chansession.c	Mon Oct 11 15:42:14 2021 +0800
@@ -64,7 +64,6 @@
 static void get_termmodes(const struct ChanSess *chansess);
 
 const struct ChanType svrchansess = {
-	0, /* sepfds */
 	"session", /* name */
 	newchansess, /* inithandler */
 	sesscheckclose, /* checkclosehandler */
@@ -769,6 +768,7 @@
 	ses.maxfd = MAX(ses.maxfd, channel->writefd);
 	ses.maxfd = MAX(ses.maxfd, channel->readfd);
 	ses.maxfd = MAX(ses.maxfd, channel->errfd);
+	channel->bidir_fd = 0;
 
 	addchildpid(chansess, chansess->pid);
 
@@ -895,6 +895,7 @@
 		channel->readfd = chansess->master;
 		/* don't need to set stderr here */
 		ses.maxfd = MAX(ses.maxfd, chansess->master);
+		channel->bidir_fd = 1;
 
 		setnonblocking(chansess->master);
 
--- a/svr-tcpfwd.c	Mon Oct 11 15:16:54 2021 +0800
+++ b/svr-tcpfwd.c	Mon Oct 11 15:42:14 2021 +0800
@@ -59,7 +59,6 @@
 
 #if DROPBEAR_SVR_REMOTETCPFWD
 static const struct ChanType svr_chan_tcpremote = {
-	1, /* sepfds */
 	"forwarded-tcpip",
 	tcp_prio_inithandler,
 	NULL,
@@ -241,7 +240,6 @@
 #if DROPBEAR_SVR_LOCALTCPFWD
 
 const struct ChanType svr_chan_tcpdirect = {
-	1, /* sepfds */
 	"direct-tcpip",
 	newtcpdirect, /* init */
 	NULL, /* checkclose */
--- a/svr-x11fwd.c	Mon Oct 11 15:16:54 2021 +0800
+++ b/svr-x11fwd.c	Mon Oct 11 15:42:14 2021 +0800
@@ -211,7 +211,6 @@
 }
 
 static const struct ChanType chan_x11 = {
-	0, /* sepfds */
 	"x11",
 	x11_inithandler, /* inithandler */
 	NULL, /* checkclose */