4 * @brief Generic constructor for eap_methods.
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29 #include "eap_method.h"
33 #include <utils/linked_list.h>
34 #include <utils/identification.h>
37 ENUM_BEGIN(eap_type_names
, EAP_IDENTITY
, EAP_TOKEN_CARD
,
42 "EAP_ONE_TIME_PASSWORD",
44 ENUM_NEXT(eap_type_names
, EAP_SIM
, EAP_SIM
, EAP_TOKEN_CARD
,
46 ENUM_NEXT(eap_type_names
, EAP_AKA
, EAP_AKA
, EAP_SIM
,
48 ENUM_END(eap_type_names
, EAP_AKA
);
50 ENUM(eap_code_names
, EAP_REQUEST
, EAP_FAILURE
,
57 ENUM(eap_role_names
, EAP_SERVER
, EAP_PEER
,
63 typedef struct module_entry_t module_entry_t
;
66 * Representation of a loaded module: EAP type, library handle, constructor
68 struct module_entry_t
{
71 eap_constructor_t constructor
;
74 /** List of module_entry_t's */
75 static linked_list_t
*modules
= NULL
;
78 * unload modules at daemon shutdown
80 void eap_method_unload()
84 module_entry_t
*entry
;
86 while (modules
->remove_last(modules
, (void**)&entry
) == SUCCESS
)
88 DBG2(DBG_CFG
, "unloaded module for %s", eap_type_names
, entry
->type
);
89 dlclose(entry
->handle
);
92 modules
->destroy(modules
);
98 * Load EAP modules at daemon startup
100 void eap_method_load(char *directory
)
102 struct dirent
* entry
;
106 modules
= linked_list_create();
108 dir
= opendir(directory
);
111 DBG1(DBG_CFG
, "error opening EAP modules directory %s", directory
);
115 DBG1(DBG_CFG
, "loading EAP modules from '%s'", directory
);
117 while ((entry
= readdir(dir
)) != NULL
)
120 module_entry_t module
, *loaded_module
;
121 eap_method_t
*method
;
122 identification_t
*id
;
125 snprintf(file
, sizeof(file
), "%s/%s", directory
, entry
->d_name
);
127 ending
= entry
->d_name
+ strlen(entry
->d_name
) - 3;
128 if (ending
<= entry
->d_name
|| !streq(ending
, ".so"))
130 /* skip anything which does not look like a library */
131 DBG2(DBG_CFG
, " skipping %s, doesn't look like a library",
136 /* try to load the library */
137 module
.handle
= dlopen(file
, RTLD_LAZY
);
138 if (module
.handle
== NULL
)
140 DBG1(DBG_CFG
, " opening EAP module %s failed: %s", entry
->d_name
,
144 module
.constructor
= dlsym(module
.handle
, "eap_create");
145 if (module
.constructor
== NULL
)
147 DBG1(DBG_CFG
, " EAP module %s has no eap_create() function, skipped",
149 dlclose(module
.handle
);
153 /* get the type implemented in the method, create an instance for it */
154 id
= identification_create_from_string("john@doe.xyz");
155 method
= module
.constructor(EAP_SERVER
, id
, id
);
158 method
= module
.constructor(EAP_PEER
, id
, id
);
163 DBG1(DBG_CFG
, " unable to create instance of EAP method %s, skipped",
165 dlclose(module
.handle
);
168 module
.type
= method
->get_type(method
);
169 method
->destroy(method
);
171 DBG1(DBG_CFG
, " loaded EAP method %N successfully from %s",
172 eap_type_names
, module
.type
, entry
->d_name
);
174 loaded_module
= malloc_thing(module_entry_t
);
175 memcpy(loaded_module
, &module
, sizeof(module
));
176 modules
->insert_last(modules
, loaded_module
);
182 * Described in header.
184 eap_method_t
*eap_method_create(eap_type_t type
, eap_role_t role
,
185 identification_t
*server
,
186 identification_t
*peer
)
188 eap_method_t
*method
= NULL
;
189 iterator_t
*iterator
;
190 module_entry_t
*entry
;
192 iterator
= modules
->create_iterator(modules
, TRUE
);
193 while (iterator
->iterate(iterator
, (void**)&entry
))
195 if (entry
->type
== type
)
197 method
= entry
->constructor(role
, server
, peer
);
204 iterator
->destroy(iterator
);
208 DBG1(DBG_CFG
, "no EAP module found for %N %N",
209 eap_type_names
, type
, eap_role_names
, role
);