]> andersk Git - openssh.git/blobdiff - sshconnect.c
- (stevesk) OpenSSH CVS update:
[openssh.git] / sshconnect.c
index 5554c0643c6164d8b92038d46dcff5347ed0562b..b54e75a8a29fbb29ff5fbf3163d91727043bfce3 100644 (file)
@@ -2,13 +2,18 @@
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
- * Created: Sat Mar 18 22:15:47 1995 ylo
  * Code to connect to a remote host, and to perform the client side of the
  * login (authentication) dialog.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.71 2000/04/26 21:28:33 markus Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.83 2000/11/30 22:53:35 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/dsa.h>
@@ -104,15 +109,15 @@ ssh_proxy_connect(const char *host, u_short port, uid_t original_real_uid,
 
                /* Stderr is left as it is so that error messages get
                   printed on the user's terminal. */
-               argv[0] = "/bin/sh";
+               argv[0] = _PATH_BSHELL;
                argv[1] = "-c";
                argv[2] = command_string;
                argv[3] = NULL;
 
                /* Execute the proxy command.  Note that we gave up any
                   extra privileges above. */
-               execv("/bin/sh", argv);
-               perror("/bin/sh");
+               execv(_PATH_BSHELL, argv);
+               perror(_PATH_BSHELL);
                exit(1);
        }
        /* Parent. */
@@ -189,8 +194,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
        int gaierr;
        struct linger linger;
 
-       debug("ssh_connect: getuid %d geteuid %d anon %d",
-             (int) getuid(), (int) geteuid(), anonymous);
+       debug("ssh_connect: getuid %u geteuid %u anon %d",
+             (u_int) getuid(), (u_int) geteuid(), anonymous);
 
        /* Get default port if port has not been set. */
        if (port == 0) {
@@ -239,7 +244,11 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
 
                        /* Create a socket for connecting. */
                        sock = ssh_create_socket(original_real_uid,
-                           !anonymous && geteuid() == 0 && port < IPPORT_RESERVED,
+#ifdef HAVE_CYGWIN
+                           !anonymous,
+#else
+                           !anonymous && geteuid() == 0,
+#endif
                            ai->ai_family);
                        if (sock < 0)
                                continue;
@@ -251,7 +260,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
                        temporarily_use_uid(original_real_uid);
                        if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) {
                                /* Successful connection. */
-                               memcpy(hostaddr, ai->ai_addr, sizeof(*(ai->ai_addr)));
+                               memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
                                restore_uid();
                                break;
                        } else {
@@ -297,21 +306,6 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
        return 1;
 }
 
-char *
-chop(char *s)
-{
-       char *t = s;
-       while (*t) {
-               if(*t == '\n' || *t == '\r') {
-                       *t = '\0';
-                       return s;
-               }
-               t++;
-       }
-       return s;
-
-}
-
 /*
  * Waits for the server identification string, and sends our own
  * identification string.
@@ -323,25 +317,31 @@ ssh_exchange_identification()
        int remote_major, remote_minor, i, mismatch;
        int connection_in = packet_get_connection_in();
        int connection_out = packet_get_connection_out();
+       int minor1 = PROTOCOL_MINOR_1; 
 
        /* Read other side\'s version identification. */
-       for (i = 0; i < sizeof(buf) - 1; i++) {
-               int len = read(connection_in, &buf[i], 1);
-               if (len < 0)
-                       fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
-               if (len != 1)
-                       fatal("ssh_exchange_identification: Connection closed by remote host");
-               if (buf[i] == '\r') {
-                       buf[i] = '\n';
-                       buf[i + 1] = 0;
-                       continue;               /**XXX wait for \n */
+       for (;;) {
+               for (i = 0; i < sizeof(buf) - 1; i++) {
+                       int len = atomicio(read, connection_in, &buf[i], 1);
+                       if (len < 0)
+                               fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
+                       if (len != 1)
+                               fatal("ssh_exchange_identification: Connection closed by remote host");
+                       if (buf[i] == '\r') {
+                               buf[i] = '\n';
+                               buf[i + 1] = 0;
+                               continue;               /**XXX wait for \n */
+                       }
+                       if (buf[i] == '\n') {
+                               buf[i + 1] = 0;
+                               break;
+                       }
                }
-               if (buf[i] == '\n') {
-                       buf[i + 1] = 0;
+               buf[sizeof(buf) - 1] = 0;
+               if (strncmp(buf, "SSH-", 4) == 0)
                        break;
-               }
+               debug("ssh_exchange_identification: %s", buf);
        }
-       buf[sizeof(buf) - 1] = 0;
        server_version_string = xstrdup(buf);
 
        /*
@@ -371,9 +371,10 @@ ssh_exchange_identification()
                }
                if (remote_minor < 3) {
                        fatal("Remote machine has too old SSH software version.");
-               } else if (remote_minor == 3) {
+               } else if (remote_minor == 3 || remote_minor == 4) {
                        /* We speak 1.3, too. */
                        enable_compat13();
+                       minor1 = 3;
                        if (options.forward_agent) {
                                log("Agent forwarding disabled for protocol 1.3");
                                options.forward_agent = 0;
@@ -399,7 +400,7 @@ ssh_exchange_identification()
        /* Send our own protocol version identification. */
        snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
            compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
-           compat20 ? PROTOCOL_MINOR_2 : PROTOCOL_MINOR_1,
+           compat20 ? PROTOCOL_MINOR_2 : minor1,
            SSH_VERSION);
        if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
                fatal("write: %.100s", strerror(errno));
@@ -441,8 +442,10 @@ read_yes_or_no(const char *prompt, int defval)
                        retval = defval;
                if (strcmp(buf, "yes") == 0)
                        retval = 1;
-               if (strcmp(buf, "no") == 0)
+               else if (strcmp(buf, "no") == 0)
                        retval = 0;
+               else
+                       fprintf(stderr, "Please type 'yes' or 'no'.\n");
 
                if (retval != -1) {
                        if (f != stdin)
@@ -461,6 +464,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
        const char *user_hostfile, const char *system_hostfile)
 {
        Key *file_key;
+       char *type = key_type(host_key);
        char *ip = NULL;
        char hostline[1000], *hostp;
        HostStatus host_status;
@@ -504,13 +508,11 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
        if (options.proxy_command != NULL && options.check_host_ip)
                options.check_host_ip = 0;
 
-       if (options.check_host_ip) {
-               if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),
-                   NULL, 0, NI_NUMERICHOST) != 0)
-                       fatal("check_host_key: getnameinfo failed");
-               ip = xstrdup(ntop);
-       }
-
+       if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),
+                       NULL, 0, NI_NUMERICHOST) != 0)
+               fatal("check_host_key: getnameinfo failed");
+       ip = xstrdup(ntop);
+  
        /*
         * Store the host key from the known host file in here so that we can
         * compare it with the key for the IP address.
@@ -547,18 +549,19 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
        switch (host_status) {
        case HOST_OK:
                /* The host is known and the key matches. */
-               debug("Host '%.200s' is known and matches the host key.", host);
+               debug("Host '%.200s' is known and matches the %s host key.",
+                   host, type);
                if (options.check_host_ip) {
                        if (ip_status == HOST_NEW) {
                                if (!add_host_to_hostfile(user_hostfile, ip, host_key))
-                                       log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).",
-                                           ip, user_hostfile);
+                                       log("Failed to add the %s host key for IP address '%.30s' to the list of known hosts (%.30s).",
+                                           type, ip, user_hostfile);
                                else
-                                       log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.",
-                                           ip);
+                                       log("Warning: Permanently added the %s host key for IP address '%.30s' to the list of known hosts.",
+                                           type, ip);
                        } else if (ip_status != HOST_OK)
-                               log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'",
-                                   host, ip);
+                               log("Warning: the %s host key for '%.200s' differs from the key for the IP address '%.30s'",
+                                   type, host, ip);
                }
                break;
        case HOST_NEW:
@@ -566,16 +569,16 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                if (options.strict_host_key_checking == 1) {
                        /* User has requested strict host key checking.  We will not add the host key
                           automatically.  The only alternative left is to abort. */
-                       fatal("No host key is known for %.200s and you have requested strict checking.", host);
+                       fatal("No %s host key is known for %.200s and you have requested strict checking.", type, host);
                } else if (options.strict_host_key_checking == 2) {
                        /* The default */
                        char prompt[1024];
                        char *fp = key_fingerprint(host_key);
                        snprintf(prompt, sizeof(prompt),
-                           "The authenticity of host '%.200s' can't be established.\n"
-                           "Key fingerprint is %s.\n"
+                           "The authenticity of host '%.200s (%s)' can't be established.\n"
+                           "%s key fingerprint is %s.\n"
                            "Are you sure you want to continue connecting (yes/no)? ",
-                           host, fp);
+                           host, ip, type, fp);
                        if (!read_yes_or_no(prompt, -1))
                                fatal("Aborted by user!\n");
                }
@@ -590,8 +593,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                        log("Failed to add the host to the list of known hosts (%.500s).",
                            user_hostfile);
                else
-                       log("Warning: Permanently added '%.200s' to the list of known hosts.",
-                           hostp);
+                       log("Warning: Permanently added '%.200s' (%s) to the list of known hosts.",
+                           hostp, type);
                break;
        case HOST_CHANGED:
                if (options.check_host_ip && host_ip_differ) {
@@ -605,7 +608,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                        error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                        error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
                        error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
-                       error("The host key for %s has changed,", host);
+                       error("The %s host key for %s has changed,", type, host);
                        error("and the key for the according IP address %s", ip);
                        error("%s. This could either mean that", msg);
                        error("DNS SPOOFING is happening or the IP address for the host");
@@ -617,7 +620,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
                error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
-               error("It is also possible that the host key has just been changed.");
+               error("It is also possible that the %s host key has just been changed.", type);
                error("Please contact your system administrator.");
                error("Add correct host key in %.100s to get rid of this message.",
                      user_hostfile);
@@ -627,7 +630,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                 * to edit the key manually and we can only abort.
                 */
                if (options.strict_host_key_checking)
-                       fatal("Host key for %.200s has changed and you have requested strict checking.", host);
+                       fatal("%s host key for %.200s has changed and you have requested strict checking.", type, host);
 
                /*
                 * If strict host key checking has not been requested, allow
@@ -642,6 +645,14 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                        error("Agent forwarding is disabled to avoid trojan horses.");
                        options.forward_agent = 0;
                }
+               if (options.forward_x11) {
+                       error("X11 forwarding is disabled to avoid trojan horses.");
+                       options.forward_x11 = 0;
+               }
+               if (options.num_local_forwards > 0 || options.num_remote_forwards > 0) {
+                       error("Port forwarding is disabled to avoid trojan horses.");
+                       options.num_local_forwards = options.num_remote_forwards = 0;
+               }
                /*
                 * XXX Should permit the user to change to use the new id.
                 * This could be done by converting the host key to an
@@ -651,8 +662,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                 */
                break;
        }
-       if (options.check_host_ip)
-               xfree(ip);
+
+       xfree(ip);
 }
 
 /*
@@ -673,7 +684,7 @@ ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost,
        /* Get local user name.  Use it as server user if no user name was given. */
        pw = getpwuid(original_real_uid);
        if (!pw)
-               fatal("User id %d not found from user database.", original_real_uid);
+               fatal("User id %u not found from user database.", original_real_uid);
        local_user = xstrdup(pw->pw_name);
        server_user = options.user ? options.user : local_user;
 
This page took 0.081739 seconds and 4 git commands to generate.