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 49190560d..f8ebd9875 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -50,6 +50,13 @@ extern pid_t proxy_command_pid;
50#define INET6_ADDRSTRLEN 46 50#define INET6_ADDRSTRLEN 46
51#endif 51#endif
52 52
53static sig_atomic_t banner_timedout;
54
55static void banner_alarm_catch (int signum)
56{
57 banner_timedout = 1;
58}
59
53static int show_other_keys(const char *, Key *); 60static int show_other_keys(const char *, Key *);
54static void warn_changed_key(Key *); 61static void warn_changed_key(Key *);
55 62
@@ -157,7 +164,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
157 buffer_free(&command); 164 buffer_free(&command);
158 165
159 /* Set the connection file descriptors. */ 166 /* Set the connection file descriptors. */
160 packet_set_connection(pout[0], pin[1]); 167 packet_set_connection(pout[0], pin[1], options.setuptimeout);
161 168
162 /* Indicate OK return */ 169 /* Indicate OK return */
163 return 0; 170 return 0;
@@ -408,7 +415,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
408 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 415 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
409 416
410 /* Set the connection. */ 417 /* Set the connection. */
411 packet_set_connection(sock, sock); 418 packet_set_connection(sock, sock, options.setuptimeout);
412 419
413 return 0; 420 return 0;
414} 421}
@@ -425,24 +432,41 @@ ssh_exchange_identification(void)
425 int connection_in = packet_get_connection_in(); 432 int connection_in = packet_get_connection_in();
426 int connection_out = packet_get_connection_out(); 433 int connection_out = packet_get_connection_out();
427 int minor1 = PROTOCOL_MINOR_1; 434 int minor1 = PROTOCOL_MINOR_1;
435 struct sigaction sa, osa;
428 436
429 /* Read other side\'s version identification. */ 437 /* Read other side's version identification.
438 * If SetupTimeOut has been set, give up after
439 * the specified amount of time
440 */
441 if(options.setuptimeout > 0){
442 memset(&sa, 0, sizeof(sa));
443 sa.sa_handler = banner_alarm_catch;
444 /*throw away any pending alarms, since we'd block otherwise*/
445 alarm(0);
446 sigaction(SIGALRM, &sa, &osa);
447 alarm(options.setuptimeout);
448 }
430 for (;;) { 449 for (;;) {
431 for (i = 0; i < sizeof(buf) - 1; i++) { 450 for (i = 0; i < sizeof(buf) - 1; ) {
432 int len = atomicio(read, connection_in, &buf[i], 1); 451 int len = read(connection_in, &buf[i], 1);
433 if (len < 0) 452 if (banner_timedout)
453 fatal("ssh_exchange_identification: Timeout waiting for version information.");
454 if (len < 0) {
455 if (errno == EINTR)
456 continue;
434 fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); 457 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
458 }
435 if (len != 1) 459 if (len != 1)
436 fatal("ssh_exchange_identification: Connection closed by remote host"); 460 fatal("ssh_exchange_identification: Connection closed by remote host");
437 if (buf[i] == '\r') {
438 buf[i] = '\n';
439 buf[i + 1] = 0;
440 continue; /**XXX wait for \n */
441 }
442 if (buf[i] == '\n') { 461 if (buf[i] == '\n') {
443 buf[i + 1] = 0; 462 buf[i + 1] = 0;
444 break; 463 break;
445 } 464 }
465 if (buf[i] == '\r') {
466 buf[i] = '\n';
467 buf[i + 1] = 0; /**XXX wait for \n */
468 }
469 i++;
446 } 470 }
447 buf[sizeof(buf) - 1] = 0; 471 buf[sizeof(buf) - 1] = 0;
448 if (strncmp(buf, "SSH-", 4) == 0) 472 if (strncmp(buf, "SSH-", 4) == 0)
@@ -451,6 +475,14 @@ ssh_exchange_identification(void)
451 } 475 }
452 server_version_string = xstrdup(buf); 476 server_version_string = xstrdup(buf);
453 477
478 /* If SetupTimeOut has been set, unset the alarm now, and
479 * put the correct handler for SIGALRM back.
480 */
481 if (options.setuptimeout > 0) {
482 alarm(0);
483 sigaction(SIGALRM,&osa,NULL);
484 }
485
454 /* 486 /*
455 * Check that the versions match. In future this might accept 487 * Check that the versions match. In future this might accept
456 * several versions and set appropriate flags to handle them. 488 * several versions and set appropriate flags to handle them.