rpms/openssh/devel openssh-4.2p1-controldisplay.patch, NONE, 1.1.4.1 openssh-4.3p2-controlpersist.patch, NONE, 1.1.4.1 openssh-4.5p1-controlcleanup.patch, NONE, 1.1.2.1 openssh-4.5p1-multidisplay.patch, NONE, 1.1.2.1 openssh.spec, 1.108, 1.108.2.1

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Sat Mar 24 16:37:06 UTC 2007


Author: dwmw2

Update of /cvs/dist/rpms/openssh/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv27867

Modified Files:
      Tag: private-openssh-4_5p1-6-controlpersist-branch
	openssh.spec 
Added Files:
      Tag: private-openssh-4_5p1-6-controlpersist-branch
	openssh-4.2p1-controldisplay.patch 
	openssh-4.3p2-controlpersist.patch 
	openssh-4.5p1-controlcleanup.patch 
	openssh-4.5p1-multidisplay.patch 
Log Message:
Build ControlPersist improvements for rawhide


openssh-4.2p1-controldisplay.patch:
 clientloop.c |   31 ++++++++++++++++++++++++++-----
 clientloop.h |    2 +-
 ssh.c        |   12 +++++++++++-
 3 files changed, 38 insertions(+), 7 deletions(-)

--- NEW FILE openssh-4.2p1-controldisplay.patch ---
--- openssh-4.2p1/clientloop.c~	2005-09-04 14:09:30.000000000 +0100
+++ openssh-4.2p1/clientloop.c	2005-09-04 15:00:09.000000000 +0100
@@ -144,6 +144,9 @@ struct confirm_ctx {
 	int want_agent_fwd;
 	Buffer cmd;
 	char *term;
+	char *display;
+	char *x_proto;
+	char *x_data;
 	struct termios tio;
 	char **env;
 };
@@ -633,7 +636,6 @@ static void
 client_extra_session2_setup(int id, void *arg)
 {
 	struct confirm_ctx *cctx = arg;
-	const char *display;
 	Channel *c;
 	int i;
 
@@ -642,15 +644,15 @@ client_extra_session2_setup(int id, void
 	if ((c = channel_lookup(id)) == NULL)
 		fatal("%s: no channel for id %d", __func__, id);
 
-	display = getenv("DISPLAY");
-	if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
+	if (cctx->want_x_fwd && options.forward_x11) {
 		char *proto, *data;
 		/* Get reasonable local authentication information. */
-		client_x11_get_proto(display, options.xauth_location,
+		client_x11_get_proto(cctx->display, options.xauth_location,
 		    options.forward_x11_trusted, &proto, &data);
 		/* Request forwarding with authentication spoofing. */
 		debug("Requesting X11 forwarding with authentication spoofing.");
-		x11_request_forwarding_with_spoofing(id, display, proto, data);
+		x11_request_forwarding_with_spoofing(id, cctx->display, 
+		    cctx->x_proto, cctx->x_data);
 		/* XXX wait for reply */
 	}
 
@@ -667,6 +670,11 @@ client_extra_session2_setup(int id, void
 	c->confirm_ctx = NULL;
 	buffer_free(&cctx->cmd);
 	xfree(cctx->term);
+	if (cctx->display) {
+		xfree(cctx->display);
+		xfree(cctx->x_proto);
+		xfree(cctx->x_data);
+	}
 	if (cctx->env != NULL) {
 		for (i = 0; cctx->env[i] != NULL; i++)
 			xfree(cctx->env[i]);
@@ -813,6 +819,14 @@ client_process_control(fd_set * readset)
 	cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0;
 	cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
 	cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
+
+	if (cctx->want_x_fwd) {
+		cctx->display = buffer_get_string(&m, &len);
+		cctx->x_proto = buffer_get_string(&m, &len);
+		cctx->x_data = buffer_get_string(&m, &len);
+		debug2("%s: got X11 display %s, auth proto %s, data %s.",
+		    __func__, cctx->display, cctx->x_proto, cctx->x_data);
+	}
 	cctx->term = buffer_get_string(&m, &len);
 
 	cmd = buffer_get_string(&m, &len);
@@ -854,11 +866,17 @@ client_process_control(fd_set * readset)
 		close(new_fd[2]);
 		buffer_free(&m);
 		xfree(cctx->term);
+		if (cctx->display) {
+			xfree(cctx->display);
+			xfree(cctx->x_proto);
+			xfree(cctx->x_data);
+		}
 		if (env_len != 0) {
 			for (i = 0; i < env_len; i++)
 				xfree(cctx->env[i]);
 			xfree(cctx->env);
 		}
+		xfree(cctx);
 		return;
 	}
 	buffer_free(&m);
--- openssh-4.2p1/clientloop.h~	2005-07-06 00:44:19.000000000 +0100
+++ openssh-4.2p1/clientloop.h	2005-09-04 14:18:31.000000000 +0100
@@ -44,7 +44,7 @@ void	 client_session2_setup(int, int, in
 	    int, Buffer *, char **, dispatch_fn *);
 
 /* Multiplexing protocol version */
-#define SSHMUX_VER			1
+#define SSHMUX_VER			2
 
 /* Multiplexing control protocol flags */
 #define SSHMUX_COMMAND_OPEN		1	/* Open new connection */
--- openssh-4.2p1/ssh.c~	2005-08-12 13:10:56.000000000 +0100
+++ openssh-4.2p1/ssh.c	2005-09-04 14:45:50.000000000 +0100
@@ -1211,6 +1211,7 @@ control_client(const char *path)
 	Buffer m;
 	char *term;
 	extern char **environ;
+	char *display = NULL, *x_proto, *x_data;
 	u_int  flags;
 
 	if (mux_command == 0)
@@ -1270,8 +1271,12 @@ control_client(const char *path)
 		flags |= SSHMUX_FLAG_TTY;
 	if (subsystem_flag)
 		flags |= SSHMUX_FLAG_SUBSYS;
-	if (options.forward_x11)
+	if (options.forward_x11 && (display = getenv("DISPLAY")) != NULL) {
+		/* Get reasonable local authentication information. */
+		client_x11_get_proto(display, options.xauth_location,
+		    options.forward_x11_trusted, &x_proto, &x_data);
 		flags |= SSHMUX_FLAG_X11_FWD;
+	}
 	if (options.forward_agent)
 		flags |= SSHMUX_FLAG_AGENT_FWD;
 
@@ -1311,6 +1316,11 @@ control_client(const char *path)
 	}
 
 	/* SSHMUX_COMMAND_OPEN */
+	if (display) {
+		buffer_put_cstring(&m, display);
+		buffer_put_cstring(&m, x_proto);
+		buffer_put_cstring(&m, x_data);
+	}
 	buffer_put_cstring(&m, term ? term : "");
 	buffer_append(&command, "\0", 1);
 	buffer_put_cstring(&m, buffer_ptr(&command));

openssh-4.3p2-controlpersist.patch:
 clientloop.c |   22 +++++++++++++++++++++-
 readconf.c   |    7 ++++++-
 readconf.h   |    1 +
 3 files changed, 28 insertions(+), 2 deletions(-)

--- NEW FILE openssh-4.3p2-controlpersist.patch ---
--- openssh/clientloop.c~	2005-06-17 03:59:35.000000000 +0100
+++ openssh/clientloop.c	2005-06-23 11:05:11.000000000 +0100
@@ -1271,8 +1271,28 @@ static void
 client_channel_closed(int id, void *arg)
 {
 	channel_cancel_cleanup(id);
-	session_closed = 1;
 	leave_raw_mode();
+	if (options.control_persist && options.control_path != NULL && control_fd != -1) {
+		int pid = fork();
+
+		if (pid < 0) {
+			error("fork: %.100s", strerror(errno));
+			/* Just exit */
+			session_closed = 1;
+			return;
+		}
+		if (pid != 0) {
+			/* We are the parent. Exit, leaving the child to continue serving */
+			exit(exit_status);
+		}
+		session_ident = -1;
+		/* We _must_ lose our controlling tty, else subsequent control_client
+		   invocations from the same tty will cause us to get -EIO when reading
+		   from the tty */
+		setsid();
+		return;
+	}
+	session_closed = 1;
 }
 
 /*
--- openssh/readconf.c~	2005-06-16 04:19:42.000000000 +0100
+++ openssh/readconf.c	2005-06-23 11:05:11.000000000 +0100
@@ -106,7 +106,7 @@ typedef enum {
 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
-	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
+	oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts,
 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
 	oDeprecated, oUnsupported
 } OpCodes;
@@ -197,6 +197,7 @@ static struct {
 	{ "sendenv", oSendEnv },
 	{ "controlpath", oControlPath },
 	{ "controlmaster", oControlMaster },
+	{ "controlpersist", oControlPersist },
 	{ "hashknownhosts", oHashKnownHosts },
 	{ NULL, oBadOption }
 };
@@ -818,6 +819,10 @@ parse_int:
 			*intptr = value;
 		break;
 
+	case oControlPersist:
+		intptr = &options->control_persist;
+		goto parse_flag;
+
 	case oHashKnownHosts:
 		intptr = &options->hash_known_hosts;
 		goto parse_flag;
--- openssh/readconf.h~	2005-06-16 04:19:42.000000000 +0100
+++ openssh/readconf.h	2005-06-23 11:02:01.000000000 +0100
@@ -112,6 +112,7 @@ typedef struct {
 
 	char	*control_path;
 	int	control_master;
+	int	control_persist;
 
 	int	hash_known_hosts;
 }       Options;

openssh-4.5p1-controlcleanup.patch:
 ssh.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletion(-)

--- NEW FILE openssh-4.5p1-controlcleanup.patch ---
--- openssh-4.5p1/ssh.c~	2007-03-24 16:25:18.000000000 +0000
+++ openssh-4.5p1/ssh.c	2007-03-24 16:31:06.000000000 +0000
@@ -1347,7 +1347,11 @@
 		}
 		if (errno == ENOENT)
 			debug("Control socket \"%.100s\" does not exist", path);
-		else {
+		else if (errno == ECONNREFUSED) {
+			debug("Control socket connect(%.100s): %s", path,
+			    strerror(errno));
+			unlink(path);
+		} else {
 			error("Control socket connect(%.100s): %s", path,
 			    strerror(errno));
 		}

openssh-4.5p1-multidisplay.patch:
 openssh-4.5p1-multidisplay/channels.c   |  355 +++++++++++++++++++-------------
 openssh-4.5p1-multidisplay/channels.h   |    6 
 openssh-4.5p1-multidisplay/clientloop.c |    5 
 openssh-4.5p1/cipher.c.orig             |only
 4 files changed, 226 insertions(+), 140 deletions(-)

--- NEW FILE openssh-4.5p1-multidisplay.patch ---
diff -ur openssh-4.5p1/channels.c openssh-4.5p1-multidisplay/channels.c
--- openssh-4.5p1/channels.c	2006-08-30 02:07:40.000000000 +0100
+++ openssh-4.5p1-multidisplay/channels.c	2007-03-24 16:22:37.000000000 +0000
@@ -96,6 +96,11 @@
  */
 static int channel_max_fd = 0;
 
+/*
+ * Flag indicating that channel fds have been modified, used to restart
+ * preparations for select if necessary
+ */
+static int channel_fds_changed = 0;
 
 /* -- tcp forwarding */
 
@@ -136,23 +141,31 @@
 /* Maximum number of fake X11 displays to try. */
 #define MAX_DISPLAYS  1000
 
-/* Saved X11 local (client) display. */
-static char *x11_saved_display = NULL;
-
-/* Saved X11 authentication protocol name. */
-static char *x11_saved_proto = NULL;
+struct x11_fwd {
+	/* Saved X11 local (client) display. */
+	char *saved_display;
+
+	/* Saved X11 authentication protocol name. */
+	char *saved_proto;
+
+	/* Saved X11 authentication data.  These are the real data. */
+	u_char *saved_data;
+	u_int saved_data_len;
 
-/* Saved X11 authentication data.  This is the real data. */
-static char *x11_saved_data = NULL;
-static u_int x11_saved_data_len = 0;
+	/*
+	 * Fake X11 authentication data.  This is what the server will be 
+	 sending us; we should replace any occurrences with the real data.
+	*/
+	u_char *fake_data;
+	u_int fake_data_len;
+
+	u_int usecount;
+	struct x11_fwd *next;
+};
 
-/*
- * Fake X11 authentication data.  This is what the server will be sending us;
- * we should replace any occurrences of this by the real data.
- */
-static u_char *x11_fake_data = NULL;
-static u_int x11_fake_data_len;
+static struct x11_fwd *x11_fwds = NULL;
 
+static void x11_put_fwd(struct x11_fwd *fwd);
 
 /* -- agent forwarding */
 
@@ -218,6 +231,16 @@
 channel_register_fds(Channel *c, int rfd, int wfd, int efd,
     int extusage, int nonblock)
 {
+	c->rfd = rfd;
+	c->wfd = wfd;
+	c->sock = (rfd == wfd) ? rfd : -1;
+	c->ctl_fd = -1; /* XXX: set elsewhere */
+	c->efd = efd;
+	channel_fds_changed = 1;
+
+	if (rfd == -1 && wfd == -1 && efd == -1)
+		return;
+
 	/* Update the maximum file descriptor value. */
 	channel_max_fd = MAX(channel_max_fd, rfd);
 	channel_max_fd = MAX(channel_max_fd, wfd);
@@ -225,11 +248,6 @@
 
 	/* XXX set close-on-exec -markus */
 
-	c->rfd = rfd;
-	c->wfd = wfd;
-	c->sock = (rfd == wfd) ? rfd : -1;
-	c->ctl_fd = -1; /* XXX: set elsewhere */
-	c->efd = efd;
 	c->extended_usage = extusage;
 
 	/* XXX ugly hack: nonblock is only set by the server */
@@ -403,6 +421,8 @@
 		c->remote_name = NULL;
 	}
 	channels[c->self] = NULL;
+	if (c->x11_fwd)
+		x11_put_fwd(c->x11_fwd);
 	xfree(c);
 }
 
@@ -826,6 +846,54 @@
 		FD_SET(c->sock, writeset);
 }
 
+static struct x11_fwd *
+x11_lookup_fwd_by_fakedata(unsigned char *proto, u_int protolen, unsigned char *data, u_int datalen)
+{
+	struct x11_fwd *fwd;
+
+	for (fwd = x11_fwds; fwd; fwd = fwd->next) {
+		if (protolen == strlen(fwd->saved_proto) &&
+		    !memcmp(fwd->saved_proto, proto, protolen) &&
+		    fwd->fake_data_len == datalen &&
+		    !memcmp(fwd->fake_data, data, datalen))
+			break;
+	}
+	return fwd;
+}
+
+static struct x11_fwd *
+x11_lookup_fwd_by_realdata(const char *display, const char *proto, const u_char *authdata, u_int datalen)
+{
+	struct x11_fwd *fwd;
+
+	for (fwd = x11_fwds; fwd; fwd = fwd->next) {
+		if (!strcmp(display, fwd->saved_display) &&
+		    !strcmp(proto, fwd->saved_proto) &&
+		    datalen == fwd->saved_data_len &&
+		    !memcmp(authdata, fwd->saved_data, datalen))
+			break;
+	}
+	return fwd;
+}
+
+static void x11_put_fwd(struct x11_fwd *fwd)
+{
+	fwd->usecount--;
+	debug("Decrease usecount on X11 forward data for %s to %d.", fwd->saved_display, fwd->usecount);
+	if (!fwd->usecount) {
+		struct x11_fwd **tmp = &x11_fwds;
+		while (*tmp) {
+			if (*tmp == fwd) {
+				*tmp = fwd->next;
+				xfree(fwd);
+				return;
+			}
+			tmp = &(*tmp)->next;
+		}
+		fatal("X11 forward data not found.");
+	}
+}
+
 /*
  * This is a special state for X11 authentication spoofing.  An opened X11
  * connection (when authentication spoofing is being done) remains in this
@@ -836,10 +904,13 @@
  * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok
  */
 static int
-x11_open_helper(Buffer *b)
+x11_open_helper(Channel *c)
 {
+	Buffer *b = &c->output;
 	u_char *ucp;
 	u_int proto_len, data_len;
+	struct x11_fwd *fwd;
+	int sock;
 
 	/* Check if the fixed size part of the packet is in buffer. */
 	if (buffer_len(b) < 12)
@@ -864,50 +935,54 @@
 	    12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
 		return 0;
 
-	/* Check if authentication protocol matches. */
-	if (proto_len != strlen(x11_saved_proto) ||
-	    memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) {
-		debug2("X11 connection uses different authentication protocol.");
-		return -1;
-	}
-	/* Check if authentication data matches our fake data. */
-	if (data_len != x11_fake_data_len ||
-	    memcmp(ucp + 12 + ((proto_len + 3) & ~3),
-		x11_fake_data, x11_fake_data_len) != 0) {
-		debug2("X11 auth data does not match fake data.");
-		return -1;
-	}
-	/* Check fake data length */
-	if (x11_fake_data_len != x11_saved_data_len) {
-		error("X11 fake_data_len %d != saved_data_len %d",
-		    x11_fake_data_len, x11_saved_data_len);
+	fwd = x11_lookup_fwd_by_fakedata(ucp+12, proto_len, 
+		  ucp + 12 + ((proto_len + 3) & ~3), data_len);
+
+	if (!fwd) {
+		debug("No matching X11 forward found.");
 		return -1;
 	}
+	fwd->usecount++;
+	debug("Increase use count for X11 fwd for display %s to %d.", fwd->saved_display, fwd->usecount);
+	c->x11_fwd = fwd;
 	/*
-	 * Received authentication protocol and data match
-	 * our fake data. Substitute the fake data with real
-	 * data.
+	 * We found a matching X11 forward. Substitute the fake data 
+	 * with real data.
 	 */
 	memcpy(ucp + 12 + ((proto_len + 3) & ~3),
-	    x11_saved_data, x11_saved_data_len);
-	return 1;
+	    fwd->saved_data, fwd->saved_data_len);
+
+	sock = x11_connect_display(fwd->saved_display);
+	if (sock == -1)
+		return -2;
+	channel_register_fds(c, sock, sock, -1, 0, 1);
+	c->type = SSH_CHANNEL_OPEN;
+
+	/* Because we registered a new fd, the channel_pre handlers will be
+	   called again immediately. And because we changed the channel type
+	   to SSH_CHANNEL_OPEN, the x11 function won't be called next time.
+	   It's just a normal channel now */
+	return 0;
 }
 
 static void
 channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset)
 {
-	int ret = x11_open_helper(&c->output);
+	int ret = x11_open_helper(c);
 
-	if (ret == 1) {
-		/* Start normal processing for the channel. */
-		c->type = SSH_CHANNEL_OPEN;
-		channel_pre_open_13(c, readset, writeset);
-	} else if (ret == -1) {
+	if (ret < 0) {
 		/*
 		 * We have received an X11 connection that has bad
 		 * authentication information.
 		 */
-		logit("X11 connection rejected because of wrong authentication.");
+		switch (ret) {
+		case -1:
+			logit("X11 connection rejected because of wrong authentication.");
+			break;
+		case -2:
+			logit("X11 connection rejected due to failure to connect to local server.");
+			break;
+		}
 		buffer_clear(&c->input);
 		buffer_clear(&c->output);
 		channel_close_fd(&c->sock);
@@ -922,15 +997,17 @@
 static void
 channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
 {
-	int ret = x11_open_helper(&c->output);
-
-	/* c->force_drain = 1; */
+	int ret = x11_open_helper(c);
 
-	if (ret == 1) {
-		c->type = SSH_CHANNEL_OPEN;
-		channel_pre_open(c, readset, writeset);
-	} else if (ret == -1) {
-		logit("X11 connection rejected because of wrong authentication.");
+	if (ret < 0) {
+		switch (ret) {
+		case -1:
+			logit("X11 connection rejected because of wrong authentication.");
+			break;
+		case -2:
+			logit("X11 connection rejected due to failure to connect to local server.");
+			break;
+		}
 		debug2("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
 		chan_read_failed(c);
 		buffer_clear(&c->input);
@@ -1834,26 +1911,30 @@
 {
 	u_int n, sz, nfdset;
 
-	n = MAX(*maxfdp, channel_max_fd);
+	for (channel_fds_changed = 1; channel_fds_changed;) {
+		channel_fds_changed = 0;
+		n = MAX(*maxfdp, channel_max_fd);
+
+		nfdset = howmany(n+1, NFDBITS);
+		/* Explicitly test here, because xrealloc isn't always called */
+		if (nfdset && SIZE_T_MAX / nfdset < sizeof(fd_mask))
+			fatal("channel_prepare_select: max_fd (%d) is too large", n);
+		sz = nfdset * sizeof(fd_mask);
+
+		/* perhaps check sz < nalloc/2 and shrink? */
+		if (*readsetp == NULL || sz > *nallocp) {
+			*readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask));
+			*writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask));
+			*nallocp = sz;
+		}
+		*maxfdp = n;
+		memset(*readsetp, 0, sz);
+		memset(*writesetp, 0, sz);
 
-	nfdset = howmany(n+1, NFDBITS);
-	/* Explicitly test here, because xrealloc isn't always called */
-	if (nfdset && SIZE_T_MAX / nfdset < sizeof(fd_mask))
-		fatal("channel_prepare_select: max_fd (%d) is too large", n);
-	sz = nfdset * sizeof(fd_mask);
-
-	/* perhaps check sz < nalloc/2 and shrink? */
-	if (*readsetp == NULL || sz > *nallocp) {
-		*readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask));
-		*writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask));
-		*nallocp = sz;
-	}
-	*maxfdp = n;
-	memset(*readsetp, 0, sz);
-	memset(*writesetp, 0, sz);
+		if (!rekeying)
+			channel_handler(channel_pre, *readsetp, *writesetp);
+	}
 
-	if (!rekeying)
-		channel_handler(channel_pre, *readsetp, *writesetp);
 }
 
 /*
@@ -2973,23 +3054,16 @@
 }
 
 int
-x11_connect_display(void)
+x11_connect_display(char *display)
 {
 	u_int display_number;
-	const char *display;
 	char buf[1024], *cp;
 	struct addrinfo hints, *ai, *aitop;
 	char strport[NI_MAXSERV];
 	int gaierr, sock = 0;
 
-	/* Try to open a socket for the local X server. */
-	display = getenv("DISPLAY");
-	if (!display) {
-		error("DISPLAY not set.");
-		return -1;
-	}
 	/*
-	 * Now we decode the value of the DISPLAY variable and make a
+	 * Decode the value of the DISPLAY variable and make a
 	 * connection to the real X server.
 	 */
 
@@ -3078,7 +3152,7 @@
 x11_input_open(int type, u_int32_t seq, void *ctxt)
 {
 	Channel *c = NULL;
-	int remote_id, sock = 0;
+	int remote_id;
 	char *remote_host;
 
 	debug("Received X11 open request.");
@@ -3092,27 +3166,20 @@
 	}
 	packet_check_eom();
 
-	/* Obtain a connection to the real X display. */
-	sock = x11_connect_display();
-	if (sock != -1) {
-		/* Allocate a channel for this connection. */
-		c = channel_new("connected x11 socket",
-		    SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0,
-		    remote_host, 1);
-		c->remote_id = remote_id;
-		c->force_drain = 1;
-	}
+	/* Allocate a channel for this connection. */
+	c = channel_new("connected x11 socket",
+	    SSH_CHANNEL_X11_OPEN, -1, -1, -1, 0, 0, 0,
+	    remote_host, 1);
+	c->remote_id = remote_id;
+	c->force_drain = 1;
+
 	xfree(remote_host);
-	if (c == NULL) {
-		/* Send refusal to the remote host. */
-		packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
-		packet_put_int(remote_id);
-	} else {
-		/* Send a confirmation to the remote host. */
-		packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
-		packet_put_int(remote_id);
-		packet_put_int(c->self);
-	}
+
+	/* Send a confirmation to the remote host. */
+	packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
+	packet_put_int(remote_id);
+	packet_put_int(c->self);
+
 	packet_send();
 }
 
@@ -3149,21 +3216,62 @@
 x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
     const char *proto, const char *data)
 {
+	Channel *c = NULL;
 	u_int data_len = (u_int) strlen(data) / 2;
 	u_int i, value;
 	char *new_data;
+	u_char *realdata;
 	int screen_number;
 	const char *cp;
 	u_int32_t rnd = 0;
+	struct x11_fwd *fwd;
 
-	if (x11_saved_display == NULL)
-		x11_saved_display = xstrdup(disp);
-	else if (strcmp(disp, x11_saved_display) != 0) {
-		error("x11_request_forwarding_with_spoofing: different "
-		    "$DISPLAY already forwarded");
-		return;
+	if (compat20) {
+		c = channel_lookup(client_session_id);
+		if (!c)
+			error("%s: channel %d: unknown channel", __func__, client_session_id);
+	}
+		
+	/* Convert real authentication data to binary */
+	realdata = xmalloc(data_len);
+	for (i = 0; i < data_len; i++) {
+		if (sscanf(data + 2 * i, "%2x", &value) != 1)
+			fatal("x11_request_forwarding: bad "
+			    "authentication data: %.100s", data);
+		realdata[i] = value;
+	}
+
+	fwd = x11_lookup_fwd_by_realdata(disp, proto, realdata, data_len);
+	if (fwd) {
+		fwd->usecount++;
+		debug("Increase use count for X11 fwd for display %s to %d.", disp, fwd->usecount);
+		xfree(realdata);
+	} else {
+		/* No existing forward. Create a new one */
+		debug("Create new X11 fake auth data for display %s.", disp);
+		fwd = xmalloc(sizeof(*fwd));
+		fwd->saved_display = xstrdup(disp);
+		fwd->saved_proto = xstrdup(proto);
+		fwd->saved_data = realdata;
+		fwd->saved_data_len = data_len;
+		fwd->fake_data = xmalloc(data_len);
+		fwd->fake_data_len = data_len;
+
+		for (i = 0; i < data_len; i++) {
+			if (i % 4 == 0)
+				rnd = arc4random();
+			fwd->fake_data[i] = rnd & 0xff;
+			rnd >>= 8;
+		}
+
+		fwd->usecount = 1;
+		fwd->next = x11_fwds;
+		x11_fwds = fwd;
 	}
 
+	if (c)
+		c->x11_fwd = fwd;
+		
 	cp = strchr(disp, ':');
 	if (cp)
 		cp = strchr(cp, '.');
@@ -3172,31 +3280,8 @@
 	else
 		screen_number = 0;
 
-	if (x11_saved_proto == NULL) {
-		/* Save protocol name. */
-		x11_saved_proto = xstrdup(proto);
-		/*
-		 * Extract real authentication data and generate fake data
-		 * of the same length.
-		 */
-		x11_saved_data = xmalloc(data_len);
-		x11_fake_data = xmalloc(data_len);
-		for (i = 0; i < data_len; i++) {
-			if (sscanf(data + 2 * i, "%2x", &value) != 1)
-				fatal("x11_request_forwarding: bad "
-				    "authentication data: %.100s", data);
-			if (i % 4 == 0)
-				rnd = arc4random();
-			x11_saved_data[i] = value;
-			x11_fake_data[i] = rnd & 0xff;
-			rnd >>= 8;
-		}
-		x11_saved_data_len = data_len;
-		x11_fake_data_len = data_len;
-	}
-
 	/* Convert the fake data into hex. */
-	new_data = tohex(x11_fake_data, data_len);
+	new_data = tohex(fwd->fake_data, data_len);
 
 	/* Send the request packet. */
 	if (compat20) {
diff -ur openssh-4.5p1/channels.h openssh-4.5p1-multidisplay/channels.h
--- openssh-4.5p1/channels.h	2006-08-05 03:39:39.000000000 +0100
+++ openssh-4.5p1-multidisplay/channels.h	2007-03-24 16:18:19.000000000 +0000
@@ -57,6 +57,7 @@
 
 #define SSH_CHANNEL_PATH_LEN		256
 
+struct x11_fwd;
 struct Channel;
 typedef struct Channel Channel;
 
@@ -114,6 +115,9 @@
 	channel_outfilter_fn	*output_filter;
 
 	int     datagram;	/* keep boundaries */
+
+	/* X11 forwarding data */
+	struct x11_fwd		*x11_fwd;
 };
 
 #define CHAN_EXTENDED_IGNORE		0
@@ -221,7 +225,7 @@
 
 /* x11 forwarding */
 
-int	 x11_connect_display(void);
+int	 x11_connect_display(char *);
 int	 x11_create_display_inet(int, int, int, u_int *, int **);
 void     x11_input_open(int, u_int32_t, void *);
 void	 x11_request_forwarding_with_spoofing(int, const char *, const char *,
Only in openssh-4.5p1: cipher.c.orig
diff -ur openssh-4.5p1/clientloop.c openssh-4.5p1-multidisplay/clientloop.c
--- openssh-4.5p1/clientloop.c	2006-10-23 18:02:41.000000000 +0100
+++ openssh-4.5p1-multidisplay/clientloop.c	2007-03-24 16:18:19.000000000 +0000
@@ -1736,11 +1736,8 @@
 	debug("client_request_x11: request from %s %d", originator,
 	    originator_port);
 	xfree(originator);
-	sock = x11_connect_display();
-	if (sock < 0)
-		return NULL;
 	c = channel_new("x11",
-	    SSH_CHANNEL_X11_OPEN, sock, sock, -1,
+	    SSH_CHANNEL_X11_OPEN, -1, -1, -1,
 	    CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
 	c->force_drain = 1;
 	return c;


Index: openssh.spec
===================================================================
RCS file: /cvs/dist/rpms/openssh/devel/openssh.spec,v
retrieving revision 1.108
retrieving revision 1.108.2.1
diff -u -r1.108 -r1.108.2.1
--- openssh.spec	20 Mar 2007 09:13:40 -0000	1.108
+++ openssh.spec	24 Mar 2007 16:37:03 -0000	1.108.2.1
@@ -52,7 +52,7 @@
 %define rescue 0
 %{?build_rescue:%define rescue 1}
 %{?build_rescue:%define rescue_rel rescue}
-
+%define rescue_rel .persist.1
 # Turn off some stuff for resuce builds
 %if %{rescue}
 %define kerberos5 0
@@ -90,6 +90,11 @@
 Patch48: openssh-4.3p2-pam-session.patch
 Patch49: openssh-4.3p2-gssapi-canohost.patch
 Patch50: openssh-4.5p1-mls.patch
+Patch100: openssh-4.3p2-controlpersist.patch
+Patch101: openssh-4.2p1-controldisplay.patch
+Patch102: openssh-4.5p1-multidisplay.patch
+Patch103: openssh-4.5p1-controlcleanup.patch
+
 License: BSD
 Group: Applications/Internet
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -217,6 +222,10 @@
 %patch48 -p1 -b .pam-sesssion
 %patch49 -p1 -b .canohost
 %patch50 -p1 -b .mls
+%patch100 -p1 -b .persist
+%patch101 -p1 -b .cdisplay
+%patch102 -p1 -b .multidisplay
+%patch103 -p1 -b .controlcleanup
 
 autoreconf
 




More information about the fedora-cvs-commits mailing list