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);