]> andersk Git - openssh.git/blobdiff - ssh.c
- (tim) [configure.ac] set TEST_SHELL for OpenServer 6
[openssh.git] / ssh.c
diff --git a/ssh.c b/ssh.c
index 1f50727e934a839dd192edd9043666a30a964361..43ecbd924a4727fc1bddadd0612d9822ed6b149d 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.231 2005/02/16 09:56:44 otto Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.240 2005/05/27 08:30:37 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;
@@ -158,9 +158,10 @@ usage(void)
 {
        fprintf(stderr,
 "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
-"           [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n"
-"           [-L port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd]\n"
-"           [-o option] [-p port] [-R port:host:hostport] [-S ctl_path]\n"
+"           [-D 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"
        );
        exit(1);
@@ -178,14 +179,13 @@ int
 main(int ac, char **av)
 {
        int i, opt, exit_status;
-       u_short fwd_port, fwd_host_port;
-       char sfwd_port[6], sfwd_host_port[6];
        char *p, *cp, *line, buf[256];
        struct stat st;
        struct passwd *pw;
        int dummy;
        extern int optind, optreset;
        extern char *optarg;
+       Forward fwd;
 
        __progname = ssh_get_progname(av[0]);
        init_rng();
@@ -401,39 +401,51 @@ again:
                        break;
 
                case 'L':
-               case 'R':
-                       if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]",
-                           sfwd_port, buf, sfwd_host_port) != 3 &&
-                           sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]",
-                           sfwd_port, buf, sfwd_host_port) != 3) {
+                       if (parse_forward(&fwd, optarg))
+                               add_local_forward(&options, &fwd);
+                       else {
                                fprintf(stderr,
-                                   "Bad forwarding specification '%s'\n",
+                                   "Bad local forwarding specification '%s'\n",
                                    optarg);
-                               usage();
-                               /* NOTREACHED */
+                               exit(1);
                        }
-                       if ((fwd_port = a2port(sfwd_port)) == 0 ||
-                           (fwd_host_port = a2port(sfwd_host_port)) == 0) {
+                       break;
+
+               case 'R':
+                       if (parse_forward(&fwd, optarg)) {
+                               add_remote_forward(&options, &fwd);
+                       } else {
                                fprintf(stderr,
-                                   "Bad forwarding port(s) '%s'\n", optarg);
+                                   "Bad remote forwarding specification "
+                                   "'%s'\n", optarg);
                                exit(1);
                        }
-                       if (opt == 'L')
-                               add_local_forward(&options, fwd_port, buf,
-                                   fwd_host_port);
-                       else if (opt == 'R')
-                               add_remote_forward(&options, fwd_port, buf,
-                                   fwd_host_port);
                        break;
 
                case 'D':
-                       fwd_port = a2port(optarg);
-                       if (fwd_port == 0) {
+                       cp = p = xstrdup(optarg);
+                       memset(&fwd, '\0', sizeof(fwd));
+                       fwd.connect_host = "socks";
+                       if ((fwd.listen_host = hpdelim(&cp)) == NULL) {
+                               fprintf(stderr, "Bad dynamic forwarding "
+                                   "specification '%.100s'\n", optarg);
+                               exit(1);
+                       }
+                       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 = "";
+                       }
+
+                       if (fwd.listen_port == 0) {
                                fprintf(stderr, "Bad dynamic port '%s'\n",
                                    optarg);
                                exit(1);
                        }
-                       add_local_forward(&options, fwd_port, "socks", 0);
+                       add_local_forward(&options, &fwd);
+                       xfree(p);
                        break;
 
                case 'C':
@@ -538,7 +550,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;
@@ -600,8 +612,13 @@ again:
                options.control_path = tilde_expand_filename(
                   options.control_path, original_real_uid);
        }
-       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 && options.control_master == 0) {
+               if (mux_command == 0)
+                       mux_command = SSHMUX_COMMAND_OPEN;
+               control_client(options.control_path);
+       }
 
        /* Open a connection to the remote host. */
        if (ssh_connect(host, &hostaddr, options.port,
@@ -842,14 +859,19 @@ ssh_init_forwarding(void)
 
        /* Initiate local TCP/IP port forwardings. */
        for (i = 0; i < options.num_local_forwards; i++) {
-               debug("Connections to local port %d forwarded to remote address %.200s:%d",
-                   options.local_forwards[i].port,
-                   options.local_forwards[i].host,
-                   options.local_forwards[i].host_port);
+               debug("Local connections to %.200s:%d forwarded to remote "
+                   "address %.200s:%d",
+                   (options.local_forwards[i].listen_host == NULL) ?
+                   (options.gateway_ports ? "*" : "LOCALHOST") :
+                   options.local_forwards[i].listen_host,
+                   options.local_forwards[i].listen_port,
+                   options.local_forwards[i].connect_host,
+                   options.local_forwards[i].connect_port);
                success += channel_setup_local_fwd_listener(
-                   options.local_forwards[i].port,
-                   options.local_forwards[i].host,
-                   options.local_forwards[i].host_port,
+                   options.local_forwards[i].listen_host,
+                   options.local_forwards[i].listen_port,
+                   options.local_forwards[i].connect_host,
+                   options.local_forwards[i].connect_port,
                    options.gateway_ports);
        }
        if (i > 0 && success == 0)
@@ -857,14 +879,19 @@ ssh_init_forwarding(void)
 
        /* Initiate remote TCP/IP port forwardings. */
        for (i = 0; i < options.num_remote_forwards; i++) {
-               debug("Connections to remote port %d forwarded to local address %.200s:%d",
-                   options.remote_forwards[i].port,
-                   options.remote_forwards[i].host,
-                   options.remote_forwards[i].host_port);
+               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_port,
+                   options.remote_forwards[i].connect_host,
+                   options.remote_forwards[i].connect_port);
                channel_request_remote_forwarding(
-                   options.remote_forwards[i].port,
-                   options.remote_forwards[i].host,
-                   options.remote_forwards[i].host_port);
+                   options.remote_forwards[i].listen_host,
+                   options.remote_forwards[i].listen_port,
+                   options.remote_forwards[i].connect_host,
+                   options.remote_forwards[i].connect_port);
        }
 }
 
@@ -1040,12 +1067,12 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
                return;
        debug("remote forward %s for: listen %d, connect %s:%d",
            type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
-           options.remote_forwards[i].port,
-           options.remote_forwards[i].host,
-           options.remote_forwards[i].host_port);
+           options.remote_forwards[i].listen_port,
+           options.remote_forwards[i].connect_host,
+           options.remote_forwards[i].connect_port);
        if (type == SSH2_MSG_REQUEST_FAILURE)
-               logit("Warning: remote port forwarding failed for listen port %d",
-                   options.remote_forwards[i].port);
+               logit("Warning: remote port forwarding failed for listen "
+                   "port %d", options.remote_forwards[i].listen_port);
 }
 
 static void
@@ -1073,7 +1100,7 @@ ssh_control_listener(void)
        old_umask = umask(0177);
        if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) {
                control_fd = -1;
-               if (errno == EINVAL)
+               if (errno == EINVAL || errno == EADDRINUSE)
                        fatal("ControlSocket %s already exists",
                            options.control_path);
                else
@@ -1268,15 +1295,6 @@ 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);
-       }
-
        memset(&addr, '\0', sizeof(addr));
        addr.sun_family = AF_UNIX;
        addr_len = offsetof(struct sockaddr_un, sun_path) +
@@ -1289,8 +1307,29 @@ 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 = "";
@@ -1323,7 +1362,7 @@ control_client(const char *path)
 
        switch (mux_command) {
        case SSHMUX_COMMAND_ALIVE_CHECK:
-               fprintf(stderr, "Master running (pid=%d)\r\n", 
+               fprintf(stderr, "Master running (pid=%d)\r\n",
                    control_server_pid);
                exit(0);
        case SSHMUX_COMMAND_TERMINATE:
This page took 0.046622 seconds and 4 git commands to generate.