]> andersk Git - gssapi-openssh.git/blobdiff - openssh/ssh.c
Import of OpenSSH 4.2p1
[gssapi-openssh.git] / openssh / ssh.c
index 1f19229b717a98bb2b941d0c152d53455708cf2e..c9e5aac7a9af4e7c4e4e412c7f384ca270cbce20 100644 (file)
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.234 2005/03/10 22:01:06 deraadt Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.249 2005/07/30 01:26:16 djm Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -145,7 +145,7 @@ pid_t proxy_command_pid = 0;
 int control_fd = -1;
 
 /* Multiplexing control command */
-static u_int mux_command = SSHMUX_COMMAND_OPEN;
+static u_int mux_command = 0;
 
 /* Only used in control client mode */
 volatile sig_atomic_t control_client_terminate = 0;
@@ -185,6 +185,7 @@ main(int ac, char **av)
        int dummy;
        extern int optind, optreset;
        extern char *optarg;
+       struct servent *sp;
        Forward fwd;
 
        __progname = ssh_get_progname(av[0]);
@@ -386,8 +387,10 @@ again:
                        }
                        break;
                case 'M':
-                       options.control_master =
-                           (options.control_master >= 1) ? 2 : 1;
+                       if (options.control_master == SSHCTL_MASTER_YES)
+                               options.control_master = SSHCTL_MASTER_ASK;
+                       else
+                               options.control_master = SSHCTL_MASTER_YES;
                        break;
                case 'p':
                        options.port = a2port(optarg);
@@ -436,7 +439,7 @@ again:
                                fwd.listen_host = cleanhostname(fwd.listen_host);
                        } else {
                                fwd.listen_port = a2port(fwd.listen_host);
-                               fwd.listen_host = "";
+                               fwd.listen_host = NULL;
                        }
 
                        if (fwd.listen_port == 0) {
@@ -550,7 +553,7 @@ again:
        if (no_tty_flag)
                tty_flag = 0;
        /* Do not allocate a tty if stdin is not a tty. */
-       if (!isatty(fileno(stdin)) && !force_tty_flag) {
+       if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
                if (tty_flag)
                        logit("Pseudo-terminal will not be allocated because stdin is not a terminal.");
                tty_flag = 0;
@@ -604,16 +607,31 @@ again:
                                *p = tolower(*p);
        }
 
+       /* Get default port if port has not been set. */
+       if (options.port == 0) {
+               sp = getservbyname(SSH_SERVICE_NAME, "tcp");
+               options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
+       }
+
        if (options.proxy_command != NULL &&
            strcmp(options.proxy_command, "none") == 0)
                options.proxy_command = NULL;
+       if (options.control_path != NULL &&
+           strcmp(options.control_path, "none") == 0)
+               options.control_path = NULL;
 
        if (options.control_path != NULL) {
-               options.control_path = tilde_expand_filename(
-                  options.control_path, original_real_uid);
+               snprintf(buf, sizeof(buf), "%d", options.port);
+               cp = tilde_expand_filename(options.control_path,
+                   original_real_uid);
+               options.control_path = percent_expand(cp, "p", buf, "h", host,
+                   "r", options.user, (char *)NULL);
+               xfree(cp);
        }
-       if (options.control_path != NULL && options.control_master == 0)
-               control_client(options.control_path); /* This doesn't return */
+       if (mux_command != 0 && options.control_path == NULL)
+               fatal("No ControlPath specified for \"-O\" command");
+       if (options.control_path != NULL)
+               control_client(options.control_path);
 
        /* Open a connection to the remote host. */
        if (ssh_connect(host, &hostaddr, options.port,
@@ -742,110 +760,6 @@ again:
        return exit_status;
 }
 
-#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
-
-static void
-x11_get_proto(char **_proto, char **_data)
-{
-       char cmd[1024];
-       char line[512];
-       char xdisplay[512];
-       static char proto[512], data[512];
-       FILE *f;
-       int got_data = 0, generated = 0, do_unlink = 0, i;
-       char *display, *xauthdir, *xauthfile;
-       struct stat st;
-
-       xauthdir = xauthfile = NULL;
-       *_proto = proto;
-       *_data = data;
-       proto[0] = data[0] = '\0';
-
-       if (!options.xauth_location ||
-           (stat(options.xauth_location, &st) == -1)) {
-               debug("No xauth program.");
-       } else {
-               if ((display = getenv("DISPLAY")) == NULL) {
-                       debug("x11_get_proto: DISPLAY not set");
-                       return;
-               }
-               /*
-                * Handle FamilyLocal case where $DISPLAY does
-                * not match an authorization entry.  For this we
-                * just try "xauth list unix:displaynum.screennum".
-                * XXX: "localhost" match to determine FamilyLocal
-                *      is not perfect.
-                */
-               if (strncmp(display, "localhost:", 10) == 0) {
-                       snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
-                           display + 10);
-                       display = xdisplay;
-               }
-               if (options.forward_x11_trusted == 0) {
-                       xauthdir = xmalloc(MAXPATHLEN);
-                       xauthfile = xmalloc(MAXPATHLEN);
-                       strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
-                       if (mkdtemp(xauthdir) != NULL) {
-                               do_unlink = 1;
-                               snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
-                                   xauthdir);
-                               snprintf(cmd, sizeof(cmd),
-                                   "%s -f %s generate %s " SSH_X11_PROTO
-                                   " untrusted timeout 1200 2>" _PATH_DEVNULL,
-                                   options.xauth_location, xauthfile, display);
-                               debug2("x11_get_proto: %s", cmd);
-                               if (system(cmd) == 0)
-                                       generated = 1;
-                       }
-               }
-               snprintf(cmd, sizeof(cmd),
-                   "%s %s%s list %s . 2>" _PATH_DEVNULL,
-                   options.xauth_location,
-                   generated ? "-f " : "" ,
-                   generated ? xauthfile : "",
-                   display);
-               debug2("x11_get_proto: %s", cmd);
-               f = popen(cmd, "r");
-               if (f && fgets(line, sizeof(line), f) &&
-                   sscanf(line, "%*s %511s %511s", proto, data) == 2)
-                       got_data = 1;
-               if (f)
-                       pclose(f);
-       }
-
-       if (do_unlink) {
-               unlink(xauthfile);
-               rmdir(xauthdir);
-       }
-       if (xauthdir)
-               xfree(xauthdir);
-       if (xauthfile)
-               xfree(xauthfile);
-
-       /*
-        * If we didn't get authentication data, just make up some
-        * data.  The forwarding code will check the validity of the
-        * response anyway, and substitute this data.  The X11
-        * server, however, will ignore this fake data and use
-        * whatever authentication mechanisms it was using otherwise
-        * for the local connection.
-        */
-       if (!got_data) {
-               u_int32_t rnd = 0;
-
-               logit("Warning: No xauth data; "
-                   "using fake authentication data for X11 forwarding.");
-               strlcpy(proto, SSH_X11_PROTO, sizeof proto);
-               for (i = 0; i < 16; i++) {
-                       if (i % 4 == 0)
-                               rnd = arc4random();
-                       snprintf(data + 2 * i, sizeof data - 2 * i, "%02x",
-                           rnd & 0xff);
-                       rnd >>= 8;
-               }
-       }
-}
-
 static void
 ssh_init_forwarding(void)
 {
@@ -876,8 +790,8 @@ ssh_init_forwarding(void)
        for (i = 0; i < options.num_remote_forwards; i++) {
                debug("Remote connections from %.200s:%d forwarded to "
                    "local address %.200s:%d",
-                   (options.remote_forwards[i].listen_host == NULL) ? 
-                   (options.gateway_ports ? "*" : "LOCALHOST") : 
+                   (options.remote_forwards[i].listen_host == NULL) ?
+                   (options.gateway_ports ? "*" : "LOCALHOST") :
                    options.remote_forwards[i].listen_host,
                    options.remote_forwards[i].listen_port,
                    options.remote_forwards[i].connect_host,
@@ -908,6 +822,7 @@ ssh_session(void)
        int have_tty = 0;
        struct winsize ws;
        char *cp;
+       const char *display;
 
        /* Enable compression if requested. */
        if (options.compression) {
@@ -969,13 +884,15 @@ ssh_session(void)
                        packet_disconnect("Protocol error waiting for pty request response.");
        }
        /* Request X11 forwarding if enabled and DISPLAY is set. */
-       if (options.forward_x11 && getenv("DISPLAY") != NULL) {
+       display = getenv("DISPLAY");
+       if (options.forward_x11 && display != NULL) {
                char *proto, *data;
                /* Get reasonable local authentication information. */
-               x11_get_proto(&proto, &data);
+               client_x11_get_proto(display, options.xauth_location,
+                   options.forward_x11_trusted, &proto, &data);
                /* Request forwarding with authentication spoofing. */
                debug("Requesting X11 forwarding with authentication spoofing.");
-               x11_request_forwarding_with_spoofing(0, proto, data);
+               x11_request_forwarding_with_spoofing(0, display, proto, data);
 
                /* Read response from the server. */
                type = packet_read();
@@ -1077,9 +994,12 @@ ssh_control_listener(void)
        mode_t old_umask;
        int addr_len;
 
-       if (options.control_path == NULL || options.control_master <= 0)
+       if (options.control_path == NULL ||
+           options.control_master == SSHCTL_MASTER_NO)
                return;
 
+       debug("setting up multiplex master socket");
+
        memset(&addr, '\0', sizeof(addr));
        addr.sun_family = AF_UNIX;
        addr_len = offsetof(struct sockaddr_un, sun_path) +
@@ -1114,15 +1034,18 @@ static void
 ssh_session2_setup(int id, void *arg)
 {
        extern char **environ;
-
+       const char *display;
        int interactive = tty_flag;
-       if (options.forward_x11 && getenv("DISPLAY") != NULL) {
+
+       display = getenv("DISPLAY");
+       if (options.forward_x11 && display != NULL) {
                char *proto, *data;
                /* Get reasonable local authentication information. */
-               x11_get_proto(&proto, &data);
+               client_x11_get_proto(display, options.xauth_location,
+                   options.forward_x11_trusted, &proto, &data);
                /* Request forwarding with authentication spoofing. */
                debug("Requesting X11 forwarding with authentication spoofing.");
-               x11_request_forwarding_with_spoofing(id, proto, data);
+               x11_request_forwarding_with_spoofing(id, display, proto, data);
                interactive = 1;
                /* XXX wait for reply */
        }
@@ -1290,13 +1213,18 @@ control_client(const char *path)
        extern char **environ;
        u_int  flags;
 
-       if (stdin_null_flag) {
-               if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
-                       fatal("open(/dev/null): %s", strerror(errno));
-               if (dup2(fd, STDIN_FILENO) == -1)
-                       fatal("dup2: %s", strerror(errno));
-               if (fd > STDERR_FILENO)
-                       close(fd);
+       if (mux_command == 0)
+               mux_command = SSHMUX_COMMAND_OPEN;
+
+       switch (options.control_master) {
+       case SSHCTL_MASTER_AUTO:
+       case SSHCTL_MASTER_AUTO_ASK:
+               debug("auto-mux: Trying existing master");
+               /* FALLTHROUGH */
+       case SSHCTL_MASTER_NO:
+               break;
+       default:
+               return;
        }
 
        memset(&addr, '\0', sizeof(addr));
@@ -1311,31 +1239,55 @@ control_client(const char *path)
        if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
                fatal("%s socket(): %s", __func__, strerror(errno));
 
-       if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1)
-               fatal("Couldn't connect to %s: %s", path, strerror(errno));
+       if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) {
+               if (mux_command != SSHMUX_COMMAND_OPEN) {
+                       fatal("Control socket connect(%.100s): %s", path,
+                           strerror(errno));
+               }
+               if (errno == ENOENT)
+                       debug("Control socket \"%.100s\" does not exist", path);
+               else {
+                       error("Control socket connect(%.100s): %s", path,
+                           strerror(errno));
+               }
+               close(sock);
+               return;
+       }
+
+       if (stdin_null_flag) {
+               if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
+                       fatal("open(/dev/null): %s", strerror(errno));
+               if (dup2(fd, STDIN_FILENO) == -1)
+                       fatal("dup2: %s", strerror(errno));
+               if (fd > STDERR_FILENO)
+                       close(fd);
+       }
 
-       if ((term = getenv("TERM")) == NULL)
-               term = "";
+       term = getenv("TERM");
 
        flags = 0;
        if (tty_flag)
                flags |= SSHMUX_FLAG_TTY;
        if (subsystem_flag)
                flags |= SSHMUX_FLAG_SUBSYS;
+       if (options.forward_x11)
+               flags |= SSHMUX_FLAG_X11_FWD;
+       if (options.forward_agent)
+               flags |= SSHMUX_FLAG_AGENT_FWD;
 
        buffer_init(&m);
 
        /* Send our command to server */
        buffer_put_int(&m, mux_command);
        buffer_put_int(&m, flags);
-       if (ssh_msg_send(sock, /* version */1, &m) == -1)
+       if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
                fatal("%s: msg_send", __func__);
        buffer_clear(&m);
 
        /* Get authorisation status and PID of controlee */
        if (ssh_msg_recv(sock, &m) == -1)
                fatal("%s: msg_recv", __func__);
-       if (buffer_get_char(&m) != 1)
+       if (buffer_get_char(&m) != SSHMUX_VER)
                fatal("%s: wrong version", __func__);
        if (buffer_get_int(&m) != 1)
                fatal("Connection to master denied");
@@ -1359,7 +1311,7 @@ control_client(const char *path)
        }
 
        /* SSHMUX_COMMAND_OPEN */
-       buffer_put_cstring(&m, term);
+       buffer_put_cstring(&m, term ? term : "");
        buffer_append(&command, "\0", 1);
        buffer_put_cstring(&m, buffer_ptr(&command));
 
@@ -1381,7 +1333,7 @@ control_client(const char *path)
                        }
        }
 
-       if (ssh_msg_send(sock, /* version */1, &m) == -1)
+       if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
                fatal("%s: msg_send", __func__);
 
        mm_send_fd(sock, STDIN_FILENO);
@@ -1392,7 +1344,7 @@ control_client(const char *path)
        buffer_clear(&m);
        if (ssh_msg_recv(sock, &m) == -1)
                fatal("%s: msg_recv", __func__);
-       if (buffer_get_char(&m) != 1)
+       if (buffer_get_char(&m) != SSHMUX_VER)
                fatal("%s: wrong version", __func__);
        buffer_free(&m);
 
This page took 0.044282 seconds and 4 git commands to generate.