From 70728eb1b6005fe6e400e5df3534ed7087acc380 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 24 Mar 2015 18:36:49 +0100 Subject: [PATCH] child-sa: Add a new state to track rekeyed IKEv1 CHILD_SAs This is needed to handle DELETEs properly, which was previously done via CHILD_REKEYING, which we don't use anymore since 5c6a62ceb6 as it prevents reauthentication. --- src/libcharon/plugins/stroke/stroke_list.c | 3 ++- src/libcharon/plugins/vici/vici_query.c | 3 ++- src/libcharon/processing/jobs/rekey_ike_sa_job.c | 3 ++- src/libcharon/sa/child_sa.c | 1 + src/libcharon/sa/child_sa.h | 5 +++++ src/libcharon/sa/ikev1/tasks/quick_delete.c | 2 +- src/libcharon/sa/ikev1/tasks/quick_mode.c | 3 ++- 7 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index 8afd7dbd9..68b8232bc 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -323,7 +323,8 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) } } - else if (child_sa->get_state(child_sa) == CHILD_REKEYING) + else if (child_sa->get_state(child_sa) == CHILD_REKEYING || + child_sa->get_state(child_sa) == CHILD_REKEYED) { rekey = child_sa->get_lifetime(child_sa, TRUE); fprintf(out, ", expires in %V", &now, &rekey); diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c index 84fc23c6a..3e0d73cdf 100644 --- a/src/libcharon/plugins/vici/vici_query.c +++ b/src/libcharon/plugins/vici/vici_query.c @@ -68,7 +68,8 @@ static void list_child(private_vici_query_t *this, vici_builder_t *b, b->add_kv(b, "state", "%N", child_sa_state_names, child->get_state(child)); b->add_kv(b, "mode", "%N", ipsec_mode_names, child->get_mode(child)); if (child->get_state(child) == CHILD_INSTALLED || - child->get_state(child) == CHILD_REKEYING) + child->get_state(child) == CHILD_REKEYING || + child->get_state(child) == CHILD_REKEYED) { b->add_kv(b, "protocol", "%N", protocol_id_names, child->get_protocol(child)); diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.c b/src/libcharon/processing/jobs/rekey_ike_sa_job.c index 516dc5dd5..403d826a3 100644 --- a/src/libcharon/processing/jobs/rekey_ike_sa_job.c +++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.c @@ -67,7 +67,8 @@ static u_int32_t get_retry_delay(ike_sa_t *ike_sa) enumerator = ike_sa->create_child_sa_enumerator(ike_sa); while (enumerator->enumerate(enumerator, &child_sa)) { - if (child_sa->get_state(child_sa) != CHILD_INSTALLED) + if (child_sa->get_state(child_sa) != CHILD_INSTALLED && + child_sa->get_state(child_sa) != CHILD_REKEYED) { retry = RETRY_INTERVAL - (random() % RETRY_JITTER); DBG1(DBG_IKE, "unable to reauthenticate in CHILD_SA %N state, " diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index 068092d60..9ea384e5a 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -34,6 +34,7 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING, "INSTALLED", "UPDATING", "REKEYING", + "REKEYED", "RETRYING", "DELETING", "DESTROYING", diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h index 83b8c096c..debe8eb2c 100644 --- a/src/libcharon/sa/child_sa.h +++ b/src/libcharon/sa/child_sa.h @@ -67,6 +67,11 @@ enum child_sa_state_t { */ CHILD_REKEYING, + /** + * CHILD_SA that was rekeyed, but stays installed + */ + CHILD_REKEYED, + /** * CHILD_SA negotiation failed, but gets retried */ diff --git a/src/libcharon/sa/ikev1/tasks/quick_delete.c b/src/libcharon/sa/ikev1/tasks/quick_delete.c index 4206182a0..1b95a8b11 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_delete.c +++ b/src/libcharon/sa/ikev1/tasks/quick_delete.c @@ -105,7 +105,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol, this->spi = spi = child_sa->get_spi(child_sa, TRUE); } - rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYING; + rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYED; child_sa->set_state(child_sa, CHILD_DELETING); my_ts = linked_list_create_from_enumerator( diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 982c12851..96edfd8d8 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -402,7 +402,7 @@ static bool install(private_quick_mode_t *this) { charon->bus->child_rekey(charon->bus, old, this->child_sa); /* rekeyed CHILD_SAs stay installed until they expire */ - old->set_state(old, CHILD_INSTALLED); + old->set_state(old, CHILD_REKEYED); } else { @@ -988,6 +988,7 @@ static void check_for_rekeyed_child(private_quick_mode_t *this) { case CHILD_INSTALLED: case CHILD_REKEYING: + case CHILD_REKEYED: policies = child_sa->create_policy_enumerator(child_sa); if (policies->enumerate(policies, &local, &remote) && local->equals(local, this->tsr) &&