aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorClavister OpenSource <opensource@clavister.com>2011-12-09 11:41:26 +0100
committerClavister OpenSource <opensource@clavister.com>2012-03-20 17:31:14 +0100
commita064eaa8a63a7ed2b3d8b5f0807d791d9ed89f5c (patch)
tree3702cfaa4cf74b8192aad59133062d632b660610 /src
parent751bd02e98a8802139755c58148f9e5da14ce143 (diff)
downloadstrongswan-a064eaa8a63a7ed2b3d8b5f0807d791d9ed89f5c.tar.bz2
strongswan-a064eaa8a63a7ed2b3d8b5f0807d791d9ed89f5c.tar.xz
Handling of initial contact
Diffstat (limited to 'src')
-rwxr-xr-x[-rw-r--r--]src/libcharon/sa/ike_sa.h5
-rwxr-xr-x[-rw-r--r--]src/libcharon/sa/ike_sa_manager.c11
-rwxr-xr-xsrc/libcharon/sa/tasks/main_mode.c51
3 files changed, 67 insertions, 0 deletions
diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h
index 27eab5445..15fd35c25 100644..100755
--- a/src/libcharon/sa/ike_sa.h
+++ b/src/libcharon/sa/ike_sa.h
@@ -153,6 +153,11 @@ enum ike_condition_t {
* IKE_SA is stale, the peer is currently unreachable (MOBIKE)
*/
COND_STALE = (1<<7),
+
+ /**
+ * Initial contact received
+ */
+ COND_INIT_CONTACT_SEEN = (1<<8),
};
/**
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index ffbc2ec3b..776b2b7ae 100644..100755
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -1358,6 +1358,17 @@ METHOD(ike_sa_manager_t, checkin, void,
if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED &&
entry->my_id == NULL && entry->other_id == NULL)
{
+ if (ike_sa->get_version(ike_sa) == IKEV1)
+ {
+ /* If authenticated and received INITIAL_CONTACT,
+ * delete any existing IKE_SAs with that peer. */
+ if (ike_sa->has_condition(ike_sa, COND_INIT_CONTACT_SEEN))
+ {
+ this->public.check_uniqueness(&this->public, ike_sa, TRUE);
+ ike_sa->set_condition(ike_sa, COND_INIT_CONTACT_SEEN, FALSE);
+ }
+ }
+
entry->my_id = my_id->clone(my_id);
entry->other_id = other_id->clone(other_id);
if (!entry->other)
diff --git a/src/libcharon/sa/tasks/main_mode.c b/src/libcharon/sa/tasks/main_mode.c
index ab38ec29b..e1f583cb8 100755
--- a/src/libcharon/sa/tasks/main_mode.c
+++ b/src/libcharon/sa/tasks/main_mode.c
@@ -263,6 +263,52 @@ static auth_method_t get_auth_method(private_main_mode_t *this)
return AUTH_RSA;
}
}
+/**
+ * Check for notify errors, return TRUE if error found
+ */
+static bool has_notify_errors(private_main_mode_t *this, message_t *message)
+{
+ enumerator_t *enumerator;
+ payload_t *payload;
+ bool err = FALSE;
+
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ if (payload->get_type(payload) == NOTIFY_V1)
+ {
+ notify_payload_t *notify;
+ notify_type_t type;
+
+ notify = (notify_payload_t*)payload;
+ type = notify->get_notify_type(notify);
+ if (type < 16384)
+ {
+ DBG1(DBG_IKE, "received %N error notify",
+ notify_type_names, type);
+ err = TRUE;
+ }
+ else if (type == INITIAL_CONTACT_IKEV1)
+ {
+ if (!this->initiator && this->state == MM_AUTH)
+ {
+ /* If authenticated and received INITIAL_CONTACT,
+ * delete any existing IKE_SAs with that peer.
+ * The delete takes place when the SA is checked in due
+ * to other id not known until the 3rd message.*/
+ this->ike_sa->set_condition(this->ike_sa, COND_INIT_CONTACT_SEEN, TRUE);
+ }
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received %N notify", notify_type_names, type);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return err;
+}
METHOD(task_t, build_i, status_t,
private_main_mode_t *this, message_t *message)
@@ -503,6 +549,11 @@ METHOD(task_t, process_r, status_t,
return FAILED;
}
this->state = MM_AUTH;
+
+ if (has_notify_errors(this, message))
+ {
+ return FAILED;
+ }
return NEED_MORE;
}
default: