diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2017-03-13 17:23:46 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2017-03-13 17:23:46 +0000 |
commit | b708eca497b93b252b8dd60765a7906a78957183 (patch) | |
tree | 812197adce8c773da400fdb851016c54fd644151 /sbin | |
parent | 36e22aedec6e78b82d6bc13caad5058af4f8090d (diff) |
Don't rekey acquired Child SAs
From and OK markus, OK reyk
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/iked/iked.h | 3 | ||||
-rw-r--r-- | sbin/iked/ikev2.c | 24 |
2 files changed, 19 insertions, 8 deletions
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h index 89625e612a2..92df7b01b26 100644 --- a/sbin/iked/iked.h +++ b/sbin/iked/iked.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iked.h,v 1.105 2017/03/13 15:06:51 patrick Exp $ */ +/* $OpenBSD: iked.h,v 1.106 2017/03/13 17:23:45 mikeb Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -173,6 +173,7 @@ struct iked_childsa { uint8_t csa_persistent;/* do not rekey */ uint8_t csa_esn; /* use ESN */ uint8_t csa_transport; /* transport mode */ + uint8_t csa_acquired; /* no rekey for me */ struct iked_spi csa_spi; diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c index cdfbd5c41e4..2b6ba82ef94 100644 --- a/sbin/iked/ikev2.c +++ b/sbin/iked/ikev2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ikev2.c,v 1.138 2017/03/13 15:06:51 patrick Exp $ */ +/* $OpenBSD: ikev2.c,v 1.139 2017/03/13 17:23:45 mikeb Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -104,7 +104,7 @@ int ikev2_set_sa_proposal(struct iked_sa *, struct iked_policy *, unsigned int); int ikev2_childsa_negotiate(struct iked *, struct iked_sa *, - struct iked_kex *, struct iked_proposals *, int, int); + struct iked_kex *, struct iked_proposals *, int, int, int); int ikev2_match_proposals(struct iked_proposal *, struct iked_proposal *, struct iked_transform **); int ikev2_valid_proposal(struct iked_proposal *, @@ -1141,7 +1141,7 @@ ikev2_init_done(struct iked *env, struct iked_sa *sa) return (0); /* ignored */ ret = ikev2_childsa_negotiate(env, sa, &sa->sa_kex, &sa->sa_proposals, - sa->sa_hdr.sh_initiator, 0); + sa->sa_hdr.sh_initiator, 0, 0); if (ret == 0) ret = ikev2_childsa_enable(env, sa); if (ret == 0) { @@ -2302,7 +2302,7 @@ ikev2_resp_ike_auth(struct iked *env, struct iked_sa *sa) return (-1); if (ikev2_childsa_negotiate(env, sa, &sa->sa_kex, &sa->sa_proposals, - sa->sa_hdr.sh_initiator, 0) < 0) + sa->sa_hdr.sh_initiator, 0, 0) < 0) return (-1); /* New encrypted message buffer */ @@ -2930,7 +2930,7 @@ ikev2_init_create_child_sa(struct iked *env, struct iked_message *msg) sa->sa_rnonce = ibuf_dup(msg->msg_nonce); if (ikev2_childsa_negotiate(env, sa, &sa->sa_kex, &sa->sa_proposals, 1, - pfs)) { + pfs, !csa)) { log_debug("%s: failed to get CHILD SAs", __func__); return (-1); } @@ -3251,7 +3251,8 @@ ikev2_resp_create_child_sa(struct iked *env, struct iked_message *msg) ibuf_release(kex->kex_rnonce); kex->kex_rnonce = nonce; - if (ikev2_childsa_negotiate(env, sa, kex, &proposals, 0, pfs)) { + if (ikev2_childsa_negotiate(env, sa, kex, &proposals, 0, + pfs, !rekeying)) { log_debug("%s: failed to get CHILD SAs", __func__); goto fail; } @@ -4336,7 +4337,7 @@ ikev2_sa_tag(struct iked_sa *sa, struct iked_id *id) int ikev2_childsa_negotiate(struct iked *env, struct iked_sa *sa, struct iked_kex *kex, struct iked_proposals *proposals, int initiator, - int pfs) + int pfs, int acquired) { struct iked_proposal *prop; struct iked_transform *xform, *encrxf = NULL, *integrxf = NULL; @@ -4492,6 +4493,7 @@ ikev2_childsa_negotiate(struct iked *env, struct iked_sa *sa, csa->csa_ikesa = sa; csa->csa_spi.spi_protoid = prop->prop_protoid; csa->csa_esn = esn; + csa->csa_acquired = acquired; /* Set up responder's SPIs */ if (initiator) { @@ -4980,6 +4982,8 @@ ikev2_rekey_sa(struct iked *env, struct iked_spi *rekey) if (csa->csa_rekey) /* See if it's already taken care of */ return (0); + if (csa->csa_acquired) /* Don't rekey, wait for hard expire */ + return (0); if (csa->csa_saproto == IKEV2_SAPROTO_IPCOMP) /* no rekey */ return (0); if ((sa = csa->csa_ikesa) == NULL) { @@ -5011,6 +5015,7 @@ ikev2_drop_sa(struct iked *env, struct iked_spi *drop) struct iked_sa *sa; struct ikev2_delete *del; uint32_t spi32; + int acquired; key.csa_spi = *drop; csa = RB_FIND(iked_activesas, &env->sc_activesas, &key); @@ -5043,6 +5048,7 @@ ikev2_drop_sa(struct iked *env, struct iked_spi *drop) spi32 = htobe32(csa->csa_spi.spi); else spi32 = htobe32(csa->csa_peerspi); + acquired = csa->csa_acquired; if (ikev2_childsa_delete(env, sa, csa->csa_saproto, csa->csa_peerspi, NULL, 0)) @@ -5067,6 +5073,10 @@ ikev2_drop_sa(struct iked *env, struct iked_spi *drop) sa->sa_stateflags |= IKED_REQ_INF; + /* Don't automatically re-initiate Child SAs that have been acquired */ + if (acquired) + goto done; + /* Initiate Child SA creation */ if (ikev2_send_create_child_sa(env, sa, NULL, drop->spi_protoid)) log_warnx("%s: failed to initiate a CREATE_CHILD_SA exchange", |