View | Details | Raw Unified | Return to bug 2763 | Differences between
and this patch

Collapse All | Expand All

(-)a/ssh.c (-16 / +70 lines)
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
	/*

Return to bug 2763