*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.163 2005/05/24 17:32:44 avsm Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.172 2006/02/08 12:15:27 stevesk Exp $");
+
+#include <paths.h>
#include <openssl/bn.h>
#include "readconf.h"
#include "atomicio.h"
#include "misc.h"
-
#include "dns.h"
char *client_version_string = NULL;
char *server_version_string = NULL;
-int matching_host_key_dns = 0;
+static int matching_host_key_dns = 0;
/* import */
extern Options options;
static int
ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
{
- Buffer command;
- const char *cp;
- char *command_string;
+ char *command_string, *tmp;
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);
* Use "exec" to avoid "sh -c" processes on some platforms
* (e.g. Solaris)
*/
- 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);
+ 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);
/* Create pipes for communicating with the proxy. */
if (pipe(pin) < 0 || pipe(pout) < 0)
close(pout[1]);
/* Free the command name. */
- buffer_free(&command);
+ xfree(command_string);
/* Set the connection file descriptors. */
packet_set_connection(pout[0], pin[1]);
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);
ssh_exchange_identification(void)
{
char buf[256], remote_version[256]; /* must be same size! */
- int remote_major, remote_minor, i, mismatch;
+ int remote_major, remote_minor, 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));
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;
salen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
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;
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 */
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));
+}