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

Collapse All | Expand All

(-)a/configure.ac (+13 lines)
Lines 493-498 SPP_MSG="no" Link Here
493
# the --with-solaris-privs option and --with-sandbox=solaris).
493
# the --with-solaris-privs option and --with-sandbox=solaris).
494
SOLARIS_PRIVS="no"
494
SOLARIS_PRIVS="no"
495
495
496
# Support for IPv6 source address preference selection
497
IPV6_SRC_ADDR_PREF_MSG="no"
498
496
# Check for some target-specific stuff
499
# Check for some target-specific stuff
497
case "$host" in
500
case "$host" in
498
*-*-aix*)
501
*-*-aix*)
Lines 784-789 main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) Link Here
784
			[Define if cmsg_type is not passed correctly])
787
			[Define if cmsg_type is not passed correctly])
785
		;;
788
		;;
786
	esac
789
	esac
790
	# linux specific IPv6 sock options
791
	AC_CHECK_HEADERS([linux/in6.h])
792
	if test "x$ac_cv_header_linux_in6_h" = "xyes" ; then
793
		AC_DEFINE([HAS_IPV6_SRC_PREF], [1],
794
		    [System has IPv6 source address preference flags])
795
		AC_DEFINE([LINUX_IPV6_PREF_FLAGS], [1],
796
		    [Use Linux specific IPv6 options])
797
		IPV6_SRC_ADDR_PREF_MSG="yes (Linux)"
798
	fi
787
	# tun(4) forwarding compat code
799
	# tun(4) forwarding compat code
788
	AC_CHECK_HEADERS([linux/if_tun.h])
800
	AC_CHECK_HEADERS([linux/if_tun.h])
789
	if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then
801
	if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then
Lines 5099-5104 echo " Solaris project support: $SP_MSG" Link Here
5099
echo "         Solaris privilege support: $SPP_MSG"
5111
echo "         Solaris privilege support: $SPP_MSG"
5100
echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
5112
echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
5101
echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
5113
echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
5114
echo "IPv6 src addr preference selection: $IPV6_SRC_ADDR_PREF_MSG"
5102
echo "                  BSD Auth support: $BSD_AUTH_MSG"
5115
echo "                  BSD Auth support: $BSD_AUTH_MSG"
5103
echo "              Random number source: $RAND_MSG"
5116
echo "              Random number source: $RAND_MSG"
5104
echo "             Privsep sandbox style: $SANDBOX_STYLE"
5117
echo "             Privsep sandbox style: $SANDBOX_STYLE"
(-)a/ssh_config.5 (+16 lines)
Lines 284-289 Note that this option does not work if Link Here
284
.Cm UsePrivilegedPort
284
.Cm UsePrivilegedPort
285
is set to
285
is set to
286
.Dq yes .
286
.Dq yes .
287
.Pp
288
Additionally, this option may be used to control the selection of IPv6
289
binding addresses on platforms that support it.
290
A
291
.Cm BindAddress
292
of
293
.Dq %public
294
or
295
.Dq %pub
296
will cause
297
.Xr ssh 1
298
to use a stable public IPv6 address, while
299
.Dq %temp
300
or
301
.Dq %tmp
302
will prefer a randomised temporary address.
287
.It Cm CanonicalDomains
303
.It Cm CanonicalDomains
288
When
304
When
289
.Cm CanonicalizeHostname
305
.Cm CanonicalizeHostname
(-)a/sshconnect.c (-6 / +78 lines)
Lines 66-71 Link Here
66
#include "ssherr.h"
66
#include "ssherr.h"
67
#include "authfd.h"
67
#include "authfd.h"
68
68
69
#ifdef LINUX_IPV6_PREF_FLAGS
70
#  include <linux/in6.h>
71
#endif
72
69
char *client_version_string = NULL;
73
char *client_version_string = NULL;
70
char *server_version_string = NULL;
74
char *server_version_string = NULL;
71
Key *previous_host_key = NULL;
75
Key *previous_host_key = NULL;
Lines 267-272 ssh_kill_proxy_command(void) Link Here
267
		kill(proxy_command_pid, SIGHUP);
271
		kill(proxy_command_pid, SIGHUP);
268
}
272
}
269
273
274
#ifdef HAS_IPV6_SRC_PREF
275
enum ssh_bindpref {BINDPREF_PUB, BINDPREF_TMP};
276
277
static int
278
ssh_mod_ipv6bindpref(int fd, enum ssh_bindpref pref)
279
{
280
#  ifdef LINUX_IPV6_PREF_FLAGS
281
	int val;
282
	int err;
283
	socklen_t len = sizeof(val);
284
	int add = 0;
285
	switch (pref) {
286
	case BINDPREF_PUB:
287
		add = IPV6_PREFER_SRC_PUBLIC;
288
		break;
289
	case BINDPREF_TMP:
290
		add = IPV6_PREFER_SRC_TMP;
291
		break;
292
	default:
293
		error("Unknown ssh_bindpref value");
294
		return -1;
295
	}
296
	err = getsockopt(fd, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, &val, &len);
297
	if (err < 0) {
298
		error("getsockopt IPV6_ADDR_PREFERENCES: %.100s",
299
		      strerror(errno));
300
		return err;
301
	}
302
303
	val &= ~(IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP|
304
	         IPV6_PREFER_SRC_PUBTMP_DEFAULT);
305
	val |= add;
306
	err = setsockopt(fd, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, &val, len);
307
	if (err < 0) {
308
		error("setsockopt IPV6_ADDR_PREFERENCES: %.100s",
309
		      strerror(errno));
310
	}
311
	return err;
312
#  else
313
	error("Setting IPv6 address source address not supported");
314
	return -1;
315
#  endif
316
}
317
#endif
318
270
/*
319
/*
271
 * Creates a (possibly privileged) socket for use as the ssh connection.
320
 * Creates a (possibly privileged) socket for use as the ssh connection.
272
 */
321
 */
Lines 275-280 ssh_create_socket(int privileged, struct addrinfo *ai) Link Here
275
{
324
{
276
	int sock, r, gaierr;
325
	int sock, r, gaierr;
277
	struct addrinfo hints, *res = NULL;
326
	struct addrinfo hints, *res = NULL;
327
	char *bind_address = options.bind_address;
278
328
279
	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
329
	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
280
	if (sock < 0) {
330
	if (sock < 0) {
Lines 283-301 ssh_create_socket(int privileged, struct addrinfo *ai) Link Here
283
	}
333
	}
284
	fcntl(sock, F_SETFD, FD_CLOEXEC);
334
	fcntl(sock, F_SETFD, FD_CLOEXEC);
285
335
336
	/* Set IPV6_ADDR_PREFERENCES through magic bind address */
337
	if (bind_address && bind_address[0] == '%') {
338
#if defined(HAS_IPV6_SRC_PREF)
339
		if (ai->ai_family != AF_INET6) {
340
			debug("Not setting address preference on"
341
			      " non-IPv6 socket");
342
		} else if (strcmp(bind_address, "%pub") == 0 ||
343
			   strcmp(bind_address, "%public") == 0) {
344
			debug("Setting preference for public IPv6 address");
345
			ssh_mod_ipv6bindpref(sock, BINDPREF_PUB);
346
		} else if (strcmp(bind_address, "%tmp") == 0 ||
347
			   strcmp(bind_address, "%temp") == 0) {
348
			debug("Setting preference for temporary IPv6 address");
349
			ssh_mod_ipv6bindpref(sock, BINDPREF_TMP);
350
		} else {
351
			error("Unknown bind address preference: '%s'",
352
			      bind_address);
353
		}
354
#else
355
		error("IPv6 address preference selection not supported");
356
#endif
357
		bind_address = NULL;
358
	}
286
	/* Bind the socket to an alternative local IP address */
359
	/* Bind the socket to an alternative local IP address */
287
	if (options.bind_address == NULL && !privileged)
360
	if (bind_address == NULL && !privileged)
288
		return sock;
361
		return sock;
289
362
290
	if (options.bind_address) {
363
	if (bind_address) {
291
		memset(&hints, 0, sizeof(hints));
364
		memset(&hints, 0, sizeof(hints));
292
		hints.ai_family = ai->ai_family;
365
		hints.ai_family = ai->ai_family;
293
		hints.ai_socktype = ai->ai_socktype;
366
		hints.ai_socktype = ai->ai_socktype;
294
		hints.ai_protocol = ai->ai_protocol;
367
		hints.ai_protocol = ai->ai_protocol;
295
		hints.ai_flags = AI_PASSIVE;
368
		hints.ai_flags = AI_PASSIVE;
296
		gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res);
369
		gaierr = getaddrinfo(bind_address, NULL, &hints, &res);
297
		if (gaierr) {
370
		if (gaierr) {
298
			error("getaddrinfo: %s: %s", options.bind_address,
371
			error("getaddrinfo: %s: %s", bind_address,
299
			    ssh_gai_strerror(gaierr));
372
			    ssh_gai_strerror(gaierr));
300
			close(sock);
373
			close(sock);
301
			return -1;
374
			return -1;
Lines 316-322 ssh_create_socket(int privileged, struct addrinfo *ai) Link Here
316
		}
389
		}
317
	} else {
390
	} else {
318
		if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
391
		if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
319
			error("bind: %s: %s", options.bind_address,
392
			error("bind: %s: %s", bind_address,
320
			    strerror(errno));
393
			    strerror(errno));
321
 fail:
394
 fail:
322
			close(sock);
395
			close(sock);
323
- 

Return to bug 2606