]> andersk Git - openssh.git/blobdiff - sshconnect.c
20070326
[openssh.git] / sshconnect.c
index f33cf52b14a1b1ca77bb37fcd2ac7da678cb9078..a222233d0aa99b29f48d2bed061ee3d318ab5a3e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.193 2006/07/22 20:48:23 stevesk Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.200 2006/10/10 10:12:45 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
 
 #include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include <ctype.h>
 #include <errno.h>
-#if defined(HAVE_NETDB_H)
-# include <netdb.h>
-#endif
+#include <netdb.h>
 #ifdef HAVE_PATHS_H
 #include <paths.h>
 #endif
 #include <pwd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-#include "ssh.h"
 #include "xmalloc.h"
+#include "key.h"
+#include "hostfile.h"
+#include "ssh.h"
 #include "rsa.h"
 #include "buffer.h"
 #include "packet.h"
@@ -317,9 +324,11 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
                    gai_strerror(gaierr));
 
        for (attempt = 0; attempt < connection_attempts; attempt++) {
-               if (attempt > 0)
+               if (attempt > 0) {
+                       /* Sleep a moment before retrying. */
+                       sleep(1);
                        debug("Trying again...");
-
+               }
                /*
                 * Loop through addresses for this host, and try each one in
                 * sequence until the connection succeeds.
@@ -356,9 +365,6 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
                }
                if (sock != -1)
                        break;  /* Successful connection. */
-
-               /* Sleep a moment before retrying. */
-               sleep(1);
        }
 
        freeaddrinfo(aitop);
@@ -519,9 +525,13 @@ confirm(const char *prompt)
  * check whether the supplied host key is valid, return -1 if the key
  * is not valid. the user_hostfile will not be updated if 'readonly' is true.
  */
+#define RDRW   0
+#define RDONLY 1
+#define ROQUIET        2
 static int
-check_host_key(char *hostname, struct sockaddr *hostaddr, Key *host_key,
-    int readonly, const char *user_hostfile, const char *system_hostfile)
+check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
+    Key *host_key, int readonly, const char *user_hostfile,
+    const char *system_hostfile)
 {
        Key *file_key;
        const char *type = key_type(host_key);
@@ -576,7 +586,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, Key *host_key,
                if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),
                    NULL, 0, NI_NUMERICHOST) != 0)
                        fatal("check_host_key: getnameinfo failed");
-               ip = put_host_port(ntop, options.port);
+               ip = put_host_port(ntop, port);
        } else {
                ip = xstrdup("<no hostip for proxy command>");
        }
@@ -598,7 +608,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, Key *host_key,
                host = xstrdup(options.host_key_alias);
                debug("using hostkeyalias: %s", host);
        } else {
-               host = put_host_port(hostname, options.port);
+               host = put_host_port(hostname, port);
        }
 
        /*
@@ -667,6 +677,15 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, Key *host_key,
                }
                break;
        case HOST_NEW:
+               if (options.host_key_alias == NULL && port != 0 &&
+                   port != SSH_DEFAULT_PORT) {
+                       debug("checking without port identifier");
+                       if (check_host_key(hostname, hostaddr, 0, host_key, 2,
+                           user_hostfile, system_hostfile) == 0) {
+                               debug("found matching key w/out port");
+                               break;
+                       }
+               }
                if (readonly)
                        goto fail;
                /* The host is new. */
@@ -746,6 +765,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, Key *host_key,
                            "list of known hosts.", hostp, type);
                break;
        case HOST_CHANGED:
+               if (readonly == ROQUIET)
+                       goto fail;
                if (options.check_host_ip && host_ip_differ) {
                        char *key_msg;
                        if (ip_status == HOST_NEW)
@@ -784,7 +805,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, Key *host_key,
                /*
                 * If strict host key checking has not been requested, allow
                 * the connection but without MITM-able authentication or
-                * agent forwarding.
+                * forwarding.
                 */
                if (options.password_authentication) {
                        error("Password authentication is disabled to avoid "
@@ -819,6 +840,11 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, Key *host_key,
                        options.num_local_forwards =
                            options.num_remote_forwards = 0;
                }
+               if (options.tun_open != SSH_TUNMODE_NO) {
+                       error("Tunnel forwarding is disabled to avoid "
+                           "man-in-the-middle attacks.");
+                       options.tun_open = SSH_TUNMODE_NO;
+               }
                /*
                 * XXX Should permit the user to change to use the new id.
                 * This could be done by converting the host key to an
@@ -899,12 +925,13 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
        /* return ok if the key can be found in an old keyfile */
        if (stat(options.system_hostfile2, &st) == 0 ||
            stat(options.user_hostfile2, &st) == 0) {
-               if (check_host_key(host, hostaddr, host_key, /*readonly*/ 1,
-                   options.user_hostfile2, options.system_hostfile2) == 0)
+               if (check_host_key(host, hostaddr, options.port, host_key,
+                   RDONLY, options.user_hostfile2,
+                   options.system_hostfile2) == 0)
                        return 0;
        }
-       return check_host_key(host, hostaddr, host_key, /*readonly*/ 0,
-           options.user_hostfile, options.system_hostfile);
+       return check_host_key(host, hostaddr, options.port, host_key,
+           RDRW, options.user_hostfile, options.system_hostfile);
 }
 
 /*
This page took 0.037177 seconds and 4 git commands to generate.