diff --git a/src/charon/plugins/stroke/stroke_control.c b/src/charon/plugins/stroke/stroke_control.c index ef918bb4a..c572117a2 100644 --- a/src/charon/plugins/stroke/stroke_control.c +++ b/src/charon/plugins/stroke/stroke_control.c @@ -357,6 +357,46 @@ static void terminate_srcip(private_stroke_control_t *this, DESTROY_IF(end); } +/** + * Implementation of stroke_control_t.purge_ike + */ +static void purge_ike(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out) +{ + enumerator_t *enumerator; + iterator_t *iterator; + ike_sa_t *ike_sa; + child_sa_t *child_sa; + linked_list_t *list; + uintptr_t del; + stroke_log_info_t info; + + info.out = out; + info.level = msg->output_verbosity; + + list = linked_list_create(); + enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + while (enumerator->enumerate(enumerator, &ike_sa)) + { + iterator = ike_sa->create_child_sa_iterator(ike_sa); + if (!iterator->iterate(iterator, (void**)&child_sa)) + { + list->insert_last(list, + (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa)); + } + iterator->destroy(iterator); + } + enumerator->destroy(enumerator); + + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &del)) + { + charon->controller->terminate_ike(charon->controller, del, + (controller_cb_t)stroke_log, &info); + } + enumerator->destroy(enumerator); + list->destroy(list); +} + /** * Implementation of stroke_control_t.route. */ @@ -441,6 +481,7 @@ stroke_control_t *stroke_control_create() this->public.initiate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))initiate; this->public.terminate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate; this->public.terminate_srcip = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate_srcip; + this->public.purge_ike = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))purge_ike; this->public.route = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))route; this->public.unroute = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))unroute; this->public.destroy = (void(*)(stroke_control_t*))destroy; diff --git a/src/charon/plugins/stroke/stroke_control.h b/src/charon/plugins/stroke/stroke_control.h index 08b8ea39f..5a61a90a4 100644 --- a/src/charon/plugins/stroke/stroke_control.h +++ b/src/charon/plugins/stroke/stroke_control.h @@ -53,6 +53,13 @@ struct stroke_control_t { */ void (*terminate_srcip)(stroke_control_t *this, stroke_msg_t *msg, FILE *out); + /** + * Delete IKE_SAs without a CHILD_SA. + * + * @param msg stroke message + */ + void (*purge_ike)(stroke_control_t *this, stroke_msg_t *msg, FILE *out); + /** * Route a connection. * @@ -68,9 +75,9 @@ struct stroke_control_t { void (*unroute)(stroke_control_t *this, stroke_msg_t *msg, FILE *out); /** - * Destroy a stroke_control instance. - */ - void (*destroy)(stroke_control_t *this); + * Destroy a stroke_control instance. + */ + void (*destroy)(stroke_control_t *this); }; /** diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c index 906473ca1..f61171e22 100644 --- a/src/charon/plugins/stroke/stroke_socket.c +++ b/src/charon/plugins/stroke/stroke_socket.c @@ -341,8 +341,15 @@ static void stroke_reread(private_stroke_socket_t *this, static void stroke_purge(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out) { - charon->credentials->flush_cache(charon->credentials, - CERT_X509_OCSP_RESPONSE); + if (msg->purge.flags & PURGE_OCSP) + { + charon->credentials->flush_cache(charon->credentials, + CERT_X509_OCSP_RESPONSE); + } + if (msg->purge.flags & PURGE_IKE) + { + this->control->purge_ike(this->control, msg, out); + } } /** diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c index 412efc26b..c27a8ca3e 100644 --- a/src/stroke/stroke.c +++ b/src/stroke/stroke.c @@ -248,7 +248,8 @@ static int reread(stroke_keyword_t kw) } static int purge_flags[] = { - PURGE_OCSP + PURGE_OCSP, + PURGE_IKE, }; static int purge(stroke_keyword_t kw) @@ -332,6 +333,8 @@ static void exit_usage(char *error) printf(" stroke rereadsecrets|rereadcrls|rereadall\n"); printf(" Purge ocsp cache entries:\n"); printf(" stroke purgeocsp\n"); + printf(" Purge IKE_SAs without a CHILD_SA:\n"); + printf(" stroke purgeike\n"); printf(" Show leases of a pool:\n"); printf(" stroke leases [POOL [ADDRESS]]\n"); exit_error(error); @@ -443,6 +446,7 @@ int main(int argc, char *argv[]) res = reread(token->kw); break; case STROKE_PURGE_OCSP: + case STROKE_PURGE_IKE: res = purge(token->kw); break; case STROKE_LEASES: diff --git a/src/stroke/stroke_keywords.h b/src/stroke/stroke_keywords.h index d50b11374..6332000db 100644 --- a/src/stroke/stroke_keywords.h +++ b/src/stroke/stroke_keywords.h @@ -48,6 +48,7 @@ typedef enum { STROKE_REREAD_CRLS, STROKE_REREAD_ALL, STROKE_PURGE_OCSP, + STROKE_PURGE_IKE, STROKE_LEASES } stroke_keyword_t; diff --git a/src/stroke/stroke_keywords.txt b/src/stroke/stroke_keywords.txt index 3ce4211e0..96fa0bf3a 100644 --- a/src/stroke/stroke_keywords.txt +++ b/src/stroke/stroke_keywords.txt @@ -55,4 +55,5 @@ rereadacerts, STROKE_REREAD_ACERTS rereadcrls, STROKE_REREAD_CRLS rereadall, STROKE_REREAD_ALL purgeocsp, STROKE_PURGE_OCSP +purgeike, STROKE_PURGE_IKE leases, STROKE_LEASES diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h index 37183094d..704c88c58 100644 --- a/src/stroke/stroke_msg.h +++ b/src/stroke/stroke_msg.h @@ -103,6 +103,8 @@ enum purge_flag_t { PURGE_NONE = 0x0000, /** purge ocsp cache entries */ PURGE_OCSP = 0x0001, + /** purge IKE_SAs without a CHILD_SA */ + PURGE_IKE = 0x0002, }; /**