~ubuntu-branches/ubuntu/vivid/wpasupplicant/vivid

« back to all changes in this revision

Viewing changes to src/eap_peer/eap_methods.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2008-03-12 20:03:04 UTC
  • mfrom: (1.1.10 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20080312200304-4331y9wj46pdd34z
Tags: 0.6.3-1
* New upstream release.
* Drop patches applied upstream:
  - debian/patches/30_wpa_gui_qt4_eventhistoryui_rework.patch
  - debian/patches/31_wpa_gui_qt4_eventhistory_always_scrollbar.patch
  - debian/patches/32_wpa_gui_qt4_eventhistory_scroll_with_events.patch
  - debian/patches/40_dbus_ssid_data.patch
* Tidy up the clean target of debian/rules. Now that the madwifi headers are
  handled differently we no longer need to do any cleanup.
* Fix formatting error in debian/ifupdown/wpa_action.8 to make lintian
  quieter.
* Add patch to fix formatting errors in manpages build from sgml source. Use
  <emphasis> tags to hightlight keywords instead of surrounding them in
  strong quotes.
  - debian/patches/41_manpage_format_fixes.patch
* wpasupplicant binary package no longer suggests pcscd, guessnet, iproute
  or wireless-tools, nor does it recommend dhcp3-client. These are not
  needed.
* Add debian/patches/10_silence_siocsiwauth_icotl_failure.patch to disable
  ioctl failure messages that occur under normal conditions.
* Cherry pick two upstream git commits concerning the dbus interface:
  - debian/patches/11_avoid_dbus_version_namespace.patch
  - debian/patches/12_fix_potential_use_after_free.patch
* Add debian/patches/42_manpage_explain_available_drivers.patch to explain
  that not all of the driver backends are available in the provided
  wpa_supplicant binary, and that the canonical list of supported driver
  backends can be retrieved from the wpa_supplicant -h (help) output.
  (Closes: #466910)
* Add debian/patches/20_wpa_gui_qt4_disable_link_prl.patch to remove
  link_prl CONFIG compile flag added by qmake-qt4 >= 4.3.4-2 to avoid excess
  linking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * EAP peer: Method registration
 
3
 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
#ifdef CONFIG_DYNAMIC_EAP_METHODS
 
17
#include <dlfcn.h>
 
18
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
 
19
 
 
20
#include "common.h"
 
21
#include "eap_i.h"
 
22
#include "eap_methods.h"
 
23
 
 
24
 
 
25
static struct eap_method *eap_methods = NULL;
 
26
 
 
27
 
 
28
/**
 
29
 * eap_peer_get_eap_method - Get EAP method based on type number
 
30
 * @vendor: EAP Vendor-Id (0 = IETF)
 
31
 * @method: EAP type number
 
32
 * Returns: Pointer to EAP method or %NULL if not found
 
33
 */
 
34
const struct eap_method * eap_peer_get_eap_method(int vendor, EapType method)
 
35
{
 
36
        struct eap_method *m;
 
37
        for (m = eap_methods; m; m = m->next) {
 
38
                if (m->vendor == vendor && m->method == method)
 
39
                        return m;
 
40
        }
 
41
        return NULL;
 
42
}
 
43
 
 
44
 
 
45
/**
 
46
 * eap_peer_get_type - Get EAP type for the given EAP method name
 
47
 * @name: EAP method name, e.g., TLS
 
48
 * @vendor: Buffer for returning EAP Vendor-Id
 
49
 * Returns: EAP method type or %EAP_TYPE_NONE if not found
 
50
 *
 
51
 * This function maps EAP type names into EAP type numbers based on the list of
 
52
 * EAP methods included in the build.
 
53
 */
 
54
EapType eap_peer_get_type(const char *name, int *vendor)
 
55
{
 
56
        struct eap_method *m;
 
57
        for (m = eap_methods; m; m = m->next) {
 
58
                if (os_strcmp(m->name, name) == 0) {
 
59
                        *vendor = m->vendor;
 
60
                        return m->method;
 
61
                }
 
62
        }
 
63
        *vendor = EAP_VENDOR_IETF;
 
64
        return EAP_TYPE_NONE;
 
65
}
 
66
 
 
67
 
 
68
/**
 
69
 * eap_get_name - Get EAP method name for the given EAP type
 
70
 * @vendor: EAP Vendor-Id (0 = IETF)
 
71
 * @type: EAP method type
 
72
 * Returns: EAP method name, e.g., TLS, or %NULL if not found
 
73
 *
 
74
 * This function maps EAP type numbers into EAP type names based on the list of
 
75
 * EAP methods included in the build.
 
76
 */
 
77
const char * eap_get_name(int vendor, EapType type)
 
78
{
 
79
        struct eap_method *m;
 
80
        for (m = eap_methods; m; m = m->next) {
 
81
                if (m->vendor == vendor && m->method == type)
 
82
                        return m->name;
 
83
        }
 
84
        return NULL;
 
85
}
 
86
 
 
87
 
 
88
/**
 
89
 * eap_get_names - Get space separated list of names for supported EAP methods
 
90
 * @buf: Buffer for names
 
91
 * @buflen: Buffer length
 
92
 * Returns: Number of characters written into buf (not including nul
 
93
 * termination)
 
94
 */
 
95
size_t eap_get_names(char *buf, size_t buflen)
 
96
{
 
97
        char *pos, *end;
 
98
        struct eap_method *m;
 
99
        int ret;
 
100
 
 
101
        if (buflen == 0)
 
102
                return 0;
 
103
 
 
104
        pos = buf;
 
105
        end = pos + buflen;
 
106
 
 
107
        for (m = eap_methods; m; m = m->next) {
 
108
                ret = os_snprintf(pos, end - pos, "%s%s",
 
109
                                  m == eap_methods ? "" : " ", m->name);
 
110
                if (ret < 0 || ret >= end - pos)
 
111
                        break;
 
112
                pos += ret;
 
113
        }
 
114
        buf[buflen - 1] = '\0';
 
115
 
 
116
        return pos - buf;
 
117
}
 
118
 
 
119
 
 
120
/**
 
121
 * eap_get_names_as_string_array - Get supported EAP methods as string array
 
122
 * @num: Buffer for returning the number of items in array, not including %NULL
 
123
 * terminator. This parameter can be %NULL if the length is not needed.
 
124
 * Returns: A %NULL-terminated array of strings, or %NULL on error.
 
125
 *
 
126
 * This function returns the list of names for all supported EAP methods as an
 
127
 * array of strings. The caller must free the returned array items and the
 
128
 * array.
 
129
 */
 
130
char ** eap_get_names_as_string_array(size_t *num)
 
131
{
 
132
        struct eap_method *m;
 
133
        size_t array_len = 0;
 
134
        char **array;
 
135
        int i = 0, j;
 
136
 
 
137
        for (m = eap_methods; m; m = m->next)
 
138
                array_len++;
 
139
 
 
140
        array = os_zalloc(sizeof(char *) * (array_len + 1));
 
141
        if (array == NULL)
 
142
                return NULL;
 
143
 
 
144
        for (m = eap_methods; m; m = m->next) {
 
145
                array[i++] = os_strdup(m->name);
 
146
                if (array[i - 1] == NULL) {
 
147
                        for (j = 0; j < i; j++)
 
148
                                os_free(array[j]);
 
149
                        os_free(array);
 
150
                        return NULL;
 
151
                }
 
152
        }
 
153
        array[i] = NULL;
 
154
 
 
155
        if (num)
 
156
                *num = array_len;
 
157
 
 
158
        return array;
 
159
}
 
160
 
 
161
 
 
162
/**
 
163
 * eap_peer_get_methods - Get a list of enabled EAP peer methods
 
164
 * @count: Set to number of available methods
 
165
 * Returns: List of enabled EAP peer methods
 
166
 */
 
167
const struct eap_method * eap_peer_get_methods(size_t *count)
 
168
{
 
169
        int c = 0;
 
170
        struct eap_method *m;
 
171
 
 
172
        for (m = eap_methods; m; m = m->next)
 
173
                c++;
 
174
        
 
175
        *count = c;
 
176
        return eap_methods;
 
177
}
 
178
 
 
179
 
 
180
#ifdef CONFIG_DYNAMIC_EAP_METHODS
 
181
/**
 
182
 * eap_peer_method_load - Load a dynamic EAP method library (shared object)
 
183
 * @so: File path for the shared object file to load
 
184
 * Returns: 0 on success, -1 on failure
 
185
 */
 
186
int eap_peer_method_load(const char *so)
 
187
{
 
188
        void *handle;
 
189
        int (*dyn_init)(void);
 
190
        int ret;
 
191
 
 
192
        handle = dlopen(so, RTLD_LAZY);
 
193
        if (handle == NULL) {
 
194
                wpa_printf(MSG_ERROR, "EAP: Failed to open dynamic EAP method "
 
195
                           "'%s': %s", so, dlerror());
 
196
                return -1;
 
197
        }
 
198
 
 
199
        dyn_init = dlsym(handle, "eap_peer_method_dynamic_init");
 
200
        if (dyn_init == NULL) {
 
201
                dlclose(handle);
 
202
                wpa_printf(MSG_ERROR, "EAP: Invalid EAP method '%s' - no "
 
203
                           "eap_peer_method_dynamic_init()", so);
 
204
                return -1;
 
205
        }
 
206
 
 
207
        ret = dyn_init();
 
208
        if (ret) {
 
209
                dlclose(handle);
 
210
                wpa_printf(MSG_ERROR, "EAP: Failed to add EAP method '%s' - "
 
211
                           "ret %d", so, ret);
 
212
                return ret;
 
213
        }
 
214
 
 
215
        /* Store the handle for this shared object. It will be freed with
 
216
         * dlclose() when the EAP method is unregistered. */
 
217
        eap_methods->dl_handle = handle;
 
218
 
 
219
        wpa_printf(MSG_DEBUG, "EAP: Loaded dynamic EAP method: '%s'", so);
 
220
 
 
221
        return 0;
 
222
}
 
223
 
 
224
 
 
225
/**
 
226
 * eap_peer_method_unload - Unload a dynamic EAP method library (shared object)
 
227
 * @method: Pointer to the dynamically loaded EAP method
 
228
 * Returns: 0 on success, -1 on failure
 
229
 *
 
230
 * This function can be used to unload EAP methods that have been previously
 
231
 * loaded with eap_peer_method_load(). Before unloading the method, all
 
232
 * references to the method must be removed to make sure that no dereferences
 
233
 * of freed memory will occur after unloading.
 
234
 */
 
235
int eap_peer_method_unload(struct eap_method *method)
 
236
{
 
237
        struct eap_method *m, *prev;
 
238
        void *handle;
 
239
 
 
240
        m = eap_methods;
 
241
        prev = NULL;
 
242
        while (m) {
 
243
                if (m == method)
 
244
                        break;
 
245
                prev = m;
 
246
                m = m->next;
 
247
        }
 
248
 
 
249
        if (m == NULL || m->dl_handle == NULL)
 
250
                return -1;
 
251
 
 
252
        if (prev)
 
253
                prev->next = m->next;
 
254
        else
 
255
                eap_methods = m->next;
 
256
 
 
257
        handle = m->dl_handle;
 
258
 
 
259
        if (m->free)
 
260
                m->free(m);
 
261
        else
 
262
                eap_peer_method_free(m);
 
263
 
 
264
        dlclose(handle);
 
265
 
 
266
        return 0;
 
267
}
 
268
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
 
269
 
 
270
 
 
271
/**
 
272
 * eap_peer_method_alloc - Allocate EAP peer method structure
 
273
 * @version: Version of the EAP peer method interface (set to
 
274
 * EAP_PEER_METHOD_INTERFACE_VERSION)
 
275
 * @vendor: EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF)
 
276
 * @method: EAP type number (EAP_TYPE_*)
 
277
 * @name: Name of the method (e.g., "TLS")
 
278
 * Returns: Allocated EAP method structure or %NULL on failure
 
279
 *
 
280
 * The returned structure should be freed with eap_peer_method_free() when it
 
281
 * is not needed anymore.
 
282
 */
 
283
struct eap_method * eap_peer_method_alloc(int version, int vendor,
 
284
                                          EapType method, const char *name)
 
285
{
 
286
        struct eap_method *eap;
 
287
        eap = os_zalloc(sizeof(*eap));
 
288
        if (eap == NULL)
 
289
                return NULL;
 
290
        eap->version = version;
 
291
        eap->vendor = vendor;
 
292
        eap->method = method;
 
293
        eap->name = name;
 
294
        return eap;
 
295
}
 
296
 
 
297
 
 
298
/**
 
299
 * eap_peer_method_free - Free EAP peer method structure
 
300
 * @method: Method structure allocated with eap_peer_method_alloc()
 
301
 */
 
302
void eap_peer_method_free(struct eap_method *method)
 
303
{
 
304
        os_free(method);
 
305
}
 
306
 
 
307
 
 
308
/**
 
309
 * eap_peer_method_register - Register an EAP peer method
 
310
 * @method: EAP method to register
 
311
 * Returns: 0 on success, -1 on invalid method, or -2 if a matching EAP method
 
312
 * has already been registered
 
313
 *
 
314
 * Each EAP peer method needs to call this function to register itself as a
 
315
 * supported EAP method.
 
316
 */
 
317
int eap_peer_method_register(struct eap_method *method)
 
318
{
 
319
        struct eap_method *m, *last = NULL;
 
320
 
 
321
        if (method == NULL || method->name == NULL ||
 
322
            method->version != EAP_PEER_METHOD_INTERFACE_VERSION)
 
323
                return -1;
 
324
 
 
325
        for (m = eap_methods; m; m = m->next) {
 
326
                if ((m->vendor == method->vendor &&
 
327
                     m->method == method->method) ||
 
328
                    os_strcmp(m->name, method->name) == 0)
 
329
                        return -2;
 
330
                last = m;
 
331
        }
 
332
 
 
333
        if (last)
 
334
                last->next = method;
 
335
        else
 
336
                eap_methods = method;
 
337
 
 
338
        return 0;
 
339
}
 
340
 
 
341
 
 
342
/**
 
343
 * eap_peer_register_methods - Register statically linked EAP peer methods
 
344
 * Returns: 0 on success, -1 on failure
 
345
 *
 
346
 * This function is called at program initialization to register all EAP peer
 
347
 * methods that were linked in statically.
 
348
 */
 
349
int eap_peer_register_methods(void)
 
350
{
 
351
        int ret = 0;
 
352
 
 
353
#ifdef EAP_MD5
 
354
        if (ret == 0) {
 
355
                int eap_peer_md5_register(void);
 
356
                ret = eap_peer_md5_register();
 
357
        }
 
358
#endif /* EAP_MD5 */
 
359
 
 
360
#ifdef EAP_TLS
 
361
        if (ret == 0) {
 
362
                int eap_peer_tls_register(void);
 
363
                ret = eap_peer_tls_register();
 
364
        }
 
365
#endif /* EAP_TLS */
 
366
 
 
367
#ifdef EAP_MSCHAPv2
 
368
        if (ret == 0) {
 
369
                int eap_peer_mschapv2_register(void);
 
370
                ret = eap_peer_mschapv2_register();
 
371
        }
 
372
#endif /* EAP_MSCHAPv2 */
 
373
 
 
374
#ifdef EAP_PEAP
 
375
        if (ret == 0) {
 
376
                int eap_peer_peap_register(void);
 
377
                ret = eap_peer_peap_register();
 
378
        }
 
379
#endif /* EAP_PEAP */
 
380
 
 
381
#ifdef EAP_TTLS
 
382
        if (ret == 0) {
 
383
                int eap_peer_ttls_register(void);
 
384
                ret = eap_peer_ttls_register();
 
385
        }
 
386
#endif /* EAP_TTLS */
 
387
 
 
388
#ifdef EAP_GTC
 
389
        if (ret == 0) {
 
390
                int eap_peer_gtc_register(void);
 
391
                ret = eap_peer_gtc_register();
 
392
        }
 
393
#endif /* EAP_GTC */
 
394
 
 
395
#ifdef EAP_OTP
 
396
        if (ret == 0) {
 
397
                int eap_peer_otp_register(void);
 
398
                ret = eap_peer_otp_register();
 
399
        }
 
400
#endif /* EAP_OTP */
 
401
 
 
402
#ifdef EAP_SIM
 
403
        if (ret == 0) {
 
404
                int eap_peer_sim_register(void);
 
405
                ret = eap_peer_sim_register();
 
406
        }
 
407
#endif /* EAP_SIM */
 
408
 
 
409
#ifdef EAP_LEAP
 
410
        if (ret == 0) {
 
411
                int eap_peer_leap_register(void);
 
412
                ret = eap_peer_leap_register();
 
413
        }
 
414
#endif /* EAP_LEAP */
 
415
 
 
416
#ifdef EAP_PSK
 
417
        if (ret == 0) {
 
418
                int eap_peer_psk_register(void);
 
419
                ret = eap_peer_psk_register();
 
420
        }
 
421
#endif /* EAP_PSK */
 
422
 
 
423
#ifdef EAP_AKA
 
424
        if (ret == 0) {
 
425
                int eap_peer_aka_register(void);
 
426
                ret = eap_peer_aka_register();
 
427
        }
 
428
#endif /* EAP_AKA */
 
429
 
 
430
#ifdef EAP_FAST
 
431
        if (ret == 0) {
 
432
                int eap_peer_fast_register(void);
 
433
                ret = eap_peer_fast_register();
 
434
        }
 
435
#endif /* EAP_FAST */
 
436
 
 
437
#ifdef EAP_PAX
 
438
        if (ret == 0) {
 
439
                int eap_peer_pax_register(void);
 
440
                ret = eap_peer_pax_register();
 
441
        }
 
442
#endif /* EAP_PAX */
 
443
 
 
444
#ifdef EAP_SAKE
 
445
        if (ret == 0) {
 
446
                int eap_peer_sake_register(void);
 
447
                ret = eap_peer_sake_register();
 
448
        }
 
449
#endif /* EAP_SAKE */
 
450
 
 
451
#ifdef EAP_GPSK
 
452
        if (ret == 0) {
 
453
                int eap_peer_gpsk_register(void);
 
454
                ret = eap_peer_gpsk_register();
 
455
        }
 
456
#endif /* EAP_GPSK */
 
457
 
 
458
#ifdef EAP_IKEV2
 
459
        if (ret == 0) {
 
460
                int eap_peer_ikev2_register(void);
 
461
                ret = eap_peer_ikev2_register();
 
462
        }
 
463
#endif /* EAP_IKEV2 */
 
464
 
 
465
#ifdef EAP_VENDOR_TEST
 
466
        if (ret == 0) {
 
467
                int eap_peer_vendor_test_register(void);
 
468
                ret = eap_peer_vendor_test_register();
 
469
        }
 
470
#endif /* EAP_VENDOR_TEST */
 
471
 
 
472
#ifdef EAP_TNC
 
473
        if (ret == 0) {
 
474
                int eap_peer_tnc_register(void);
 
475
                ret = eap_peer_tnc_register();
 
476
        }
 
477
#endif /* EAP_TNC */
 
478
 
 
479
        return ret;
 
480
}
 
481
 
 
482
 
 
483
/**
 
484
 * eap_peer_unregister_methods - Unregister EAP peer methods
 
485
 *
 
486
 * This function is called at program termination to unregister all EAP peer
 
487
 * methods.
 
488
 */
 
489
void eap_peer_unregister_methods(void)
 
490
{
 
491
        struct eap_method *m;
 
492
#ifdef CONFIG_DYNAMIC_EAP_METHODS
 
493
        void *handle;
 
494
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
 
495
 
 
496
        while (eap_methods) {
 
497
                m = eap_methods;
 
498
                eap_methods = eap_methods->next;
 
499
 
 
500
#ifdef CONFIG_DYNAMIC_EAP_METHODS
 
501
                handle = m->dl_handle;
 
502
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
 
503
 
 
504
                if (m->free)
 
505
                        m->free(m);
 
506
                else
 
507
                        eap_peer_method_free(m);
 
508
 
 
509
#ifdef CONFIG_DYNAMIC_EAP_METHODS
 
510
                if (handle)
 
511
                        dlclose(handle);
 
512
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
 
513
        }
 
514
}