|
Lines 255-260
resolve_host(const char *name, int port, int logerr, char *cname, size_t clen)
Link Here
|
| 255 |
return res; |
255 |
return res; |
| 256 |
} |
256 |
} |
| 257 |
|
257 |
|
|
|
258 |
/* Returns non-zero if name can only be an address and not a hostname */ |
| 259 |
static int |
| 260 |
is_addr_fast(const char *name) |
| 261 |
{ |
| 262 |
return (strchr(name, '%') != NULL || strchr(name, ':') != NULL || |
| 263 |
strspn(name, "0123456789.") == strlen(name)); |
| 264 |
} |
| 265 |
|
| 266 |
/* Returns non-zero if name represents a valid, single address */ |
| 267 |
static int |
| 268 |
is_addr(const char *name) |
| 269 |
{ |
| 270 |
char strport[NI_MAXSERV]; |
| 271 |
struct addrinfo hints, *res; |
| 272 |
|
| 273 |
if (is_addr_fast(name)) |
| 274 |
return 1; |
| 275 |
|
| 276 |
snprintf(strport, sizeof strport, "%u", default_ssh_port()); |
| 277 |
memset(&hints, 0, sizeof(hints)); |
| 278 |
hints.ai_family = options.address_family == -1 ? |
| 279 |
AF_UNSPEC : options.address_family; |
| 280 |
hints.ai_socktype = SOCK_STREAM; |
| 281 |
hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV; |
| 282 |
if (getaddrinfo(name, strport, &hints, &res) != 0) |
| 283 |
return 0; |
| 284 |
if (res == NULL || res->ai_next != NULL) { |
| 285 |
freeaddrinfo(res); |
| 286 |
return 0; |
| 287 |
} |
| 288 |
freeaddrinfo(res); |
| 289 |
return 1; |
| 290 |
} |
| 291 |
|
| 258 |
/* |
292 |
/* |
| 259 |
* Attempt to resolve a numeric host address / port to a single address. |
293 |
* Attempt to resolve a numeric host address / port to a single address. |
| 260 |
* Returns a canonical address string. |
294 |
* Returns a canonical address string. |
|
Lines 360-379
resolve_canonicalize(char **hostp, int port)
Link Here
|
| 360 |
char *cp, *fullhost, newname[NI_MAXHOST]; |
394 |
char *cp, *fullhost, newname[NI_MAXHOST]; |
| 361 |
struct addrinfo *addrs; |
395 |
struct addrinfo *addrs; |
| 362 |
|
396 |
|
| 363 |
if (options.canonicalize_hostname == SSH_CANONICALISE_NO) |
|
|
| 364 |
return NULL; |
| 365 |
|
| 366 |
/* |
397 |
/* |
| 367 |
* Don't attempt to canonicalize names that will be interpreted by |
398 |
* Attempt to canonicalise addresses, regardless of |
| 368 |
* a proxy unless the user specifically requests so. |
399 |
* whether hostname canonicalisation was requested |
| 369 |
*/ |
400 |
*/ |
| 370 |
direct = option_clear_or_none(options.proxy_command) && |
|
|
| 371 |
options.jump_host == NULL; |
| 372 |
if (!direct && |
| 373 |
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
| 374 |
return NULL; |
| 375 |
|
| 376 |
/* Try numeric hostnames first */ |
| 377 |
if ((addrs = resolve_addr(*hostp, port, |
401 |
if ((addrs = resolve_addr(*hostp, port, |
| 378 |
newname, sizeof(newname))) != NULL) { |
402 |
newname, sizeof(newname))) != NULL) { |
| 379 |
debug2("%s: hostname %.100s is address", __func__, *hostp); |
403 |
debug2("%s: hostname %.100s is address", __func__, *hostp); |
|
Lines 386-391
resolve_canonicalize(char **hostp, int port)
Link Here
|
| 386 |
return addrs; |
410 |
return addrs; |
| 387 |
} |
411 |
} |
| 388 |
|
412 |
|
|
|
413 |
/* |
| 414 |
* If this looks like an address but didn't parse as one, it might |
| 415 |
* be an address with an invalid interface scope. Skip further |
| 416 |
* attempts at canonicalisation. |
| 417 |
*/ |
| 418 |
if (is_addr_fast(*hostp)) { |
| 419 |
debug("%s: hostname %.100s is an unrecognised address", |
| 420 |
__func__, *hostp); |
| 421 |
return NULL; |
| 422 |
} |
| 423 |
|
| 424 |
if (options.canonicalize_hostname == SSH_CANONICALISE_NO) |
| 425 |
return NULL; |
| 426 |
|
| 427 |
/* |
| 428 |
* Don't attempt to canonicalize names that will be interpreted by |
| 429 |
* a proxy unless the user specifically requests so. |
| 430 |
*/ |
| 431 |
direct = option_clear_or_none(options.proxy_command) && |
| 432 |
options.jump_host == NULL; |
| 433 |
if (!direct && |
| 434 |
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
| 435 |
return NULL; |
| 436 |
|
| 389 |
/* If domain name is anchored, then resolve it now */ |
437 |
/* If domain name is anchored, then resolve it now */ |
| 390 |
if ((*hostp)[strlen(*hostp) - 1] == '.') { |
438 |
if ((*hostp)[strlen(*hostp) - 1] == '.') { |
| 391 |
debug3("%s: name is fully qualified", __func__); |
439 |
debug3("%s: name is fully qualified", __func__); |
|
Lines 498-504
main(int ac, char **av)
Link Here
|
| 498 |
{ |
546 |
{ |
| 499 |
struct ssh *ssh = NULL; |
547 |
struct ssh *ssh = NULL; |
| 500 |
int i, r, opt, exit_status, use_syslog, direct, timeout_ms; |
548 |
int i, r, opt, exit_status, use_syslog, direct, timeout_ms; |
| 501 |
int config_test = 0, opt_terminated = 0; |
549 |
int was_addr, config_test = 0, opt_terminated = 0; |
| 502 |
char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; |
550 |
char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; |
| 503 |
char cname[NI_MAXHOST]; |
551 |
char cname[NI_MAXHOST]; |
| 504 |
struct stat st; |
552 |
struct stat st; |
|
Lines 1024-1032
main(int ac, char **av)
Link Here
|
| 1024 |
options.hostname = xstrdup(host); |
1072 |
options.hostname = xstrdup(host); |
| 1025 |
} |
1073 |
} |
| 1026 |
|
1074 |
|
| 1027 |
/* If canonicalization requested then try to apply it */ |
1075 |
/* Don't lowercase addresses, they will be explicitly canonicalised */ |
| 1028 |
lowercase(host); |
1076 |
if ((was_addr = is_addr(host)) == 0) |
| 1029 |
if (options.canonicalize_hostname != SSH_CANONICALISE_NO) |
1077 |
lowercase(host); |
|
|
1078 |
|
| 1079 |
/* |
| 1080 |
* Try to canonicalize if requested by configuration or the |
| 1081 |
* hostname is an address. |
| 1082 |
*/ |
| 1083 |
if (options.canonicalize_hostname != SSH_CANONICALISE_NO || was_addr) |
| 1030 |
addrs = resolve_canonicalize(&host, options.port); |
1084 |
addrs = resolve_canonicalize(&host, options.port); |
| 1031 |
|
1085 |
|
| 1032 |
/* |
1086 |
/* |