View | Details | Raw Unified | Return to bug 1685
Collapse All | Expand All

(-)a/sshconnect.c (-20 / +25 lines)
Lines 323-336 check_ifaddrs(const char *ifname, int af, const struct ifaddrs *ifaddrs, Link Here
323
323
324
/*
324
/*
325
 * Creates a (possibly privileged) socket for use as the ssh connection.
325
 * Creates a (possibly privileged) socket for use as the ssh connection.
326
 * Returns socket on success.
327
 * On failure, returns -1 and either logs the error or sets errno.
326
 */
328
 */
327
static int
329
static int
328
ssh_create_socket(int privileged, struct addrinfo *ai)
330
ssh_create_socket(int privileged, struct addrinfo *ai)
329
{
331
{
330
	int sock, r, oerrno;
332
	int sock, r, oerrno, fail_errno = 0;
331
	struct sockaddr_storage bindaddr;
333
	struct sockaddr_storage bindaddr;
332
	socklen_t bindaddrlen = 0;
334
	socklen_t bindaddrlen = 0;
333
	struct addrinfo hints, *res = NULL;
335
	struct addrinfo hints, *res = NULL, *bind_ai;
334
	struct ifaddrs *ifaddrs = NULL;
336
	struct ifaddrs *ifaddrs = NULL;
335
	char ntop[NI_MAXHOST];
337
	char ntop[NI_MAXHOST];
336
338
Lines 348-354 ssh_create_socket(int privileged, struct addrinfo *ai) Link Here
348
350
349
	if (options.bind_address != NULL) {
351
	if (options.bind_address != NULL) {
350
		memset(&hints, 0, sizeof(hints));
352
		memset(&hints, 0, sizeof(hints));
351
		hints.ai_family = ai->ai_family;
353
		hints.ai_family = AF_UNSPEC;
352
		hints.ai_socktype = ai->ai_socktype;
354
		hints.ai_socktype = ai->ai_socktype;
353
		hints.ai_protocol = ai->ai_protocol;
355
		hints.ai_protocol = ai->ai_protocol;
354
		hints.ai_flags = AI_PASSIVE;
356
		hints.ai_flags = AI_PASSIVE;
Lines 358-384 ssh_create_socket(int privileged, struct addrinfo *ai) Link Here
358
			    ssh_gai_strerror(r));
360
			    ssh_gai_strerror(r));
359
			goto fail;
361
			goto fail;
360
		}
362
		}
361
		if (res == NULL) {
363
		for (bind_ai = res; bind_ai != NULL;
362
			error("getaddrinfo: no addrs");
364
		    bind_ai = bind_ai->ai_next) {
365
			if (bind_ai->ai_family == ai->ai_family)
366
				break;
367
		}
368
		if (bind_ai == NULL) {
369
			debug("%s: no suitable bind address", __func__);
370
			fail_errno = EADDRNOTAVAIL;
363
			goto fail;
371
			goto fail;
364
		}
372
		}
365
		if (res->ai_addrlen > sizeof(bindaddr)) {
373
		if (bind_ai->ai_addrlen > sizeof(bindaddr)) {
366
			error("%s: addr doesn't fit", __func__);
374
			error("%s: bind address doesn't fit", __func__);
367
			goto fail;
375
			goto fail;
368
		}
376
		}
369
		memcpy(&bindaddr, res->ai_addr, res->ai_addrlen);
377
		memcpy(&bindaddr, bind_ai->ai_addr, bind_ai->ai_addrlen);
370
		bindaddrlen = res->ai_addrlen;
378
		bindaddrlen = bind_ai->ai_addrlen;
371
	} else if (options.bind_interface != NULL) {
379
	} else if (options.bind_interface != NULL) {
372
		if ((r = getifaddrs(&ifaddrs)) != 0) {
380
		if ((r = getifaddrs(&ifaddrs)) != 0) {
373
			error("getifaddrs: %s: %s", options.bind_interface,
381
			error("%s: BindInterface getifaddrs: %s: %s",
374
			      strerror(errno));
382
			    __func__, options.bind_interface, strerror(errno));
375
			goto fail;
383
			goto fail;
376
		}
384
		}
377
		bindaddrlen = sizeof(bindaddr);
385
		bindaddrlen = sizeof(bindaddr);
378
		if (check_ifaddrs(options.bind_interface, ai->ai_family,
386
		if (check_ifaddrs(options.bind_interface, ai->ai_family,
379
		    ifaddrs, &bindaddr, &bindaddrlen) != 0) {
387
		    ifaddrs, &bindaddr, &bindaddrlen) != 0) {
380
			logit("getifaddrs: %s: no suitable addresses",
388
			debug("%s: no suitable addresses from BindInterface %s",
381
			      options.bind_interface);
389
			      __func__, options.bind_interface);
390
			fail_errno = EADDRNOTAVAIL;
382
			goto fail;
391
			goto fail;
383
		}
392
		}
384
	}
393
	}
Lines 399-406 ssh_create_socket(int privileged, struct addrinfo *ai) Link Here
399
		oerrno = errno;
408
		oerrno = errno;
400
		PRIV_END;
409
		PRIV_END;
401
		if (r < 0) {
410
		if (r < 0) {
402
			error("bindresvport_sa %s: %s", ntop,
411
			error("bindresvport_sa %s: %s", ntop, strerror(oerrno));
403
			    strerror(oerrno));
404
			goto fail;
412
			goto fail;
405
		}
413
		}
406
	} else if (bind(sock, (struct sockaddr *)&bindaddr, bindaddrlen) != 0) {
414
	} else if (bind(sock, (struct sockaddr *)&bindaddr, bindaddrlen) != 0) {
Lines 418-423 fail: Link Here
418
		freeaddrinfo(res);
426
		freeaddrinfo(res);
419
	if (ifaddrs != NULL)
427
	if (ifaddrs != NULL)
420
		freeifaddrs(ifaddrs);
428
		freeifaddrs(ifaddrs);
429
	errno = fail_errno;
421
	return sock;
430
	return sock;
422
}
431
}
423
432
Lines 541-552 ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop, Link Here
541
				host, ntop, strport);
550
				host, ntop, strport);
542
551
543
			/* Create a socket for connecting. */
552
			/* Create a socket for connecting. */
544
			sock = ssh_create_socket(needpriv, ai);
553
			if ((sock = ssh_create_socket(needpriv, ai)) < 0)
545
			if (sock < 0) {
546
				/* Any error is already output */
547
				errno = 0;
548
				continue;
554
				continue;
549
			}
550
555
551
			if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
556
			if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
552
			    timeout_ms) >= 0) {
557
			    timeout_ms) >= 0) {

Return to bug 1685