View | Details | Raw Unified | Return to bug 91
Collapse All | Expand All

(-)orig/clientloop.c (-5 / +40 lines)
Lines 316-325 Link Here
316
 * one of the file descriptors).
316
 * one of the file descriptors).
317
 */
317
 */
318
318
319
static void
319
static int
320
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
320
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
321
    int *maxfdp, int *nallocp, int rekeying)
321
    int *maxfdp, int *nallocp, int rekeying)
322
{
322
{
323
	struct timeval tv, *tvp;
324
	int n;
325
	extern Options options;
326
323
	/* Add any selections by the channel mechanism. */
327
	/* Add any selections by the channel mechanism. */
324
	channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying);
328
	channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying);
325
329
Lines 348-354 Link Here
348
			/* clear mask since we did not call select() */
352
			/* clear mask since we did not call select() */
349
			memset(*readsetp, 0, *nallocp);
353
			memset(*readsetp, 0, *nallocp);
350
			memset(*writesetp, 0, *nallocp);
354
			memset(*writesetp, 0, *nallocp);
351
			return;
355
			return 0;
352
		} else {
356
		} else {
353
			FD_SET(connection_in, *readsetp);
357
			FD_SET(connection_in, *readsetp);
354
		}
358
		}
Lines 367-373 Link Here
367
	 * SSH_MSG_IGNORE packet when the timeout expires.
371
	 * SSH_MSG_IGNORE packet when the timeout expires.
368
	 */
372
	 */
369
373
370
	if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) {
374
	/*
375
	 * We don't do the 'random' bit, but we want periodic ignored
376
	 * message anyway, so as to notice when the other ends TCP
377
	 * has given up during an outage.
378
	 */
379
380
	if (options.protocolkeepalives > 0) {
381
	        tvp = &tv;
382
		tv.tv_sec = options.protocolkeepalives;
383
		tv.tv_usec = 0;
384
	} else
385
	        tvp = 0;
386
387
	n = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
388
	if (n < 0) {
371
		char buf[100];
389
		char buf[100];
372
390
373
		/*
391
		/*
Lines 379-390 Link Here
379
		memset(*writesetp, 0, *nallocp);
397
		memset(*writesetp, 0, *nallocp);
380
398
381
		if (errno == EINTR)
399
		if (errno == EINTR)
382
			return;
400
			return 0;
383
		/* Note: we might still have data in the buffers. */
401
		/* Note: we might still have data in the buffers. */
384
		snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
402
		snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
385
		buffer_append(&stderr_buffer, buf, strlen(buf));
403
		buffer_append(&stderr_buffer, buf, strlen(buf));
386
		quit_pending = 1;
404
		quit_pending = 1;
387
	}
405
	}
406
	return n == 0;
388
}
407
}
389
408
390
static void
409
static void
Lines 777-782 Link Here
777
{
796
{
778
	fd_set *readset = NULL, *writeset = NULL;
797
	fd_set *readset = NULL, *writeset = NULL;
779
	double start_time, total_time;
798
	double start_time, total_time;
799
	int timed_out;
780
	int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
800
	int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
781
	char buf[100];
801
	char buf[100];
782
802
Lines 884-890 Link Here
884
		 * available on one of the descriptors).
904
		 * available on one of the descriptors).
885
		 */
905
		 */
886
		max_fd2 = max_fd;
906
		max_fd2 = max_fd;
887
		client_wait_until_can_do_something(&readset, &writeset,
907
		timed_out = client_wait_until_can_do_something(&readset, &writeset,
888
		    &max_fd2, &nalloc, rekeying);
908
		    &max_fd2, &nalloc, rekeying);
889
909
890
		if (quit_pending)
910
		if (quit_pending)
Lines 907-912 Link Here
907
927
908
		if (quit_pending)
928
		if (quit_pending)
909
			break;
929
			break;
930
931
		if(timed_out) {
932
		        /*
933
			 * Nothing is happening, so synthesize some
934
			 * bogus activity
935
			 */
936
		        packet_start(compat20
937
				     ? SSH2_MSG_IGNORE
938
				     : SSH_MSG_IGNORE);
939
			packet_put_cstring("");
940
			packet_send();
941
			if (FD_ISSET(connection_out, writeset))
942
			        packet_write_poll();
943
			continue;
944
		}
910
945
911
		if (!compat20) {
946
		if (!compat20) {
912
			/* Buffer data from stdin */
947
			/* Buffer data from stdin */
(-)orig/packet.c (-2 / +14 lines)
Lines 74-79 Link Here
74
 */
74
 */
75
static int connection_in = -1;
75
static int connection_in = -1;
76
static int connection_out = -1;
76
static int connection_out = -1;
77
static int setup_timeout = -1;
77
78
78
/* Protocol flags for the remote side. */
79
/* Protocol flags for the remote side. */
79
static u_int remote_protocol_flags = 0;
80
static u_int remote_protocol_flags = 0;
Lines 123-135 Link Here
123
 * packet_set_encryption_key is called.
124
 * packet_set_encryption_key is called.
124
 */
125
 */
125
void
126
void
126
packet_set_connection(int fd_in, int fd_out)
127
packet_set_connection(int fd_in, int fd_out, int new_setup_timeout)
127
{
128
{
128
	Cipher *none = cipher_by_name("none");
129
	Cipher *none = cipher_by_name("none");
129
	if (none == NULL)
130
	if (none == NULL)
130
		fatal("packet_set_connection: cannot load cipher 'none'");
131
		fatal("packet_set_connection: cannot load cipher 'none'");
131
	connection_in = fd_in;
132
	connection_in = fd_in;
132
	connection_out = fd_out;
133
	connection_out = fd_out;
134
	setup_timeout = new_setup_timeout;
133
	cipher_init(&send_context, none, (u_char *) "", 0, NULL, 0);
135
	cipher_init(&send_context, none, (u_char *) "", 0, NULL, 0);
134
	cipher_init(&receive_context, none, (u_char *) "", 0, NULL, 0);
136
	cipher_init(&receive_context, none, (u_char *) "", 0, NULL, 0);
135
	newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
137
	newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
Lines 615-620 Link Here
615
	int type, len;
617
	int type, len;
616
	fd_set *setp;
618
	fd_set *setp;
617
	char buf[8192];
619
	char buf[8192];
620
	struct timeval tv, *tvp;
618
	DBG(debug("packet_read()"));
621
	DBG(debug("packet_read()"));
619
622
620
	setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) *
623
	setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) *
Lines 646-655 Link Here
646
		    sizeof(fd_mask));
649
		    sizeof(fd_mask));
647
		FD_SET(connection_in, setp);
650
		FD_SET(connection_in, setp);
648
651
652
		if (setup_timeout > 0) {
653
			tvp = &tv;
654
			tv.tv_sec = setup_timeout;
655
			tv.tv_usec = 0;
656
		} else
657
			tvp = 0;
658
649
		/* Wait for some data to arrive. */
659
		/* Wait for some data to arrive. */
650
		while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 &&
660
		while (select(connection_in + 1, setp, NULL, NULL, tvp) == -1 &&
651
		    (errno == EAGAIN || errno == EINTR))
661
		    (errno == EAGAIN || errno == EINTR))
652
			;
662
			;
663
		if (!FD_ISSET(connection_in, setp))
664
			fatal("packet_read: Setup timeout expired, giving up");
653
665
654
		/* Read data from the socket. */
666
		/* Read data from the socket. */
655
		len = read(connection_in, buf, sizeof(buf));
667
		len = read(connection_in, buf, sizeof(buf));
(-)orig/packet.h (-1 / +1 lines)
Lines 18-24 Link Here
18
18
19
#include <openssl/bn.h>
19
#include <openssl/bn.h>
20
20
21
void     packet_set_connection(int, int);
21
void     packet_set_connection(int, int, int);
22
void     packet_set_nonblocking(void);
22
void     packet_set_nonblocking(void);
23
int      packet_get_connection_in(void);
23
int      packet_get_connection_in(void);
24
int      packet_get_connection_out(void);
24
int      packet_get_connection_out(void);
(-)orig/readconf.c (-1 / +24 lines)
Lines 83-88 Link Here
83
     UseRsh no
83
     UseRsh no
84
     StrictHostKeyChecking yes
84
     StrictHostKeyChecking yes
85
     KeepAlives no
85
     KeepAlives no
86
     ProtocolKeepAlives 0
87
     SetupTimeOut 0
86
     IdentityFile ~/.ssh/identity
88
     IdentityFile ~/.ssh/identity
87
     Port 22
89
     Port 22
88
     EscapeChar ~
90
     EscapeChar ~
Lines 115-121 Link Here
115
	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
117
	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
116
	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
118
	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
117
	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
119
	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
118
	oClearAllForwardings, oNoHostAuthenticationForLocalhost 
120
	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
121
	oProtocolKeepAlives, oSetupTimeOut 
119
} OpCodes;
122
} OpCodes;
120
123
121
/* Textual representations of the tokens. */
124
/* Textual representations of the tokens. */
Lines 187-192 Link Here
187
	{ "smartcarddevice", oSmartcardDevice },
190
	{ "smartcarddevice", oSmartcardDevice },
188
	{ "clearallforwardings", oClearAllForwardings }, 
191
	{ "clearallforwardings", oClearAllForwardings }, 
189
	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 
192
	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 
193
	{ "protocolkeepalives", oProtocolKeepAlives },
194
	{ "setuptimeout", oSetupTimeOut },
190
	{ NULL, 0 }
195
	{ NULL, 0 }
191
};
196
};
192
197
Lines 420-425 Link Here
420
		intptr = &options->no_host_authentication_for_localhost;
425
		intptr = &options->no_host_authentication_for_localhost;
421
		goto parse_flag;
426
		goto parse_flag;
422
427
428
	case oProtocolKeepAlives:
429
	        intptr = &options->protocolkeepalives;
430
		goto parse_int;
431
432
	case oSetupTimeOut:
433
	        intptr = &options->setuptimeout;
434
		goto parse_int;
435
423
	case oNumberOfPasswordPrompts:
436
	case oNumberOfPasswordPrompts:
424
		intptr = &options->number_of_password_prompts;
437
		intptr = &options->number_of_password_prompts;
425
		goto parse_int;
438
		goto parse_int;
Lines 772-777 Link Here
772
	options->strict_host_key_checking = -1;
785
	options->strict_host_key_checking = -1;
773
	options->compression = -1;
786
	options->compression = -1;
774
	options->keepalives = -1;
787
	options->keepalives = -1;
788
	options->protocolkeepalives = -1;
789
	options->setuptimeout = -1;
775
	options->compression_level = -1;
790
	options->compression_level = -1;
776
	options->port = -1;
791
	options->port = -1;
777
	options->connection_attempts = -1;
792
	options->connection_attempts = -1;
Lines 865-870 Link Here
865
		options->compression = 0;
880
		options->compression = 0;
866
	if (options->keepalives == -1)
881
	if (options->keepalives == -1)
867
		options->keepalives = 1;
882
		options->keepalives = 1;
883
	if (options->protocolkeepalives == -1){
884
	  if (options->batch_mode == 1) /*in batch mode, default is 5mins */
885
	        options->protocolkeepalives = 300;
886
	  else  options->protocolkeepalives = 0;}
887
	if (options->setuptimeout == -1){
888
	  if (options->batch_mode == 1) /*in batch mode, default is 5mins */
889
	        options->setuptimeout = 300;
890
	  else  options->setuptimeout = 0;}
868
	if (options->compression_level == -1)
891
	if (options->compression_level == -1)
869
		options->compression_level = 6;
892
		options->compression_level = 6;
870
	if (options->port == -1)
893
	if (options->port == -1)
(-)orig/readconf.h (+2 lines)
Lines 63-68 Link Here
63
	int     compression_level;	/* Compression level 1 (fast) to 9
63
	int     compression_level;	/* Compression level 1 (fast) to 9
64
					 * (best). */
64
					 * (best). */
65
	int     keepalives;	/* Set SO_KEEPALIVE. */
65
	int     keepalives;	/* Set SO_KEEPALIVE. */
66
        int     protocolkeepalives; /* ssh-level keepalives */
67
        int     setuptimeout; /* timeout in the protocol banner exchange */
66
	LogLevel log_level;	/* Level for logging. */
68
	LogLevel log_level;	/* Level for logging. */
67
69
68
	int     port;		/* Port to connect. */
70
	int     port;		/* Port to connect. */
(-)orig/ssh-keyscan.c (-1 / +1 lines)
Lines 348-354 Link Here
348
{
348
{
349
	int j;
349
	int j;
350
350
351
	packet_set_connection(c->c_fd, c->c_fd);
351
	packet_set_connection(c->c_fd, c->c_fd, timeout);
352
	enable_compat20();
352
	enable_compat20();
353
	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA?
353
	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA?
354
	    "ssh-dss": "ssh-rsa";
354
	    "ssh-dss": "ssh-rsa";
(-)orig/ssh.1 (-2 / +34 lines)
Lines 711-718 Link Here
711
If set to
711
If set to
712
.Dq yes ,
712
.Dq yes ,
713
passphrase/password querying will be disabled.
713
passphrase/password querying will be disabled.
714
In addition, the 
715
.Cm ProtocolKeepAlives 
716
and
717
.Cm SetupTimeOut
718
options will both be set to 300 seconds by default.
714
This option is useful in scripts and other batch jobs where no user
719
This option is useful in scripts and other batch jobs where no user
715
is present to supply the password.
720
is present to supply the password,
721
and where it is desirable to detect a
722
broken network swiftly.
716
The argument must be
723
The argument must be
717
.Dq yes
724
.Dq yes
718
or
725
or
Lines 930-936 Link Here
930
Specifies whether the system should send keepalive messages to the
937
Specifies whether the system should send keepalive messages to the
931
other side.
938
other side.
932
If they are sent, death of the connection or crash of one
939
If they are sent, death of the connection or crash of one
933
of the machines will be properly noticed.
940
of the machines will be properly noticed.  This option only uses TCP
941
keepalives (as opposed to using ssh level keepalives), so takes a long
942
time to notice when the connection dies.  As such, you probably want
943
the 
944
.Cm ProtocolKeepAlives 
945
option as well.
934
However, this means that
946
However, this means that
935
connections will die if the route is down temporarily, and some people
947
connections will die if the route is down temporarily, and some people
936
find it annoying.
948
find it annoying.
Lines 1029-1034 Link Here
1029
.Nm
1041
.Nm
1030
tries version 2 and falls back to version 1
1042
tries version 2 and falls back to version 1
1031
if version 2 is not available.
1043
if version 2 is not available.
1044
.It Cm ProtocolKeepAlives
1045
Specifies the interval at which IGNORE packets will be sent to
1046
the server during dile periods. Use this option in scripts to detect
1047
when the network fails. The argument must be an integer. The default
1048
is 0 (disabled), or 300 if the 
1049
.Cm BatchMode
1050
option is set.
1032
.It Cm ProxyCommand
1051
.It Cm ProxyCommand
1033
Specifies the command to use to connect to the server.
1052
Specifies the command to use to connect to the server.
1034
The command
1053
The command
Lines 1121-1126 Link Here
1121
.Dq no .
1140
.Dq no .
1122
The default is
1141
The default is
1123
.Dq yes .
1142
.Dq yes .
1143
.It Cm SetupTimeOut
1144
Normally,
1145
.Nm ssh
1146
blocks indefinitly whilst waiting to receive the ssh banner and other
1147
setup protocol from the server, during the session setup.  This can cause
1148
.Nm ssh
1149
to hang under certain circumstances.  If this option is set,
1150
.Nm ssh
1151
will give up if no data from the server is received for the specified
1152
number of seconds. The argument must be an integer. The default is 0
1153
(disabled), or 300 if
1154
.Cm BatchMode
1155
is set.
1124
.It Cm SmartcardDevice
1156
.It Cm SmartcardDevice
1125
Specifies which smartcard device to use. The argument to this keyword is
1157
Specifies which smartcard device to use. The argument to this keyword is
1126
the device
1158
the device
(-)orig/sshconnect.c (-11 / +43 lines)
Lines 42-47 Link Here
42
#define INET6_ADDRSTRLEN 46
42
#define INET6_ADDRSTRLEN 46
43
#endif
43
#endif
44
44
45
static sig_atomic_t banner_timedout;
46
45
static const char *
47
static const char *
46
sockaddr_ntop(struct sockaddr *sa)
48
sockaddr_ntop(struct sockaddr *sa)
47
{
49
{
Lines 63-68 Link Here
63
	return addrbuf;
65
	return addrbuf;
64
}
66
}
65
67
68
static void banner_alarm_catch (int signum)
69
{
70
        banner_timedout = 1;
71
}
72
66
/*
73
/*
67
 * Connect to the given ssh server using a proxy command.
74
 * Connect to the given ssh server using a proxy command.
68
 */
75
 */
Lines 158-164 Link Here
158
	buffer_free(&command);
165
	buffer_free(&command);
159
166
160
	/* Set the connection file descriptors. */
167
	/* Set the connection file descriptors. */
161
	packet_set_connection(pout[0], pin[1]);
168
	packet_set_connection(pout[0], pin[1], options.setuptimeout);
162
169
163
	/* Indicate OK return */
170
	/* Indicate OK return */
164
	return 0;
171
	return 0;
Lines 378-384 Link Here
378
		error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
385
		error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
379
386
380
	/* Set the connection. */
387
	/* Set the connection. */
381
	packet_set_connection(sock, sock);
388
	packet_set_connection(sock, sock, options.setuptimeout);
382
389
383
	return 0;
390
	return 0;
384
}
391
}
Lines 395-418 Link Here
395
	int connection_in = packet_get_connection_in();
402
	int connection_in = packet_get_connection_in();
396
	int connection_out = packet_get_connection_out();
403
	int connection_out = packet_get_connection_out();
397
	int minor1 = PROTOCOL_MINOR_1;
404
	int minor1 = PROTOCOL_MINOR_1;
405
	struct sigaction sa, osa;
398
406
399
	/* Read other side\'s version identification. */
407
	/* Read other side's version identification.
408
	 * If SetupTimeOut has been set, give up after
409
	 * the specified amount of time
410
	 */
411
	if(options.setuptimeout > 0){
412
        	memset(&sa, 0, sizeof(sa));
413
		sa.sa_handler = banner_alarm_catch;
414
		/*throw away any pending alarms, since we'd block otherwise*/
415
		alarm(0);
416
		sigaction(SIGALRM, &sa, &osa);
417
		alarm(options.setuptimeout);
418
	}
400
	for (;;) {
419
	for (;;) {
401
		for (i = 0; i < sizeof(buf) - 1; i++) {
420
		for (i = 0; i < sizeof(buf) - 1; ) {
402
			int len = atomicio(read, connection_in, &buf[i], 1);
421
			int len = read(connection_in, &buf[i], 1);
403
			if (len < 0)
422
			if (banner_timedout)
423
				fatal("ssh_exchange_identification: Timeout waiting for version information.");
424
			if (len < 0) {
425
				if (errno == EINTR)
426
					continue;
404
				fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
427
				fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
428
			}
405
			if (len != 1)
429
			if (len != 1)
406
				fatal("ssh_exchange_identification: Connection closed by remote host");
430
				fatal("ssh_exchange_identification: Connection closed by remote host");
407
			if (buf[i] == '\r') {
408
				buf[i] = '\n';
409
				buf[i + 1] = 0;
410
				continue;		/**XXX wait for \n */
411
			}
412
			if (buf[i] == '\n') {
431
			if (buf[i] == '\n') {
413
				buf[i + 1] = 0;
432
				buf[i + 1] = 0;
414
				break;
433
				break;
415
			}
434
			}
435
			if (buf[i] == '\r') {
436
				buf[i] = '\n';
437
				buf[i + 1] = 0;		/**XXX wait for \n */
438
			}
439
			i++;
416
		}
440
		}
417
		buf[sizeof(buf) - 1] = 0;
441
		buf[sizeof(buf) - 1] = 0;
418
		if (strncmp(buf, "SSH-", 4) == 0)
442
		if (strncmp(buf, "SSH-", 4) == 0)
Lines 420-425 Link Here
420
		debug("ssh_exchange_identification: %s", buf);
445
		debug("ssh_exchange_identification: %s", buf);
421
	}
446
	}
422
	server_version_string = xstrdup(buf);
447
	server_version_string = xstrdup(buf);
448
449
	/* If SetupTimeOut has been set, unset the alarm now, and
450
	 * put the correct handler for SIGALRM back.
451
	 */
452
	if (options.setuptimeout > 0) {
453
	        alarm(0);
454
		sigaction(SIGALRM,&osa,NULL);
455
	}
423
456
424
	/*
457
	/*
425
	 * Check that the versions match.  In future this might accept
458
	 * Check that the versions match.  In future this might accept
(-)orig/sshd.c (-1 / +1 lines)
Lines 1129-1135 Link Here
1129
	 * Register our connection.  This turns encryption off because we do
1129
	 * Register our connection.  This turns encryption off because we do
1130
	 * not have a key.
1130
	 * not have a key.
1131
	 */
1131
	 */
1132
	packet_set_connection(sock_in, sock_out);
1132
	packet_set_connection(sock_in, sock_out, -1);
1133
1133
1134
	remote_port = get_remote_port();
1134
	remote_port = get_remote_port();
1135
	remote_ip = get_remote_ipaddr();
1135
	remote_ip = get_remote_ipaddr();

Return to bug 91