-/**
- * @file eap_method.c
- *
- * @brief Generic constructor for eap_methods.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id$
*/
-#include <string.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <error.h>
-#include <dlfcn.h>
-
#include "eap_method.h"
-#include <daemon.h>
-#include <library.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-
-ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_TOKEN_CARD,
+ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_GTC,
"EAP_IDENTITY",
"EAP_NOTIFICATION",
"EAP_NAK",
"EAP_MD5",
- "EAP_ONE_TIME_PASSWORD",
- "EAP_TOKEN_CARD");
-ENUM_NEXT(eap_type_names, EAP_SIM, EAP_SIM, EAP_TOKEN_CARD,
+ "EAP_OTP",
+ "EAP_GTC");
+ENUM_NEXT(eap_type_names, EAP_SIM, EAP_SIM, EAP_GTC,
"EAP_SIM");
ENUM_NEXT(eap_type_names, EAP_AKA, EAP_AKA, EAP_SIM,
"EAP_AKA");
-ENUM_NEXT(eap_type_names, EAP_EXPANDED, EAP_EXPERIMENTAL, EAP_AKA,
+ENUM_NEXT(eap_type_names, EAP_MSCHAPV2, EAP_MSCHAPV2, EAP_AKA,
+ "EAP_MSCHAPV2");
+ENUM_NEXT(eap_type_names, EAP_EXPANDED, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
"EAP_EXPANDED",
"EAP_EXPERIMENTAL");
ENUM_END(eap_type_names, EAP_EXPERIMENTAL);
"EAP_PEER",
);
-
-typedef struct module_entry_t module_entry_t;
-
-/**
- * Representation of a loaded module: EAP type, library handle, constructor
- */
-struct module_entry_t {
- eap_type_t type;
- u_int32_t vendor;
- void *handle;
- eap_constructor_t constructor;
-};
-
-/** List of module_entry_t's */
-static linked_list_t *modules = NULL;
-
-/**
- * unload modules at daemon shutdown
- */
-void eap_method_unload()
-{
- if (modules)
- {
- module_entry_t *entry;
-
- while (modules->remove_last(modules, (void**)&entry) == SUCCESS)
- {
- DBG2(DBG_CFG, "unloaded module EAP module %d-%d",
- entry->type, entry->vendor);
- dlclose(entry->handle);
- free(entry);
- }
- modules->destroy(modules);
- modules = NULL;
- }
-}
-
-/**
- * Load EAP modules at daemon startup
- */
-void eap_method_load(char *directory)
-{
- struct dirent* entry;
- DIR* dir;
-
- eap_method_unload();
- modules = linked_list_create();
-
- dir = opendir(directory);
- if (dir == NULL)
- {
- DBG1(DBG_CFG, "error opening EAP modules directory %s", directory);
- return;
- }
-
- DBG1(DBG_CFG, "loading EAP modules from '%s'", directory);
-
- while ((entry = readdir(dir)) != NULL)
- {
- char file[256];
- module_entry_t module, *loaded_module;
- eap_method_t *method;
- identification_t *id;
- char *ending;
-
- snprintf(file, sizeof(file), "%s/%s", directory, entry->d_name);
-
- ending = entry->d_name + strlen(entry->d_name) - 3;
- if (ending <= entry->d_name || !streq(ending, ".so"))
- {
- /* skip anything which does not look like a library */
- DBG2(DBG_CFG, " skipping %s, doesn't look like a library",
- entry->d_name);
- continue;
- }
-
- /* try to load the library */
- module.handle = dlopen(file, RTLD_LAZY);
- if (module.handle == NULL)
- {
- DBG1(DBG_CFG, " opening EAP module %s failed: %s", entry->d_name,
- dlerror());
- continue;
- }
- module.constructor = dlsym(module.handle, "eap_create");
- if (module.constructor == NULL)
- {
- DBG1(DBG_CFG, " EAP module %s has no eap_create() function, skipped",
- entry->d_name);
- dlclose(module.handle);
- continue;
- }
-
- /* get the type implemented in the method, create an instance for it */
- id = identification_create_from_string("john@doe.xyz");
- method = module.constructor(EAP_SERVER, id, id);
- if (method == NULL)
- {
- method = module.constructor(EAP_PEER, id, id);
- }
- id->destroy(id);
- if (method == NULL)
- {
- DBG1(DBG_CFG, " unable to create instance of EAP method %s, skipped",
- entry->d_name);
- dlclose(module.handle);
- continue;
- }
- module.type = method->get_type(method, &module.vendor);
- method->destroy(method);
-
- if (module.vendor)
- {
- DBG1(DBG_CFG, " loaded EAP method %d, vendor %d successfully from %s",
- module.type, module.vendor, entry->d_name);
- }
- else
- {
- DBG1(DBG_CFG, " loaded EAP method %N successfully from %s",
- eap_type_names, module.type, entry->d_name);
- }
-
- loaded_module = malloc_thing(module_entry_t);
- memcpy(loaded_module, &module, sizeof(module));
- modules->insert_last(modules, loaded_module);
- }
- closedir(dir);
-}
-
-/*
- * Described in header.
- */
-eap_method_t *eap_method_create(eap_type_t type, u_int32_t vendor, eap_role_t role,
- identification_t *server, identification_t *peer)
-{
- eap_method_t *method = NULL;
- iterator_t *iterator;
- module_entry_t *entry;
-
- iterator = modules->create_iterator(modules, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
- {
- if (entry->type == type && entry->vendor == vendor)
- {
- method = entry->constructor(role, server, peer);
- if (method)
- {
- break;
- }
- }
- }
- iterator->destroy(iterator);
-
- if (method == NULL)
- {
- if (vendor)
- {
- DBG1(DBG_CFG, "no vendor %d specific EAP module found for method "
- "%d %N", vendor, type, eap_role_names, role);
- }
- else
- {
- DBG1(DBG_CFG, "no EAP module found for %N %N",
- eap_type_names, type, eap_role_names, role);
- }
- }
- return method;
-}