diff options
author | Martin Willi <martin@strongswan.org> | 2008-04-14 13:23:24 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-04-14 13:23:24 +0000 |
commit | 0644ebd3de62e1df38fce4373460a9d1d2957981 (patch) | |
tree | 3bcc3bfedb4767bbdbd2c2fea7ed7f167709d078 /src/charon/sa/tasks/ike_auth.c | |
parent | a593db5d35ebc7b0492b57c7aa6b8a6ad394fd8e (diff) | |
download | strongswan-0644ebd3de62e1df38fce4373460a9d1d2957981.tar.bz2 strongswan-0644ebd3de62e1df38fce4373460a9d1d2957981.tar.xz |
implemented IKE_SA uniqueness using ipsec.conf uniqueids paramater
additionally supports a "keep" value to keep the old IKE_SA
Diffstat (limited to 'src/charon/sa/tasks/ike_auth.c')
-rw-r--r-- | src/charon/sa/tasks/ike_auth.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c index 3984936db..c3a3f3bd4 100644 --- a/src/charon/sa/tasks/ike_auth.c +++ b/src/charon/sa/tasks/ike_auth.c @@ -89,6 +89,68 @@ struct private_ike_auth_t { }; /** + * check uniqueness and delete duplicates + */ +static bool check_uniqueness(private_ike_auth_t *this) +{ + ike_sa_t *duplicate; + unique_policy_t policy; + status_t status = SUCCESS; + peer_cfg_t *peer_cfg; + bool cancel = FALSE; + + peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); + policy = peer_cfg->get_unique_policy(peer_cfg); + if (policy == UNIQUE_NO) + { + return FALSE; + } + duplicate = charon->ike_sa_manager->checkout_duplicate( + charon->ike_sa_manager, this->ike_sa); + if (duplicate) + { + peer_cfg = duplicate->get_peer_cfg(duplicate); + if (peer_cfg && + peer_cfg->equals(peer_cfg, this->ike_sa->get_peer_cfg(this->ike_sa))) + { + switch (duplicate->get_state(duplicate)) + { + case IKE_ESTABLISHED: + case IKE_REKEYING: + switch (policy) + { + case UNIQUE_REPLACE: + DBG1(DBG_IKE, "deleting duplicate IKE_SA due " + "uniqueness policy"); + status = duplicate->delete(duplicate); + break; + case UNIQUE_KEEP: + DBG1(DBG_IKE, "cancelling IKE_SA setup due " + "uniqueness policy"); + cancel = TRUE; + break; + default: + break; + } + break; + default: + break; + } + } + if (status == DESTROY_ME) + { + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, + duplicate); + } + else + { + charon->ike_sa_manager->checkin(charon->ike_sa_manager, duplicate); + } + } + return cancel; +} + +/** * build the AUTH payload */ static status_t build_auth(private_ike_auth_t *this, message_t *message) @@ -576,6 +638,12 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) return FAILED; } + if (check_uniqueness(this)) + { + message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty); + return FAILED; + } + /* use "traditional" authentication if we could authenticate peer */ if (this->peer_authenticated) { |