From 5313d2d78ca150515f7f5eb39801c100690b6b29 Mon Sep 17 00:00:00 2001 From: Yves-Alexis Perez Date: Fri, 1 Nov 2013 13:32:07 +0100 Subject: Imported Upstream version 5.1.1 --- src/libcharon/sa/ike_sa_manager.c | 58 ++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 13 deletions(-) (limited to 'src/libcharon/sa/ike_sa_manager.c') diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index 4fbc4da8e..5768803aa 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -28,6 +28,7 @@ #include #include #include +#include /* the default size of the hash table (MUST be a power of 2) */ #define DEFAULT_HASHTABLE_SIZE 1 @@ -1764,6 +1765,40 @@ static void adopt_children(ike_sa_t *old, ike_sa_t *new) enumerator->destroy(enumerator); } +/** + * Check if the replaced IKE_SA might get reauthenticated from host + */ +static bool is_ikev1_reauth(ike_sa_t *duplicate, host_t *host) +{ + return duplicate->get_version(duplicate) == IKEV1 && + host->equals(host, duplicate->get_other_host(duplicate)); +} + +/** + * Delete an existing IKE_SA due to a unique replace policy + */ +static status_t enforce_replace(private_ike_sa_manager_t *this, + ike_sa_t *duplicate, ike_sa_t *new, + identification_t *other, host_t *host) +{ + charon->bus->alert(charon->bus, ALERT_UNIQUE_REPLACE); + + if (is_ikev1_reauth(duplicate, host)) + { + /* looks like a reauthentication attempt */ + adopt_children(duplicate, new); + /* For IKEv1 we have to delay the delete for the old IKE_SA. Some + * peers need to complete the new SA first, otherwise the quick modes + * might get lost. */ + lib->scheduler->schedule_job(lib->scheduler, (job_t*) + delete_ike_sa_job_create(duplicate->get_id(duplicate), TRUE), 10); + return SUCCESS; + } + DBG1(DBG_IKE, "deleting duplicate IKE_SA for peer '%Y' due to " + "uniqueness policy", other); + return duplicate->delete(duplicate); +} + METHOD(ike_sa_manager_t, check_uniqueness, bool, private_ike_sa_manager_t *this, ike_sa_t *ike_sa, bool force_replace) { @@ -1815,20 +1850,17 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool, switch (policy) { case UNIQUE_REPLACE: - charon->bus->alert(charon->bus, ALERT_UNIQUE_REPLACE); - if (duplicate->get_version(duplicate) == IKEV1) - { - adopt_children(duplicate, ike_sa); - } - DBG1(DBG_IKE, "deleting duplicate IKE_SA for peer " - "'%Y' due to uniqueness policy", other); - status = duplicate->delete(duplicate); + status = enforce_replace(this, duplicate, ike_sa, + other, other_host); break; case UNIQUE_KEEP: - cancel = TRUE; - /* we keep the first IKE_SA and delete all - * other duplicates that might exist */ - policy = UNIQUE_REPLACE; + if (!is_ikev1_reauth(duplicate, other_host)) + { + cancel = TRUE; + /* we keep the first IKE_SA and delete all + * other duplicates that might exist */ + policy = UNIQUE_REPLACE; + } break; default: break; @@ -2101,7 +2133,7 @@ ike_sa_manager_t *ike_sa_manager_create() }, ); - this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED); + this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); if (this->hasher == NULL) { DBG1(DBG_MGR, "manager initialization failed, no hasher supported"); -- cgit v1.2.3