summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/sshconnect.c b/sshconnect.c
index dfeddd39e..e0d1a8c7e 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -51,6 +51,13 @@ extern pid_t proxy_command_pid;
51#define INET6_ADDRSTRLEN 46 51#define INET6_ADDRSTRLEN 46
52#endif 52#endif
53 53
54static sig_atomic_t banner_timedout;
55
56static void banner_alarm_catch (int signum)
57{
58 banner_timedout = 1;
59}
60
54static int show_other_keys(const char *, Key *); 61static int show_other_keys(const char *, Key *);
55static void warn_changed_key(Key *); 62static void warn_changed_key(Key *);
56 63
@@ -158,7 +165,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
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;
@@ -423,7 +430,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
423 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 430 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
424 431
425 /* Set the connection. */ 432 /* Set the connection. */
426 packet_set_connection(sock, sock); 433 packet_set_connection(sock, sock, options.setuptimeout);
427 434
428 return 0; 435 return 0;
429} 436}
@@ -440,24 +447,41 @@ ssh_exchange_identification(void)
440 int connection_in = packet_get_connection_in(); 447 int connection_in = packet_get_connection_in();
441 int connection_out = packet_get_connection_out(); 448 int connection_out = packet_get_connection_out();
442 int minor1 = PROTOCOL_MINOR_1; 449 int minor1 = PROTOCOL_MINOR_1;
450 struct sigaction sa, osa;
443 451
444 /* Read other side\'s version identification. */ 452 /* Read other side's version identification.
453 * If SetupTimeOut has been set, give up after
454 * the specified amount of time
455 */
456 if(options.setuptimeout > 0){
457 memset(&sa, 0, sizeof(sa));
458 sa.sa_handler = banner_alarm_catch;
459 /*throw away any pending alarms, since we'd block otherwise*/
460 alarm(0);
461 sigaction(SIGALRM, &sa, &osa);
462 alarm(options.setuptimeout);
463 }
445 for (;;) { 464 for (;;) {
446 for (i = 0; i < sizeof(buf) - 1; i++) { 465 for (i = 0; i < sizeof(buf) - 1; ) {
447 int len = atomicio(read, connection_in, &buf[i], 1); 466 int len = read(connection_in, &buf[i], 1);
448 if (len < 0) 467 if (banner_timedout)
468 fatal("ssh_exchange_identification: Timeout waiting for version information.");
469 if (len < 0) {
470 if (errno == EINTR)
471 continue;
449 fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); 472 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
473 }
450 if (len != 1) 474 if (len != 1)
451 fatal("ssh_exchange_identification: Connection closed by remote host"); 475 fatal("ssh_exchange_identification: Connection closed by remote host");
452 if (buf[i] == '\r') {
453 buf[i] = '\n';
454 buf[i + 1] = 0;
455 continue; /**XXX wait for \n */
456 }
457 if (buf[i] == '\n') { 476 if (buf[i] == '\n') {
458 buf[i + 1] = 0; 477 buf[i + 1] = 0;
459 break; 478 break;
460 } 479 }
480 if (buf[i] == '\r') {
481 buf[i] = '\n';
482 buf[i + 1] = 0; /**XXX wait for \n */
483 }
484 i++;
461 } 485 }
462 buf[sizeof(buf) - 1] = 0; 486 buf[sizeof(buf) - 1] = 0;
463 if (strncmp(buf, "SSH-", 4) == 0) 487 if (strncmp(buf, "SSH-", 4) == 0)
@@ -466,6 +490,14 @@ ssh_exchange_identification(void)
466 } 490 }
467 server_version_string = xstrdup(buf); 491 server_version_string = xstrdup(buf);
468 492
493 /* If SetupTimeOut has been set, unset the alarm now, and
494 * put the correct handler for SIGALRM back.
495 */
496 if (options.setuptimeout > 0) {
497 alarm(0);
498 sigaction(SIGALRM,&osa,NULL);
499 }
500
469 /* 501 /*
470 * Check that the versions match. In future this might accept 502 * Check that the versions match. In future this might accept
471 * several versions and set appropriate flags to handle them. 503 * several versions and set appropriate flags to handle them.