From 55c61d73c42cdfc7148f52f555b721b7592a078c Mon Sep 17 00:00:00 2001 From: dlg Date: Mon, 7 Aug 2023 03:35:06 +0000 Subject: [PATCH] add a struct sadb_x_iface message for interface SAs this allows userland to install (and see) security associations for route-based ipsec vpns. if this message is part of an SA, it causes the TDBF_IFACE flag and associated fields in a tdb to be set. the interface unit field in this message maps to minor number of the sec(4) interface you want to the SA to work with. ie, set the sadb_x_iface_unit field in struct sadb_x_iface to 1 to set up an SA for use with sec1. the sadb_x_iface_direction in the message uses IPSP_DIRECTION_IN and IPSP_DIRECTION_OUT to specify in which direction that SA is supposed to process traffic. support from many including markus@ tobhe@ claudio@ sthen@ patrick@ now is a good time deraadt@ --- sys/net/pfkeyv2.c | 15 ++++++++++++++- sys/net/pfkeyv2.h | 15 +++++++++++++-- sys/net/pfkeyv2_convert.c | 26 +++++++++++++++++++++++++- sys/net/pfkeyv2_parsemessage.c | 19 +++++++++++++------ 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index cdc5ce2b231..e750ae8bdbe 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.c,v 1.256 2023/04/22 20:51:56 mvs Exp $ */ +/* $OpenBSD: pfkeyv2.c,v 1.257 2023/08/07 03:35:06 dlg Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -868,6 +868,9 @@ pfkeyv2_get(struct tdb *tdb, void **headers, void **buffer, int *lenp, i += sizeof(struct sadb_x_tap); #endif + if (ISSET(tdb->tdb_flags, TDBF_IFACE)) + i += sizeof(struct sadb_x_iface); + if (lenp) *lenp = i; @@ -979,6 +982,12 @@ pfkeyv2_get(struct tdb *tdb, void **headers, void **buffer, int *lenp, } #endif + /* Export sec(4) interface information, if present */ + if (ISSET(tdb->tdb_flags, TDBF_IFACE)) { + headers[SADB_X_EXT_IFACE] = p; + export_iface(&p, tdb); + } + headers[SADB_X_EXT_COUNTER] = p; export_counter(&p, tdb); @@ -1360,6 +1369,7 @@ pfkeyv2_dosend(struct socket *so, void *message, int len) import_tag(newsa, headers[SADB_X_EXT_TAG]); import_tap(newsa, headers[SADB_X_EXT_TAP]); #endif + import_iface(newsa, headers[SADB_X_EXT_IFACE]); /* Exclude sensitive data from reply message. */ headers[SADB_EXT_KEY_AUTH] = NULL; @@ -1411,6 +1421,8 @@ pfkeyv2_dosend(struct socket *so, void *message, int len) import_tag(sa2, headers[SADB_X_EXT_TAG]); import_tap(sa2, headers[SADB_X_EXT_TAP]); #endif + import_iface(sa2, headers[SADB_X_EXT_IFACE]); + if (headers[SADB_EXT_ADDRESS_SRC] || headers[SADB_EXT_ADDRESS_PROXY]) { mtx_enter(&tdb_sadb_mtx); @@ -1535,6 +1547,7 @@ pfkeyv2_dosend(struct socket *so, void *message, int len) import_tag(newsa, headers[SADB_X_EXT_TAG]); import_tap(newsa, headers[SADB_X_EXT_TAP]); #endif + import_iface(newsa, headers[SADB_X_EXT_IFACE]); /* Exclude sensitive data from reply message. */ headers[SADB_EXT_KEY_AUTH] = NULL; diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index db0a7cd1433..64aa6454de9 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.h,v 1.93 2022/08/27 20:28:01 mvs Exp $ */ +/* $OpenBSD: pfkeyv2.h,v 1.94 2023/08/07 03:35:06 dlg Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) January 1998 * @@ -252,6 +252,14 @@ struct sadb_x_mtu { uint32_t sadb_x_mtu_mtu; }; +struct sadb_x_iface { + uint16_t sadb_x_iface_len; + uint16_t sadb_x_iface_exttype; + uint32_t sadb_x_iface_unit; + uint8_t sadb_x_iface_direction; + uint8_t sadb_x_iface_reserved[7]; +}; + #ifdef _KERNEL #define SADB_X_GETSPROTO(x) \ ( (x) == SADB_SATYPE_AH ? IPPROTO_AH :\ @@ -300,7 +308,8 @@ struct sadb_x_mtu { #define SADB_X_EXT_RDOMAIN 37 #define SADB_X_EXT_MTU 38 #define SADB_X_EXT_REPLAY 39 -#define SADB_EXT_MAX 39 +#define SADB_X_EXT_IFACE 40 +#define SADB_EXT_MAX 40 /* Fix pfkeyv2.c struct pfkeyv2_socket if SATYPE_MAX > 31 */ #define SADB_SATYPE_UNSPEC 0 @@ -438,6 +447,7 @@ void export_mtu(void **, struct tdb *); void export_tap(void **, struct tdb *); void export_satype(void **, struct tdb *); void export_counter(void **, struct tdb *); +void export_iface(void **, struct tdb *); void import_address(struct sockaddr *, struct sadb_address *); void import_identities(struct ipsec_ids **, int, struct sadb_ident *, @@ -452,6 +462,7 @@ void import_udpencap(struct tdb *, struct sadb_x_udpencap *); void import_tag(struct tdb *, struct sadb_x_tag *); void import_rdomain(struct tdb *, struct sadb_x_rdomain *); void import_tap(struct tdb *, struct sadb_x_tap *); +void import_iface(struct tdb *, struct sadb_x_iface *); extern const uint64_t sadb_exts_allowed_out[SADB_MAX+1]; extern const uint64_t sadb_exts_required_out[SADB_MAX+1]; diff --git a/sys/net/pfkeyv2_convert.c b/sys/net/pfkeyv2_convert.c index c342b50ac1a..68686055a11 100644 --- a/sys/net/pfkeyv2_convert.c +++ b/sys/net/pfkeyv2_convert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2_convert.c,v 1.79 2022/01/20 17:13:12 bluhm Exp $ */ +/* $OpenBSD: pfkeyv2_convert.c,v 1.80 2023/08/07 03:35:06 dlg Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@keromytis.org) * @@ -951,6 +951,30 @@ export_tap(void **p, struct tdb *tdb) } #endif +/* Import interface information for SA */ +void +import_iface(struct tdb *tdb, struct sadb_x_iface *siface) +{ + if (siface != NULL) { + SET(tdb->tdb_flags, TDBF_IFACE); + tdb->tdb_iface = siface->sadb_x_iface_unit; + tdb->tdb_iface_dir = siface->sadb_x_iface_direction; + } +} + +/* Export interface information for SA */ +void +export_iface(void **p, struct tdb *tdb) +{ + struct sadb_x_iface *siface = (struct sadb_x_iface *)*p; + + siface->sadb_x_iface_len = sizeof(*siface) / sizeof(uint64_t); + siface->sadb_x_iface_unit = tdb->tdb_iface; + siface->sadb_x_iface_direction = tdb->tdb_iface_dir; + + *p += sizeof(*siface); +} + void export_satype(void **p, struct tdb *tdb) { diff --git a/sys/net/pfkeyv2_parsemessage.c b/sys/net/pfkeyv2_parsemessage.c index 5345ccaf7c9..edb1cc76c3a 100644 --- a/sys/net/pfkeyv2_parsemessage.c +++ b/sys/net/pfkeyv2_parsemessage.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2_parsemessage.c,v 1.60 2021/07/14 22:39:26 tobhe Exp $ */ +/* $OpenBSD: pfkeyv2_parsemessage.c,v 1.61 2023/08/07 03:35:06 dlg Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -135,6 +135,7 @@ #define BITMAP_X_COUNTER (1LL << SADB_X_EXT_COUNTER) #define BITMAP_X_MTU (1LL << SADB_X_EXT_MTU) #define BITMAP_X_REPLAY (1LL << SADB_X_EXT_REPLAY) +#define BITMAP_X_IFACE (1LL << SADB_X_EXT_IFACE) uint64_t sadb_exts_allowed_in[SADB_MAX+1] = { @@ -143,9 +144,9 @@ uint64_t sadb_exts_allowed_in[SADB_MAX+1] = /* GETSPI */ BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE, /* UPDATE */ - BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN, + BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN | BITMAP_X_IFACE, /* ADD */ - BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN, + BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN | BITMAP_X_IFACE, /* DELETE */ BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_RDOMAIN, /* GET */ @@ -215,13 +216,13 @@ const uint64_t sadb_exts_allowed_out[SADB_MAX+1] = /* GETSPI */ BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, /* UPDATE */ - BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN, + BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN | BITMAP_X_IFACE, /* ADD */ - BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN, + BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN | BITMAP_X_IFACE, /* DELETE */ BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_RDOMAIN, /* GET */ - BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_FLOW_TYPE | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_COUNTER | BITMAP_X_RDOMAIN | BITMAP_X_MTU | BITMAP_X_REPLAY, + BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_FLOW_TYPE | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_COUNTER | BITMAP_X_RDOMAIN | BITMAP_X_MTU | BITMAP_X_REPLAY | BITMAP_X_IFACE, /* ACQUIRE */ BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL, /* REGISTER */ @@ -881,6 +882,12 @@ pfkeyv2_parsemessage(void *p, int len, void **headers) } break; #endif + case SADB_X_EXT_IFACE: + if (i != sizeof(struct sadb_x_iface)) { + DPRINTF("bad IFACE header length"); + return (EINVAL); + } + break; default: DPRINTF("unknown extension header type %d", sadb_ext->sadb_ext_type); -- 2.20.1