]> andersk Git - openssh.git/blobdiff - ssh.c
- (djm) Bug #406: s/msg_send/ssh_msg_send/ for Mac OS X 1.2
[openssh.git] / ssh.c
diff --git a/ssh.c b/ssh.c
index 0afdba7b51979c29815a36657e8ee4f3db5a6fa6..2c589de824859bddac85a403ab9f9106c7668758 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.174 2002/05/23 19:39:34 markus Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.186 2002/09/19 01:58:18 djm Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -53,7 +53,6 @@ RCSID("$OpenBSD: ssh.c,v 1.174 2002/05/23 19:39:34 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. */
@@ -287,15 +259,6 @@ main(int ac, char **av)
        /* 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':
@@ -591,7 +554,7 @@ 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. */
@@ -650,33 +613,17 @@ 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
@@ -689,18 +636,23 @@ again:
        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(
@@ -717,15 +669,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
@@ -736,21 +681,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();
 
@@ -795,6 +725,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;
 }
 
@@ -806,11 +744,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)
                        /*
@@ -825,7 +771,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)
@@ -844,6 +790,7 @@ x11_get_proto(char **_proto, char **_data)
        if (!got_data) {
                u_int32_t rand = 0;
 
+               log("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)
@@ -893,11 +840,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);
        }
 }
 
This page took 0.046482 seconds and 4 git commands to generate.