diff options
author | Colin Watson <cjwatson@debian.org> | 2003-09-01 00:51:03 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2003-09-01 00:51:03 +0000 |
commit | 79cf0b3654d7b597de323153eb57015cdfbd90a4 (patch) | |
tree | 274e78bc3369e218e59aa1fcc9b7e90697f424f1 /sshconnect.c | |
parent | d984a3c6658e950881edcfb2aae464add93f68d4 (diff) |
Debian release 3.4p1-1.
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 b89321fb8..8eb5fda7d 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -46,6 +46,8 @@ extern uid_t original_effective_uid; | |||
46 | #define INET6_ADDRSTRLEN 46 | 46 | #define INET6_ADDRSTRLEN 46 |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | static sig_atomic_t banner_timedout; | ||
50 | |||
49 | static const char * | 51 | static const char * |
50 | sockaddr_ntop(struct sockaddr *sa, socklen_t salen) | 52 | sockaddr_ntop(struct sockaddr *sa, socklen_t salen) |
51 | { | 53 | { |
@@ -57,6 +59,11 @@ sockaddr_ntop(struct sockaddr *sa, socklen_t salen) | |||
57 | return addrbuf; | 59 | return addrbuf; |
58 | } | 60 | } |
59 | 61 | ||
62 | static void banner_alarm_catch (int signum) | ||
63 | { | ||
64 | banner_timedout = 1; | ||
65 | } | ||
66 | |||
60 | /* | 67 | /* |
61 | * Connect to the given ssh server using a proxy command. | 68 | * Connect to the given ssh server using a proxy command. |
62 | */ | 69 | */ |
@@ -152,7 +159,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | |||
152 | buffer_free(&command); | 159 | buffer_free(&command); |
153 | 160 | ||
154 | /* Set the connection file descriptors. */ | 161 | /* Set the connection file descriptors. */ |
155 | packet_set_connection(pout[0], pin[1]); | 162 | packet_set_connection(pout[0], pin[1], options.setuptimeout); |
156 | 163 | ||
157 | /* Indicate OK return */ | 164 | /* Indicate OK return */ |
158 | return 0; | 165 | return 0; |
@@ -353,7 +360,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
353 | error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); | 360 | error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); |
354 | 361 | ||
355 | /* Set the connection. */ | 362 | /* Set the connection. */ |
356 | packet_set_connection(sock, sock); | 363 | packet_set_connection(sock, sock, options.setuptimeout); |
357 | 364 | ||
358 | return 0; | 365 | return 0; |
359 | } | 366 | } |
@@ -370,24 +377,41 @@ ssh_exchange_identification(void) | |||
370 | int connection_in = packet_get_connection_in(); | 377 | int connection_in = packet_get_connection_in(); |
371 | int connection_out = packet_get_connection_out(); | 378 | int connection_out = packet_get_connection_out(); |
372 | int minor1 = PROTOCOL_MINOR_1; | 379 | int minor1 = PROTOCOL_MINOR_1; |
380 | struct sigaction sa, osa; | ||
373 | 381 | ||
374 | /* Read other side\'s version identification. */ | 382 | /* Read other side's version identification. |
383 | * If SetupTimeOut has been set, give up after | ||
384 | * the specified amount of time | ||
385 | */ | ||
386 | if(options.setuptimeout > 0){ | ||
387 | memset(&sa, 0, sizeof(sa)); | ||
388 | sa.sa_handler = banner_alarm_catch; | ||
389 | /*throw away any pending alarms, since we'd block otherwise*/ | ||
390 | alarm(0); | ||
391 | sigaction(SIGALRM, &sa, &osa); | ||
392 | alarm(options.setuptimeout); | ||
393 | } | ||
375 | for (;;) { | 394 | for (;;) { |
376 | for (i = 0; i < sizeof(buf) - 1; i++) { | 395 | for (i = 0; i < sizeof(buf) - 1; ) { |
377 | int len = atomicio(read, connection_in, &buf[i], 1); | 396 | int len = read(connection_in, &buf[i], 1); |
378 | if (len < 0) | 397 | if (banner_timedout) |
398 | fatal("ssh_exchange_identification: Timeout waiting for version information."); | ||
399 | if (len < 0) { | ||
400 | if (errno == EINTR) | ||
401 | continue; | ||
379 | fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); | 402 | fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); |
403 | } | ||
380 | if (len != 1) | 404 | if (len != 1) |
381 | fatal("ssh_exchange_identification: Connection closed by remote host"); | 405 | fatal("ssh_exchange_identification: Connection closed by remote host"); |
382 | if (buf[i] == '\r') { | ||
383 | buf[i] = '\n'; | ||
384 | buf[i + 1] = 0; | ||
385 | continue; /**XXX wait for \n */ | ||
386 | } | ||
387 | if (buf[i] == '\n') { | 406 | if (buf[i] == '\n') { |
388 | buf[i + 1] = 0; | 407 | buf[i + 1] = 0; |
389 | break; | 408 | break; |
390 | } | 409 | } |
410 | if (buf[i] == '\r') { | ||
411 | buf[i] = '\n'; | ||
412 | buf[i + 1] = 0; /**XXX wait for \n */ | ||
413 | } | ||
414 | i++; | ||
391 | } | 415 | } |
392 | buf[sizeof(buf) - 1] = 0; | 416 | buf[sizeof(buf) - 1] = 0; |
393 | if (strncmp(buf, "SSH-", 4) == 0) | 417 | if (strncmp(buf, "SSH-", 4) == 0) |
@@ -396,6 +420,14 @@ ssh_exchange_identification(void) | |||
396 | } | 420 | } |
397 | server_version_string = xstrdup(buf); | 421 | server_version_string = xstrdup(buf); |
398 | 422 | ||
423 | /* If SetupTimeOut has been set, unset the alarm now, and | ||
424 | * put the correct handler for SIGALRM back. | ||
425 | */ | ||
426 | if (options.setuptimeout > 0) { | ||
427 | alarm(0); | ||
428 | sigaction(SIGALRM,&osa,NULL); | ||
429 | } | ||
430 | |||
399 | /* | 431 | /* |
400 | * Check that the versions match. In future this might accept | 432 | * Check that the versions match. In future this might accept |
401 | * several versions and set appropriate flags to handle them. | 433 | * several versions and set appropriate flags to handle them. |