mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-26 07:15:36 +02:00
upstream: add a "match localnetwork" predicate.
This allows matching on the addresses of available network interfaces and may be used to vary the effective client configuration based on network location (e.g. to use a ProxyJump when not on a particular network). ok markus@ OpenBSD-Commit-ID: cffb6ff9a3803abfc52b5cad0aa190c5e424c139
This commit is contained in:
parent
beec17bb31
commit
3071d85a47
77
readconf.c
77
readconf.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: readconf.c,v 1.377 2023/06/21 05:10:26 djm Exp $ */
|
/* $OpenBSD: readconf.c,v 1.378 2023/07/17 04:04:36 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/in_systm.h>
|
#include <netinet/in_systm.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
@ -28,6 +29,9 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#ifdef HAVE_IFADDRS_H
|
||||||
|
# include <ifaddrs.h>
|
||||||
|
#endif
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#ifdef HAVE_PATHS_H
|
#ifdef HAVE_PATHS_H
|
||||||
@ -576,6 +580,60 @@ execute_in_shell(const char *cmd)
|
|||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether a local network interface address appears in CIDR pattern-
|
||||||
|
* list 'addrlist'. Returns 1 if matched or 0 otherwise.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
check_match_ifaddrs(const char *addrlist)
|
||||||
|
{
|
||||||
|
struct ifaddrs *ifa, *ifaddrs = NULL;
|
||||||
|
int r, found = 0;
|
||||||
|
char addr[NI_MAXHOST];
|
||||||
|
socklen_t salen;
|
||||||
|
|
||||||
|
if (getifaddrs(&ifaddrs) != 0) {
|
||||||
|
error("match localnetwork: getifaddrs failed: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
|
||||||
|
if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL ||
|
||||||
|
(ifa->ifa_flags & IFF_UP) == 0)
|
||||||
|
continue;
|
||||||
|
switch (ifa->ifa_addr->sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
salen = sizeof(struct sockaddr_in);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
salen = sizeof(struct sockaddr_in6);
|
||||||
|
break;
|
||||||
|
case AF_LINK:
|
||||||
|
/* ignore */
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
debug2_f("interface %s: unsupported address family %d",
|
||||||
|
ifa->ifa_name, ifa->ifa_addr->sa_family);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((r = getnameinfo(ifa->ifa_addr, salen, addr, sizeof(addr),
|
||||||
|
NULL, 0, NI_NUMERICHOST)) != 0) {
|
||||||
|
debug2_f("interface %s getnameinfo failed: %s",
|
||||||
|
ifa->ifa_name, gai_strerror(r));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
debug3_f("interface %s addr %s", ifa->ifa_name, addr);
|
||||||
|
if (addr_match_cidr_list(addr, addrlist) == 1) {
|
||||||
|
debug3_f("matched interface %s: address %s in %s",
|
||||||
|
ifa->ifa_name, addr, addrlist);
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
freeifaddrs(ifaddrs);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse and execute a Match directive.
|
* Parse and execute a Match directive.
|
||||||
*/
|
*/
|
||||||
@ -680,6 +738,15 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
|
|||||||
r = match_pattern_list(pw->pw_name, arg, 0) == 1;
|
r = match_pattern_list(pw->pw_name, arg, 0) == 1;
|
||||||
if (r == (negate ? 1 : 0))
|
if (r == (negate ? 1 : 0))
|
||||||
this_result = result = 0;
|
this_result = result = 0;
|
||||||
|
} else if (strcasecmp(attrib, "localnetwork") == 0) {
|
||||||
|
if (addr_match_cidr_list(NULL, arg) == -1) {
|
||||||
|
/* Error already printed */
|
||||||
|
result = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
r = check_match_ifaddrs(arg) == 1;
|
||||||
|
if (r == (negate ? 1 : 0))
|
||||||
|
this_result = result = 0;
|
||||||
} else if (strcasecmp(attrib, "exec") == 0) {
|
} else if (strcasecmp(attrib, "exec") == 0) {
|
||||||
char *conn_hash_hex, *keyalias;
|
char *conn_hash_hex, *keyalias;
|
||||||
|
|
||||||
@ -733,9 +800,11 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
|
|||||||
result = -1;
|
result = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
|
debug3("%.200s line %d: %smatched '%s%s%.100s%s' ",
|
||||||
filename, linenum, this_result ? "": "not ",
|
filename, linenum, this_result ? "": "not ", oattrib,
|
||||||
oattrib, criteria);
|
criteria == NULL ? "" : " \"",
|
||||||
|
criteria == NULL ? "" : criteria,
|
||||||
|
criteria == NULL ? "" : "\"");
|
||||||
free(criteria);
|
free(criteria);
|
||||||
}
|
}
|
||||||
if (attributes == 0) {
|
if (attributes == 0) {
|
||||||
|
16
ssh_config.5
16
ssh_config.5
@ -33,8 +33,8 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $OpenBSD: ssh_config.5,v 1.380 2023/03/27 03:56:11 dtucker Exp $
|
.\" $OpenBSD: ssh_config.5,v 1.381 2023/07/17 04:04:36 djm Exp $
|
||||||
.Dd $Mdocdate: March 27 2023 $
|
.Dd $Mdocdate: July 17 2023 $
|
||||||
.Dt SSH_CONFIG 5
|
.Dt SSH_CONFIG 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -141,6 +141,7 @@ The available criteria keywords are:
|
|||||||
.Cm canonical ,
|
.Cm canonical ,
|
||||||
.Cm final ,
|
.Cm final ,
|
||||||
.Cm exec ,
|
.Cm exec ,
|
||||||
|
.Cm localnetwork ,
|
||||||
.Cm host ,
|
.Cm host ,
|
||||||
.Cm originalhost ,
|
.Cm originalhost ,
|
||||||
.Cm user ,
|
.Cm user ,
|
||||||
@ -195,6 +196,17 @@ accept the tokens described in the
|
|||||||
.Sx TOKENS
|
.Sx TOKENS
|
||||||
section.
|
section.
|
||||||
.Pp
|
.Pp
|
||||||
|
The
|
||||||
|
.Cm localnetwork
|
||||||
|
keyword matches the addresses of active local network interfaces against the
|
||||||
|
supplied list of networks in CIDR format.
|
||||||
|
This may be convenient for varying the effective configuration on devices that
|
||||||
|
roam between networks.
|
||||||
|
Note that network address is not a trustworthy criteria in many
|
||||||
|
situations (e.g. when the network is automatically configured using DHCP)
|
||||||
|
and so caution should be applied if using it to control security-sensitive
|
||||||
|
configuration.
|
||||||
|
.Pp
|
||||||
The other keywords' criteria must be single entries or comma-separated
|
The other keywords' criteria must be single entries or comma-separated
|
||||||
lists and may use the wildcard and negation operators described in the
|
lists and may use the wildcard and negation operators described in the
|
||||||
.Sx PATTERNS
|
.Sx PATTERNS
|
||||||
|
Loading…
x
Reference in New Issue
Block a user