mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-27 07:44:29 +02:00
upstream commit
when hostname canonicalisation is enabled, try to parse hostnames as addresses before looking them up for canonicalisation. fixes bz#2074 and avoids needless DNS lookups in some cases; ok markus
This commit is contained in:
parent
2ae4f337b2
commit
9010902954
77
ssh.c
77
ssh.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh.c,v 1.412 2015/01/14 20:05:27 djm Exp $ */
|
/* $OpenBSD: ssh.c,v 1.413 2015/01/16 07:19:48 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -276,6 +276,60 @@ resolve_host(const char *name, int port, int logerr, char *cname, size_t clen)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempt to resolve a numeric host address / port to a single address.
|
||||||
|
* Returns a canonical address string.
|
||||||
|
* Returns NULL on failure.
|
||||||
|
* NB. this function must operate with a options having undefined members.
|
||||||
|
*/
|
||||||
|
static struct addrinfo *
|
||||||
|
resolve_addr(const char *name, int port, char *caddr, size_t clen)
|
||||||
|
{
|
||||||
|
char addr[NI_MAXHOST], strport[NI_MAXSERV];
|
||||||
|
struct addrinfo hints, *res;
|
||||||
|
int gaierr;
|
||||||
|
|
||||||
|
if (port <= 0)
|
||||||
|
port = default_ssh_port();
|
||||||
|
snprintf(strport, sizeof strport, "%u", port);
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = options.address_family == -1 ?
|
||||||
|
AF_UNSPEC : options.address_family;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV;
|
||||||
|
if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) {
|
||||||
|
debug2("%s: could not resolve name %.100s as address: %s",
|
||||||
|
__func__, name, ssh_gai_strerror(gaierr));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (res == NULL) {
|
||||||
|
debug("%s: getaddrinfo %.100s returned no addresses",
|
||||||
|
__func__, name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (res->ai_next != NULL) {
|
||||||
|
debug("%s: getaddrinfo %.100s returned multiple addresses",
|
||||||
|
__func__, name);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if ((gaierr = getnameinfo(res->ai_addr, res->ai_addrlen,
|
||||||
|
addr, sizeof(addr), NULL, 0, NI_NUMERICHOST)) != 0) {
|
||||||
|
debug("%s: Could not format address for name %.100s: %s",
|
||||||
|
__func__, name, ssh_gai_strerror(gaierr));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (strlcpy(caddr, addr, clen) >= clen) {
|
||||||
|
error("%s: host \"%s\" addr \"%s\" too long (max %lu)",
|
||||||
|
__func__, name, addr, (u_long)clen);
|
||||||
|
if (clen > 0)
|
||||||
|
*caddr = '\0';
|
||||||
|
fail:
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether the cname is a permitted replacement for the hostname
|
* Check whether the cname is a permitted replacement for the hostname
|
||||||
* and perform the replacement if it is.
|
* and perform the replacement if it is.
|
||||||
@ -326,7 +380,7 @@ static struct addrinfo *
|
|||||||
resolve_canonicalize(char **hostp, int port)
|
resolve_canonicalize(char **hostp, int port)
|
||||||
{
|
{
|
||||||
int i, ndots;
|
int i, ndots;
|
||||||
char *cp, *fullhost, cname_target[NI_MAXHOST];
|
char *cp, *fullhost, newname[NI_MAXHOST];
|
||||||
struct addrinfo *addrs;
|
struct addrinfo *addrs;
|
||||||
|
|
||||||
if (options.canonicalize_hostname == SSH_CANONICALISE_NO)
|
if (options.canonicalize_hostname == SSH_CANONICALISE_NO)
|
||||||
@ -340,6 +394,19 @@ resolve_canonicalize(char **hostp, int port)
|
|||||||
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
|
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/* Try numeric hostnames first */
|
||||||
|
if ((addrs = resolve_addr(*hostp, port,
|
||||||
|
newname, sizeof(newname))) != NULL) {
|
||||||
|
debug2("%s: hostname %.100s is address", __func__, *hostp);
|
||||||
|
if (strcasecmp(*hostp, newname) != 0) {
|
||||||
|
debug2("%s: canonicalised address \"%s\" => \"%s\"",
|
||||||
|
__func__, *hostp, newname);
|
||||||
|
free(*hostp);
|
||||||
|
*hostp = xstrdup(newname);
|
||||||
|
}
|
||||||
|
return addrs;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't apply canonicalization to sufficiently-qualified hostnames */
|
/* Don't apply canonicalization to sufficiently-qualified hostnames */
|
||||||
ndots = 0;
|
ndots = 0;
|
||||||
for (cp = *hostp; *cp != '\0'; cp++) {
|
for (cp = *hostp; *cp != '\0'; cp++) {
|
||||||
@ -353,20 +420,20 @@ resolve_canonicalize(char **hostp, int port)
|
|||||||
}
|
}
|
||||||
/* Attempt each supplied suffix */
|
/* Attempt each supplied suffix */
|
||||||
for (i = 0; i < options.num_canonical_domains; i++) {
|
for (i = 0; i < options.num_canonical_domains; i++) {
|
||||||
*cname_target = '\0';
|
*newname = '\0';
|
||||||
xasprintf(&fullhost, "%s.%s.", *hostp,
|
xasprintf(&fullhost, "%s.%s.", *hostp,
|
||||||
options.canonical_domains[i]);
|
options.canonical_domains[i]);
|
||||||
debug3("%s: attempting \"%s\" => \"%s\"", __func__,
|
debug3("%s: attempting \"%s\" => \"%s\"", __func__,
|
||||||
*hostp, fullhost);
|
*hostp, fullhost);
|
||||||
if ((addrs = resolve_host(fullhost, port, 0,
|
if ((addrs = resolve_host(fullhost, port, 0,
|
||||||
cname_target, sizeof(cname_target))) == NULL) {
|
newname, sizeof(newname))) == NULL) {
|
||||||
free(fullhost);
|
free(fullhost);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Remove trailing '.' */
|
/* Remove trailing '.' */
|
||||||
fullhost[strlen(fullhost) - 1] = '\0';
|
fullhost[strlen(fullhost) - 1] = '\0';
|
||||||
/* Follow CNAME if requested */
|
/* Follow CNAME if requested */
|
||||||
if (!check_follow_cname(&fullhost, cname_target)) {
|
if (!check_follow_cname(&fullhost, newname)) {
|
||||||
debug("Canonicalized hostname \"%s\" => \"%s\"",
|
debug("Canonicalized hostname \"%s\" => \"%s\"",
|
||||||
*hostp, fullhost);
|
*hostp, fullhost);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user