diff options
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/iked/config.c | 4 | ||||
-rw-r--r-- | sbin/iked/iked.h | 4 | ||||
-rw-r--r-- | sbin/iked/ikev2.c | 63 | ||||
-rw-r--r-- | sbin/iked/parse.y | 11 |
4 files changed, 77 insertions, 5 deletions
diff --git a/sbin/iked/config.c b/sbin/iked/config.c index ecf03e64cd3..a77e5320381 100644 --- a/sbin/iked/config.c +++ b/sbin/iked/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.73 2020/11/25 22:17:13 tobhe Exp $ */ +/* $OpenBSD: config.c,v 1.74 2020/11/29 21:00:43 tobhe Exp $ */ /* * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> @@ -880,6 +880,8 @@ config_getstatic(struct iked *env, struct imsg *imsg) log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no "); log_debug("%s: %smobike", __func__, env->sc_mobike ? "" : "no "); log_debug("%s: nattport %u", __func__, env->sc_nattport); + log_debug("%s: %sstickyaddress", __func__, + env->sc_stickyaddress ? "" : "no "); return (0); } diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h index 416fc507ab5..f50df6e64e0 100644 --- a/sbin/iked/iked.h +++ b/sbin/iked/iked.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iked.h,v 1.175 2020/11/26 22:24:06 tobhe Exp $ */ +/* $OpenBSD: iked.h,v 1.176 2020/11/29 21:00:43 tobhe Exp $ */ /* * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> @@ -716,6 +716,7 @@ struct iked_static { uint8_t st_frag; /* fragmentation */ uint8_t st_mobike; /* MOBIKE */ in_port_t st_nattport; + int st_stickyaddress; /* addr per DSTID */ }; struct iked { @@ -733,6 +734,7 @@ struct iked { #define sc_frag sc_static.st_frag #define sc_mobike sc_static.st_mobike #define sc_nattport sc_static.st_nattport +#define sc_stickyaddress sc_static.st_stickyaddress struct iked_policies sc_policies; struct iked_policy *sc_defaultcon; diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c index 59f234d699d..e61a84eb44a 100644 --- a/sbin/iked/ikev2.c +++ b/sbin/iked/ikev2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ikev2.c,v 1.289 2020/11/28 20:26:50 tobhe Exp $ */ +/* $OpenBSD: ikev2.c,v 1.290 2020/11/29 21:00:43 tobhe Exp $ */ /* * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> @@ -6602,6 +6602,7 @@ ikev2_cp_setaddr_pool(struct iked *env, struct iked_sa *sa, struct sockaddr_in *in4 = NULL, *cfg4 = NULL; struct sockaddr_in6 *in6 = NULL, *cfg6 = NULL; struct iked_sa key; + struct iked_sa *osa; char idstr[IKED_ID_SIZE]; struct iked_addr addr; uint32_t mask, host, lower, upper, start, nhost; @@ -6620,6 +6621,66 @@ ikev2_cp_setaddr_pool(struct iked *env, struct iked_sa *sa, bzero(&addr, sizeof(addr)); addr.addr_af = family; + /* check if old IKESA for same DSTID already exists and transfer IPs */ + if (env->sc_stickyaddress && + (osa = sa_dstid_lookup(env, sa)) != NULL && + ((family == AF_INET && osa->sa_addrpool) || + (family == AF_INET6 && osa->sa_addrpool6))) { + /* we have to transfer both, even if we just need one */ + if (osa->sa_addrpool) { + if (RB_REMOVE(iked_addrpool, &env->sc_addrpool, osa) + != osa) { + log_info("%s: addrpool error", + SPI_SA(osa, __func__)); + return (-1); + } + } + if (osa->sa_addrpool6) { + if (RB_REMOVE(iked_addrpool6, &env->sc_addrpool6, osa) + != osa) { + log_info("%s: addrpool6 error", + SPI_SA(osa, __func__)); + return (-1); + } + } + sa_dstid_remove(env, osa); + sa->sa_addrpool = osa->sa_addrpool; + osa->sa_addrpool = NULL; + sa->sa_addrpool6 = osa->sa_addrpool6; + osa->sa_addrpool6 = NULL; + if (osa->sa_state < IKEV2_STATE_CLOSING) { + if (osa->sa_state == IKEV2_STATE_ESTABLISHED) + ikev2_disable_timer(env, osa); + ikev2_ike_sa_setreason(osa, + "address re-use (identical dstid)"); + ikev2_ikesa_delete(env, osa, 1); + timer_add(env, &osa->sa_timer, + 3 * IKED_RETRANSMIT_TIMEOUT); + } + if (sa->sa_addrpool) { + RB_INSERT(iked_addrpool, &env->sc_addrpool, sa); + log_info( + "%s: giving up assigned address %s to IKESA %s", + SPI_SA(osa, __func__), + print_host((struct sockaddr *) + &sa->sa_addrpool->addr, NULL, 0), + print_spi(sa->sa_hdr.sh_ispi, 8)); + } + if (sa->sa_addrpool6) { + RB_INSERT(iked_addrpool6, &env->sc_addrpool6, sa); + log_info( + "%s: giving up assigned v6 address %s to IKESA %s", + SPI_SA(osa, __func__), + print_host((struct sockaddr *) + &sa->sa_addrpool6->addr, NULL, 0), + print_spi(sa->sa_hdr.sh_ispi, 8)); + } + if (family == AF_INET && sa->sa_addrpool != NULL) + memcpy(&addr, sa->sa_addrpool, sizeof(addr)); + else if (family == AF_INET6 && sa->sa_addrpool6 != NULL) + memcpy(&addr, sa->sa_addrpool6, sizeof(addr)); + goto done; + } switch (addr.addr_af) { case AF_INET: cfg4 = (struct sockaddr_in *)&ikecfg->cfg.address.addr; diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y index 037894e85d7..e5d645d4c11 100644 --- a/sbin/iked/parse.y +++ b/sbin/iked/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.117 2020/11/03 16:45:40 tobhe Exp $ */ +/* $OpenBSD: parse.y,v 1.118 2020/11/29 21:00:44 tobhe Exp $ */ /* * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> @@ -100,6 +100,7 @@ static int passive = 0; static int decouple = 0; static int mobike = 1; static int enforcesingleikesa = 0; +static int stickyaddress = 0; static int fragmentation = 0; static int dpd_interval = IKED_IKE_SA_ALIVE_TIMEOUT; static char *ocsp_url = NULL; @@ -454,6 +455,7 @@ typedef struct { %token IPCOMP OCSP IKELIFETIME MOBIKE NOMOBIKE RDOMAIN %token FRAGMENTATION NOFRAGMENTATION DPD_CHECK_INTERVAL %token ENFORCESINGLEIKESA NOENFORCESINGLEIKESA +%token STICKYADDRESS NOSTICKYADDRESS %token TOLERATE MAXAGE DYNAMIC %token CERTPARTIALCHAIN %token REQUEST @@ -524,6 +526,8 @@ set : SET ACTIVE { passive = 0; } | SET NOMOBIKE { mobike = 0; } | SET ENFORCESINGLEIKESA { enforcesingleikesa = 1; } | SET NOENFORCESINGLEIKESA { enforcesingleikesa = 0; } + | SET STICKYADDRESS { stickyaddress = 1; } + | SET NOSTICKYADDRESS { stickyaddress = 0; } | SET OCSP STRING { if ((ocsp_url = strdup($3)) == NULL) { yyerror("cannot set ocsp_url"); @@ -1364,6 +1368,7 @@ lookup(char *s) { "noesn", NOESN }, { "nofragmentation", NOFRAGMENTATION }, { "nomobike", NOMOBIKE }, + { "nostickyaddress", NOSTICKYADDRESS }, { "ocsp", OCSP }, { "passive", PASSIVE }, { "peer", PEER }, @@ -1378,6 +1383,7 @@ lookup(char *s) { "set", SET }, { "skip", SKIP }, { "srcid", SRCID }, + { "stickyaddress", STICKYADDRESS }, { "tag", TAG }, { "tap", TAP }, { "tcpmd5", TCPMD5 }, @@ -1765,7 +1771,7 @@ parse_config(const char *filename, struct iked *x_env) free(ocsp_url); mobike = 1; - enforcesingleikesa = 0; + enforcesingleikesa = stickyaddress = 0; cert_partial_chain = decouple = passive = 0; ocsp_tolerate = 0; ocsp_url = NULL; @@ -1786,6 +1792,7 @@ parse_config(const char *filename, struct iked *x_env) env->sc_decoupled = decouple ? 1 : 0; env->sc_mobike = mobike; env->sc_enforcesingleikesa = enforcesingleikesa; + env->sc_stickyaddress = stickyaddress; env->sc_frag = fragmentation; env->sc_alive_timeout = dpd_interval; env->sc_ocsp_url = ocsp_url; |