version 1.469, 2017/11/01 00:04:15 |
version 1.470, 2018/01/23 05:06:25 |
|
|
return res; |
return res; |
} |
} |
|
|
|
/* Returns non-zero if name can only be an address and not a hostname */ |
|
static int |
|
is_addr_fast(const char *name) |
|
{ |
|
return (strchr(name, '%') != NULL || strchr(name, ':') != NULL || |
|
strspn(name, "0123456789.") == strlen(name)); |
|
} |
|
|
|
/* Returns non-zero if name represents a valid, single address */ |
|
static int |
|
is_addr(const char *name) |
|
{ |
|
char strport[NI_MAXSERV]; |
|
struct addrinfo hints, *res; |
|
|
|
if (is_addr_fast(name)) |
|
return 1; |
|
|
|
snprintf(strport, sizeof strport, "%u", default_ssh_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 (getaddrinfo(name, strport, &hints, &res) != 0) |
|
return 0; |
|
if (res == NULL || res->ai_next != NULL) { |
|
freeaddrinfo(res); |
|
return 0; |
|
} |
|
freeaddrinfo(res); |
|
return 1; |
|
} |
|
|
/* |
/* |
* Attempt to resolve a numeric host address / port to a single address. |
* Attempt to resolve a numeric host address / port to a single address. |
* Returns a canonical address string. |
* Returns a canonical address string. |
|
|
char *cp, *fullhost, newname[NI_MAXHOST]; |
char *cp, *fullhost, newname[NI_MAXHOST]; |
struct addrinfo *addrs; |
struct addrinfo *addrs; |
|
|
if (options.canonicalize_hostname == SSH_CANONICALISE_NO) |
|
return NULL; |
|
|
|
/* |
/* |
* Don't attempt to canonicalize names that will be interpreted by |
* Attempt to canonicalise addresses, regardless of |
* a proxy unless the user specifically requests so. |
* whether hostname canonicalisation was requested |
*/ |
*/ |
direct = option_clear_or_none(options.proxy_command) && |
|
options.jump_host == NULL; |
|
if (!direct && |
|
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
|
return NULL; |
|
|
|
/* Try numeric hostnames first */ |
|
if ((addrs = resolve_addr(*hostp, port, |
if ((addrs = resolve_addr(*hostp, port, |
newname, sizeof(newname))) != NULL) { |
newname, sizeof(newname))) != NULL) { |
debug2("%s: hostname %.100s is address", __func__, *hostp); |
debug2("%s: hostname %.100s is address", __func__, *hostp); |
|
|
return addrs; |
return addrs; |
} |
} |
|
|
|
/* |
|
* If this looks like an address but didn't parse as one, it might |
|
* be an address with an invalid interface scope. Skip further |
|
* attempts at canonicalisation. |
|
*/ |
|
if (is_addr_fast(*hostp)) { |
|
debug("%s: hostname %.100s is an unrecognised address", |
|
__func__, *hostp); |
|
return NULL; |
|
} |
|
|
|
if (options.canonicalize_hostname == SSH_CANONICALISE_NO) |
|
return NULL; |
|
|
|
/* |
|
* Don't attempt to canonicalize names that will be interpreted by |
|
* a proxy unless the user specifically requests so. |
|
*/ |
|
direct = option_clear_or_none(options.proxy_command) && |
|
options.jump_host == NULL; |
|
if (!direct && |
|
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
|
return NULL; |
|
|
/* If domain name is anchored, then resolve it now */ |
/* If domain name is anchored, then resolve it now */ |
if ((*hostp)[strlen(*hostp) - 1] == '.') { |
if ((*hostp)[strlen(*hostp) - 1] == '.') { |
debug3("%s: name is fully qualified", __func__); |
debug3("%s: name is fully qualified", __func__); |
|
|
{ |
{ |
struct ssh *ssh = NULL; |
struct ssh *ssh = NULL; |
int i, r, opt, exit_status, use_syslog, direct, timeout_ms; |
int i, r, opt, exit_status, use_syslog, direct, timeout_ms; |
int config_test = 0, opt_terminated = 0; |
int was_addr, config_test = 0, opt_terminated = 0; |
char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; |
char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; |
char cname[NI_MAXHOST]; |
char cname[NI_MAXHOST]; |
struct stat st; |
struct stat st; |
|
|
options.hostname = xstrdup(host); |
options.hostname = xstrdup(host); |
} |
} |
|
|
/* If canonicalization requested then try to apply it */ |
/* Don't lowercase addresses, they will be explicitly canonicalised */ |
lowercase(host); |
if ((was_addr = is_addr(host)) == 0) |
if (options.canonicalize_hostname != SSH_CANONICALISE_NO) |
lowercase(host); |
|
|
|
/* |
|
* Try to canonicalize if requested by configuration or the |
|
* hostname is an address. |
|
*/ |
|
if (options.canonicalize_hostname != SSH_CANONICALISE_NO || was_addr) |
addrs = resolve_canonicalize(&host, options.port); |
addrs = resolve_canonicalize(&host, options.port); |
|
|
/* |
/* |