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 dae25969a..013a896b7 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -47,6 +47,13 @@ extern pid_t proxy_command_pid; | |||
47 | #define INET6_ADDRSTRLEN 46 | 47 | #define INET6_ADDRSTRLEN 46 |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | static sig_atomic_t banner_timedout; | ||
51 | |||
52 | static void banner_alarm_catch (int signum) | ||
53 | { | ||
54 | banner_timedout = 1; | ||
55 | } | ||
56 | |||
50 | static int show_other_keys(const char *, Key *); | 57 | static int show_other_keys(const char *, Key *); |
51 | 58 | ||
52 | /* | 59 | /* |
@@ -153,7 +160,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | |||
153 | buffer_free(&command); | 160 | buffer_free(&command); |
154 | 161 | ||
155 | /* Set the connection file descriptors. */ | 162 | /* Set the connection file descriptors. */ |
156 | packet_set_connection(pout[0], pin[1]); | 163 | packet_set_connection(pout[0], pin[1], options.setuptimeout); |
157 | 164 | ||
158 | /* Indicate OK return */ | 165 | /* Indicate OK return */ |
159 | return 0; | 166 | return 0; |
@@ -346,7 +353,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
346 | error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); | 353 | error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); |
347 | 354 | ||
348 | /* Set the connection. */ | 355 | /* Set the connection. */ |
349 | packet_set_connection(sock, sock); | 356 | packet_set_connection(sock, sock, options.setuptimeout); |
350 | 357 | ||
351 | return 0; | 358 | return 0; |
352 | } | 359 | } |
@@ -363,24 +370,41 @@ ssh_exchange_identification(void) | |||
363 | int connection_in = packet_get_connection_in(); | 370 | int connection_in = packet_get_connection_in(); |
364 | int connection_out = packet_get_connection_out(); | 371 | int connection_out = packet_get_connection_out(); |
365 | int minor1 = PROTOCOL_MINOR_1; | 372 | int minor1 = PROTOCOL_MINOR_1; |
373 | struct sigaction sa, osa; | ||
366 | 374 | ||
367 | /* Read other side\'s version identification. */ | 375 | /* Read other side's version identification. |
376 | * If SetupTimeOut has been set, give up after | ||
377 | * the specified amount of time | ||
378 | */ | ||
379 | if(options.setuptimeout > 0){ | ||
380 | memset(&sa, 0, sizeof(sa)); | ||
381 | sa.sa_handler = banner_alarm_catch; | ||
382 | /*throw away any pending alarms, since we'd block otherwise*/ | ||
383 | alarm(0); | ||
384 | sigaction(SIGALRM, &sa, &osa); | ||
385 | alarm(options.setuptimeout); | ||
386 | } | ||
368 | for (;;) { | 387 | for (;;) { |
369 | for (i = 0; i < sizeof(buf) - 1; i++) { | 388 | for (i = 0; i < sizeof(buf) - 1; ) { |
370 | int len = atomicio(read, connection_in, &buf[i], 1); | 389 | int len = read(connection_in, &buf[i], 1); |
371 | if (len < 0) | 390 | if (banner_timedout) |
391 | fatal("ssh_exchange_identification: Timeout waiting for version information."); | ||
392 | if (len < 0) { | ||
393 | if (errno == EINTR) | ||
394 | continue; | ||
372 | fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); | 395 | fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); |
396 | } | ||
373 | if (len != 1) | 397 | if (len != 1) |
374 | fatal("ssh_exchange_identification: Connection closed by remote host"); | 398 | fatal("ssh_exchange_identification: Connection closed by remote host"); |
375 | if (buf[i] == '\r') { | ||
376 | buf[i] = '\n'; | ||
377 | buf[i + 1] = 0; | ||
378 | continue; /**XXX wait for \n */ | ||
379 | } | ||
380 | if (buf[i] == '\n') { | 399 | if (buf[i] == '\n') { |
381 | buf[i + 1] = 0; | 400 | buf[i + 1] = 0; |
382 | break; | 401 | break; |
383 | } | 402 | } |
403 | if (buf[i] == '\r') { | ||
404 | buf[i] = '\n'; | ||
405 | buf[i + 1] = 0; /**XXX wait for \n */ | ||
406 | } | ||
407 | i++; | ||
384 | } | 408 | } |
385 | buf[sizeof(buf) - 1] = 0; | 409 | buf[sizeof(buf) - 1] = 0; |
386 | if (strncmp(buf, "SSH-", 4) == 0) | 410 | if (strncmp(buf, "SSH-", 4) == 0) |
@@ -389,6 +413,14 @@ ssh_exchange_identification(void) | |||
389 | } | 413 | } |
390 | server_version_string = xstrdup(buf); | 414 | server_version_string = xstrdup(buf); |
391 | 415 | ||
416 | /* If SetupTimeOut has been set, unset the alarm now, and | ||
417 | * put the correct handler for SIGALRM back. | ||
418 | */ | ||
419 | if (options.setuptimeout > 0) { | ||
420 | alarm(0); | ||
421 | sigaction(SIGALRM,&osa,NULL); | ||
422 | } | ||
423 | |||
392 | /* | 424 | /* |
393 | * Check that the versions match. In future this might accept | 425 | * Check that the versions match. In future this might accept |
394 | * several versions and set appropriate flags to handle them. | 426 | * several versions and set appropriate flags to handle them. |