Module Name:    src
Committed By:   ws
Date:           Fri Dec  1 12:07:20 UTC 2023

Modified Files:
        src/crypto/external/bsd/openssh/dist: readconf.c readconf.h scp.1
            sftp.1 ssh.1 ssh_config.5 sshconnect.c

Log Message:
Add option IPv6PreferTemporary to allow selection of
temporary vs. static IPv6 addresses on a host by host basis.


To generate a diff of this commit:
cvs rdiff -u -r1.42 -r1.43 src/crypto/external/bsd/openssh/dist/readconf.c
cvs rdiff -u -r1.32 -r1.33 src/crypto/external/bsd/openssh/dist/readconf.h
cvs rdiff -u -r1.30 -r1.31 src/crypto/external/bsd/openssh/dist/scp.1
cvs rdiff -u -r1.29 -r1.30 src/crypto/external/bsd/openssh/dist/sftp.1
cvs rdiff -u -r1.37 -r1.38 src/crypto/external/bsd/openssh/dist/ssh.1
cvs rdiff -u -r1.38 -r1.39 src/crypto/external/bsd/openssh/dist/ssh_config.5
cvs rdiff -u -r1.35 -r1.36 src/crypto/external/bsd/openssh/dist/sshconnect.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/external/bsd/openssh/dist/readconf.c
diff -u src/crypto/external/bsd/openssh/dist/readconf.c:1.42 src/crypto/external/bsd/openssh/dist/readconf.c:1.43
--- src/crypto/external/bsd/openssh/dist/readconf.c:1.42	Wed Oct 25 20:19:57 2023
+++ src/crypto/external/bsd/openssh/dist/readconf.c	Fri Dec  1 12:07:19 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: readconf.c,v 1.42 2023/10/25 20:19:57 christos Exp $	*/
+/*	$NetBSD: readconf.c,v 1.43 2023/12/01 12:07:19 ws Exp $	*/
 /* $OpenBSD: readconf.c,v 1.381 2023/08/28 03:31:16 djm Exp $ */
 
 /*
@@ -15,7 +15,7 @@
  */
 
 #include "includes.h"
-__RCSID("$NetBSD: readconf.c,v 1.42 2023/10/25 20:19:57 christos Exp $");
+__RCSID("$NetBSD: readconf.c,v 1.43 2023/12/01 12:07:19 ws Exp $");
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
@@ -160,6 +160,7 @@ typedef enum {
 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
 	oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
+	oIPv6PreferTemporary,
 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
@@ -303,6 +304,7 @@ static struct {
 	{ "casignaturealgorithms", oCASignatureAlgorithms },
 	{ "bindaddress", oBindAddress },
 	{ "bindinterface", oBindInterface },
+	{ "ipv6prefertemporary", oIPv6PreferTemporary },
 	{ "clearallforwardings", oClearAllForwardings },
 	{ "enablesshkeysign", oEnableSSHKeysign },
 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
@@ -1474,6 +1476,10 @@ parse_char_array:
 		charptr = &options->bind_interface;
 		goto parse_string;
 
+	case oIPv6PreferTemporary:
+		intptr = &options->ipv6_prefer_temporary;
+		goto parse_flag;
+
 	case oPKCS11Provider:
 		charptr = &options->pkcs11_provider;
 		goto parse_string;
@@ -2615,6 +2621,7 @@ initialize_options(Options * options)
 	options->preferred_authentications = NULL;
 	options->bind_address = NULL;
 	options->bind_interface = NULL;
+	options->ipv6_prefer_temporary = -1;
 	options->pkcs11_provider = NULL;
 	options->sk_provider = NULL;
 	options->enable_ssh_keysign = - 1;

Index: src/crypto/external/bsd/openssh/dist/readconf.h
diff -u src/crypto/external/bsd/openssh/dist/readconf.h:1.32 src/crypto/external/bsd/openssh/dist/readconf.h:1.33
--- src/crypto/external/bsd/openssh/dist/readconf.h:1.32	Wed Oct 25 20:19:57 2023
+++ src/crypto/external/bsd/openssh/dist/readconf.h	Fri Dec  1 12:07:19 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: readconf.h,v 1.32 2023/10/25 20:19:57 christos Exp $	*/
+/*	$NetBSD: readconf.h,v 1.33 2023/12/01 12:07:19 ws Exp $	*/
 /* $OpenBSD: readconf.h,v 1.152 2023/08/28 03:31:16 djm Exp $ */
 
 /*
@@ -99,6 +99,7 @@ typedef struct {
 	char   *preferred_authentications;
 	char   *bind_address;	/* local socket address for connection to sshd */
 	char   *bind_interface;	/* local interface for bind address */
+	int	ipv6_prefer_temporary; /* Prefer temporary IPv6 address */
 	char   *pkcs11_provider; /* PKCS#11 provider */
 	char   *sk_provider; /* Security key provider */
 	int	verify_host_key_dns;	/* Verify host key using DNS */

Index: src/crypto/external/bsd/openssh/dist/scp.1
diff -u src/crypto/external/bsd/openssh/dist/scp.1:1.30 src/crypto/external/bsd/openssh/dist/scp.1:1.31
--- src/crypto/external/bsd/openssh/dist/scp.1:1.30	Fri Jul 28 05:06:44 2023
+++ src/crypto/external/bsd/openssh/dist/scp.1	Fri Dec  1 12:07:19 2023
@@ -1,4 +1,4 @@
-.\"	$NetBSD: scp.1,v 1.30 2023/07/28 05:06:44 rin Exp $
+.\"	$NetBSD: scp.1,v 1.31 2023/12/01 12:07:19 ws Exp $
 .\"
 .\" scp.1
 .\"
@@ -196,6 +196,7 @@ For full details of the options listed b
 .It IdentityAgent
 .It IdentityFile
 .It IPQoS
+.It IPv6PreferTemporary
 .It KbdInteractiveAuthentication
 .It KbdInteractiveDevices
 .It KexAlgorithms

Index: src/crypto/external/bsd/openssh/dist/sftp.1
diff -u src/crypto/external/bsd/openssh/dist/sftp.1:1.29 src/crypto/external/bsd/openssh/dist/sftp.1:1.30
--- src/crypto/external/bsd/openssh/dist/sftp.1:1.29	Fri Jul 28 04:49:38 2023
+++ src/crypto/external/bsd/openssh/dist/sftp.1	Fri Dec  1 12:07:19 2023
@@ -1,4 +1,4 @@
-.\"	$NetBSD: sftp.1,v 1.29 2023/07/28 04:49:38 rin Exp $
+.\"	$NetBSD: sftp.1,v 1.30 2023/12/01 12:07:19 ws Exp $
 .\" $OpenBSD: sftp.1,v 1.143 2022/12/16 03:40:03 djm Exp $
 .\"
 .\" Copyright (c) 2001 Damien Miller.  All rights reserved.
@@ -258,6 +258,7 @@ For full details of the options listed b
 .It IdentityAgent
 .It IdentityFile
 .It IPQoS
+.It IPv6PreferTemporary
 .It KbdInteractiveAuthentication
 .It KbdInteractiveDevices
 .It KexAlgorithms

Index: src/crypto/external/bsd/openssh/dist/ssh.1
diff -u src/crypto/external/bsd/openssh/dist/ssh.1:1.37 src/crypto/external/bsd/openssh/dist/ssh.1:1.38
--- src/crypto/external/bsd/openssh/dist/ssh.1:1.37	Wed Oct 25 20:19:57 2023
+++ src/crypto/external/bsd/openssh/dist/ssh.1	Fri Dec  1 12:07:19 2023
@@ -1,4 +1,4 @@
-.\"	$NetBSD: ssh.1,v 1.37 2023/10/25 20:19:57 christos Exp $
+.\"	$NetBSD: ssh.1,v 1.38 2023/12/01 12:07:19 ws Exp $
 .\"
 .\" Author: Tatu Ylonen <y...@cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <y...@cs.hut.fi>, Espoo, Finland
@@ -548,6 +548,7 @@ For full details of the options listed b
 .It IdentityAgent
 .It IdentityFile
 .It IPQoS
+.It IPv6PreferTemporary
 .It KbdInteractiveAuthentication
 .It KbdInteractiveDevices
 .It KexAlgorithms

Index: src/crypto/external/bsd/openssh/dist/ssh_config.5
diff -u src/crypto/external/bsd/openssh/dist/ssh_config.5:1.38 src/crypto/external/bsd/openssh/dist/ssh_config.5:1.39
--- src/crypto/external/bsd/openssh/dist/ssh_config.5:1.38	Wed Oct 25 20:19:57 2023
+++ src/crypto/external/bsd/openssh/dist/ssh_config.5	Fri Dec  1 12:07:19 2023
@@ -1,4 +1,4 @@
-.\"	$NetBSD: ssh_config.5,v 1.38 2023/10/25 20:19:57 christos Exp $
+.\"	$NetBSD: ssh_config.5,v 1.39 2023/12/01 12:07:19 ws Exp $
 .\"
 .\" Author: Tatu Ylonen <y...@cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <y...@cs.hut.fi>, Espoo, Finland
@@ -1162,6 +1162,17 @@ for interactive sessions and
 .Cm cs1
 (Lower Effort)
 for non-interactive sessions.
+.It Cm IPv6PreferTemporary
+In the absence of an explicitly specified
+.Cm BindAddress ,
+this defines whether to prefer temporary addresses as source address.
+The argument to this can by either
+.Cm yes ,
+meaning to prefer any temporary address, or
+.Cm no ,
+resulting in the use of a permanent address, if available.
+If this option isn't specified,
+the address selection depends on the OS configuration.
 .It Cm KbdInteractiveAuthentication
 Specifies whether to use keyboard-interactive authentication.
 The argument to this keyword must be

Index: src/crypto/external/bsd/openssh/dist/sshconnect.c
diff -u src/crypto/external/bsd/openssh/dist/sshconnect.c:1.35 src/crypto/external/bsd/openssh/dist/sshconnect.c:1.36
--- src/crypto/external/bsd/openssh/dist/sshconnect.c:1.35	Fri Jul 28 05:02:46 2023
+++ src/crypto/external/bsd/openssh/dist/sshconnect.c	Fri Dec  1 12:07:19 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: sshconnect.c,v 1.35 2023/07/28 05:02:46 rin Exp $	*/
+/*	$NetBSD: sshconnect.c,v 1.36 2023/12/01 12:07:19 ws Exp $	*/
 /* $OpenBSD: sshconnect.c,v 1.363 2023/03/10 07:17:08 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <y...@cs.hut.fi>
@@ -15,7 +15,7 @@
  */
 
 #include "includes.h"
-__RCSID("$NetBSD: sshconnect.c,v 1.35 2023/07/28 05:02:46 rin Exp $");
+__RCSID("$NetBSD: sshconnect.c,v 1.36 2023/12/01 12:07:19 ws Exp $");
 
 #include <sys/param.h>	/* roundup */
 #include <sys/types.h>
@@ -27,6 +27,8 @@ __RCSID("$NetBSD: sshconnect.c,v 1.35 20
 
 #include <net/if.h>
 #include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet6/ip6_var.h>
 #include <rpc/rpc.h>
 
 #include <ctype.h>
@@ -312,29 +314,30 @@ ssh_set_socket_recvbuf(int sock)
  */
 static int
 check_ifaddrs(const char *ifname, int af, const struct ifaddrs *ifaddrs,
-    struct sockaddr_storage *resultp, socklen_t *rlenp)
+    int prefertemp, struct sockaddr_storage *resultp, socklen_t *rlenp)
 {
 	struct sockaddr_in6 *sa6;
 	struct sockaddr_in *sa;
 	struct in6_addr *v6addr;
 	const struct ifaddrs *ifa;
-	int allow_local;
+	int try;
 
 	/*
+	 * Prefer temporary addresses according to prefertemp.
 	 * Prefer addresses that are not loopback or linklocal, but use them
 	 * if nothing else matches.
 	 */
-	for (allow_local = 0; allow_local < 2; allow_local++) {
+	for (try = 0; try < 3; try++) {
 		for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
 			if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL ||
 			    (ifa->ifa_flags & IFF_UP) == 0 ||
 			    ifa->ifa_addr->sa_family != af ||
-			    strcmp(ifa->ifa_name, options.bind_interface) != 0)
+			    strcmp(ifa->ifa_name, ifname) != 0)
 				continue;
 			switch (ifa->ifa_addr->sa_family) {
 			case AF_INET:
 				sa = (struct sockaddr_in *)ifa->ifa_addr;
-				if (!allow_local && sa->sin_addr.s_addr ==
+				if (try < 2 && sa->sin_addr.s_addr ==
 				    htonl(INADDR_LOOPBACK))
 					continue;
 				if (*rlenp < sizeof(struct sockaddr_in)) {
@@ -347,7 +350,7 @@ check_ifaddrs(const char *ifname, int af
 			case AF_INET6:
 				sa6 = (struct sockaddr_in6 *)ifa->ifa_addr;
 				v6addr = &sa6->sin6_addr;
-				if (!allow_local &&
+				if (try < 2 &&
 				    (IN6_IS_ADDR_LINKLOCAL(v6addr) ||
 				    IN6_IS_ADDR_LOOPBACK(v6addr)))
 					continue;
@@ -355,6 +358,26 @@ check_ifaddrs(const char *ifname, int af
 					error_f("v6 addr doesn't fit");
 					return -1;
 				}
+
+				/*
+				 * For now, ignore scope and
+				 * don't allow deprecated addresses.  XXX
+				 */
+				if (ifa->ifa_addrflags & IN6_IFF_ANYCAST)
+					continue;
+				if (ifa->ifa_addrflags & IN6_IFF_NOTREADY)
+					continue;
+				if (ifa->ifa_addrflags & IN6_IFF_DETACHED)
+					continue;
+				if (ifa->ifa_addrflags & IN6_IFF_DEPRECATED)
+					continue;
+
+				if (prefertemp >= 0 && try < 1) {
+					int istemp = ifa->ifa_addrflags
+						& IN6_IFF_TEMPORARY;
+					if (!!istemp != prefertemp)
+						continue;
+				}
 				*rlenp = sizeof(struct sockaddr_in6);
 				memcpy(resultp, sa6, *rlenp);
 				return 0;
@@ -392,9 +415,6 @@ ssh_create_socket(struct addrinfo *ai)
 		set_sock_tos(sock, options.ip_qos_interactive);
 
 	/* Bind the socket to an alternative local IP address */
-	if (options.bind_address == NULL && options.bind_interface == NULL)
-		return sock;
-
 	if (options.bind_address != NULL) {
 		memset(&hints, 0, sizeof(hints));
 		hints.ai_family = ai->ai_family;
@@ -421,12 +441,27 @@ ssh_create_socket(struct addrinfo *ai)
 		}
 		bindaddrlen = sizeof(bindaddr);
 		if (check_ifaddrs(options.bind_interface, ai->ai_family,
-		    ifaddrs, &bindaddr, &bindaddrlen) != 0) {
+		    ifaddrs, options.ipv6_prefer_temporary,
+		    &bindaddr, &bindaddrlen) != 0) {
 			logit("getifaddrs: %s: no suitable addresses",
 			    options.bind_interface);
 			goto fail;
 		}
+	} else {
+		/* Apply user specified temporary address preference */
+		if (ai->ai_family == AF_INET6
+		    && options.ipv6_prefer_temporary >= 0) {
+			int temp = options.ipv6_prefer_temporary
+				? IP6PO_TEMPADDR_PREFER
+				: IP6PO_TEMPADDR_NOTPREFER;
+			if (setsockopt(sock, IPPROTO_IPV6, IPV6_PREFER_TEMPADDR,
+			    &temp, sizeof temp) < 0)
+				error("setsockopt(IPV6_PREFER_TEMPADDR: %.100s",
+				    strerror(errno));
+		}
+		return sock;
 	}
+
 	if ((r = getnameinfo((struct sockaddr *)&bindaddr, bindaddrlen,
 	    ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST)) != 0) {
 		error_f("getnameinfo failed: %s", ssh_gai_strerror(r));

Reply via email to