On Sat, 2 Apr 2011, Damien Miller wrote:

> AI_FQDN solves these problems quite nicely. It is also useful for web
> browsers that face a similar problem (e.g. https://intranet/) but
> getting them to adopt it might be more tricky. I'd love to see this get
> deployed so we can use it in OpenSSH (which we can change quickly)

... and here is a diff to do it:

(NB. this diff doesn't include any backwards compatibility so hosts that
are known only by unqualified names might trigger "new hostkey" messages)

Index: ssh.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/ssh.c,v
retrieving revision 1.356
diff -u -p -r1.356 ssh.c
--- ssh.c       6 Jan 2011 22:23:53 -0000       1.356
+++ ssh.c       3 Apr 2011 01:44:37 -0000
@@ -571,9 +571,9 @@ main(int ac, char **av)
                                usage();
                        options.user = p;
                        *cp = '\0';
-                       host = ++cp;
+                       host = xstrdup(++cp);
                } else
-                       host = *av;
+                       host = xstrdup(*av);
                if (ac > 1) {
                        optind = optreset = 1;
                        goto again;
@@ -739,7 +739,7 @@ main(int ac, char **av)
        timeout_ms = options.connection_timeout * 1000;
 
        /* Open a connection to the remote host. */
-       if (ssh_connect(host, &hostaddr, options.port,
+       if (ssh_connect(&host, &hostaddr, options.port,
            options.address_family, options.connection_attempts, &timeout_ms,
            options.tcp_keep_alive, 
            original_effective_uid == 0 && options.use_privileged_port,
Index: sshconnect.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sshconnect.c,v
retrieving revision 1.232
diff -u -p -r1.232 sshconnect.c
--- sshconnect.c        16 Jan 2011 11:50:36 -0000      1.232
+++ sshconnect.c        3 Apr 2011 01:44:37 -0000
@@ -324,7 +324,7 @@ timeout_connect(int sockfd, const struct
  * the daemon.
  */
 int
-ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
+ssh_connect(char **host, struct sockaddr_storage * hostaddr,
     u_short port, int family, int connection_attempts, int *timeout_ms,
     int want_keepalive, int needpriv, const char *proxy_command)
 {
@@ -338,17 +338,20 @@ ssh_connect(const char *host, struct soc
 
        /* If a proxy command is given, connect using it. */
        if (proxy_command != NULL)
-               return ssh_proxy_connect(host, port, proxy_command);
+               return ssh_proxy_connect(*host, port, proxy_command);
 
        /* No proxy command. */
 
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = family;
        hints.ai_socktype = SOCK_STREAM;
+#ifdef AI_FQDN
+       hints.ai_flags = AI_FQDN;
+#endif
        snprintf(strport, sizeof strport, "%u", port);
-       if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
+       if ((gaierr = getaddrinfo(*host, strport, &hints, &aitop)) != 0)
                fatal("%s: Could not resolve hostname %.100s: %s", __progname,
-                   host, ssh_gai_strerror(gaierr));
+                   *host, ssh_gai_strerror(gaierr));
 
        for (attempt = 0; attempt < connection_attempts; attempt++) {
                if (attempt > 0) {
@@ -370,7 +373,7 @@ ssh_connect(const char *host, struct soc
                                continue;
                        }
                        debug("Connecting to %.200s [%.100s] port %s.",
-                               host, ntop, strport);
+                           *host, ntop, strport);
 
                        /* Create a socket for connecting. */
                        sock = ssh_create_socket(needpriv, ai);
@@ -382,6 +385,15 @@ ssh_connect(const char *host, struct soc
                            timeout_ms) >= 0) {
                                /* Successful connection. */
                                memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
+#ifdef AI_FQDN
+                               if (ai->ai_canonname != NULL ||
+                                   strcmp(*host, ai->ai_canonname) != 0) {
+                                       debug3("%s: canonicalised %s => %s",
+                                           __func__, *host, ai->ai_canonname);
+                                       free(*host);
+                                       *host = xstrdup(ai->ai_canonname);
+                               }
+#endif
                                break;
                        } else {
                                debug("connect to address %s port %s: %s",
@@ -399,7 +411,7 @@ ssh_connect(const char *host, struct soc
        /* Return failure if we didn't get a successful connection. */
        if (sock == -1) {
                error("ssh: connect to host %s port %s: %s",
-                   host, strport, strerror(errno));
+                   *host, strport, strerror(errno));
                return (-1);
        }
 
Index: sshconnect.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sshconnect.h,v
retrieving revision 1.27
diff -u -p -r1.27 sshconnect.h
--- sshconnect.h        29 Nov 2010 23:45:51 -0000      1.27
+++ sshconnect.h        3 Apr 2011 01:44:37 -0000
@@ -32,7 +32,7 @@ struct Sensitive {
 };
 
 int
-ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int,
+ssh_connect(char **, struct sockaddr_storage *, u_short, int, int,
     int *, int, int, const char *);
 void    ssh_kill_proxy_command(void);

Reply via email to