summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c74
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"
16RCSID("$OpenBSD: sshconnect.c,v 1.161 2005/03/02 01:00:06 djm 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
@@ -59,12 +59,11 @@ static void warn_changed_key(Key *);
59static int 59static int
60ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) 60ssh_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
421ssh_exchange_identification(void) 393ssh_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 */