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 11008e544..5158416f0 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;
@@ -422,7 +429,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
422 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 429 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
423 430
424 /* Set the connection. */ 431 /* Set the connection. */
425 packet_set_connection(sock, sock); 432 packet_set_connection(sock, sock, options.setuptimeout);
426 433
427 return 0; 434 return 0;
428} 435}
@@ -439,24 +446,41 @@ ssh_exchange_identification(void)
439 int connection_in = packet_get_connection_in(); 446 int connection_in = packet_get_connection_in();
440 int connection_out = packet_get_connection_out(); 447 int connection_out = packet_get_connection_out();
441 int minor1 = PROTOCOL_MINOR_1; 448 int minor1 = PROTOCOL_MINOR_1;
449 struct sigaction sa, osa;
442 450
443 /* Read other side\'s version identification. */ 451 /* Read other side's version identification.
452 * If SetupTimeOut has been set, give up after
453 * the specified amount of time
454 */
455 if(options.setuptimeout > 0){
456 memset(&sa, 0, sizeof(sa));
457 sa.sa_handler = banner_alarm_catch;
458 /*throw away any pending alarms, since we'd block otherwise*/
459 alarm(0);
460 sigaction(SIGALRM, &sa, &osa);
461 alarm(options.setuptimeout);
462 }
444 for (;;) { 463 for (;;) {
445 for (i = 0; i < sizeof(buf) - 1; i++) { 464 for (i = 0; i < sizeof(buf) - 1; ) {
446 int len = atomicio(read, connection_in, &buf[i], 1); 465 int len = read(connection_in, &buf[i], 1);
447 if (len < 0) 466 if (banner_timedout)
467 fatal("ssh_exchange_identification: Timeout waiting for version information.");
468 if (len < 0) {
469 if (errno == EINTR)
470 continue;
448 fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); 471 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
472 }
449 if (len != 1) 473 if (len != 1)
450 fatal("ssh_exchange_identification: Connection closed by remote host"); 474 fatal("ssh_exchange_identification: Connection closed by remote host");
451 if (buf[i] == '\r') {
452 buf[i] = '\n';
453 buf[i + 1] = 0;
454 continue; /**XXX wait for \n */
455 }
456 if (buf[i] == '\n') { 475 if (buf[i] == '\n') {
457 buf[i + 1] = 0; 476 buf[i + 1] = 0;
458 break; 477 break;
459 } 478 }
479 if (buf[i] == '\r') {
480 buf[i] = '\n';
481 buf[i + 1] = 0; /**XXX wait for \n */
482 }
483 i++;
460 } 484 }
461 buf[sizeof(buf) - 1] = 0; 485 buf[sizeof(buf) - 1] = 0;
462 if (strncmp(buf, "SSH-", 4) == 0) 486 if (strncmp(buf, "SSH-", 4) == 0)
@@ -465,6 +489,14 @@ ssh_exchange_identification(void)
465 } 489 }
466 server_version_string = xstrdup(buf); 490 server_version_string = xstrdup(buf);
467 491
492 /* If SetupTimeOut has been set, unset the alarm now, and
493 * put the correct handler for SIGALRM back.
494 */
495 if (options.setuptimeout > 0) {
496 alarm(0);
497 sigaction(SIGALRM,&osa,NULL);
498 }
499
468 /* 500 /*
469 * Check that the versions match. In future this might accept 501 * Check that the versions match. In future this might accept
470 * several versions and set appropriate flags to handle them. 502 * several versions and set appropriate flags to handle them.