diff options
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/cmd/ssh/include/channels.h | 9 | ||||
| -rw-r--r-- | usr/src/cmd/ssh/libssh/common/channels.c | 29 | ||||
| -rw-r--r-- | usr/src/cmd/ssh/ssh/clientloop.c | 25 | ||||
| -rw-r--r-- | usr/src/cmd/ssh/sshd/altprivsep.c | 21 | 
4 files changed, 54 insertions, 30 deletions
| diff --git a/usr/src/cmd/ssh/include/channels.h b/usr/src/cmd/ssh/include/channels.h index 1845845f6a..83b41df0dd 100644 --- a/usr/src/cmd/ssh/include/channels.h +++ b/usr/src/cmd/ssh/include/channels.h @@ -33,8 +33,7 @@   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   */  /* - * Copyright 2009 Sun Microsystems, Inc.  All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.   */  /*	$OpenBSD: channels.h,v 1.70 2002/06/24 14:33:27 markus Exp $	*/ @@ -88,7 +87,11 @@ struct Channel {  	int     isatty;		/* rfd is a tty */  	int     wfd_isatty;	/* wfd is a tty */  	int     force_drain;	/* force close on iEOF */ -	int     delayed;		/* fdset hack */ +	int     delayed;	/* post-select handlers for newly created +				 * channels are delayed until the first call +				 * to a matching pre-select handler.  +				 * this way post-select handlers are not +				 * accidenly called if a FD gets reused */  	Buffer  input;		/* data read from socket, to be sent over  				 * encrypted connection */  	Buffer  output;		/* data received over encrypted connection for diff --git a/usr/src/cmd/ssh/libssh/common/channels.c b/usr/src/cmd/ssh/libssh/common/channels.c index 3a0e6bad22..7133758b73 100644 --- a/usr/src/cmd/ssh/libssh/common/channels.c +++ b/usr/src/cmd/ssh/libssh/common/channels.c @@ -38,8 +38,7 @@   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   */  /* - * Copyright 2009 Sun Microsystems, Inc.  All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.   */  #include "includes.h" @@ -270,6 +269,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,  	c->detach_user = NULL;  	c->confirm = NULL;  	c->input_filter = NULL; +	c->delayed = 1;		/* prevent call to channel_post handler */  	debug("channel %d: new [%s]", found, remote_name);  	return c;  } @@ -598,11 +598,11 @@ channel_request_start(int local_id, char *service, int wantconfirm)  {  	Channel *c = channel_lookup(local_id); +	debug("channel request %d: %s", local_id, service);  	if (c == NULL) {  		log("channel_request_start: %d: unknown channel id", local_id);  		return;  	} -	debug("channel request %d: %s", local_id, service) ;  	packet_start(SSH2_MSG_CHANNEL_REQUEST);  	packet_put_int(c->remote_id);  	packet_put_cstring(service); @@ -1090,7 +1090,6 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)  	int have, ret;  	have = buffer_len(&c->input); -	c->delayed = 0;  	debug2("channel %d: pre_dynamic: have %d", c->self, have);  	/* buffer_dump(&c->input); */  	/* check if the fixed size part of the packet is in buffer. */ @@ -1283,16 +1282,8 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)  		nc->host_port = c->host_port;  		strlcpy(nc->path, c->path, sizeof(nc->path)); -		if (nextstate == SSH_CHANNEL_DYNAMIC) { -			/* -			 * do not call the channel_post handler until -			 * this flag has been reset by a pre-handler. -			 * otherwise the FD_ISSET calls might overflow -			 */ -			nc->delayed = 1; -		} else { +		if (nextstate != SSH_CHANNEL_DYNAMIC)  			port_open_helper(nc, rtype); -		}  	}  } @@ -1541,8 +1532,6 @@ channel_check_window(Channel *c)  static void  channel_post_open(Channel *c, fd_set * readset, fd_set * writeset)  { -	if (c->delayed) -		return;  	channel_handle_rfd(c, readset, writeset);  	channel_handle_wfd(c, readset, writeset);  	if (!compat20) @@ -1672,17 +1661,23 @@ static void  channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)  {  	static int did_init = 0; -	int i; +	int i, oalloc;  	Channel *c;  	if (!did_init) {  		channel_handler_init();  		did_init = 1;  	} -	for (i = 0; i < channels_alloc; i++) { +	for (i = 0, oalloc = channels_alloc; i < oalloc; i++) {  		c = channels[i];  		if (c == NULL)  			continue; +		if (c->delayed) { +			if (ftab == channel_pre) +				c->delayed = 0; +			else +				continue; +		}  		if (ftab[c->type] != NULL)  			(*ftab[c->type])(c, readset, writeset);  		channel_garbage_collect(c); diff --git a/usr/src/cmd/ssh/ssh/clientloop.c b/usr/src/cmd/ssh/ssh/clientloop.c index bd94ebaa26..f101c4a6b4 100644 --- a/usr/src/cmd/ssh/ssh/clientloop.c +++ b/usr/src/cmd/ssh/ssh/clientloop.c @@ -59,8 +59,7 @@   */  /* - * Copyright 2009 Sun Microsystems, Inc.  All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.   */  #include "includes.h" @@ -406,10 +405,30 @@ static void  client_check_window_change(void)  {  	struct winsize ws; +	Channel *c;  	if (! received_window_change_signal)  		return; -	/** XXX race */ +	 +	/* +	 * We want to send a window-change request only when a session is +	 * already established and alive. +	 * +	 * Note: During session handshake we cannot send window-change request, +	 * because we do not know the remote channel ID yet. We have to store +	 * the information about signals which have arrived and send the +	 * window-change request when the channel and the session are fully +	 * established. +	 */ +	if (compat20) { +		if (session_ident == -1 || session_closed) +			return; +		c = channel_lookup(session_ident); +		if (c == NULL || c->type != SSH_CHANNEL_OPEN || +		    c->remote_id == -1) +			return; +	} +  	received_window_change_signal = 0;  	if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) diff --git a/usr/src/cmd/ssh/sshd/altprivsep.c b/usr/src/cmd/ssh/sshd/altprivsep.c index a2c437cb6f..6f954feab5 100644 --- a/usr/src/cmd/ssh/sshd/altprivsep.c +++ b/usr/src/cmd/ssh/sshd/altprivsep.c @@ -18,8 +18,7 @@   *   * CDDL HEADER END   * - * Copyright 2009 Sun Microsystems, Inc.  All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.   */  #include <fcntl.h> @@ -331,7 +330,7 @@ altprivsep_rekey(int type, u_int32_t seq, void *ctxt)  	if (type != SSH2_MSG_NEWKEYS) {  		debug2("Forwarding re-key packet (%d) to monitor", type);  		if (!altprivsep_fwd_packet(type)) -			fatal("Monitor not responding"); +			fatal("altprivsep_rekey: Monitor not responding");  	}  	/* tell server_loop2() that we're re-keying */ @@ -361,7 +360,7 @@ altprivsep_process_input(fd_set *rset)  	debug2("reading from pipe to monitor (%d)", pipe_fd);  	if ((type = altprivsep_packet_read()) == -1) -		fatal("Monitor not responding"); +		fatal("altprivsep_process_input: Monitor not responding");  	if (!compat20)  		return; /* shouldn't happen! but be safe */ @@ -857,6 +856,7 @@ altprivsep_packet_send(void)  	u_char	plen_buf[sizeof (plen)];  	u_char padlen;	/* padding length */  	fd_set *setp; +	int err;  	if (pipe_fd == -1)  		return (-1); @@ -922,12 +922,15 @@ altprivsep_packet_send(void)  	return (1);  pipe_gone: +	 +	err = errno;  	(void) close(pipe_fd);  	pipe_fd = -1; -	fatal("Monitor not responding"); +	fatal("altprvsep_packet_send: Monitor not responding: %.100s", +	    strerror(err));  	/* NOTREACHED */  	return (0); @@ -944,6 +947,7 @@ altprivsep_packet_read(void)  	u_char plen_buf[sizeof (plen)];  	u_char padlen;  	fd_set *setp; +	int err;  	if (pipe_fd == -1)  		return (-1); @@ -995,12 +999,15 @@ altprivsep_packet_read(void)  pipe_gone: +	err = errno; +  	(void) close(pipe_fd);  	pipe_fd = -1;  	if (len < 0) -		fatal("Monitor not responding"); +		fatal("altpriv_packet_read: Monitor not responding %.100s", +		    strerror(err));  	debug2("Monitor pipe closed by monitor");  	return (0); @@ -1014,7 +1021,7 @@ altprivsep_packet_read_expect(int expected)  	type = altprivsep_packet_read();  	if (type <= 0) -		fatal("Monitor not responding"); +		fatal("altprivsep_packet_read_expect: Monitor not responding");  	if (type != expected)  		fatal("Protocol error in privilege separation; expected " | 
