]> andersk Git - openssh.git/blobdiff - ssh.c
fix spacing of include
[openssh.git] / ssh.c
diff --git a/ssh.c b/ssh.c
index 2e93b161ae1a8e2ec6ad1771145f60d0b534ec8c..b248c0280e22de1bfeb5b26f12325ae3fbd8a165 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,9 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.244 2005/06/17 22:53:46 djm Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.258 2006/02/08 12:15:27 stevesk Exp $");
+
+#include <paths.h>
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -158,13 +160,13 @@ usage(void)
 {
        fprintf(stderr,
 "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
-"           [-D port] [-e escape_char] [-F configfile]\n"
+"           [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
 "           [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
 "           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
 "           [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
-"           [user@]hostname [command]\n"
+"           [-w tunnel:tunnel] [user@]hostname [command]\n"
        );
-       exit(1);
+       exit(255);
 }
 
 static int ssh_session(void);
@@ -188,6 +190,9 @@ main(int ac, char **av)
        struct servent *sp;
        Forward fwd;
 
+       /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
+       sanitise_stdfd();
+
        __progname = ssh_get_progname(av[0]);
        init_rng();
 
@@ -220,7 +225,7 @@ main(int ac, char **av)
        pw = getpwuid(original_real_uid);
        if (!pw) {
                logit("You don't exist, go away!");
-               exit(1);
+               exit(255);
        }
        /* Take a copy of the returned structure. */
        pw = pwcopy(pw);
@@ -241,7 +246,7 @@ main(int ac, char **av)
 
 again:
        while ((opt = getopt(ac, av,
-           "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) {
+           "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
                switch (opt) {
                case '1':
                        options.protocol = SSH_PROTO_1;
@@ -337,6 +342,15 @@ again:
                        if (opt == 'V')
                                exit(0);
                        break;
+               case 'w':
+                       if (options.tun_open == -1)
+                               options.tun_open = SSH_TUNMODE_DEFAULT;
+                       options.tun_local = a2tun(optarg, &options.tun_remote);
+                       if (options.tun_local == SSH_TUNID_ERR) {
+                               fprintf(stderr, "Bad tun device '%s'\n", optarg);
+                               exit(255);
+                       }
+                       break;
                case 'q':
                        options.log_level = SYSLOG_LEVEL_QUIET;
                        break;
@@ -352,7 +366,7 @@ again:
                        else {
                                fprintf(stderr, "Bad escape character '%s'.\n",
                                    optarg);
-                               exit(1);
+                               exit(255);
                        }
                        break;
                case 'c':
@@ -367,7 +381,7 @@ again:
                                        fprintf(stderr,
                                            "Unknown cipher type '%s'\n",
                                            optarg);
-                                       exit(1);
+                                       exit(255);
                                }
                                if (options.cipher == SSH_CIPHER_3DES)
                                        options.ciphers = "3des-cbc";
@@ -383,7 +397,7 @@ again:
                        else {
                                fprintf(stderr, "Unknown mac type '%s'\n",
                                    optarg);
-                               exit(1);
+                               exit(255);
                        }
                        break;
                case 'M':
@@ -396,7 +410,7 @@ again:
                        options.port = a2port(optarg);
                        if (options.port == 0) {
                                fprintf(stderr, "Bad port '%s'\n", optarg);
-                               exit(1);
+                               exit(255);
                        }
                        break;
                case 'l':
@@ -410,7 +424,7 @@ again:
                                fprintf(stderr,
                                    "Bad local forwarding specification '%s'\n",
                                    optarg);
-                               exit(1);
+                               exit(255);
                        }
                        break;
 
@@ -421,7 +435,7 @@ again:
                                fprintf(stderr,
                                    "Bad remote forwarding specification "
                                    "'%s'\n", optarg);
-                               exit(1);
+                               exit(255);
                        }
                        break;
 
@@ -432,20 +446,20 @@ again:
                        if ((fwd.listen_host = hpdelim(&cp)) == NULL) {
                                fprintf(stderr, "Bad dynamic forwarding "
                                    "specification '%.100s'\n", optarg);
-                               exit(1);
+                               exit(255);
                        }
                        if (cp != NULL) {
                                fwd.listen_port = a2port(cp);
                                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) {
                                fprintf(stderr, "Bad dynamic port '%s'\n",
                                    optarg);
-                               exit(1);
+                               exit(255);
                        }
                        add_local_forward(&options, &fwd);
                        xfree(p);
@@ -466,7 +480,7 @@ again:
                        line = xstrdup(optarg);
                        if (process_config_line(&options, host ? host : "",
                            line, "command-line", 0, &dummy) != 0)
-                               exit(1);
+                               exit(255);
                        xfree(line);
                        break;
                case 's':
@@ -607,9 +621,18 @@ 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) {
                snprintf(buf, sizeof(buf), "%d", options.port);
@@ -624,12 +647,6 @@ again:
        if (options.control_path != NULL)
                control_client(options.control_path);
 
-       /* 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;
-       }
-
        /* Open a connection to the remote host. */
        if (ssh_connect(host, &hostaddr, options.port,
            options.address_family, options.connection_attempts,
@@ -639,7 +656,7 @@ again:
            original_effective_uid == 0 && options.use_privileged_port,
 #endif
            options.proxy_command) != 0)
-               exit(1);
+               exit(255);
 
        /*
         * If we successfully made the connection, load the host private key
@@ -692,7 +709,7 @@ again:
 
        /*
         * Now that we are back to our own permissions, create ~/.ssh
-        * directory if it doesn\'t already exist.
+        * directory if it doesn't already exist.
         */
        snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
        if (stat(buf, &st) < 0)
@@ -787,9 +804,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,
+                   (options.remote_forwards[i].listen_host == NULL) ?
+                   "LOCALHOST" : options.remote_forwards[i].listen_host,
                    options.remote_forwards[i].listen_port,
                    options.remote_forwards[i].connect_host,
                    options.remote_forwards[i].connect_port);
@@ -805,7 +821,7 @@ static void
 check_agent_present(void)
 {
        if (options.forward_agent) {
-               /* Clear agent forwarding if we don\'t have an agent. */
+               /* Clear agent forwarding if we don't have an agent. */
                if (!ssh_agent_present())
                        options.forward_agent = 0;
        }
@@ -1007,7 +1023,7 @@ ssh_control_listener(void)
                fatal("ControlPath too long");
 
        if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
-               fatal("%s socket(): %s\n", __func__, strerror(errno));
+               fatal("%s socket(): %s", __func__, strerror(errno));
 
        old_umask = umask(0177);
        if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) {
@@ -1016,12 +1032,12 @@ ssh_control_listener(void)
                        fatal("ControlSocket %s already exists",
                            options.control_path);
                else
-                       fatal("%s bind(): %s\n", __func__, strerror(errno));
+                       fatal("%s bind(): %s", __func__, strerror(errno));
        }
        umask(old_umask);
 
        if (listen(control_fd, 64) == -1)
-               fatal("%s listen(): %s\n", __func__, strerror(errno));
+               fatal("%s listen(): %s", __func__, strerror(errno));
 
        set_nonblock(control_fd);
 }
@@ -1034,7 +1050,7 @@ ssh_session2_setup(int id, void *arg)
        const char *display;
        int interactive = tty_flag;
 
-       display = getenv("DISPLAY");    
+       display = getenv("DISPLAY");
        if (options.forward_x11 && display != NULL) {
                char *proto, *data;
                /* Get reasonable local authentication information. */
@@ -1054,6 +1070,33 @@ ssh_session2_setup(int id, void *arg)
                packet_send();
        }
 
+       if (options.tun_open != SSH_TUNMODE_NO) {
+               Channel *c;
+               int fd;
+
+               debug("Requesting tun.");
+               if ((fd = tun_open(options.tun_local,
+                   options.tun_open)) >= 0) {
+                       c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
+                           CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
+                           0, "tun", 1);
+                       c->datagram = 1;
+#if defined(SSH_TUN_FILTER)
+                       if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
+                               channel_register_filter(c->self, sys_tun_infilter,
+                                   sys_tun_outfilter);
+#endif
+                       packet_start(SSH2_MSG_CHANNEL_OPEN);
+                       packet_put_cstring("tun@openssh.com");
+                       packet_put_int(c->self);
+                       packet_put_int(c->local_window_max);
+                       packet_put_int(c->local_maxpacket);
+                       packet_put_int(options.tun_open);
+                       packet_put_int(options.tun_remote);
+                       packet_send();
+               }
+       }
+
        client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
            NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply);
 
@@ -1118,6 +1161,11 @@ ssh_session2(void)
        if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
                id = ssh_session2_open();
 
+       /* Execute a local command */
+       if (options.local_command != NULL &&
+           options.permit_local_command)
+               ssh_local_cmd(options.local_command);
+
        /* If requested, let ssh continue in the background. */
        if (fork_after_authentication_flag)
                if (daemon(1, 1) < 0)
@@ -1247,41 +1295,44 @@ control_client(const char *path)
                        error("Control socket connect(%.100s): %s", path,
                            strerror(errno));
                }
-               close(sock);
-               return;
-       }
+               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 (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");
@@ -1305,7 +1356,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));
 
@@ -1327,7 +1378,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);
@@ -1338,7 +1389,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.08777 seconds and 4 git commands to generate.