summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2005-09-14 12:45:47 +0000
committerColin Watson <cjwatson@debian.org>2005-09-14 12:45:47 +0000
commit9b71add4cecf753c45f5fbd6ff0913bc95b3e95d (patch)
treed4ea8fdb30c7949c6433f5277c39548ea579d4dc /sshconnect.c
parented07bcbea56007ab5b218ddf3aa6a7d4e21966e0 (diff)
parent16704d57999d987fb8d9ba53379841a79f016d67 (diff)
Merge 4.2p1 to the trunk.
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c81
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"
16RCSID("$OpenBSD: sshconnect.c,v 1.162 2005/03/10 22:01:06 deraadt Exp $"); 16RCSID("$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 *);
66static int 66static int
67ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) 67ssh_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
428ssh_exchange_identification(void) 400ssh_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 */