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 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
58static sig_atomic_t banner_timedout;
59
60static void banner_alarm_catch (int signum)
61{
62 banner_timedout = 1;
63}
64
58static int show_other_keys(const char *, Key *); 65static 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.