source: rtems-libbsd/freebsd/contrib/wpa/src/eap_peer/eap_methods.c @ 79ad952

55-freebsd-126-freebsd-12
Last change on this file since 79ad952 was 79ad952, checked in by Christian Mauderer <Christian.Mauderer@…>, on 11/02/17 at 14:07:23

wpa_supplicant: Include rtems-bsd-program.h.

  • Property mode set to 100644
File size: 8.5 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * EAP peer: Method registration
5 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
6 *
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
9 */
10
11#ifdef __rtems__
12#define RTEMS_BSD_PROGRAM_NO_FREE_WRAP
13#endif /* __rtems__ */
14#include "includes.h"
15#ifdef CONFIG_DYNAMIC_EAP_METHODS
16#include <dlfcn.h>
17#endif /* CONFIG_DYNAMIC_EAP_METHODS */
18
19#include "common.h"
20#include "eap_i.h"
21#include "eap_methods.h"
22
23
24static struct eap_method *eap_methods = NULL;
25
26
27/**
28 * eap_peer_get_eap_method - Get EAP method based on type number
29 * @vendor: EAP Vendor-Id (0 = IETF)
30 * @method: EAP type number
31 * Returns: Pointer to EAP method or %NULL if not found
32 */
33const struct eap_method * eap_peer_get_eap_method(int vendor, EapType method)
34{
35        struct eap_method *m;
36        for (m = eap_methods; m; m = m->next) {
37                if (m->vendor == vendor && m->method == method)
38                        return m;
39        }
40        return NULL;
41}
42
43
44/**
45 * eap_peer_get_type - Get EAP type for the given EAP method name
46 * @name: EAP method name, e.g., TLS
47 * @vendor: Buffer for returning EAP Vendor-Id
48 * Returns: EAP method type or %EAP_TYPE_NONE if not found
49 *
50 * This function maps EAP type names into EAP type numbers based on the list of
51 * EAP methods included in the build.
52 */
53EapType eap_peer_get_type(const char *name, int *vendor)
54{
55        struct eap_method *m;
56        for (m = eap_methods; m; m = m->next) {
57                if (os_strcmp(m->name, name) == 0) {
58                        *vendor = m->vendor;
59                        return m->method;
60                }
61        }
62        *vendor = EAP_VENDOR_IETF;
63        return EAP_TYPE_NONE;
64}
65
66
67/**
68 * eap_get_name - Get EAP method name for the given EAP type
69 * @vendor: EAP Vendor-Id (0 = IETF)
70 * @type: EAP method type
71 * Returns: EAP method name, e.g., TLS, or %NULL if not found
72 *
73 * This function maps EAP type numbers into EAP type names based on the list of
74 * EAP methods included in the build.
75 */
76const char * eap_get_name(int vendor, EapType type)
77{
78        struct eap_method *m;
79        if (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_EXPANDED)
80                return "expanded";
81        for (m = eap_methods; m; m = m->next) {
82                if (m->vendor == vendor && m->method == type)
83                        return m->name;
84        }
85        return NULL;
86}
87
88
89/**
90 * eap_get_names - Get space separated list of names for supported EAP methods
91 * @buf: Buffer for names
92 * @buflen: Buffer length
93 * Returns: Number of characters written into buf (not including nul
94 * termination)
95 */
96size_t eap_get_names(char *buf, size_t buflen)
97{
98        char *pos, *end;
99        struct eap_method *m;
100        int ret;
101
102        if (buflen == 0)
103                return 0;
104
105        pos = buf;
106        end = pos + buflen;
107
108        for (m = eap_methods; m; m = m->next) {
109                ret = os_snprintf(pos, end - pos, "%s%s",
110                                  m == eap_methods ? "" : " ", m->name);
111                if (os_snprintf_error(end - pos, ret))
112                        break;
113                pos += ret;
114        }
115        buf[buflen - 1] = '\0';
116
117        return pos - buf;
118}
119
120
121/**
122 * eap_get_names_as_string_array - Get supported EAP methods as string array
123 * @num: Buffer for returning the number of items in array, not including %NULL
124 * terminator. This parameter can be %NULL if the length is not needed.
125 * Returns: A %NULL-terminated array of strings, or %NULL on error.
126 *
127 * This function returns the list of names for all supported EAP methods as an
128 * array of strings. The caller must free the returned array items and the
129 * array.
130 */
131char ** eap_get_names_as_string_array(size_t *num)
132{
133        struct eap_method *m;
134        size_t array_len = 0;
135        char **array;
136        int i = 0, j;
137
138        for (m = eap_methods; m; m = m->next)
139                array_len++;
140
141        array = os_calloc(array_len + 1, sizeof(char *));
142        if (array == NULL)
143                return NULL;
144
145        for (m = eap_methods; m; m = m->next) {
146                array[i++] = os_strdup(m->name);
147                if (array[i - 1] == NULL) {
148                        for (j = 0; j < i; j++)
149                                os_free(array[j]);
150                        os_free(array);
151                        return NULL;
152                }
153        }
154        array[i] = NULL;
155
156        if (num)
157                *num = array_len;
158
159        return array;
160}
161
162
163/**
164 * eap_peer_get_methods - Get a list of enabled EAP peer methods
165 * @count: Set to number of available methods
166 * Returns: List of enabled EAP peer methods
167 */
168const struct eap_method * eap_peer_get_methods(size_t *count)
169{
170        int c = 0;
171        struct eap_method *m;
172
173        for (m = eap_methods; m; m = m->next)
174                c++;
175       
176        *count = c;
177        return eap_methods;
178}
179
180
181#ifdef CONFIG_DYNAMIC_EAP_METHODS
182/**
183 * eap_peer_method_load - Load a dynamic EAP method library (shared object)
184 * @so: File path for the shared object file to load
185 * Returns: 0 on success, -1 on failure
186 */
187int eap_peer_method_load(const char *so)
188{
189        void *handle;
190        int (*dyn_init)(void);
191        int ret;
192
193        handle = dlopen(so, RTLD_LAZY);
194        if (handle == NULL) {
195                wpa_printf(MSG_ERROR, "EAP: Failed to open dynamic EAP method "
196                           "'%s': %s", so, dlerror());
197                return -1;
198        }
199
200        dyn_init = dlsym(handle, "eap_peer_method_dynamic_init");
201        if (dyn_init == NULL) {
202                dlclose(handle);
203                wpa_printf(MSG_ERROR, "EAP: Invalid EAP method '%s' - no "
204                           "eap_peer_method_dynamic_init()", so);
205                return -1;
206        }
207
208        ret = dyn_init();
209        if (ret) {
210                dlclose(handle);
211                wpa_printf(MSG_ERROR, "EAP: Failed to add EAP method '%s' - "
212                           "ret %d", so, ret);
213                return ret;
214        }
215
216        /* Store the handle for this shared object. It will be freed with
217         * dlclose() when the EAP method is unregistered. */
218        eap_methods->dl_handle = handle;
219
220        wpa_printf(MSG_DEBUG, "EAP: Loaded dynamic EAP method: '%s'", so);
221
222        return 0;
223}
224
225
226/**
227 * eap_peer_method_unload - Unload a dynamic EAP method library (shared object)
228 * @method: Pointer to the dynamically loaded EAP method
229 * Returns: 0 on success, -1 on failure
230 *
231 * This function can be used to unload EAP methods that have been previously
232 * loaded with eap_peer_method_load(). Before unloading the method, all
233 * references to the method must be removed to make sure that no dereferences
234 * of freed memory will occur after unloading.
235 */
236int eap_peer_method_unload(struct eap_method *method)
237{
238        struct eap_method *m, *prev;
239        void *handle;
240
241        m = eap_methods;
242        prev = NULL;
243        while (m) {
244                if (m == method)
245                        break;
246                prev = m;
247                m = m->next;
248        }
249
250        if (m == NULL || m->dl_handle == NULL)
251                return -1;
252
253        if (prev)
254                prev->next = m->next;
255        else
256                eap_methods = m->next;
257
258        handle = m->dl_handle;
259
260        if (m->free)
261                m->free(m);
262        else
263                eap_peer_method_free(m);
264
265        dlclose(handle);
266
267        return 0;
268}
269#endif /* CONFIG_DYNAMIC_EAP_METHODS */
270
271
272/**
273 * eap_peer_method_alloc - Allocate EAP peer method structure
274 * @version: Version of the EAP peer method interface (set to
275 * EAP_PEER_METHOD_INTERFACE_VERSION)
276 * @vendor: EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF)
277 * @method: EAP type number (EAP_TYPE_*)
278 * @name: Name of the method (e.g., "TLS")
279 * Returns: Allocated EAP method structure or %NULL on failure
280 *
281 * The returned structure should be freed with eap_peer_method_free() when it
282 * is not needed anymore.
283 */
284struct eap_method * eap_peer_method_alloc(int version, int vendor,
285                                          EapType method, const char *name)
286{
287        struct eap_method *eap;
288        eap = os_zalloc(sizeof(*eap));
289        if (eap == NULL)
290                return NULL;
291        eap->version = version;
292        eap->vendor = vendor;
293        eap->method = method;
294        eap->name = name;
295        return eap;
296}
297
298
299/**
300 * eap_peer_method_free - Free EAP peer method structure
301 * @method: Method structure allocated with eap_peer_method_alloc()
302 */
303void eap_peer_method_free(struct eap_method *method)
304{
305        os_free(method);
306}
307
308
309/**
310 * eap_peer_method_register - Register an EAP peer method
311 * @method: EAP method to register
312 * Returns: 0 on success, -1 on invalid method, or -2 if a matching EAP method
313 * has already been registered
314 *
315 * Each EAP peer method needs to call this function to register itself as a
316 * supported EAP method.
317 */
318int eap_peer_method_register(struct eap_method *method)
319{
320        struct eap_method *m, *last = NULL;
321
322        if (method == NULL || method->name == NULL ||
323            method->version != EAP_PEER_METHOD_INTERFACE_VERSION)
324                return -1;
325
326        for (m = eap_methods; m; m = m->next) {
327                if ((m->vendor == method->vendor &&
328                     m->method == method->method) ||
329                    os_strcmp(m->name, method->name) == 0)
330                        return -2;
331                last = m;
332        }
333
334        if (last)
335                last->next = method;
336        else
337                eap_methods = method;
338
339        return 0;
340}
341
342
343/**
344 * eap_peer_unregister_methods - Unregister EAP peer methods
345 *
346 * This function is called at program termination to unregister all EAP peer
347 * methods.
348 */
349void eap_peer_unregister_methods(void)
350{
351        struct eap_method *m;
352#ifdef CONFIG_DYNAMIC_EAP_METHODS
353        void *handle;
354#endif /* CONFIG_DYNAMIC_EAP_METHODS */
355
356        while (eap_methods) {
357                m = eap_methods;
358                eap_methods = eap_methods->next;
359
360#ifdef CONFIG_DYNAMIC_EAP_METHODS
361                handle = m->dl_handle;
362#endif /* CONFIG_DYNAMIC_EAP_METHODS */
363
364                if (m->free)
365                        m->free(m);
366                else
367                        eap_peer_method_free(m);
368
369#ifdef CONFIG_DYNAMIC_EAP_METHODS
370                if (handle)
371                        dlclose(handle);
372#endif /* CONFIG_DYNAMIC_EAP_METHODS */
373        }
374}
Note: See TracBrowser for help on using the repository browser.