diff options
author | Clavister OpenSource <opensource@clavister.com> | 2011-12-09 11:41:26 +0100 |
---|---|---|
committer | Clavister OpenSource <opensource@clavister.com> | 2012-03-20 17:31:14 +0100 |
commit | a064eaa8a63a7ed2b3d8b5f0807d791d9ed89f5c (patch) | |
tree | 3702cfaa4cf74b8192aad59133062d632b660610 | |
parent | 751bd02e98a8802139755c58148f9e5da14ce143 (diff) | |
download | strongswan-a064eaa8a63a.tar.bz2 strongswan-a064eaa8a63a.tar.xz |
Handling of initial contact
-rwxr-xr-x[-rw-r--r--] | src/libcharon/sa/ike_sa.h | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | src/libcharon/sa/ike_sa_manager.c | 11 | ||||
-rwxr-xr-x | src/libcharon/sa/tasks/main_mode.c | 51 |
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: |