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