From: Martin Willi Date: Thu, 14 Mar 2013 13:01:17 +0000 (+0100) Subject: Add an option to delete any established IKE_SA if RADIUS server is not responding X-Git-Tag: 5.0.3rc1~52^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1ba1cd0c9b64e3eebc6ea2ccdc819c7d50b03f42;p=thirdparty%2Fstrongswan.git Add an option to delete any established IKE_SA if RADIUS server is not responding --- diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c index a39eb80984..7b3c152b31 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius.c +++ b/src/libcharon/plugins/eap_radius/eap_radius.c @@ -253,7 +253,7 @@ METHOD(eap_method_t, initiate, status_t, } else { - charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING); + eap_radius_handle_timeout(NULL); } request->destroy(request); return status; diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c index 0764f33bb6..7375937496 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c @@ -164,10 +164,6 @@ static bool send_message(private_eap_radius_accounting_t *this, ack = response->get_code(response) == RMC_ACCOUNTING_RESPONSE; response->destroy(response); } - else - { - charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING); - } client->destroy(client); } return ack; @@ -268,6 +264,10 @@ static void send_start(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa) entry = this->sessions->put(this->sessions, (void*)(uintptr_t)id, entry); this->mutex->unlock(this->mutex); } + else + { + eap_radius_handle_timeout(ike_sa->get_id(ike_sa)); + } message->destroy(message); free(entry); } @@ -323,7 +323,10 @@ static void send_stop(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa) value = htonl(entry->cause); message->add(message, RAT_ACCT_TERMINATE_CAUSE, chunk_from_thing(value)); - send_message(this, message); + if (!send_message(this, message)) + { + eap_radius_handle_timeout(NULL); + } message->destroy(message); free(entry); } diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c index 75d7f8b966..c32f52183a 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c @@ -24,9 +24,10 @@ #include #include -#include #include #include +#include +#include /** * Default RADIUS server port for authentication @@ -320,3 +321,48 @@ radius_client_t *eap_radius_create_client() } return NULL; } + +/** + * Job to delete all active IKE_SAs + */ +static job_requeue_t delete_all_async(void *data) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + + enumerator = charon->ike_sa_manager->create_enumerator( + charon->ike_sa_manager, TRUE); + while (enumerator->enumerate(enumerator, &ike_sa)) + { + lib->processor->queue_job(lib->processor, + (job_t*)delete_ike_sa_job_create(ike_sa->get_id(ike_sa), TRUE)); + } + enumerator->destroy(enumerator); + + return JOB_REQUEUE_NONE; +} + +/** + * See header. + */ +void eap_radius_handle_timeout(ike_sa_id_t *id) +{ + charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING); + + if (lib->settings->get_bool(lib->settings, + "%s.plugins.eap-radius.close_all_on_timeout", + FALSE, charon->name)) + { + DBG1(DBG_CFG, "deleting all IKE_SAs after RADIUS timeout"); + lib->processor->queue_job(lib->processor, + (job_t*)callback_job_create_with_prio( + (callback_job_cb_t)delete_all_async, NULL, NULL, + (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL)); + } + else if (id) + { + DBG1(DBG_CFG, "deleting IKE_SA after RADIUS timeout"); + lib->processor->queue_job(lib->processor, + (job_t*)delete_ike_sa_job_create(id, TRUE)); + } +} diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.h b/src/libcharon/plugins/eap_radius/eap_radius_plugin.h index 1570bd5664..80fa209d62 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.h +++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.h @@ -27,6 +27,7 @@ #include #include +#include typedef struct eap_radius_plugin_t eap_radius_plugin_t; @@ -51,4 +52,14 @@ struct eap_radius_plugin_t { */ radius_client_t *eap_radius_create_client(); +/** + * Handle a RADIUS request timeout. + * + * If an IKE_SA is given, it gets deleted (unless the policy says to delete + * any established IKE_SA). + * + * @param id associated IKE_SA where timeout happened, or NULL + */ +void eap_radius_handle_timeout(ike_sa_id_t *id); + #endif /** EAP_RADIUS_PLUGIN_H_ @}*/