summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/ike_sa_manager.c
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2013-11-01 13:32:07 +0100
committerYves-Alexis Perez <corsac@debian.org>2013-11-01 13:32:07 +0100
commit5313d2d78ca150515f7f5eb39801c100690b6b29 (patch)
treec78e420367283bb1b16f14210b12687cdfbd26eb /src/libcharon/sa/ike_sa_manager.c
parent6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349 (diff)
downloadvyos-strongswan-5313d2d78ca150515f7f5eb39801c100690b6b29.tar.gz
vyos-strongswan-5313d2d78ca150515f7f5eb39801c100690b6b29.zip
Imported Upstream version 5.1.1
Diffstat (limited to 'src/libcharon/sa/ike_sa_manager.c')
-rw-r--r--src/libcharon/sa/ike_sa_manager.c58
1 files changed, 45 insertions, 13 deletions
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 <threading/rwlock.h>
#include <collections/linked_list.h>
#include <crypto/hashers/hasher.h>
+#include <processing/jobs/delete_ike_sa_job.h>
/* 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");