diff options
Diffstat (limited to 'src/libcharon/sa')
-rw-r--r-- | src/libcharon/sa/authenticator.c | 7 | ||||
-rw-r--r-- | src/libcharon/sa/authenticator.h | 5 | ||||
-rw-r--r-- | src/libcharon/sa/ike_sa.c | 2 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/authenticators/eap_authenticator.c | 17 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/task_manager_v2.c | 11 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/ike_auth.c | 24 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/ike_init.c | 9 | ||||
-rw-r--r-- | src/libcharon/sa/keymat.h | 7 |
8 files changed, 50 insertions, 32 deletions
diff --git a/src/libcharon/sa/authenticator.c b/src/libcharon/sa/authenticator.c index 91bb7715f..a32b6ab12 100644 --- a/src/libcharon/sa/authenticator.c +++ b/src/libcharon/sa/authenticator.c @@ -31,11 +31,12 @@ ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS, "RSA signature", "pre-shared key", "DSS signature"); -ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_ECDSA_521, AUTH_DSS, +ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_GSPM, AUTH_DSS, "ECDSA-256 signature", "ECDSA-384 signature", - "ECDSA-521 signature"); -ENUM_NEXT(auth_method_names, AUTH_XAUTH_INIT_PSK, AUTH_HYBRID_RESP_RSA, AUTH_ECDSA_521, + "ECDSA-521 signature", + "secure password method"); +ENUM_NEXT(auth_method_names, AUTH_XAUTH_INIT_PSK, AUTH_HYBRID_RESP_RSA, AUTH_GSPM, "XAuthInitPSK", "XAuthRespPSK", "XAuthInitRSA", diff --git a/src/libcharon/sa/authenticator.h b/src/libcharon/sa/authenticator.h index 3af939160..86b42da7a 100644 --- a/src/libcharon/sa/authenticator.h +++ b/src/libcharon/sa/authenticator.h @@ -75,6 +75,11 @@ enum auth_method_t { AUTH_ECDSA_521 = 11, /** + * Generic Secure Password Authentication Method as specified in RFC 6467 + */ + AUTH_GSPM = 12, + + /** * IKEv1 initiator XAUTH with PSK, outside of IANA range */ AUTH_XAUTH_INIT_PSK = 256, diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 5d0a5aea8..e94ebb15e 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1679,7 +1679,7 @@ static bool is_any_path_valid(private_ike_sa_t *this) { bool valid = FALSE; enumerator_t *enumerator; - host_t *src, *addr; + host_t *src = NULL, *addr; DBG1(DBG_IKE, "old path is not available anymore, try to find another"); enumerator = this->peer_addresses->create_enumerator(this->peer_addresses); diff --git a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c index b81c5c853..2e661dc66 100644 --- a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c @@ -219,23 +219,12 @@ static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this, */ static void replace_eap_identity(private_eap_authenticator_t *this) { - enumerator_t *enumerator; - auth_rule_t rule; + identification_t *eap_identity; auth_cfg_t *cfg; - void *ptr; + eap_identity = this->eap_identity->clone(this->eap_identity); cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); - enumerator = cfg->create_enumerator(cfg); - while (enumerator->enumerate(enumerator, &rule, &ptr)) - { - if (rule == AUTH_RULE_EAP_IDENTITY) - { - cfg->replace(cfg, enumerator, AUTH_RULE_EAP_IDENTITY, - this->eap_identity->clone(this->eap_identity)); - break; - } - } - enumerator->destroy(enumerator); + cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, eap_identity); } /** diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index ba7fdd2da..cc6d37849 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -610,7 +610,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request) task_t *task; message_t *message; host_t *me, *other; - bool delete = FALSE; + bool delete = FALSE, hook = FALSE; status_t status; me = request->get_destination(request); @@ -645,9 +645,11 @@ static status_t build_response(private_task_manager_t *this, message_t *request) enumerator); } break; - case DESTROY_ME: case FAILED: default: + hook = TRUE; + /* FALL */ + case DESTROY_ME: /* destroy IKE_SA, but SEND response first */ delete = TRUE; break; @@ -682,7 +684,10 @@ static status_t build_response(private_task_manager_t *this, message_t *request) this->responding.packet->clone(this->responding.packet)); if (delete) { - charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + if (hook) + { + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + } return DESTROY_ME; } return SUCCESS; diff --git a/src/libcharon/sa/ikev2/tasks/ike_auth.c b/src/libcharon/sa/ikev2/tasks/ike_auth.c index 183ca3440..6af0b3778 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_auth.c +++ b/src/libcharon/sa/ikev2/tasks/ike_auth.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -419,10 +420,14 @@ METHOD(task_t, build_i, status_t, cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE); idi = cfg->get(cfg, AUTH_RULE_IDENTITY); - if (!idi) - { - DBG1(DBG_CFG, "configuration misses IDi"); - return FAILED; + if (!idi || idi->get_type(idi) == ID_ANY) + { /* ID_ANY is invalid as IDi, use local IP address instead */ + host_t *me; + + DBG1(DBG_CFG, "no IDi configured, fall back on IP address"); + me = this->ike_sa->get_my_host(this->ike_sa); + idi = identification_create_from_sockaddr(me->get_sockaddr(me)); + cfg->add(cfg, AUTH_RULE_IDENTITY, idi); } this->ike_sa->set_my_id(this->ike_sa, idi->clone(idi)); id_payload = id_payload_create_from_identification(ID_INITIATOR, idi); @@ -689,9 +694,14 @@ METHOD(task_t, build_r, status_t, if (id->get_type(id) == ID_ANY) { /* no IDr received, apply configured ID */ if (!id_cfg || id_cfg->contains_wildcards(id_cfg)) - { - DBG1(DBG_CFG, "IDr not configured and negotiation failed"); - goto peer_auth_failed; + { /* no ID configured, use local IP address */ + host_t *me; + + DBG1(DBG_CFG, "no IDr configured, fall back on IP address"); + me = this->ike_sa->get_my_host(this->ike_sa); + id_cfg = identification_create_from_sockaddr( + me->get_sockaddr(me)); + cfg->add(cfg, AUTH_RULE_IDENTITY, id_cfg); } this->ike_sa->set_my_id(this->ike_sa, id_cfg->clone(id_cfg)); id = id_cfg; diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index de68e8662..3fbbcfd2a 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -519,9 +519,12 @@ METHOD(task_t, migrate, void, this->ike_sa = ike_sa; this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa); this->proposal = NULL; - DESTROY_IF(this->dh); - this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, - this->dh_group); + if (this->dh && this->dh->get_dh_group(this->dh) != this->dh_group) + { /* reset DH value only if group changed (INVALID_KE_PAYLOAD) */ + this->dh->destroy(this->dh); + this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, + this->dh_group); + } } METHOD(task_t, destroy, void, diff --git a/src/libcharon/sa/keymat.h b/src/libcharon/sa/keymat.h index 9de2574e1..8bfe79660 100644 --- a/src/libcharon/sa/keymat.h +++ b/src/libcharon/sa/keymat.h @@ -48,7 +48,12 @@ struct keymat_t { * * The diffie hellman is either for IKE negotiation/rekeying or * CHILD_SA rekeying (using PFS). The resulting DH object must be passed - * to derive_keys or to derive_child_keys and destroyed after use + * to derive_keys or to derive_child_keys and destroyed after use. + * + * Only DH objects allocated through this method are passed to other + * keymat_t methods, allowing private DH implementations. In some cases + * (such as retrying with a COOKIE), a DH object allocated from a different + * keymat_t instance may be passed to other methods. * * @param group diffie hellman group * @return DH object, NULL if group not supported |