diff options
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 74 |
1 files changed, 24 insertions, 50 deletions
diff --git a/sshconnect.c b/sshconnect.c index 49190560d..ba7b9b71e 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.161 2005/03/02 01:00:06 djm Exp $"); | 16 | RCSID("$OpenBSD: sshconnect.c,v 1.168 2005/07/17 07:17:55 djm Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | 19 | ||
@@ -59,12 +59,11 @@ static void warn_changed_key(Key *); | |||
59 | static int | 59 | static int |
60 | ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | 60 | ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) |
61 | { | 61 | { |
62 | Buffer command; | 62 | char *command_string, *tmp; |
63 | const char *cp; | ||
64 | char *command_string; | ||
65 | int pin[2], pout[2]; | 63 | int pin[2], pout[2]; |
66 | pid_t pid; | 64 | pid_t pid; |
67 | char strport[NI_MAXSERV]; | 65 | char strport[NI_MAXSERV]; |
66 | size_t len; | ||
68 | 67 | ||
69 | /* Convert the port number into a string. */ | 68 | /* Convert the port number into a string. */ |
70 | snprintf(strport, sizeof strport, "%hu", port); | 69 | snprintf(strport, sizeof strport, "%hu", port); |
@@ -76,31 +75,13 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | |||
76 | * Use "exec" to avoid "sh -c" processes on some platforms | 75 | * Use "exec" to avoid "sh -c" processes on some platforms |
77 | * (e.g. Solaris) | 76 | * (e.g. Solaris) |
78 | */ | 77 | */ |
79 | buffer_init(&command); | 78 | len = strlen(proxy_command) + 6; |
80 | buffer_append(&command, "exec ", 5); | 79 | tmp = xmalloc(len); |
81 | 80 | strlcpy(tmp, "exec ", len); | |
82 | for (cp = proxy_command; *cp; cp++) { | 81 | strlcat(tmp, proxy_command, len); |
83 | if (cp[0] == '%' && cp[1] == '%') { | 82 | command_string = percent_expand(tmp, "h", host, |
84 | buffer_append(&command, "%", 1); | 83 | "p", strport, (char *)NULL); |
85 | cp++; | 84 | xfree(tmp); |
86 | continue; | ||
87 | } | ||
88 | if (cp[0] == '%' && cp[1] == 'h') { | ||
89 | buffer_append(&command, host, strlen(host)); | ||
90 | cp++; | ||
91 | continue; | ||
92 | } | ||
93 | if (cp[0] == '%' && cp[1] == 'p') { | ||
94 | buffer_append(&command, strport, strlen(strport)); | ||
95 | cp++; | ||
96 | continue; | ||
97 | } | ||
98 | buffer_append(&command, cp, 1); | ||
99 | } | ||
100 | buffer_append(&command, "\0", 1); | ||
101 | |||
102 | /* Get the final command string. */ | ||
103 | command_string = buffer_ptr(&command); | ||
104 | 85 | ||
105 | /* Create pipes for communicating with the proxy. */ | 86 | /* Create pipes for communicating with the proxy. */ |
106 | if (pipe(pin) < 0 || pipe(pout) < 0) | 87 | if (pipe(pin) < 0 || pipe(pout) < 0) |
@@ -154,7 +135,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | |||
154 | close(pout[1]); | 135 | close(pout[1]); |
155 | 136 | ||
156 | /* Free the command name. */ | 137 | /* Free the command name. */ |
157 | buffer_free(&command); | 138 | xfree(command_string); |
158 | 139 | ||
159 | /* Set the connection file descriptors. */ | 140 | /* Set the connection file descriptors. */ |
160 | packet_set_connection(pout[0], pin[1]); | 141 | packet_set_connection(pout[0], pin[1]); |
@@ -247,13 +228,13 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr, | |||
247 | tv.tv_sec = timeout; | 228 | tv.tv_sec = timeout; |
248 | tv.tv_usec = 0; | 229 | tv.tv_usec = 0; |
249 | 230 | ||
250 | for(;;) { | 231 | for (;;) { |
251 | rc = select(sockfd + 1, NULL, fdset, NULL, &tv); | 232 | rc = select(sockfd + 1, NULL, fdset, NULL, &tv); |
252 | if (rc != -1 || errno != EINTR) | 233 | if (rc != -1 || errno != EINTR) |
253 | break; | 234 | break; |
254 | } | 235 | } |
255 | 236 | ||
256 | switch(rc) { | 237 | switch (rc) { |
257 | case 0: | 238 | case 0: |
258 | /* Timed out */ | 239 | /* Timed out */ |
259 | errno = ETIMEDOUT; | 240 | errno = ETIMEDOUT; |
@@ -308,18 +289,9 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
308 | int sock = -1, attempt; | 289 | int sock = -1, attempt; |
309 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 290 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
310 | struct addrinfo hints, *ai, *aitop; | 291 | struct addrinfo hints, *ai, *aitop; |
311 | struct servent *sp; | ||
312 | 292 | ||
313 | debug2("ssh_connect: needpriv %d", needpriv); | 293 | debug2("ssh_connect: needpriv %d", needpriv); |
314 | 294 | ||
315 | /* Get default port if port has not been set. */ | ||
316 | if (port == 0) { | ||
317 | sp = getservbyname(SSH_SERVICE_NAME, "tcp"); | ||
318 | if (sp) | ||
319 | port = ntohs(sp->s_port); | ||
320 | else | ||
321 | port = SSH_DEFAULT_PORT; | ||
322 | } | ||
323 | /* If a proxy command is given, connect using it. */ | 295 | /* If a proxy command is given, connect using it. */ |
324 | if (proxy_command != NULL) | 296 | if (proxy_command != NULL) |
325 | return ssh_proxy_connect(host, port, proxy_command); | 297 | return ssh_proxy_connect(host, port, proxy_command); |
@@ -421,19 +393,21 @@ static void | |||
421 | ssh_exchange_identification(void) | 393 | ssh_exchange_identification(void) |
422 | { | 394 | { |
423 | char buf[256], remote_version[256]; /* must be same size! */ | 395 | char buf[256], remote_version[256]; /* must be same size! */ |
424 | int remote_major, remote_minor, i, mismatch; | 396 | int remote_major, remote_minor, mismatch; |
425 | int connection_in = packet_get_connection_in(); | 397 | int connection_in = packet_get_connection_in(); |
426 | int connection_out = packet_get_connection_out(); | 398 | int connection_out = packet_get_connection_out(); |
427 | int minor1 = PROTOCOL_MINOR_1; | 399 | int minor1 = PROTOCOL_MINOR_1; |
400 | u_int i; | ||
428 | 401 | ||
429 | /* Read other side\'s version identification. */ | 402 | /* Read other side's version identification. */ |
430 | for (;;) { | 403 | for (;;) { |
431 | for (i = 0; i < sizeof(buf) - 1; i++) { | 404 | for (i = 0; i < sizeof(buf) - 1; i++) { |
432 | int len = atomicio(read, connection_in, &buf[i], 1); | 405 | size_t len = atomicio(read, connection_in, &buf[i], 1); |
433 | if (len < 0) | 406 | |
434 | fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); | 407 | if (len != 1 && errno == EPIPE) |
435 | if (len != 1) | ||
436 | fatal("ssh_exchange_identification: Connection closed by remote host"); | 408 | fatal("ssh_exchange_identification: Connection closed by remote host"); |
409 | else if (len != 1) | ||
410 | fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); | ||
437 | if (buf[i] == '\r') { | 411 | if (buf[i] == '\r') { |
438 | buf[i] = '\n'; | 412 | buf[i] = '\n'; |
439 | buf[i + 1] = 0; | 413 | buf[i + 1] = 0; |
@@ -573,7 +547,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, | |||
573 | switch (hostaddr->sa_family) { | 547 | switch (hostaddr->sa_family) { |
574 | case AF_INET: | 548 | case AF_INET: |
575 | local = (ntohl(((struct sockaddr_in *)hostaddr)-> | 549 | local = (ntohl(((struct sockaddr_in *)hostaddr)-> |
576 | sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; | 550 | sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; |
577 | salen = sizeof(struct sockaddr_in); | 551 | salen = sizeof(struct sockaddr_in); |
578 | break; | 552 | break; |
579 | case AF_INET6: | 553 | case AF_INET6: |
@@ -706,8 +680,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, | |||
706 | 680 | ||
707 | if (show_other_keys(host, host_key)) | 681 | if (show_other_keys(host, host_key)) |
708 | snprintf(msg1, sizeof(msg1), | 682 | snprintf(msg1, sizeof(msg1), |
709 | "\nbut keys of different type are already" | 683 | "\nbut keys of different type are already" |
710 | " known for this host."); | 684 | " known for this host."); |
711 | else | 685 | else |
712 | snprintf(msg1, sizeof(msg1), "."); | 686 | snprintf(msg1, sizeof(msg1), "."); |
713 | /* The default */ | 687 | /* The default */ |