View | Details | Raw Unified | Return to bug 52 | Differences between
and this patch

Collapse All | Expand All

(-)openssh-2.9p2/channels.c (+9 lines)
Lines 1137-1142 Link Here
1137
			continue;
1137
			continue;
1138
		if (ftab[c->type] == NULL)
1138
		if (ftab[c->type] == NULL)
1139
			continue;
1139
			continue;
1140
		if(c->istate == CHAN_INPUT_OPEN && c->rfd == -1) {
1141
			int type=c->type;
1142
			c->type=SSH_CHANNEL_CLOSED;
1143
			if(channel_find_open() == -1)
1144
			  	shutdown(packet_get_connection_out(),
1145
					 SHUT_RDWR);
1146
			c->type=type;
1147
			continue;
1148
		}
1140
		(*ftab[c->type])(c, readset, writeset);
1149
		(*ftab[c->type])(c, readset, writeset);
1141
		if (chan_is_dead(c)) {
1150
		if (chan_is_dead(c)) {
1142
			/*
1151
			/*
(-)openssh-2.9p2/clientloop.c (-10 / +39 lines)
Lines 84-89 Link Here
84
84
85
/* import options */
85
/* import options */
86
extern Options options;
86
extern Options options;
87
extern int no_tty_flag;
87
88
88
/* Flag indicating that stdin should be redirected from /dev/null. */
89
/* Flag indicating that stdin should be redirected from /dev/null. */
89
extern int stdin_null_flag;
90
extern int stdin_null_flag;
Lines 121-128 Link Here
121
static int connection_in;	/* Connection to server (input). */
122
static int connection_in;	/* Connection to server (input). */
122
static int connection_out;	/* Connection to server (output). */
123
static int connection_out;	/* Connection to server (output). */
123
static int need_rekeying;	/* Set to non-zero if rekeying is requested. */
124
static int need_rekeying;	/* Set to non-zero if rekeying is requested. */
124
static int session_closed = 0;	/* In SSH2: login session closed. */
125
enum SessionStatus {SessionOpen, SessionClose, SessionWait};
125
126
static int session_status = SessionOpen; /* In SSH2: login session closed. */
126
void	client_init_dispatch(void);
127
void	client_init_dispatch(void);
127
int	session_ident = -1;
128
int	session_ident = -1;
128
129
Lines 324-329 Link Here
324
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
325
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
325
    int *maxfdp, int rekeying)
326
    int *maxfdp, int rekeying)
326
{
327
{
328
	struct timeval timer;
329
	struct timeval *timerp;
330
	int rc;
331
	
327
	/* Add any selections by the channel mechanism. */
332
	/* Add any selections by the channel mechanism. */
328
	channel_prepare_select(readsetp, writesetp, maxfdp, rekeying);
333
	channel_prepare_select(readsetp, writesetp, maxfdp, rekeying);
329
334
Lines 346-352 Link Here
346
		if (buffer_len(&stderr_buffer) > 0)
351
		if (buffer_len(&stderr_buffer) > 0)
347
			FD_SET(fileno(stderr), *writesetp);
352
			FD_SET(fileno(stderr), *writesetp);
348
	} else {
353
	} else {
349
		FD_SET(connection_in, *readsetp);
354
		/* channel_prepare_select could have closed the last channel */
355
		if ((session_status == SessionClose)
356
		    && !channel_still_open()) {
357
			if (!packet_have_data_to_write())
358
				return;
359
		} else {
360
			FD_SET(connection_in, *readsetp);
361
		}
350
	}
362
	}
351
363
352
	/* Select server connection if have data to write to the server. */
364
	/* Select server connection if have data to write to the server. */
Lines 362-368 Link Here
362
	 * SSH_MSG_IGNORE packet when the timeout expires.
374
	 * SSH_MSG_IGNORE packet when the timeout expires.
363
	 */
375
	 */
364
376
365
	if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) {
377
	if((session_status == SessionWait && options.sleep > 0) ||
378
	    (no_tty_flag && options.sleep == -1)) {
379
		timer.tv_sec=options.sleep > 0 ? options.sleep : 0;
380
		timer.tv_usec=0;
381
		timerp=&timer;
382
	} else {
383
		timerp=NULL;
384
	}
385
	
386
	rc=select((*maxfdp)+1, *readsetp, *writesetp, NULL, timerp);
387
	if (rc < 0) {
366
		char buf[100];
388
		char buf[100];
367
389
368
		/*
390
		/*
Lines 379-385 Link Here
379
		snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
401
		snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
380
		buffer_append(&stderr_buffer, buf, strlen(buf));
402
		buffer_append(&stderr_buffer, buf, strlen(buf));
381
		quit_pending = 1;
403
		quit_pending = 1;
382
	}
404
	} else if (rc == 0 && session_status == SessionWait)
405
		session_status=SessionClose;
383
}
406
}
384
407
385
void
408
void
Lines 440-448 Link Here
440
		len = read(connection_in, buf, sizeof(buf));
463
		len = read(connection_in, buf, sizeof(buf));
441
		if (len == 0) {
464
		if (len == 0) {
442
			/* Received EOF.  The remote host has closed the connection. */
465
			/* Received EOF.  The remote host has closed the connection. */
443
			snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
466
/* 
444
				 host);
467
 * This message duplicates the one already in client_loop().
445
			buffer_append(&stderr_buffer, buf, strlen(buf));
468
 *
469
 *			snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
470
 *				 host);
471
 *			buffer_append(&stderr_buffer, buf, strlen(buf));
472
 */			
446
			quit_pending = 1;
473
			quit_pending = 1;
447
			return;
474
			return;
448
		}
475
		}
Lines 751-757 Link Here
751
	if (id != session_ident)
778
	if (id != session_ident)
752
		error("client_channel_closed: id %d != session_ident %d",
779
		error("client_channel_closed: id %d != session_ident %d",
753
		    id, session_ident);
780
		    id, session_ident);
754
	session_closed = 1;
781
	session_status = (options.sleep >= 0) ? SessionWait : SessionClose;
755
	if (in_raw_mode())
782
	if (in_raw_mode())
756
		leave_raw_mode();
783
		leave_raw_mode();
757
}
784
}
Lines 776-781 Link Here
776
	start_time = get_current_time();
803
	start_time = get_current_time();
777
804
778
	/* Initialize variables. */
805
	/* Initialize variables. */
806
	if(!have_pty) session_status=SessionWait;
779
	escape_pending = 0;
807
	escape_pending = 0;
780
	last_was_cr = 1;
808
	last_was_cr = 1;
781
	exit_status = -1;
809
	exit_status = -1;
Lines 840-846 Link Here
840
		/* Process buffered packets sent by the server. */
868
		/* Process buffered packets sent by the server. */
841
		client_process_buffered_input_packets();
869
		client_process_buffered_input_packets();
842
870
843
		if (compat20 && session_closed && !channel_still_open())
871
		if (compat20 && (session_status == SessionClose)
872
		    && !channel_still_open())
844
			break;
873
			break;
845
874
846
		rekeying = (xxx_kex != NULL && !xxx_kex->done);
875
		rekeying = (xxx_kex != NULL && !xxx_kex->done);
(-)openssh-2.9p2/nchan.c (-2 / +2 lines)
Lines 56-62 Link Here
56
56
57
/* helper */
57
/* helper */
58
static void	chan_shutdown_write(Channel *c);
58
static void	chan_shutdown_write(Channel *c);
59
static void	chan_shutdown_read(Channel *c);
59
void		chan_shutdown_read(Channel *c);
60
60
61
/*
61
/*
62
 * SSH1 specific implementation of event functions
62
 * SSH1 specific implementation of event functions
Lines 479-485 Link Here
479
		c->wfd = -1;
479
		c->wfd = -1;
480
	}
480
	}
481
}
481
}
482
static void
482
void
483
chan_shutdown_read(Channel *c)
483
chan_shutdown_read(Channel *c)
484
{
484
{
485
	if (compat20 && c->type == SSH_CHANNEL_LARVAL)
485
	if (compat20 && c->type == SSH_CHANNEL_LARVAL)
(-)openssh-2.9p2/nchan.h (+1 lines)
Lines 88-91 Link Here
88
88
89
void    chan_init_iostates(Channel * c);
89
void    chan_init_iostates(Channel * c);
90
void	chan_init(void);
90
void	chan_init(void);
91
void	chan_shutdown_read(Channel *c);
91
#endif
92
#endif
(-)openssh-2.9p2/readconf.c (-1 / +7 lines)
Lines 111-117 Link Here
111
	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
111
	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
112
	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
112
	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
113
	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
113
	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
114
	oHostKeyAlgorithms
114
	oHostKeyAlgorithms, oSleep
115
} OpCodes;
115
} OpCodes;
116
116
117
/* Textual representations of the tokens. */
117
/* Textual representations of the tokens. */
Lines 177-182 Link Here
177
	{ "dynamicforward", oDynamicForward },
177
	{ "dynamicforward", oDynamicForward },
178
	{ "preferredauthentications", oPreferredAuthentications },
178
	{ "preferredauthentications", oPreferredAuthentications },
179
	{ "hostkeyalgorithms", oHostKeyAlgorithms },
179
	{ "hostkeyalgorithms", oHostKeyAlgorithms },
180
	{ "sleep", oSleep },
180
	{ NULL, 0 }
181
	{ NULL, 0 }
181
};
182
};
182
183
Lines 494-499 Link Here
494
		intptr = &options->connection_attempts;
495
		intptr = &options->connection_attempts;
495
		goto parse_int;
496
		goto parse_int;
496
497
498
	case oSleep:
499
		intptr = &options->sleep;
500
		goto parse_int;
501
497
	case oCipher:
502
	case oCipher:
498
		intptr = &options->cipher;
503
		intptr = &options->cipher;
499
		arg = strdelim(&s);
504
		arg = strdelim(&s);
Lines 761-766 Link Here
761
	options->num_remote_forwards = 0;
766
	options->num_remote_forwards = 0;
762
	options->log_level = (LogLevel) - 1;
767
	options->log_level = (LogLevel) - 1;
763
	options->preferred_authentications = NULL;
768
	options->preferred_authentications = NULL;
769
	options->sleep = -1;
764
}
770
}
765
771
766
/*
772
/*
(-)openssh-2.9p2/readconf.h (+1 lines)
Lines 97-102 Link Here
97
	/* Remote TCP/IP forward requests. */
97
	/* Remote TCP/IP forward requests. */
98
	int     num_remote_forwards;
98
	int     num_remote_forwards;
99
	Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
99
	Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
100
        int     sleep;		/* Exit delay in seconds */
100
}       Options;
101
}       Options;
101
102
102
103
(-)openssh-2.9p2/session.c (+3 lines)
Lines 1928-1933 Link Here
1928
	 */
1928
	 */
1929
	if (c->ostate != CHAN_OUTPUT_CLOSED)
1929
	if (c->ostate != CHAN_OUTPUT_CLOSED)
1930
		chan_write_failed(c);
1930
		chan_write_failed(c);
1931
	if (c->istate == CHAN_INPUT_OPEN && compat20) {
1932
		chan_shutdown_read(c);
1933
	}
1931
	s->chanid = -1;
1934
	s->chanid = -1;
1932
}
1935
}
1933
1936
(-)openssh-2.9p2/ssh.c (-2 / +9 lines)
Lines 182-187 Link Here
182
	fprintf(stderr, "  -R listen-port:host:port   Forward remote port to local address\n");
182
	fprintf(stderr, "  -R listen-port:host:port   Forward remote port to local address\n");
183
	fprintf(stderr, "              These cause %s to listen for connections on a port, and\n", __progname);
183
	fprintf(stderr, "              These cause %s to listen for connections on a port, and\n", __progname);
184
	fprintf(stderr, "              forward them to the other side by connecting to host:port.\n");
184
	fprintf(stderr, "              forward them to the other side by connecting to host:port.\n");
185
	fprintf(stderr, "  -S delay    Set exit delay (in seconds; 0 means wait forever).\n");
185
	fprintf(stderr, "  -C          Enable compression.\n");
186
	fprintf(stderr, "  -C          Enable compression.\n");
186
	fprintf(stderr, "  -N          Do not execute a shell or command.\n");
187
	fprintf(stderr, "  -N          Do not execute a shell or command.\n");
187
	fprintf(stderr, "  -g          Allow remote hosts to connect to forwarded ports.\n");
188
	fprintf(stderr, "  -g          Allow remote hosts to connect to forwarded ports.\n");
Lines 318-324 Link Here
318
		opt = av[optind][1];
319
		opt = av[optind][1];
319
		if (!opt)
320
		if (!opt)
320
			usage();
321
			usage();
321
		if (strchr("eilcmpLRDo", opt)) {   /* options with arguments */
322
		if (strchr("eilcmpLRSDo", opt)) {  /* options with arguments */
322
			optarg = av[optind] + 2;
323
			optarg = av[optind] + 2;
323
			if (strcmp(optarg, "") == 0) {
324
			if (strcmp(optarg, "") == 0) {
324
				if (optind >= ac - 1)
325
				if (optind >= ac - 1)
Lines 488-494 Link Here
488
			}
489
			}
489
			add_local_forward(&options, fwd_port, buf, fwd_host_port);
490
			add_local_forward(&options, fwd_port, buf, fwd_host_port);
490
			break;
491
			break;
491
492
		case 'S':
493
			options.sleep = atoi(optarg);
494
			if (options.sleep < 0) {
495
				fprintf(stderr, "Bad delay value '%s'\n", optarg);
496
				exit(1);
497
			}
498
			break;
492
		case 'D':
499
		case 'D':
493
			fwd_port = a2port(optarg);
500
			fwd_port = a2port(optarg);
494
			if (fwd_port == 0) {
501
			if (fwd_port == 0) {

Return to bug 52