diff options
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/sshconnect.c b/sshconnect.c index 745eeb5c3..27b338719 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include "includes.h" | 15 | #include "includes.h" |
16 | RCSID("$OpenBSD: sshconnect.c,v 1.109 2001/06/23 15:12:21 itojun Exp $"); | 16 | RCSID("$OpenBSD: sshconnect.c,v 1.110 2001/07/25 14:35:18 markus Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | 19 | ||
@@ -41,6 +41,27 @@ extern char *__progname; | |||
41 | /* AF_UNSPEC or AF_INET or AF_INET6 */ | 41 | /* AF_UNSPEC or AF_INET or AF_INET6 */ |
42 | extern int IPv4or6; | 42 | extern int IPv4or6; |
43 | 43 | ||
44 | static const char * | ||
45 | sockaddr_ntop(struct sockaddr *sa) | ||
46 | { | ||
47 | void *addr; | ||
48 | static char addrbuf[INET6_ADDRSTRLEN]; | ||
49 | |||
50 | switch (sa->sa_family) { | ||
51 | case AF_INET: | ||
52 | addr = &((struct sockaddr_in *)sa)->sin_addr; | ||
53 | break; | ||
54 | case AF_INET6: | ||
55 | addr = &((struct sockaddr_in6 *)sa)->sin6_addr; | ||
56 | break; | ||
57 | default: | ||
58 | /* This case should be protected against elsewhere */ | ||
59 | abort(); | ||
60 | } | ||
61 | inet_ntop(sa->sa_family, addr, addrbuf, sizeof(addrbuf)); | ||
62 | return addrbuf; | ||
63 | } | ||
64 | |||
44 | /* | 65 | /* |
45 | * Connect to the given ssh server using a proxy command. | 66 | * Connect to the given ssh server using a proxy command. |
46 | */ | 67 | */ |
@@ -138,7 +159,8 @@ ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, | |||
138 | /* Set the connection file descriptors. */ | 159 | /* Set the connection file descriptors. */ |
139 | packet_set_connection(pout[0], pin[1]); | 160 | packet_set_connection(pout[0], pin[1]); |
140 | 161 | ||
141 | return 1; | 162 | /* Indicate OK return */ |
163 | return 0; | ||
142 | } | 164 | } |
143 | 165 | ||
144 | /* | 166 | /* |
@@ -208,6 +230,12 @@ ssh_create_socket(struct passwd *pw, int privileged, int family) | |||
208 | * second). If proxy_command is non-NULL, it specifies the command (with %h | 230 | * second). If proxy_command is non-NULL, it specifies the command (with %h |
209 | * and %p substituted for host and port, respectively) to use to contact | 231 | * and %p substituted for host and port, respectively) to use to contact |
210 | * the daemon. | 232 | * the daemon. |
233 | * Return values: | ||
234 | * 0 for OK | ||
235 | * ECONNREFUSED if we got a "Connection Refused" by the peer on any address | ||
236 | * ECONNABORTED if we failed without a "Connection refused" | ||
237 | * Suitable error messages for the connection failure will already have been | ||
238 | * printed. | ||
211 | */ | 239 | */ |
212 | int | 240 | int |
213 | ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | 241 | ssh_connect(const char *host, struct sockaddr_storage * hostaddr, |
@@ -222,6 +250,12 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
222 | struct addrinfo hints, *ai, *aitop; | 250 | struct addrinfo hints, *ai, *aitop; |
223 | struct linger linger; | 251 | struct linger linger; |
224 | struct servent *sp; | 252 | struct servent *sp; |
253 | /* | ||
254 | * Did we get only other errors than "Connection refused" (which | ||
255 | * should block fallback to rsh and similar), or did we get at least | ||
256 | * one "Connection refused"? | ||
257 | */ | ||
258 | int full_failure = 1; | ||
225 | 259 | ||
226 | debug("ssh_connect: getuid %u geteuid %u anon %d", | 260 | debug("ssh_connect: getuid %u geteuid %u anon %d", |
227 | (u_int) getuid(), (u_int) geteuid(), anonymous); | 261 | (u_int) getuid(), (u_int) geteuid(), anonymous); |
@@ -252,8 +286,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
252 | * Try to connect several times. On some machines, the first time | 286 | * Try to connect several times. On some machines, the first time |
253 | * will sometimes fail. In general socket code appears to behave | 287 | * will sometimes fail. In general socket code appears to behave |
254 | * quite magically on many machines. | 288 | * quite magically on many machines. |
255 | */ | 289 | */ |
256 | for (attempt = 0; attempt < connection_attempts; attempt++) { | 290 | for (attempt = 0; ;) { |
257 | if (attempt > 0) | 291 | if (attempt > 0) |
258 | debug("Trying again..."); | 292 | debug("Trying again..."); |
259 | 293 | ||
@@ -280,6 +314,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
280 | #endif | 314 | #endif |
281 | ai->ai_family); | 315 | ai->ai_family); |
282 | if (sock < 0) | 316 | if (sock < 0) |
317 | /* Any error is already output */ | ||
283 | continue; | 318 | continue; |
284 | 319 | ||
285 | /* Connect to the host. We use the user's uid in the | 320 | /* Connect to the host. We use the user's uid in the |
@@ -293,7 +328,11 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
293 | restore_uid(); | 328 | restore_uid(); |
294 | break; | 329 | break; |
295 | } else { | 330 | } else { |
296 | debug("connect: %.100s", strerror(errno)); | 331 | if (errno == ECONNREFUSED) |
332 | full_failure = 0; | ||
333 | log("ssh: connect to address %s port %s: %s", | ||
334 | sockaddr_ntop(ai->ai_addr), strport, | ||
335 | strerror(errno)); | ||
297 | restore_uid(); | 336 | restore_uid(); |
298 | /* | 337 | /* |
299 | * Close the failed socket; there appear to | 338 | * Close the failed socket; there appear to |
@@ -308,6 +347,9 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
308 | if (ai) | 347 | if (ai) |
309 | break; /* Successful connection. */ | 348 | break; /* Successful connection. */ |
310 | 349 | ||
350 | attempt++; | ||
351 | if (attempt >= connection_attempts) | ||
352 | break; | ||
311 | /* Sleep a moment before retrying. */ | 353 | /* Sleep a moment before retrying. */ |
312 | sleep(1); | 354 | sleep(1); |
313 | } | 355 | } |
@@ -316,7 +358,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
316 | 358 | ||
317 | /* Return failure if we didn't get a successful connection. */ | 359 | /* Return failure if we didn't get a successful connection. */ |
318 | if (attempt >= connection_attempts) | 360 | if (attempt >= connection_attempts) |
319 | return 0; | 361 | return full_failure ? ECONNABORTED : ECONNREFUSED; |
320 | 362 | ||
321 | debug("Connection established."); | 363 | debug("Connection established."); |
322 | 364 | ||
@@ -338,7 +380,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
338 | /* Set the connection. */ | 380 | /* Set the connection. */ |
339 | packet_set_connection(sock, sock); | 381 | packet_set_connection(sock, sock); |
340 | 382 | ||
341 | return 1; | 383 | return 0; |
342 | } | 384 | } |
343 | 385 | ||
344 | /* | 386 | /* |