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