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 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
50static sig_atomic_t banner_timedout;
51
52static void banner_alarm_catch (int signum)
53{
54 banner_timedout = 1;
55}
56
50static int show_other_keys(const char *, Key *); 57static 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.