]> andersk Git - openssh.git/blobdiff - ssh.c
*** empty log message ***
[openssh.git] / ssh.c
diff --git a/ssh.c b/ssh.c
index 2e479d521232dd5cee0a416c31f0853abc7f691e..21bfc56e372e5ac345bdfa222cac750662c45566 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.173 2002/05/23 19:24:30 markus Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.190 2003/02/06 09:27:29 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -53,7 +53,6 @@ RCSID("$OpenBSD: ssh.c,v 1.173 2002/05/23 19:24:30 markus Exp $");
 #include "xmalloc.h"
 #include "packet.h"
 #include "buffer.h"
-#include "uidswap.h"
 #include "channels.h"
 #include "key.h"
 #include "authfd.h"
@@ -136,6 +135,7 @@ Sensitive sensitive_data;
 
 /* Original real UID. */
 uid_t original_real_uid;
+uid_t original_effective_uid;
 
 /* command to be executed */
 Buffer command;
@@ -146,6 +146,9 @@ int subsystem_flag = 0;
 /* # of replies received for global requests */
 static int client_global_request_id = 0;
 
+/* pid of proxycommand child process */
+pid_t proxy_command_pid = 0;
+
 /* Prints a help message to the user.  This function never returns. */
 
 static void
@@ -174,7 +177,6 @@ usage(void)
        fprintf(stderr, "  -v          Verbose; display verbose debugging messages.\n");
        fprintf(stderr, "              Multiple -v increases verbosity.\n");
        fprintf(stderr, "  -V          Display version number only.\n");
-       fprintf(stderr, "  -P          Don't allocate a privileged port.\n");
        fprintf(stderr, "  -q          Quiet; don't display any warning messages.\n");
        fprintf(stderr, "  -f          Fork into background after authentication.\n");
        fprintf(stderr, "  -e char     Set escape character; ``none'' = disable (default: ~).\n");
@@ -200,44 +202,6 @@ usage(void)
        exit(1);
 }
 
-/*
- * Connects to the given host using rsh (or prints an error message and exits
- * if rsh is not available).  This function never returns.
- */
-static void
-rsh_connect(char *host, char *user, Buffer * command)
-{
-       char *args[10];
-       int i;
-
-       log("Using rsh.  WARNING: Connection will not be encrypted.");
-       /* Build argument list for rsh. */
-       i = 0;
-       args[i++] = _PATH_RSH;
-       /* host may have to come after user on some systems */
-       args[i++] = host;
-       if (user) {
-               args[i++] = "-l";
-               args[i++] = user;
-       }
-       if (buffer_len(command) > 0) {
-               buffer_append(command, "\0", 1);
-               args[i++] = buffer_ptr(command);
-       }
-       args[i++] = NULL;
-       if (debug_flag) {
-               for (i = 0; args[i]; i++) {
-                       if (i != 0)
-                               fprintf(stderr, " ");
-                       fprintf(stderr, "%s", args[i]);
-               }
-               fprintf(stderr, "\n");
-       }
-       execv(_PATH_RSH, args);
-       perror(_PATH_RSH);
-       exit(1);
-}
-
 static int ssh_session(void);
 static int ssh_session2(void);
 static void load_public_identity_files(void);
@@ -248,14 +212,13 @@ static void load_public_identity_files(void);
 int
 main(int ac, char **av)
 {
-       int i, opt, exit_status, cerr;
+       int i, opt, exit_status;
        u_short fwd_port, fwd_host_port;
        char sfwd_port[6], sfwd_host_port[6];
        char *p, *cp, buf[256];
        struct stat st;
        struct passwd *pw;
        int dummy;
-       uid_t original_effective_uid;
        extern int optind, optreset;
        extern char *optarg;
 
@@ -268,6 +231,15 @@ main(int ac, char **av)
         */
        original_real_uid = getuid();
        original_effective_uid = geteuid();
+       /*
+        * Use uid-swapping to give up root privileges for the duration of
+        * option processing.  We will re-instantiate the rights when we are
+        * ready to create the privileged port, and will permanently drop
+        * them when the port has been created (actually, when the connection
+        * has been made, as we may need to create the port several times).
+        */
+       PRIV_END;
 
 #ifdef HAVE_SETRLIMIT
        /* If we are installed setuid root be careful to not drop core. */
@@ -281,21 +253,12 @@ main(int ac, char **av)
        /* Get user data. */
        pw = getpwuid(original_real_uid);
        if (!pw) {
-               log("You don't exist, go away!");
+               logit("You don't exist, go away!");
                exit(1);
        }
        /* Take a copy of the returned structure. */
        pw = pwcopy(pw);
 
-       /*
-        * Use uid-swapping to give up root privileges for the duration of
-        * option processing.  We will re-instantiate the rights when we are
-        * ready to create the privileged port, and will permanently drop
-        * them when the port has been created (actually, when the connection
-        * has been made, as we may need to create the port several times).
-        */
-       temporarily_use_uid(pw);
-
        /*
         * Set our umask to something reasonable, as some files are created
         * with the default umask.  This will make them world-readable but
@@ -342,7 +305,7 @@ again:
                case 'g':
                        options.gateway_ports = 1;
                        break;
-               case 'P':
+               case 'P':       /* deprecated */
                        options.use_privileged_port = 0;
                        break;
                case 'a':
@@ -532,9 +495,9 @@ again:
        av += optind;
 
        if (ac > 0 && !host && **av != '-') {
-               if (strchr(*av, '@')) {
+               if (strrchr(*av, '@')) {
                        p = xstrdup(*av);
-                       cp = strchr(p, '@');
+                       cp = strrchr(p, '@');
                        if (cp == NULL || cp == p)
                                usage();
                        options.user = p;
@@ -542,12 +505,11 @@ again:
                        host = ++cp;
                } else
                        host = *av;
-               ac--, av++;
-               if (ac > 0) {
-                       optind = 0;
-                       optreset = 1;
+               if (ac > 1) {
+                       optind = optreset = 1;
                        goto again;
                }
+               ac--, av++;
        }
 
        /* Check that we got a host name. */
@@ -591,13 +553,13 @@ again:
        if (buffer_len(&command) == 0)
                tty_flag = 1;
 
-       /* Force no tty*/
+       /* Force no tty */
        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 (tty_flag)
-                       log("Pseudo-terminal will not be allocated because stdin is not a terminal.");
+                       logit("Pseudo-terminal will not be allocated because stdin is not a terminal.");
                tty_flag = 0;
        }
 
@@ -639,6 +601,10 @@ again:
        if (options.hostname != NULL)
                host = options.hostname;
 
+       if (options.proxy_command != NULL &&
+           strcmp(options.proxy_command, "none") == 0)
+               options.proxy_command = NULL;
+
        /* Disable rhosts authentication if not running as root. */
 #ifdef HAVE_CYGWIN
        /* Ignore uid if running under Windows */
@@ -650,55 +616,46 @@ again:
                    "originating port will not be trusted.");
                options.rhosts_authentication = 0;
        }
-       /*
-        * If using rsh has been selected, exec it now (without trying
-        * anything else).  Note that we must release privileges first.
-        */
-       if (options.use_rsh) {
-               /*
-                * Restore our superuser privileges.  This must be done
-                * before permanently setting the uid.
-                */
-               restore_uid();
-
-               /* Switch to the original uid permanently. */
-               permanently_set_uid(pw);
-
-               /* Execute rsh. */
-               rsh_connect(host, options.user, &command);
-               fatal("rsh_connect returned");
-       }
-       /* Restore our superuser privileges. */
-       restore_uid();
-
        /* Open a connection to the remote host. */
 
-       cerr = ssh_connect(host, &hostaddr, options.port, IPv4or6,
+       if (ssh_connect(host, &hostaddr, options.port, IPv4or6,
            options.connection_attempts,
-           original_effective_uid != 0 || !options.use_privileged_port,
-           pw, options.proxy_command);
+#ifdef HAVE_CYGWIN
+           options.use_privileged_port,
+#else
+           original_effective_uid == 0 && options.use_privileged_port,
+#endif
+           options.proxy_command) != 0)
+               exit(1);
 
        /*
         * If we successfully made the connection, load the host private key
         * in case we will need it later for combined rsa-rhosts
         * authentication. This must be done before releasing extra
         * privileges, because the file is only readable by root.
+        * If we cannot access the private keys, load the public keys
+        * instead and try to execute the ssh-keysign helper instead.
         */
        sensitive_data.nkeys = 0;
        sensitive_data.keys = NULL;
        sensitive_data.external_keysign = 0;
-       if (!cerr && (options.rhosts_rsa_authentication ||
-           options.hostbased_authentication)) {
+       if (options.rhosts_rsa_authentication ||
+           options.hostbased_authentication) {
                sensitive_data.nkeys = 3;
-               sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key));
+               sensitive_data.keys = xmalloc(sensitive_data.nkeys *
+                   sizeof(Key));
+
+               PRIV_START;
                sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
                    _PATH_HOST_KEY_FILE, "", NULL);
                sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
                    _PATH_HOST_DSA_KEY_FILE, "", NULL);
                sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
                    _PATH_HOST_RSA_KEY_FILE, "", NULL);
+               PRIV_END;
 
-               if (sensitive_data.keys[0] == NULL &&
+               if (options.hostbased_authentication == 1 &&
+                   sensitive_data.keys[0] == NULL &&
                    sensitive_data.keys[1] == NULL &&
                    sensitive_data.keys[2] == NULL) {
                        sensitive_data.keys[1] = key_load_public(
@@ -715,15 +672,8 @@ again:
         * user's home directory if it happens to be on a NFS volume where
         * root is mapped to nobody.
         */
-
-       /*
-        * Note that some legacy systems need to postpone the following call
-        * to permanently_set_uid() until the private hostkey is destroyed
-        * with RSA_free().  Otherwise the calling user could ptrace() the
-        * process, read the private hostkey and impersonate the host.
-        * OpenBSD does not allow ptracing of setuid processes.
-        */
-       permanently_set_uid(pw);
+       seteuid(original_real_uid);
+       setuid(original_real_uid);
 
        /*
         * Now that we are back to our own permissions, create ~/.ssh
@@ -734,21 +684,6 @@ again:
                if (mkdir(buf, 0700) < 0)
                        error("Could not create directory '%.200s'.", buf);
 
-       /* Check if the connection failed, and try "rsh" if appropriate. */
-       if (cerr) {
-               if (!options.fallback_to_rsh)
-                       exit(1);
-               if (options.port != 0)
-                       log("Secure connection to %.100s on port %hu refused; "
-                           "reverting to insecure method",
-                           host, options.port);
-               else
-                       log("Secure connection to %.100s refused; "
-                           "reverting to insecure method.", host);
-
-               rsh_connect(host, options.user, &command);
-               fatal("rsh_connect returned");
-       }
        /* load options.identity_files */
        load_public_identity_files();
 
@@ -793,6 +728,14 @@ again:
 
        exit_status = compat20 ? ssh_session2() : ssh_session();
        packet_close();
+
+       /*
+        * Send SIGHUP to proxy command if used. We don't wait() in 
+        * case it hangs and instead rely on init to reap the child
+        */
+       if (proxy_command_pid > 1)
+               kill(proxy_command_pid, SIGHUP);
+
        return exit_status;
 }
 
@@ -804,11 +747,19 @@ x11_get_proto(char **_proto, char **_data)
        FILE *f;
        int got_data = 0, i;
        char *display;
+       struct stat st;
 
        *_proto = proto;
        *_data = data;
        proto[0] = data[0] = '\0';
-       if (options.xauth_location && (display = getenv("DISPLAY"))) {
+       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;
+               }
                /* Try to get Xauthority information for the display. */
                if (strncmp(display, "localhost:", 10) == 0)
                        /*
@@ -823,7 +774,7 @@ x11_get_proto(char **_proto, char **_data)
                else
                        snprintf(line, sizeof line, "%s list %.200s 2>"
                            _PATH_DEVNULL, options.xauth_location, display);
-               debug2("x11_get_proto %s", line);
+               debug2("x11_get_proto: %s", line);
                f = popen(line, "r");
                if (f && fgets(line, sizeof(line), f) &&
                    sscanf(line, "%*s %511s %511s", proto, data) == 2)
@@ -842,6 +793,7 @@ x11_get_proto(char **_proto, char **_data)
        if (!got_data) {
                u_int32_t rand = 0;
 
+               logit("Warning: No xauth data; using fake authentication data for X11 forwarding.");
                strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);
                for (i = 0; i < 16; i++) {
                        if (i % 4 == 0)
@@ -891,11 +843,8 @@ check_agent_present(void)
 {
        if (options.forward_agent) {
                /* Clear agent forwarding if we don\'t have an agent. */
-               int authfd = ssh_get_authentication_socket();
-               if (authfd < 0)
+               if (!ssh_agent_present())
                        options.forward_agent = 0;
-               else
-                       ssh_close_authentication_socket(authfd);
        }
 }
 
@@ -924,7 +873,7 @@ ssh_session(void)
                if (type == SSH_SMSG_SUCCESS)
                        packet_start_compression(options.compression_level);
                else if (type == SSH_SMSG_FAILURE)
-                       log("Warning: Remote host refused compression.");
+                       logit("Warning: Remote host refused compression.");
                else
                        packet_disconnect("Protocol error waiting for compression response.");
        }
@@ -963,7 +912,7 @@ ssh_session(void)
                        interactive = 1;
                        have_tty = 1;
                } else if (type == SSH_SMSG_FAILURE)
-                       log("Warning: Remote host failed or refused to allocate a pseudo tty.");
+                       logit("Warning: Remote host failed or refused to allocate a pseudo tty.");
                else
                        packet_disconnect("Protocol error waiting for pty request response.");
        }
@@ -981,7 +930,7 @@ ssh_session(void)
                if (type == SSH_SMSG_SUCCESS) {
                        interactive = 1;
                } else if (type == SSH_SMSG_FAILURE) {
-                       log("Warning: Remote host denied X11 forwarding.");
+                       logit("Warning: Remote host denied X11 forwarding.");
                } else {
                        packet_disconnect("Protocol error waiting for X11 forwarding");
                }
@@ -1000,7 +949,7 @@ ssh_session(void)
                type = packet_read();
                packet_check_eom();
                if (type != SSH_SMSG_SUCCESS)
-                       log("Warning: Remote host denied authentication agent forwarding.");
+                       logit("Warning: Remote host denied authentication agent forwarding.");
        }
 
        /* Initiate port forwardings. */
@@ -1068,7 +1017,7 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt)
            options.remote_forwards[i].host,
            options.remote_forwards[i].host_port);
        if (type == SSH2_MSG_REQUEST_FAILURE)
-               log("Warning: remote port forwarding failed for listen port %d",
+               logit("Warning: remote port forwarding failed for listen port %d",
                    options.remote_forwards[i].port);
 }
 
@@ -1080,7 +1029,7 @@ ssh_session2_setup(int id, void *arg)
        int interactive = 0;
        struct termios tio;
 
-       debug("ssh_session2_setup: id %d", id);
+       debug2("ssh_session2_setup: id %d", id);
 
        if (tty_flag) {
                struct winsize ws;
This page took 0.130425 seconds and 4 git commands to generate.