diff options
author | Martin Willi <martin@revosec.ch> | 2012-03-20 17:56:18 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-03-20 17:57:53 +0100 |
commit | b1f2f05c926f3e36755bb3b2711bd1732c062047 (patch) | |
tree | 27f491ad55217d40051eb45db4de5a8a9217817a /src/libstrongswan/credentials | |
parent | 3cea55b0c819f90045a7ae5657ed476834b74746 (diff) | |
parent | d112a7e1feb583d011ba7868bb3b27b147dc2f68 (diff) | |
download | strongswan-b1f2f05c926f3e36755bb3b2711bd1732c062047.tar.bz2 strongswan-b1f2f05c926f3e36755bb3b2711bd1732c062047.tar.xz |
Merge branch 'ikev1-clean' into ikev1-master
Conflicts:
configure.in
man/ipsec.conf.5.in
src/libcharon/daemon.c
src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
src/libcharon/plugins/eap_radius/eap_radius_accounting.c
src/libcharon/plugins/eap_radius/eap_radius_forward.c
src/libcharon/plugins/farp/farp_listener.c
src/libcharon/sa/ike_sa.c
src/libcharon/sa/keymat.c
src/libcharon/sa/task_manager.c
src/libcharon/sa/trap_manager.c
src/libstrongswan/plugins/x509/x509_cert.c
src/libstrongswan/utils.h
Applied lost changes of moved files keymat.c and task_manager.c.
Updated listener_t.message hook signature in new plugins.
Diffstat (limited to 'src/libstrongswan/credentials')
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.c | 25 | ||||
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.h | 6 | ||||
-rw-r--r-- | src/libstrongswan/credentials/certificates/x509.h | 2 | ||||
-rw-r--r-- | src/libstrongswan/credentials/credential_manager.c | 141 | ||||
-rw-r--r-- | src/libstrongswan/credentials/credential_manager.h | 8 |
5 files changed, 140 insertions, 42 deletions
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index 4b5dbbcf7..0646b0e2c 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -23,11 +23,12 @@ #include <eap/eap.h> #include <credentials/certificates/certificate.h> -ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP, +ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_XAUTH, "any", "public key", "pre-shared key", "EAP", + "XAuth", ); ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_REVOCATION_CERT, @@ -37,6 +38,8 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_REVOCATION_CERT, "RULE_EAP_IDENTITY", "RULE_EAP_TYPE", "RULE_EAP_VENDOR", + "RULE_XAUTH_BACKEND", + "RULE_XAUTH_IDENTITY", "RULE_CA_CERT", "RULE_IM_CERT", "RULE_SUBJECT_CERT", @@ -142,6 +145,7 @@ static void destroy_entry_value(entry_t *entry) case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id = (identification_t*)entry->value; id->destroy(id); @@ -159,6 +163,7 @@ static void destroy_entry_value(entry_t *entry) break; } case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_XAUTH_BACKEND: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: { @@ -205,6 +210,8 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator, case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: @@ -273,6 +280,8 @@ METHOD(auth_cfg_t, get, void*, case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: @@ -313,6 +322,8 @@ static void add(private_auth_cfg_t *this, auth_rule_t type, ...) case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: @@ -434,6 +445,7 @@ METHOD(auth_cfg_t, complies, bool, case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id1, *id2; @@ -531,6 +543,7 @@ METHOD(auth_cfg_t, complies, bool, "public keys, but %d bit key used", (uintptr_t)value, strength); } + break; } } else if (t2 == AUTH_RULE_RSA_STRENGTH) @@ -541,6 +554,7 @@ METHOD(auth_cfg_t, complies, bool, DBG1(DBG_CFG, "constraint requires %d bit ECDSA, " "but RSA used", (uintptr_t)value); } + break; } else if (t2 == AUTH_RULE_ECDSA_STRENGTH) { @@ -550,6 +564,7 @@ METHOD(auth_cfg_t, complies, bool, DBG1(DBG_CFG, "constraint requires %d bit RSA, " "but ECDSA used", (uintptr_t)value); } + break; } } e2->destroy(e2); @@ -577,6 +592,8 @@ METHOD(auth_cfg_t, complies, bool, } break; } + case AUTH_RULE_XAUTH_BACKEND: + /* not enforced, just a hint for local authentication */ case AUTH_HELPER_IM_CERT: case AUTH_HELPER_SUBJECT_CERT: case AUTH_HELPER_IM_HASH_URL: @@ -650,12 +667,14 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id = (identification_t*)value; add(this, type, id->clone(id)); break; } + case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_CERT_POLICY: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: @@ -742,6 +761,7 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id1, *id2; @@ -755,6 +775,7 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) } continue; } + case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_CERT_POLICY: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: @@ -824,6 +845,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id = (identification_t*)entry->value; clone->add(clone, entry->type, id->clone(id)); @@ -840,6 +862,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, clone->add(clone, entry->type, cert->get_ref(cert)); break; } + case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_CERT_POLICY: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h index f29b01bd5..31c7e7d90 100644 --- a/src/libstrongswan/credentials/auth_cfg.h +++ b/src/libstrongswan/credentials/auth_cfg.h @@ -42,6 +42,8 @@ enum auth_class_t { AUTH_CLASS_PSK = 2, /** authentication using EAP */ AUTH_CLASS_EAP = 3, + /** authentication using IKEv1 XAUTH */ + AUTH_CLASS_XAUTH = 4, }; /** @@ -75,6 +77,10 @@ enum auth_rule_t { AUTH_RULE_EAP_TYPE, /** EAP vendor for vendor specific type, u_int32_t */ AUTH_RULE_EAP_VENDOR, + /** XAUTH backend name to use, char* */ + AUTH_RULE_XAUTH_BACKEND, + /** XAuth identity to use or require, identification_t* */ + AUTH_RULE_XAUTH_IDENTITY, /** certificate authority, certificate_t* */ AUTH_RULE_CA_CERT, /** intermediate certificate in trustchain, certificate_t* */ diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h index 5125aca26..00171a718 100644 --- a/src/libstrongswan/credentials/certificates/x509.h +++ b/src/libstrongswan/credentials/certificates/x509.h @@ -56,6 +56,8 @@ enum x509_flag_t { X509_IP_ADDR_BLOCKS = (1<<6), /** cert has CRL sign key usage */ X509_CRL_SIGN = (1<<7), + /** cert has iKEIntermediate key usage */ + X509_IKE_INTERMEDIATE = (1<<8), }; /** diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index b3461b810..d54359ebf 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -53,6 +53,11 @@ struct private_credential_manager_t { thread_value_t *local_sets; /** + * Exclusive local sets, linked_list_t with credential_set_t + */ + thread_value_t *exclusive_local_sets; + + /** * trust relationship and certificate cache */ cert_cache_t *cache; @@ -117,12 +122,23 @@ typedef struct { enumerator_t *global; /** enumerator over local sets */ enumerator_t *local; + /** enumerator over exclusive local sets */ + enumerator_t *exclusive; } sets_enumerator_t; METHOD(enumerator_t, sets_enumerate, bool, sets_enumerator_t *this, credential_set_t **set) { + if (this->exclusive) + { + if (this->exclusive->enumerate(this->exclusive, set)) + { /* only enumerate last added */ + this->exclusive->destroy(this->exclusive); + this->exclusive = NULL; + return TRUE; + } + } if (this->global) { if (this->global->enumerate(this->global, set)) @@ -145,6 +161,7 @@ METHOD(enumerator_t, sets_destroy, void, { DESTROY_IF(this->global); DESTROY_IF(this->local); + DESTROY_IF(this->exclusive); free(this); } @@ -154,19 +171,28 @@ METHOD(enumerator_t, sets_destroy, void, static enumerator_t *create_sets_enumerator(private_credential_manager_t *this) { sets_enumerator_t *enumerator; - linked_list_t *local; + linked_list_t *list; INIT(enumerator, .public = { .enumerate = (void*)_sets_enumerate, .destroy = _sets_destroy, }, - .global = this->sets->create_enumerator(this->sets), ); - local = this->local_sets->get(this->local_sets); - if (local) + + list = this->exclusive_local_sets->get(this->exclusive_local_sets); + if (list && list->get_count(list)) + { + enumerator->exclusive = list->create_enumerator(list); + } + else { - enumerator->local = local->create_enumerator(local); + enumerator->global = this->sets->create_enumerator(this->sets); + list = this->local_sets->get(this->local_sets); + if (list) + { + enumerator->local = list->create_enumerator(list); + } } return &enumerator->public; } @@ -373,26 +399,55 @@ METHOD(credential_manager_t, get_shared, shared_key_t*, } METHOD(credential_manager_t, add_local_set, void, - private_credential_manager_t *this, credential_set_t *set) + private_credential_manager_t *this, credential_set_t *set, bool exclusive) { linked_list_t *sets; + thread_value_t *tv; - sets = this->local_sets->get(this->local_sets); + if (exclusive) + { + tv = this->exclusive_local_sets; + } + else + { + tv = this->local_sets; + } + sets = tv->get(tv); if (!sets) - { /* first invocation */ + { sets = linked_list_create(); - this->local_sets->set(this->local_sets, sets); + tv->set(tv, sets); + } + if (exclusive) + { + sets->insert_first(sets, set); + } + else + { + sets->insert_last(sets, set); } - sets->insert_last(sets, set); } METHOD(credential_manager_t, remove_local_set, void, private_credential_manager_t *this, credential_set_t *set) { linked_list_t *sets; + thread_value_t *tv; - sets = this->local_sets->get(this->local_sets); - sets->remove(sets, set, NULL); + tv = this->local_sets; + sets = tv->get(tv); + if (sets && sets->remove(sets, set, NULL) && sets->get_count(sets) == 0) + { + tv->set(tv, NULL); + sets->destroy(sets); + } + tv = this->exclusive_local_sets; + sets = tv->get(tv); + if (sets && sets->remove(sets, set, NULL) && sets->get_count(sets) == 0) + { + tv->set(tv, NULL); + sets->destroy(sets); + } } METHOD(credential_manager_t, cache_cert, void, @@ -859,7 +914,7 @@ METHOD(credential_manager_t, create_public_enumerator, enumerator_t*, if (auth) { enumerator->wrapper = auth_cfg_wrapper_create(auth); - add_local_set(this, &enumerator->wrapper->set); + add_local_set(this, &enumerator->wrapper->set, FALSE); } this->lock->read_lock(this->lock); return &enumerator->public; @@ -992,42 +1047,45 @@ METHOD(credential_manager_t, get_private, private_key_t*, } } - /* if a specific certificate is preferred, check for a matching key */ - cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT); - if (cert) + if (auth) { - private = get_private_by_cert(this, cert, type); - if (private) + /* if a specific certificate is preferred, check for a matching key */ + cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT); + if (cert) { - trustchain = build_trustchain(this, cert, auth); - if (trustchain) + private = get_private_by_cert(this, cert, type); + if (private) { - auth->merge(auth, trustchain, FALSE); - trustchain->destroy(trustchain); + trustchain = build_trustchain(this, cert, auth); + if (trustchain) + { + auth->merge(auth, trustchain, FALSE); + trustchain->destroy(trustchain); + } + return private; } - return private; } - } - /* try to build a trust chain for each certificate found */ - enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE); - while (enumerator->enumerate(enumerator, &cert)) - { - private = get_private_by_cert(this, cert, type); - if (private) + /* try to build a trust chain for each certificate found */ + enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE); + while (enumerator->enumerate(enumerator, &cert)) { - trustchain = build_trustchain(this, cert, auth); - if (trustchain) + private = get_private_by_cert(this, cert, type); + if (private) { - auth->merge(auth, trustchain, FALSE); - trustchain->destroy(trustchain); - break; + trustchain = build_trustchain(this, cert, auth); + if (trustchain) + { + auth->merge(auth, trustchain, FALSE); + trustchain->destroy(trustchain); + break; + } + private->destroy(private); + private = NULL; } - private->destroy(private); - private = NULL; } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); /* if no valid trustchain was found, fall back to the first usable cert */ if (!private) @@ -1038,7 +1096,10 @@ METHOD(credential_manager_t, get_private, private_key_t*, private = get_private_by_cert(this, cert, type); if (private) { - auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert->get_ref(cert)); + if (auth) + { + auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert->get_ref(cert)); + } break; } } @@ -1100,6 +1161,7 @@ METHOD(credential_manager_t, destroy, void, this->sets->remove(this->sets, this->cache, NULL); this->sets->destroy(this->sets); this->local_sets->destroy(this->local_sets); + this->exclusive_local_sets->destroy(this->exclusive_local_sets); this->cache->destroy(this->cache); this->validators->destroy(this->validators); this->lock->destroy(this->lock); @@ -1144,6 +1206,7 @@ credential_manager_t *credential_manager_create() ); this->local_sets = thread_value_create((thread_cleanup_t)this->sets->destroy); + this->exclusive_local_sets = thread_value_create((thread_cleanup_t)this->sets->destroy); this->sets->insert_first(this->sets, this->cache); return &this->public; diff --git a/src/libstrongswan/credentials/credential_manager.h b/src/libstrongswan/credentials/credential_manager.h index 8e8f04b8c..ad789c718 100644 --- a/src/libstrongswan/credentials/credential_manager.h +++ b/src/libstrongswan/credentials/credential_manager.h @@ -89,7 +89,7 @@ struct credential_manager_t { * @param type kind of requested shared key * @param first first subject between key is shared * @param second second subject between key is shared - * @return enumerator over shared keys + * @return enumerator over (shared_key_t*,id_match_t,id_match_t) */ enumerator_t *(*create_shared_enumerator)(credential_manager_t *this, shared_key_type_t type, @@ -230,10 +230,14 @@ struct credential_manager_t { * operation, sets may be added for the calling thread only. This * does not require a write lock and is therefore a much cheaper * operation. + * The exclusive option allows to disable all other credential sets + * until the set is deregistered. * * @param set set to register + * @param exclusive TRUE to disable all other sets for this thread */ - void (*add_local_set)(credential_manager_t *this, credential_set_t *set); + void (*add_local_set)(credential_manager_t *this, credential_set_t *set, + bool exclusive); /** * Unregister a thread local credential set from the manager. |