diff options
author | Colin Watson <cjwatson@debian.org> | 2005-09-14 12:45:47 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2005-09-14 12:45:47 +0000 |
commit | 9b71add4cecf753c45f5fbd6ff0913bc95b3e95d (patch) | |
tree | d4ea8fdb30c7949c6433f5277c39548ea579d4dc /sshconnect.c | |
parent | ed07bcbea56007ab5b218ddf3aa6a7d4e21966e0 (diff) | |
parent | 16704d57999d987fb8d9ba53379841a79f016d67 (diff) |
Merge 4.2p1 to the trunk.
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 81 |
1 files changed, 33 insertions, 48 deletions
diff --git a/sshconnect.c b/sshconnect.c index 10a614127..10eaac35d 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.162 2005/03/10 22:01:06 deraadt 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 | ||
@@ -66,12 +66,11 @@ static void warn_changed_key(Key *); | |||
66 | static int | 66 | static int |
67 | ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | 67 | ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) |
68 | { | 68 | { |
69 | Buffer command; | 69 | char *command_string, *tmp; |
70 | const char *cp; | ||
71 | char *command_string; | ||
72 | int pin[2], pout[2]; | 70 | int pin[2], pout[2]; |
73 | pid_t pid; | 71 | pid_t pid; |
74 | char strport[NI_MAXSERV]; | 72 | char strport[NI_MAXSERV]; |
73 | size_t len; | ||
75 | 74 | ||
76 | /* Convert the port number into a string. */ | 75 | /* Convert the port number into a string. */ |
77 | snprintf(strport, sizeof strport, "%hu", port); | 76 | snprintf(strport, sizeof strport, "%hu", port); |
@@ -83,31 +82,13 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | |||
83 | * Use "exec" to avoid "sh -c" processes on some platforms | 82 | * Use "exec" to avoid "sh -c" processes on some platforms |
84 | * (e.g. Solaris) | 83 | * (e.g. Solaris) |
85 | */ | 84 | */ |
86 | buffer_init(&command); | 85 | len = strlen(proxy_command) + 6; |
87 | buffer_append(&command, "exec ", 5); | 86 | tmp = xmalloc(len); |
88 | 87 | strlcpy(tmp, "exec ", len); | |
89 | for (cp = proxy_command; *cp; cp++) { | 88 | strlcat(tmp, proxy_command, len); |
90 | if (cp[0] == '%' && cp[1] == '%') { | 89 | command_string = percent_expand(tmp, "h", host, |
91 | buffer_append(&command, "%", 1); | 90 | "p", strport, (char *)NULL); |
92 | cp++; | 91 | xfree(tmp); |
93 | continue; | ||
94 | } | ||
95 | if (cp[0] == '%' && cp[1] == 'h') { | ||
96 | buffer_append(&command, host, strlen(host)); | ||
97 | cp++; | ||
98 | continue; | ||
99 | } | ||
100 | if (cp[0] == '%' && cp[1] == 'p') { | ||
101 | buffer_append(&command, strport, strlen(strport)); | ||
102 | cp++; | ||
103 | continue; | ||
104 | } | ||
105 | buffer_append(&command, cp, 1); | ||
106 | } | ||
107 | buffer_append(&command, "\0", 1); | ||
108 | |||
109 | /* Get the final command string. */ | ||
110 | command_string = buffer_ptr(&command); | ||
111 | 92 | ||
112 | /* Create pipes for communicating with the proxy. */ | 93 | /* Create pipes for communicating with the proxy. */ |
113 | if (pipe(pin) < 0 || pipe(pout) < 0) | 94 | if (pipe(pin) < 0 || pipe(pout) < 0) |
@@ -161,7 +142,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | |||
161 | close(pout[1]); | 142 | close(pout[1]); |
162 | 143 | ||
163 | /* Free the command name. */ | 144 | /* Free the command name. */ |
164 | buffer_free(&command); | 145 | xfree(command_string); |
165 | 146 | ||
166 | /* Set the connection file descriptors. */ | 147 | /* Set the connection file descriptors. */ |
167 | packet_set_connection(pout[0], pin[1], options.setuptimeout); | 148 | packet_set_connection(pout[0], pin[1], options.setuptimeout); |
@@ -315,18 +296,9 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
315 | int sock = -1, attempt; | 296 | int sock = -1, attempt; |
316 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 297 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
317 | struct addrinfo hints, *ai, *aitop; | 298 | struct addrinfo hints, *ai, *aitop; |
318 | struct servent *sp; | ||
319 | 299 | ||
320 | debug2("ssh_connect: needpriv %d", needpriv); | 300 | debug2("ssh_connect: needpriv %d", needpriv); |
321 | 301 | ||
322 | /* Get default port if port has not been set. */ | ||
323 | if (port == 0) { | ||
324 | sp = getservbyname(SSH_SERVICE_NAME, "tcp"); | ||
325 | if (sp) | ||
326 | port = ntohs(sp->s_port); | ||
327 | else | ||
328 | port = SSH_DEFAULT_PORT; | ||
329 | } | ||
330 | /* If a proxy command is given, connect using it. */ | 302 | /* If a proxy command is given, connect using it. */ |
331 | if (proxy_command != NULL) | 303 | if (proxy_command != NULL) |
332 | return ssh_proxy_connect(host, port, proxy_command); | 304 | return ssh_proxy_connect(host, port, proxy_command); |
@@ -428,10 +400,11 @@ static void | |||
428 | ssh_exchange_identification(void) | 400 | ssh_exchange_identification(void) |
429 | { | 401 | { |
430 | char buf[256], remote_version[256]; /* must be same size! */ | 402 | char buf[256], remote_version[256]; /* must be same size! */ |
431 | int remote_major, remote_minor, i, mismatch; | 403 | int remote_major, remote_minor, mismatch; |
432 | int connection_in = packet_get_connection_in(); | 404 | int connection_in = packet_get_connection_in(); |
433 | int connection_out = packet_get_connection_out(); | 405 | int connection_out = packet_get_connection_out(); |
434 | int minor1 = PROTOCOL_MINOR_1; | 406 | int minor1 = PROTOCOL_MINOR_1; |
407 | u_int i; | ||
435 | struct sigaction sa, osa; | 408 | struct sigaction sa, osa; |
436 | 409 | ||
437 | /* Read other side's version identification. | 410 | /* Read other side's version identification. |
@@ -448,16 +421,28 @@ ssh_exchange_identification(void) | |||
448 | } | 421 | } |
449 | for (;;) { | 422 | for (;;) { |
450 | for (i = 0; i < sizeof(buf) - 1; ) { | 423 | for (i = 0; i < sizeof(buf) - 1; ) { |
451 | int len = read(connection_in, &buf[i], 1); | 424 | ssize_t len = read(connection_in, &buf[i], 1); |
452 | if (banner_timedout) | 425 | if (banner_timedout) |
453 | fatal("ssh_exchange_identification: Timeout waiting for version information."); | 426 | fatal("ssh_exchange_identification: Timeout waiting for version information."); |
454 | if (len < 0) { | 427 | if (len == 0) |
455 | if (errno == EINTR) | 428 | errno = EPIPE; |
429 | |||
430 | if (len != 1 && errno == EPIPE) | ||
431 | fatal("ssh_exchange_identification: Connection closed by remote host"); | ||
432 | else if (len != 1) { | ||
433 | #ifdef EWOULDBLOCK | ||
434 | if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) | ||
435 | #else | ||
436 | if (errno == EINTR || errno == EAGAIN) | ||
437 | #endif | ||
456 | continue; | 438 | continue; |
457 | fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); | 439 | fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); |
458 | } | 440 | } |
459 | if (len != 1) | 441 | if (buf[i] == '\r') { |
460 | fatal("ssh_exchange_identification: Connection closed by remote host"); | 442 | buf[i] = '\n'; |
443 | buf[i + 1] = 0; | ||
444 | continue; /**XXX wait for \n */ | ||
445 | } | ||
461 | if (buf[i] == '\n') { | 446 | if (buf[i] == '\n') { |
462 | buf[i + 1] = 0; | 447 | buf[i + 1] = 0; |
463 | break; | 448 | break; |
@@ -605,7 +590,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, | |||
605 | switch (hostaddr->sa_family) { | 590 | switch (hostaddr->sa_family) { |
606 | case AF_INET: | 591 | case AF_INET: |
607 | local = (ntohl(((struct sockaddr_in *)hostaddr)-> | 592 | local = (ntohl(((struct sockaddr_in *)hostaddr)-> |
608 | sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; | 593 | sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; |
609 | salen = sizeof(struct sockaddr_in); | 594 | salen = sizeof(struct sockaddr_in); |
610 | break; | 595 | break; |
611 | case AF_INET6: | 596 | case AF_INET6: |
@@ -738,8 +723,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, | |||
738 | 723 | ||
739 | if (show_other_keys(host, host_key)) | 724 | if (show_other_keys(host, host_key)) |
740 | snprintf(msg1, sizeof(msg1), | 725 | snprintf(msg1, sizeof(msg1), |
741 | "\nbut keys of different type are already" | 726 | "\nbut keys of different type are already" |
742 | " known for this host."); | 727 | " known for this host."); |
743 | else | 728 | else |
744 | snprintf(msg1, sizeof(msg1), "."); | 729 | snprintf(msg1, sizeof(msg1), "."); |
745 | /* The default */ | 730 | /* The default */ |