Add AUTH_RULE_IDENTITY_LOOSE which allows to use IDr loosely as initiator
authorTobias Brunner <tobias@strongswan.org>
Tue, 18 Sep 2012 09:16:10 +0000 (11:16 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 18 Sep 2012 09:16:10 +0000 (11:16 +0200)
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.

src/libcharon/sa/ikev2/tasks/ike_auth.c
src/libstrongswan/credentials/auth_cfg.c
src/libstrongswan/credentials/auth_cfg.h

index 7d462f1..cd94ccd 100644 (file)
@@ -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(
index c364e4b..360e83f 100644 (file)
@@ -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:
index 81e5ca3..79484a0 100644 (file)
@@ -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* */