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
;
107 modules
= linked_list_create();
109 if (stat(directory
, &stb
) == -1 || !(stb
.st_mode
& S_IFDIR
))
111 DBG1(DBG_CFG
, "error opening EAP modules directory %s", directory
);
116 DBG1(DBG_CFG
, "EAP modules directory %s not owned by root, skipped", directory
);
119 if (stb
.st_mode
& S_IWOTH
|| stb
.st_mode
& S_IWGRP
)
121 DBG1(DBG_CFG
, "EAP modules directory %s writable by others, skipped", directory
);
125 dir
= opendir(directory
);
128 DBG1(DBG_CFG
, "error opening EAP modules directory %s", directory
);
132 DBG1(DBG_CFG
, "loading EAP modules from '%s'", directory
);
134 while ((entry
= readdir(dir
)) != NULL
)
137 module_entry_t module
, *loaded_module
;
138 eap_method_t
*method
;
139 identification_t
*id
;
142 snprintf(file
, sizeof(file
), "%s/%s", directory
, entry
->d_name
);
144 if (stat(file
, &stb
) == -1 || !(stb
.st_mode
& S_IFREG
))
146 DBG2(DBG_CFG
, " skipping %s, doesn't look like a file",
150 ending
= entry
->d_name
+ strlen(entry
->d_name
) - 3;
151 if (ending
<= entry
->d_name
|| !streq(ending
, ".so"))
153 /* skip anything which does not look like a library */
154 DBG2(DBG_CFG
, " skipping %s, doesn't look like a library",
160 DBG1(DBG_CFG
, " skipping %s, file is not owned by root", entry
->d_name
);
163 if (stb
.st_mode
& S_IWOTH
|| stb
.st_mode
& S_IWGRP
)
165 DBG1(DBG_CFG
, " skipping %s, file is writeable by others", entry
->d_name
);
169 /* try to load the library */
170 module
.handle
= dlopen(file
, RTLD_LAZY
);
171 if (module
.handle
== NULL
)
173 DBG1(DBG_CFG
, " opening EAP module %s failed: %s", entry
->d_name
,
177 module
.constructor
= dlsym(module
.handle
, "eap_create");
178 if (module
.constructor
== NULL
)
180 DBG1(DBG_CFG
, " EAP module %s has no eap_create() function, skipped",
182 dlclose(module
.handle
);
186 /* get the type implemented in the method, create an instance for it */
187 id
= identification_create_from_string("john@doe.xyz");
188 method
= module
.constructor(EAP_SERVER
, id
, id
);
191 method
= module
.constructor(EAP_PEER
, id
, id
);
196 DBG1(DBG_CFG
, " unable to create instance of EAP method %s, skipped",
198 dlclose(module
.handle
);
201 module
.type
= method
->get_type(method
);
202 method
->destroy(method
);
204 DBG1(DBG_CFG
, " loaded EAP method %N successfully from %s",
205 eap_type_names
, module
.type
, entry
->d_name
);
207 loaded_module
= malloc_thing(module_entry_t
);
208 memcpy(loaded_module
, &module
, sizeof(module
));
209 modules
->insert_last(modules
, loaded_module
);
215 * Described in header.
217 eap_method_t
*eap_method_create(eap_type_t type
, eap_role_t role
,
218 identification_t
*server
,
219 identification_t
*peer
)
221 eap_method_t
*method
= NULL
;
222 iterator_t
*iterator
;
223 module_entry_t
*entry
;
225 iterator
= modules
->create_iterator(modules
, TRUE
);
226 while (iterator
->iterate(iterator
, (void**)&entry
))
228 if (entry
->type
== type
)
230 method
= entry
->constructor(role
, server
, peer
);
237 iterator
->destroy(iterator
);
241 DBG1(DBG_CFG
, "no EAP module found for %N %N",
242 eap_type_names
, type
, eap_role_names
, role
);