=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sshconnect.c,v retrieving revision 1.162.2.2 retrieving revision 1.163 diff -u -r1.162.2.2 -r1.163 --- src/usr.bin/ssh/sshconnect.c 2006/02/03 02:53:45 1.162.2.2 +++ src/usr.bin/ssh/sshconnect.c 2005/05/24 17:32:44 1.163 @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.162.2.2 2006/02/03 02:53:45 brad Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.163 2005/05/24 17:32:44 avsm Exp $"); #include @@ -31,12 +31,13 @@ #include "readconf.h" #include "atomicio.h" #include "misc.h" + #include "dns.h" char *client_version_string = NULL; char *server_version_string = NULL; -static int matching_host_key_dns = 0; +int matching_host_key_dns = 0; /* import */ extern Options options; @@ -54,11 +55,12 @@ static int ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) { - char *command_string, *tmp; + Buffer command; + const char *cp; + char *command_string; int pin[2], pout[2]; pid_t pid; char strport[NI_MAXSERV]; - size_t len; /* Convert the port number into a string. */ snprintf(strport, sizeof strport, "%hu", port); @@ -70,14 +72,32 @@ * Use "exec" to avoid "sh -c" processes on some platforms * (e.g. Solaris) */ - len = strlen(proxy_command) + 6; - tmp = xmalloc(len); - strlcpy(tmp, "exec ", len); - strlcat(tmp, proxy_command, len); - command_string = percent_expand(tmp, "h", host, - "p", strport, (char *)NULL); - xfree(tmp); + buffer_init(&command); + buffer_append(&command, "exec ", 5); + for (cp = proxy_command; *cp; cp++) { + if (cp[0] == '%' && cp[1] == '%') { + buffer_append(&command, "%", 1); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'h') { + buffer_append(&command, host, strlen(host)); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'p') { + buffer_append(&command, strport, strlen(strport)); + cp++; + continue; + } + buffer_append(&command, cp, 1); + } + buffer_append(&command, "\0", 1); + + /* Get the final command string. */ + command_string = buffer_ptr(&command); + /* Create pipes for communicating with the proxy. */ if (pipe(pin) < 0 || pipe(pout) < 0) fatal("Could not create pipes to communicate with the proxy: %.100s", @@ -130,7 +150,7 @@ close(pout[1]); /* Free the command name. */ - xfree(command_string); + buffer_free(&command); /* Set the connection file descriptors. */ packet_set_connection(pout[0], pin[1]); @@ -284,9 +304,18 @@ int sock = -1, attempt; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; struct addrinfo hints, *ai, *aitop; + struct servent *sp; debug2("ssh_connect: needpriv %d", needpriv); + /* Get default port if port has not been set. */ + if (port == 0) { + sp = getservbyname(SSH_SERVICE_NAME, "tcp"); + if (sp) + port = ntohs(sp->s_port); + else + port = SSH_DEFAULT_PORT; + } /* If a proxy command is given, connect using it. */ if (proxy_command != NULL) return ssh_proxy_connect(host, port, proxy_command); @@ -388,18 +417,17 @@ ssh_exchange_identification(void) { char buf[256], remote_version[256]; /* must be same size! */ - int remote_major, remote_minor, mismatch; + int remote_major, remote_minor, i, mismatch; int connection_in = packet_get_connection_in(); int connection_out = packet_get_connection_out(); int minor1 = PROTOCOL_MINOR_1; - u_int i; /* Read other side's version identification. */ for (;;) { for (i = 0; i < sizeof(buf) - 1; i++) { size_t len = atomicio(read, connection_in, &buf[i], 1); - if (len != 1 && errno == EPIPE) + if (len != 1 && errno == EPIPE) fatal("ssh_exchange_identification: Connection closed by remote host"); else if (len != 1) fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); @@ -541,7 +569,7 @@ switch (hostaddr->sa_family) { case AF_INET: local = (ntohl(((struct sockaddr_in *)hostaddr)-> - sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; + sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; break; case AF_INET6: local = IN6_IS_ADDR_LOOPBACK( @@ -595,7 +623,7 @@ file_key = key_new(host_key->type); /* - * Check if the host key is present in the user's list of known + * Check if the host key is present in the user\'s list of known * hosts or in the systemwide list. */ host_file = user_hostfile; @@ -671,8 +699,8 @@ if (show_other_keys(host, host_key)) snprintf(msg1, sizeof(msg1), - "\nbut keys of different type are already" - " known for this host."); + "\nbut keys of different type are already" + " known for this host."); else snprintf(msg1, sizeof(msg1), "."); /* The default */ @@ -1025,40 +1053,4 @@ error("Please contact your system administrator."); xfree(fp); -} - -/* - * Execute a local command - */ -int -ssh_local_cmd(const char *args) -{ - char *shell; - pid_t pid; - int status; - - if (!options.permit_local_command || - args == NULL || !*args) - return (1); - - if ((shell = getenv("SHELL")) == NULL) - shell = _PATH_BSHELL; - - pid = fork(); - if (pid == 0) { - debug3("Executing %s -c \"%s\"", shell, args); - execl(shell, shell, "-c", args, (char *)NULL); - error("Couldn't execute %s -c \"%s\": %s", - shell, args, strerror(errno)); - _exit(1); - } else if (pid == -1) - fatal("fork failed: %.100s", strerror(errno)); - while (waitpid(pid, &status, 0) == -1) - if (errno != EINTR) - fatal("Couldn't wait for child: %s", strerror(errno)); - - if (!WIFEXITED(status)) - return (1); - - return (WEXITSTATUS(status)); }