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

Collapse All | Expand All

(-)ssh.c (+68 lines)
Lines 262-267 resolve_host(const char *name, int port, int logerr, char *cname, size_t clen) Link Here
262
}
262
}
263
263
264
/*
264
/*
265
 * Attempt to resolve a numeric host address / port to a single address.
266
 * Returns a canonical address string.
267
 * Returns NULL on failure.
268
 * NB. this function must operate with a options having undefined members.
269
 */
270
static struct addrinfo *
271
resolve_addr(const char *name, int port, char *caddr, size_t clen)
272
{
273
	char addr[NI_MAXHOST], strport[NI_MAXSERV];
274
	struct addrinfo hints, *res;
275
	int gaierr;
276
277
	if (port <= 0)
278
		port = default_ssh_port();
279
	snprintf(strport, sizeof strport, "%u", port);
280
	memset(&hints, 0, sizeof(hints));
281
	hints.ai_family = options.address_family == -1 ?
282
	    AF_UNSPEC : options.address_family;
283
	hints.ai_socktype = SOCK_STREAM;
284
	hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV;
285
	if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) {
286
		debug2("%s: could not resolve name %.100s as address: %s",
287
		    __func__, name, ssh_gai_strerror(gaierr));
288
		return NULL;
289
	}
290
	if (res == NULL) {
291
		debug("%s: getaddrinfo %.100s returned no addresses",
292
		 __func__, name);
293
		return NULL;
294
	}
295
	if (res->ai_next != NULL) {
296
		debug("%s: getaddrinfo %.100s returned multiple addresses",
297
		    __func__, name);
298
		freeaddrinfo(res);
299
		return NULL;
300
	}
301
	if ((gaierr = getnameinfo(res->ai_addr, res->ai_addrlen,
302
	    addr, sizeof(addr), NULL, 0, NI_NUMERICHOST)) != 0) {
303
		debug("%s: Could not format address for name %.100s: %s",
304
		    __func__, name, ssh_gai_strerror(gaierr));
305
		freeaddrinfo(res);
306
		return NULL;
307
	}
308
	if (strlcpy(caddr, addr, clen) >= clen) {
309
		error("%s: host \"%s\" addr \"%s\" too long (max %lu)",
310
		    __func__, name,  addr, (u_long)clen);
311
		if (clen > 0)
312
			*caddr = '\0';
313
		freeaddrinfo(res);
314
		return NULL;
315
	}
316
	return res;
317
}
318
319
/*
265
 * Check whether the cname is a permitted replacement for the hostname
320
 * Check whether the cname is a permitted replacement for the hostname
266
 * and perform the replacement if it is.
321
 * and perform the replacement if it is.
267
 * NB. this function must operate with a options having undefined members.
322
 * NB. this function must operate with a options having undefined members.
Lines 325-330 resolve_canonicalize(char **hostp, int port) Link Here
325
	    options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
380
	    options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
326
		return NULL;
381
		return NULL;
327
382
383
	/* Try numeric hostnames first */
384
	if ((addrs = resolve_addr(*hostp, port,
385
	    cname_target, sizeof(cname_target))) != NULL) {
386
		debug2("%s: hostname %.100s is address", __func__, *hostp);
387
		if (strcasecmp(*hostp, cname_target) != 0) {
388
			debug2("%s: canonicalised address \"%s\" => \"%s\"",
389
			    __func__, *hostp, cname_target);
390
			free(*hostp);
391
			*hostp = xstrdup(cname_target);
392
		}
393
		return addrs;
394
	}
395
328
	/* Don't apply canonicalization to sufficiently-qualified hostnames */
396
	/* Don't apply canonicalization to sufficiently-qualified hostnames */
329
	ndots = 0;
397
	ndots = 0;
330
	for (cp = *hostp; *cp != '\0'; cp++) {
398
	for (cp = *hostp; *cp != '\0'; cp++) {

Return to bug 2074