]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Support vendor specific EAP types in eap_type_from_string()
authorMartin Willi <martin@revosec.ch>
Thu, 30 Aug 2012 15:56:16 +0000 (17:56 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 3 Sep 2012 14:13:58 +0000 (16:13 +0200)
src/libcharon/plugins/eap_dynamic/eap_dynamic.c
src/libcharon/plugins/eap_peap/eap_peap_server.c
src/libcharon/plugins/eap_ttls/eap_ttls_server.c
src/libcharon/plugins/load_tester/load_tester_config.c
src/libcharon/plugins/stroke/stroke_config.c
src/libcharon/plugins/tnc_pdp/tnc_pdp.c
src/libcharon/plugins/xauth_eap/xauth_eap.c
src/libstrongswan/eap/eap.c
src/libstrongswan/eap/eap.h

index 322263e63024c81b2df7c50796af0e80c9224f09..660ce649d544f6dd34ed27511e483c0fb1b411f3 100644 (file)
@@ -280,6 +280,7 @@ static void handle_preferred_eap_types(private_eap_dynamic_t *this,
 {
        enumerator_t *enumerator;
        eap_type_t type;
+       u_int32_t vendor;
        entry_t *entry, *pref_entry;
        linked_list_t *preferred;
        char *method;
@@ -289,11 +290,12 @@ static void handle_preferred_eap_types(private_eap_dynamic_t *this,
        enumerator = enumerator_create_token(methods, ",", " ");
        while (enumerator->enumerate(enumerator, &method))
        {
-               type = eap_type_from_string(method);
+               type = eap_type_from_string(method, &vendor);
                if (type)
                {
                        INIT(entry,
                                .type = type,
+                               .vendor = vendor,
                        );
                        preferred->insert_last(preferred, entry);
                }
index bbc937337fdff2a507b957192af96fb4bb6ab220..73c9c4fd2a556b6a532da1e5f0103fb469a87edb 100644 (file)
@@ -88,23 +88,25 @@ struct private_eap_peap_server_t {
 static status_t start_phase2_auth(private_eap_peap_server_t *this)
 {
        char *eap_type_str;
+       u_int32_t vendor;
        eap_type_t type;
 
        eap_type_str = lib->settings->get_str(lib->settings,
                                                        "%s.plugins.eap-peap.phase2_method", "mschapv2",
                                                        charon->name);
-       type = eap_type_from_string(eap_type_str);
+       type = eap_type_from_string(eap_type_str, &vendor);
        if (type == 0)
        {
                DBG1(DBG_IKE, "unrecognized phase2 method \"%s\"", eap_type_str);
                return FAILED;
        }
-       DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, type);
-               this->ph2_method = charon->eap->create_instance(charon->eap, type, 0,
-                                                               EAP_SERVER, this->server, this->peer);
+       DBG1(DBG_IKE, "phase2 method %N selected", eap_type_get_names(vendor), type);
+               this->ph2_method = charon->eap->create_instance(charon->eap, type,
+                                                               vendor, EAP_SERVER, this->server, this->peer);
        if (this->ph2_method == NULL)
        {
-               DBG1(DBG_IKE, "%N method not available", eap_type_names, type);
+               DBG1(DBG_IKE, "%N method not available",
+                        eap_type_get_names(vendor), type);
                return FAILED;
        }
 
@@ -118,7 +120,7 @@ static status_t start_phase2_auth(private_eap_peap_server_t *this)
        }
        else
        {
-               DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+               DBG1(DBG_IKE, "%N method failed", eap_type_get_names(vendor), type);
                return FAILED;
        }
 }
index 1418d6a4d192d9f5ee06830e05fdcf96a8f3eba2..21718cef65248537692a4650baea173daf37dc0a 100644 (file)
@@ -75,23 +75,25 @@ struct private_eap_ttls_server_t {
 static status_t start_phase2_auth(private_eap_ttls_server_t *this)
 {
        char *eap_type_str;
+       u_int32_t vendor;
        eap_type_t type;
 
        eap_type_str = lib->settings->get_str(lib->settings,
                                                                        "%s.plugins.eap-ttls.phase2_method", "md5",
                                                                        charon->name);
-       type = eap_type_from_string(eap_type_str);
+       type = eap_type_from_string(eap_type_str, &vendor);
        if (type == 0)
        {
                DBG1(DBG_IKE, "unrecognized phase2 method \"%s\"", eap_type_str);
                return FAILED;
        }
-       DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, type);
-               this->method = charon->eap->create_instance(charon->eap, type, 0,
+       DBG1(DBG_IKE, "phase2 method %N selected", eap_type_get_names(vendor), type);
+               this->method = charon->eap->create_instance(charon->eap, type, vendor,
                                                                EAP_SERVER, this->server, this->peer);
        if (this->method == NULL)
        {
-               DBG1(DBG_IKE, "%N method not available", eap_type_names, type);
+               DBG1(DBG_IKE, "%N method not available",
+                        eap_type_get_names(vendor), type);
                return FAILED;
        }
        if (this->method->initiate(this->method, &this->out) == NEED_MORE)
@@ -100,8 +102,8 @@ static status_t start_phase2_auth(private_eap_ttls_server_t *this)
        }
        else
        {
-               DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
-                       return FAILED;
+               DBG1(DBG_IKE, "%N method failed", eap_type_get_names(vendor), type);
+               return FAILED;
        }
 }
 
index 735f17985fab865dcdcd5ebeae4baf703e29f560..0ac0dc8139093c593a72c13acf18fd3f57429d56 100644 (file)
@@ -121,6 +121,7 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
        identification_t *id;
        auth_class_t class;
        eap_type_t type;
+       u_int32_t vendor;
        char buf[128];
        int rnd = 0;
 
@@ -174,10 +175,14 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
                        class = AUTH_CLASS_EAP;
                        if (*(str + strlen("eap")) == '-')
                        {
-                               type = eap_type_from_string(str + strlen("eap-"));
+                               type = eap_type_from_string(str + strlen("eap-"), &vendor);
                                if (type)
                                {
                                        auth->add(auth, AUTH_RULE_EAP_TYPE, type);
+                                       if (vendor)
+                                       {
+                                               auth->add(auth, AUTH_RULE_EAP_VENDOR, vendor);
+                                       }
                                }
                        }
                        if (!id)
index 4d54f644b83a5a78603d7f200f778ac5d886460a..cb7b5be004ce67c6ed1df2f913cd37d55385382d 100644 (file)
@@ -569,11 +569,11 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
        else if (strneq(auth, "eap", 3))
        {
                eap_type_t type;
-               u_int32_t vendor = 0;
+               u_int32_t vendor;
 
                cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
 
-               type = eap_type_from_string(auth);
+               type = eap_type_from_string(auth, &vendor);
                if (type)
                {
                        cfg->add(cfg, AUTH_RULE_EAP_TYPE, type);
index 570f20c643aea504381c06ceea014dcb9a8b277e..5b596b65eb6356f23159f598be6c3bfbf1c3b137 100644 (file)
@@ -56,6 +56,11 @@ struct private_tnc_pdp_t {
         */
        eap_type_t type;
 
+       /**
+        * EAP method vendor ID
+        */
+       u_int32_t vendor;
+
        /**
         * IPv4 RADIUS socket
         */
@@ -220,7 +225,7 @@ static chunk_t encrypt_mppe_key(private_tnc_pdp_t *this, u_int8_t type,
                {
                        free(data.ptr);
                        return chunk_empty;
-               }       
+               }
                *a.ptr |= 0x80;
        }
        while (mppe_key->salt == *salt);
@@ -269,7 +274,8 @@ static void send_response(private_tnc_pdp_t *this, radius_message_t *request,
        if (eap)
        {
                data = eap->get_data(eap);
-               DBG3(DBG_CFG, "%N payload %B", eap_type_names, this->type, &data);
+               DBG3(DBG_CFG, "%N payload %B",
+                        eap_type_get_names(this->vendor), this->type, &data);
 
                /* fragment data suitable for RADIUS */
                while (data.len > MAX_RADIUS_ATTRIBUTE_SIZE)
@@ -373,7 +379,7 @@ static void process_eap(private_tnc_pdp_t *this, radius_message_t *request,
                        eap_identity = chunk_create(message.ptr + 5, message.len - 5);
                        peer = identification_create_from_data(eap_identity);
                        method = charon->eap->create_instance(charon->eap, this->type,
-                                                                               0, EAP_SERVER, this->server, peer);
+                                                               this->vendor, EAP_SERVER, this->server, peer);
                        if (!method)
                        {
                                peer->destroy(peer);
@@ -574,6 +580,7 @@ tnc_pdp_t *tnc_pdp_create(u_int16_t port)
 {
        private_tnc_pdp_t *this;
        char *secret, *server, *eap_type_str;
+       u_int32_t vendor;
 
        INIT(this,
                .public = {
@@ -636,14 +643,15 @@ tnc_pdp_t *tnc_pdp_create(u_int16_t port)
 
        eap_type_str = lib->settings->get_str(lib->settings,
                                                "%s.plugins.tnc-pdp.method", "ttls", charon->name);
-       this->type = eap_type_from_string(eap_type_str);
+       this->type = eap_type_from_string(eap_type_str, &this->vendor);
        if (this->type == 0)
        {
                DBG1(DBG_CFG, "unrecognized eap method \"%s\"", eap_type_str);
                destroy(this);
                return NULL;
        }
-       DBG1(DBG_IKE, "eap method %N selected", eap_type_names, this->type);
+       DBG1(DBG_IKE, "eap method %N selected",
+                eap_type_get_names(this->vendor), this->type);
 
        lib->processor->queue_job(lib->processor,
                (job_t*)callback_job_create_with_prio((callback_job_cb_t)receive, this,
index 1da1d9f85b1218db6c0e5b3eaf2f950d10428e05..f5c3d98c9e4232e497b3158a5110e9eec8010e1b 100644 (file)
@@ -181,6 +181,7 @@ METHOD(xauth_method_t, process, status_t,
        chunk_t user = chunk_empty;
        eap_method_t *backend;
        eap_type_t type;
+       u_int32_t vendor;
        char *name;
        bool ok;
 
@@ -225,13 +226,13 @@ METHOD(xauth_method_t, process, status_t,
        name = lib->settings->get_str(lib->settings,
                                                                  "%s.plugins.xauth-eap.backend", "radius",
                                                                  charon->name);
-       type = eap_type_from_string(name);
+       type = eap_type_from_string(name, &vendor);
        if (!type)
        {
                DBG1(DBG_CFG, "Unknown XAuth-EAP method: %s", name);
                return FAILED;
        }
-       backend = charon->eap->create_instance(charon->eap, type, 0, EAP_SERVER,
+       backend = charon->eap->create_instance(charon->eap, type, vendor, EAP_SERVER,
                                                                                   this->server, this->peer);
        if (!backend)
        {
index 53319a4f6b3b5f34c736d89ce192fe4d5a0b12a9..712276c8bf5e6cfd07704b4b1574eee4456c9571 100644 (file)
@@ -121,34 +121,63 @@ enum_name_t* eap_type_get_names(pen_t vendor)
 /*
  * See header
  */
-eap_type_t eap_type_from_string(char *name)
+eap_type_t eap_type_from_string(char *name, u_int32_t *vendor)
 {
-       int i;
+       enum_name_t *enum_name;
+       int i, type;
        static struct {
                char *name;
                eap_type_t type;
        } types[] = {
                {"identity",    EAP_IDENTITY},
-               {"md5",                 EAP_MD5},
-               {"otp",                 EAP_OTP},
-               {"gtc",                 EAP_GTC},
-               {"tls",                 EAP_TLS},
-               {"ttls",                EAP_TTLS},
-               {"sim",                 EAP_SIM},
-               {"aka",                 EAP_AKA},
-               {"peap",                EAP_PEAP},
-               {"mschapv2",    EAP_MSCHAPV2},
-               {"tnc",                 EAP_TNC},
                {"dynamic",             EAP_DYNAMIC},
                {"radius",              EAP_RADIUS},
        };
+       static pen_t vendors[] = {
+               PEN_IETF,
+               PEN_MICROSOFT,
+       };
+
+       if (strneq(name, "eap-", strlen("eap-")))
+       {       /* skip 'eap-' at the beginning */
+               name += strlen("eap-");
+       }
 
+       /* check special values not found in enum_names */
        for (i = 0; i < countof(types); i++)
        {
                if (strcaseeq(name, types[i].name))
                {
+                       *vendor = 0;
                        return types[i].type;
                }
        }
-       return 0;
+
+       /* check IETF and vendor specific names */
+       for (i = 0; i < countof(vendors); i++)
+       {
+               enum_name = eap_type_get_names(vendors[i]);
+               if (enum_name != eap_vendor_names_unknown)
+               {
+                       type = enum_from_name(enum_name, name);
+                       if (type != -1)
+                       {
+                               *vendor = vendors[i];
+                               return type;
+                       }
+               }
+       }
+
+       /* parse numerical IDs */
+       switch (sscanf(name, "%d-%d", &type, &i))
+       {
+               case 1: /* IETF type */
+                       *vendor = 0;
+                       return type;
+               case 2: /* type-vendor */
+                       *vendor = i;
+                       return type;
+               default:
+                       return 0;
+       }
 }
index 40a4d3f6d46e70f22d374f2bf536a11b8f662adf..8e735daa678bd4190d306936845dc9f7f25d5b54 100644 (file)
@@ -113,11 +113,16 @@ typedef struct __attribute__((packed)) {
 } eap_packet_t;
 
 /**
- * Lookup the EAP method type from a string.
+ * Lookup the EAP method type/vendor from a string.
  *
- * @param name         EAP method name (such as "md5", "aka")
+ * The string may optionally have a leading "eap-" prefix. If the string is
+ * unknown, it is interpreted numerically, either as a single IETF number
+ * or a "type-vendor" number pair.
+ *
+ * @param name         EAP method name ("eap-md5", "aka", "ms-soh", "33-311")
+ * @param vendor       vendor ID to return
  * @return                     method type, 0 if unknown
  */
-eap_type_t eap_type_from_string(char *name);
+eap_type_t eap_type_from_string(char *name, u_int32_t *vendor);
 
 #endif /** EAP_H_ @}*/