From: Tobias Brunner Date: Tue, 18 Sep 2012 09:16:10 +0000 (+0200) Subject: Add AUTH_RULE_IDENTITY_LOOSE which allows to use IDr loosely as initiator X-Git-Tag: 5.0.1~95 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3a8852c76fd009e11e78ea377796376b1b770da6;p=thirdparty%2Fstrongswan.git Add AUTH_RULE_IDENTITY_LOOSE which allows to use IDr loosely as initiator If it is set on an auth config IDr will not be sent, and later the configured identity will not only be checked against the returned IDr, but also against other identities contained in the responder's certificate. --- diff --git a/src/libcharon/sa/ikev2/tasks/ike_auth.c b/src/libcharon/sa/ikev2/tasks/ike_auth.c index 7d462f1a7e..cd94ccd9ed 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_auth.c +++ b/src/libcharon/sa/ikev2/tasks/ike_auth.c @@ -408,7 +408,8 @@ METHOD(task_t, build_i, status_t, if (cfg) { idr = cfg->get(cfg, AUTH_RULE_IDENTITY); - if (idr && !idr->contains_wildcards(idr)) + if (!cfg->get(cfg, AUTH_RULE_IDENTITY_LOOSE) && idr && + !idr->contains_wildcards(idr)) { this->ike_sa->set_other_id(this->ike_sa, idr->clone(idr)); id_payload = id_payload_create_from_identification( diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index c364e4b64d..360e83f943 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -33,6 +33,7 @@ ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_XAUTH, ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_REVOCATION_CERT, "RULE_IDENTITY", + "RULE_IDENTITY_LOOSE", "RULE_AUTH_CLASS", "RULE_AAA_IDENTITY", "RULE_EAP_IDENTITY", @@ -70,6 +71,7 @@ static inline bool is_multi_value_rule(auth_rule_t type) case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_IDENTITY: + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_XAUTH_IDENTITY: @@ -197,6 +199,7 @@ static entry_t *entry_create(auth_rule_t type, va_list args) this->type = type; switch (type) { + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -244,6 +247,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) } switch (e1->type) { + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -331,6 +335,7 @@ static void destroy_entry_value(entry_t *entry) free(entry->value); break; } + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -361,6 +366,7 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator, entry->type = type; switch (type) { + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -447,6 +453,8 @@ METHOD(auth_cfg_t, get, void*, case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: return (void*)VALIDATION_FAILED; + case AUTH_RULE_IDENTITY_LOOSE: + return (void*)FALSE; case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: @@ -605,6 +613,17 @@ METHOD(auth_cfg_t, complies, bool, id2 = get(this, t1); if (!id2 || !id2->matches(id2, id1)) { + if (t1 == AUTH_RULE_IDENTITY && + constraints->get(constraints, AUTH_RULE_IDENTITY_LOOSE)) + { /* also verify identity against subjectAltNames */ + certificate_t *cert; + + cert = get(this, AUTH_HELPER_SUBJECT_CERT); + if (cert && cert->has_subject(cert, id1)) + { + break; + } + } success = FALSE; if (log_error) { @@ -709,6 +728,8 @@ METHOD(auth_cfg_t, complies, bool, } break; } + case AUTH_RULE_IDENTITY_LOOSE: + /* just an indication when verifying AUTH_RULE_IDENTITY */ case AUTH_RULE_XAUTH_BACKEND: /* not enforced, just a hint for local authentication */ case AUTH_HELPER_IM_CERT: @@ -843,6 +864,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy add(this, type, cert->get_ref(cert)); break; } + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_AUTH_CLASS: @@ -1001,6 +1023,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, clone->add(clone, entry->type, strdup(entry->value)); break; } + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h index 81e5ca391a..79484a04cc 100644 --- a/src/libstrongswan/credentials/auth_cfg.h +++ b/src/libstrongswan/credentials/auth_cfg.h @@ -67,6 +67,9 @@ extern enum_name_t *auth_class_names; enum auth_rule_t { /** identity to use for IKEv2 authentication exchange, identification_t* */ AUTH_RULE_IDENTITY, + /** if TRUE don't send IDr as initiator, but verify the identity after + * receiving IDr (but also verify it against subjectAltNames), bool */ + AUTH_RULE_IDENTITY_LOOSE, /** authentication class, auth_class_t */ AUTH_RULE_AUTH_CLASS, /** AAA-backend identity for EAP methods supporting it, identification_t* */