~ubuntu-branches/ubuntu/saucy/wpasupplicant/saucy

« back to all changes in this revision

Viewing changes to src/ap/wpa_auth_glue.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2010-11-22 09:43:43 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122094343-qgsxaojvmswfri77
Tags: 0.7.3-0ubuntu1
* Get wpasupplicant 0.7.3 from Debian's SVN. Leaving 0.7.3-1 as unreleased
  for now.
* Build-Depend on debhelper 8, since the packaging from Debian uses compat 8.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * hostapd / WPA authenticator glue code
 
3
 * Copyright (c) 2002-2009, 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 "utils/includes.h"
 
16
 
 
17
#include "utils/common.h"
 
18
#include "common/ieee802_11_defs.h"
 
19
#include "eapol_auth/eapol_auth_sm.h"
 
20
#include "eapol_auth/eapol_auth_sm_i.h"
 
21
#include "eap_server/eap.h"
 
22
#include "l2_packet/l2_packet.h"
 
23
#include "drivers/driver.h"
 
24
#include "hostapd.h"
 
25
#include "ieee802_1x.h"
 
26
#include "preauth_auth.h"
 
27
#include "sta_info.h"
 
28
#include "tkip_countermeasures.h"
 
29
#include "ap_drv_ops.h"
 
30
#include "ap_config.h"
 
31
#include "wpa_auth.h"
 
32
 
 
33
 
 
34
#ifdef CONFIG_IEEE80211R
 
35
static void hostapd_rrb_receive(void *ctx, const u8 *src_addr, const u8 *buf,
 
36
                                size_t len);
 
37
#endif /* CONFIG_IEEE80211R */
 
38
 
 
39
 
 
40
static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
 
41
                                  struct wpa_auth_config *wconf)
 
42
{
 
43
        wconf->wpa = conf->wpa;
 
44
        wconf->wpa_key_mgmt = conf->wpa_key_mgmt;
 
45
        wconf->wpa_pairwise = conf->wpa_pairwise;
 
46
        wconf->wpa_group = conf->wpa_group;
 
47
        wconf->wpa_group_rekey = conf->wpa_group_rekey;
 
48
        wconf->wpa_strict_rekey = conf->wpa_strict_rekey;
 
49
        wconf->wpa_gmk_rekey = conf->wpa_gmk_rekey;
 
50
        wconf->wpa_ptk_rekey = conf->wpa_ptk_rekey;
 
51
        wconf->rsn_pairwise = conf->rsn_pairwise;
 
52
        wconf->rsn_preauth = conf->rsn_preauth;
 
53
        wconf->eapol_version = conf->eapol_version;
 
54
        wconf->peerkey = conf->peerkey;
 
55
        wconf->wmm_enabled = conf->wmm_enabled;
 
56
        wconf->wmm_uapsd = conf->wmm_uapsd;
 
57
        wconf->okc = conf->okc;
 
58
#ifdef CONFIG_IEEE80211W
 
59
        wconf->ieee80211w = conf->ieee80211w;
 
60
#endif /* CONFIG_IEEE80211W */
 
61
#ifdef CONFIG_IEEE80211R
 
62
        wconf->ssid_len = conf->ssid.ssid_len;
 
63
        if (wconf->ssid_len > SSID_LEN)
 
64
                wconf->ssid_len = SSID_LEN;
 
65
        os_memcpy(wconf->ssid, conf->ssid.ssid, wconf->ssid_len);
 
66
        os_memcpy(wconf->mobility_domain, conf->mobility_domain,
 
67
                  MOBILITY_DOMAIN_ID_LEN);
 
68
        if (conf->nas_identifier &&
 
69
            os_strlen(conf->nas_identifier) <= FT_R0KH_ID_MAX_LEN) {
 
70
                wconf->r0_key_holder_len = os_strlen(conf->nas_identifier);
 
71
                os_memcpy(wconf->r0_key_holder, conf->nas_identifier,
 
72
                          wconf->r0_key_holder_len);
 
73
        }
 
74
        os_memcpy(wconf->r1_key_holder, conf->r1_key_holder, FT_R1KH_ID_LEN);
 
75
        wconf->r0_key_lifetime = conf->r0_key_lifetime;
 
76
        wconf->reassociation_deadline = conf->reassociation_deadline;
 
77
        wconf->r0kh_list = conf->r0kh_list;
 
78
        wconf->r1kh_list = conf->r1kh_list;
 
79
        wconf->pmk_r1_push = conf->pmk_r1_push;
 
80
#endif /* CONFIG_IEEE80211R */
 
81
}
 
82
 
 
83
 
 
84
static void hostapd_wpa_auth_logger(void *ctx, const u8 *addr,
 
85
                                    logger_level level, const char *txt)
 
86
{
 
87
#ifndef CONFIG_NO_HOSTAPD_LOGGER
 
88
        struct hostapd_data *hapd = ctx;
 
89
        int hlevel;
 
90
 
 
91
        switch (level) {
 
92
        case LOGGER_WARNING:
 
93
                hlevel = HOSTAPD_LEVEL_WARNING;
 
94
                break;
 
95
        case LOGGER_INFO:
 
96
                hlevel = HOSTAPD_LEVEL_INFO;
 
97
                break;
 
98
        case LOGGER_DEBUG:
 
99
        default:
 
100
                hlevel = HOSTAPD_LEVEL_DEBUG;
 
101
                break;
 
102
        }
 
103
 
 
104
        hostapd_logger(hapd, addr, HOSTAPD_MODULE_WPA, hlevel, "%s", txt);
 
105
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
 
106
}
 
107
 
 
108
 
 
109
static void hostapd_wpa_auth_disconnect(void *ctx, const u8 *addr,
 
110
                                        u16 reason)
 
111
{
 
112
        struct hostapd_data *hapd = ctx;
 
113
        wpa_printf(MSG_DEBUG, "%s: WPA authenticator requests disconnect: "
 
114
                   "STA " MACSTR " reason %d",
 
115
                   __func__, MAC2STR(addr), reason);
 
116
        ap_sta_disconnect(hapd, NULL, addr, reason);
 
117
}
 
118
 
 
119
 
 
120
static void hostapd_wpa_auth_mic_failure_report(void *ctx, const u8 *addr)
 
121
{
 
122
        struct hostapd_data *hapd = ctx;
 
123
        michael_mic_failure(hapd, addr, 0);
 
124
}
 
125
 
 
126
 
 
127
static void hostapd_wpa_auth_set_eapol(void *ctx, const u8 *addr,
 
128
                                       wpa_eapol_variable var, int value)
 
129
{
 
130
        struct hostapd_data *hapd = ctx;
 
131
        struct sta_info *sta = ap_get_sta(hapd, addr);
 
132
        if (sta == NULL)
 
133
                return;
 
134
        switch (var) {
 
135
        case WPA_EAPOL_portEnabled:
 
136
                ieee802_1x_notify_port_enabled(sta->eapol_sm, value);
 
137
                break;
 
138
        case WPA_EAPOL_portValid:
 
139
                ieee802_1x_notify_port_valid(sta->eapol_sm, value);
 
140
                break;
 
141
        case WPA_EAPOL_authorized:
 
142
                ieee802_1x_set_sta_authorized(hapd, sta, value);
 
143
                break;
 
144
        case WPA_EAPOL_portControl_Auto:
 
145
                if (sta->eapol_sm)
 
146
                        sta->eapol_sm->portControl = Auto;
 
147
                break;
 
148
        case WPA_EAPOL_keyRun:
 
149
                if (sta->eapol_sm)
 
150
                        sta->eapol_sm->keyRun = value ? TRUE : FALSE;
 
151
                break;
 
152
        case WPA_EAPOL_keyAvailable:
 
153
                if (sta->eapol_sm)
 
154
                        sta->eapol_sm->eap_if->eapKeyAvailable =
 
155
                                value ? TRUE : FALSE;
 
156
                break;
 
157
        case WPA_EAPOL_keyDone:
 
158
                if (sta->eapol_sm)
 
159
                        sta->eapol_sm->keyDone = value ? TRUE : FALSE;
 
160
                break;
 
161
        case WPA_EAPOL_inc_EapolFramesTx:
 
162
                if (sta->eapol_sm)
 
163
                        sta->eapol_sm->dot1xAuthEapolFramesTx++;
 
164
                break;
 
165
        }
 
166
}
 
167
 
 
168
 
 
169
static int hostapd_wpa_auth_get_eapol(void *ctx, const u8 *addr,
 
170
                                      wpa_eapol_variable var)
 
171
{
 
172
        struct hostapd_data *hapd = ctx;
 
173
        struct sta_info *sta = ap_get_sta(hapd, addr);
 
174
        if (sta == NULL || sta->eapol_sm == NULL)
 
175
                return -1;
 
176
        switch (var) {
 
177
        case WPA_EAPOL_keyRun:
 
178
                return sta->eapol_sm->keyRun;
 
179
        case WPA_EAPOL_keyAvailable:
 
180
                return sta->eapol_sm->eap_if->eapKeyAvailable;
 
181
        default:
 
182
                return -1;
 
183
        }
 
184
}
 
185
 
 
186
 
 
187
static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
 
188
                                           const u8 *prev_psk)
 
189
{
 
190
        struct hostapd_data *hapd = ctx;
 
191
        return hostapd_get_psk(hapd->conf, addr, prev_psk);
 
192
}
 
193
 
 
194
 
 
195
static int hostapd_wpa_auth_get_msk(void *ctx, const u8 *addr, u8 *msk,
 
196
                                    size_t *len)
 
197
{
 
198
        struct hostapd_data *hapd = ctx;
 
199
        const u8 *key;
 
200
        size_t keylen;
 
201
        struct sta_info *sta;
 
202
 
 
203
        sta = ap_get_sta(hapd, addr);
 
204
        if (sta == NULL)
 
205
                return -1;
 
206
 
 
207
        key = ieee802_1x_get_key(sta->eapol_sm, &keylen);
 
208
        if (key == NULL)
 
209
                return -1;
 
210
 
 
211
        if (keylen > *len)
 
212
                keylen = *len;
 
213
        os_memcpy(msk, key, keylen);
 
214
        *len = keylen;
 
215
 
 
216
        return 0;
 
217
}
 
218
 
 
219
 
 
220
static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
 
221
                                    const u8 *addr, int idx, u8 *key,
 
222
                                    size_t key_len)
 
223
{
 
224
        struct hostapd_data *hapd = ctx;
 
225
        const char *ifname = hapd->conf->iface;
 
226
 
 
227
        if (vlan_id > 0) {
 
228
                ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id);
 
229
                if (ifname == NULL)
 
230
                        return -1;
 
231
        }
 
232
 
 
233
        return hapd->drv.set_key(ifname, hapd, alg, addr, idx, 1, NULL, 0,
 
234
                                 key, key_len);
 
235
}
 
236
 
 
237
 
 
238
static int hostapd_wpa_auth_get_seqnum(void *ctx, const u8 *addr, int idx,
 
239
                                       u8 *seq)
 
240
{
 
241
        struct hostapd_data *hapd = ctx;
 
242
        return hostapd_get_seqnum(hapd->conf->iface, hapd, addr, idx, seq);
 
243
}
 
244
 
 
245
 
 
246
static int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
 
247
                                       const u8 *data, size_t data_len,
 
248
                                       int encrypt)
 
249
{
 
250
        struct hostapd_data *hapd = ctx;
 
251
        return hapd->drv.send_eapol(hapd, addr, data, data_len, encrypt);
 
252
}
 
253
 
 
254
 
 
255
static int hostapd_wpa_auth_for_each_sta(
 
256
        void *ctx, int (*cb)(struct wpa_state_machine *sm, void *ctx),
 
257
        void *cb_ctx)
 
258
{
 
259
        struct hostapd_data *hapd = ctx;
 
260
        struct sta_info *sta;
 
261
 
 
262
        for (sta = hapd->sta_list; sta; sta = sta->next) {
 
263
                if (sta->wpa_sm && cb(sta->wpa_sm, cb_ctx))
 
264
                        return 1;
 
265
        }
 
266
        return 0;
 
267
}
 
268
 
 
269
 
 
270
struct wpa_auth_iface_iter_data {
 
271
        int (*cb)(struct wpa_authenticator *sm, void *ctx);
 
272
        void *cb_ctx;
 
273
};
 
274
 
 
275
static int wpa_auth_iface_iter(struct hostapd_iface *iface, void *ctx)
 
276
{
 
277
        struct wpa_auth_iface_iter_data *data = ctx;
 
278
        size_t i;
 
279
        for (i = 0; i < iface->num_bss; i++) {
 
280
                if (iface->bss[i]->wpa_auth &&
 
281
                    data->cb(iface->bss[i]->wpa_auth, data->cb_ctx))
 
282
                        return 1;
 
283
        }
 
284
        return 0;
 
285
}
 
286
 
 
287
 
 
288
static int hostapd_wpa_auth_for_each_auth(
 
289
        void *ctx, int (*cb)(struct wpa_authenticator *sm, void *ctx),
 
290
        void *cb_ctx)
 
291
{
 
292
        struct hostapd_data *hapd = ctx;
 
293
        struct wpa_auth_iface_iter_data data;
 
294
        if (hapd->iface->for_each_interface == NULL)
 
295
                return -1;
 
296
        data.cb = cb;
 
297
        data.cb_ctx = cb_ctx;
 
298
        return hapd->iface->for_each_interface(hapd->iface->interfaces,
 
299
                                               wpa_auth_iface_iter, &data);
 
300
}
 
301
 
 
302
 
 
303
#ifdef CONFIG_IEEE80211R
 
304
 
 
305
struct wpa_auth_ft_iface_iter_data {
 
306
        struct hostapd_data *src_hapd;
 
307
        const u8 *dst;
 
308
        const u8 *data;
 
309
        size_t data_len;
 
310
};
 
311
 
 
312
 
 
313
static int hostapd_wpa_auth_ft_iter(struct hostapd_iface *iface, void *ctx)
 
314
{
 
315
        struct wpa_auth_ft_iface_iter_data *idata = ctx;
 
316
        struct hostapd_data *hapd;
 
317
        size_t j;
 
318
 
 
319
        for (j = 0; j < iface->num_bss; j++) {
 
320
                hapd = iface->bss[j];
 
321
                if (hapd == idata->src_hapd)
 
322
                        continue;
 
323
                if (os_memcmp(hapd->own_addr, idata->dst, ETH_ALEN) == 0) {
 
324
                        wpa_printf(MSG_DEBUG, "FT: Send RRB data directly to "
 
325
                                   "locally managed BSS " MACSTR "@%s -> "
 
326
                                   MACSTR "@%s",
 
327
                                   MAC2STR(idata->src_hapd->own_addr),
 
328
                                   idata->src_hapd->conf->iface,
 
329
                                   MAC2STR(hapd->own_addr), hapd->conf->iface);
 
330
                        hostapd_rrb_receive(hapd, idata->src_hapd->own_addr,
 
331
                                            idata->data, idata->data_len);
 
332
                        return 1;
 
333
                }
 
334
        }
 
335
 
 
336
        return 0;
 
337
}
 
338
 
 
339
#endif /* CONFIG_IEEE80211R */
 
340
 
 
341
 
 
342
static int hostapd_wpa_auth_send_ether(void *ctx, const u8 *dst, u16 proto,
 
343
                                       const u8 *data, size_t data_len)
 
344
{
 
345
        struct hostapd_data *hapd = ctx;
 
346
 
 
347
#ifdef CONFIG_IEEE80211R
 
348
        if (proto == ETH_P_RRB && hapd->iface->for_each_interface) {
 
349
                int res;
 
350
                struct wpa_auth_ft_iface_iter_data idata;
 
351
                idata.src_hapd = hapd;
 
352
                idata.dst = dst;
 
353
                idata.data = data;
 
354
                idata.data_len = data_len;
 
355
                res = hapd->iface->for_each_interface(hapd->iface->interfaces,
 
356
                                                      hostapd_wpa_auth_ft_iter,
 
357
                                                      &idata);
 
358
                if (res == 1)
 
359
                        return data_len;
 
360
        }
 
361
#endif /* CONFIG_IEEE80211R */
 
362
 
 
363
        if (hapd->driver && hapd->driver->send_ether)
 
364
                return hapd->driver->send_ether(hapd->drv_priv, dst,
 
365
                                                hapd->own_addr, proto,
 
366
                                                data, data_len);
 
367
        if (hapd->l2 == NULL)
 
368
                return -1;
 
369
        return l2_packet_send(hapd->l2, dst, proto, data, data_len);
 
370
}
 
371
 
 
372
 
 
373
#ifdef CONFIG_IEEE80211R
 
374
 
 
375
static int hostapd_wpa_auth_send_ft_action(void *ctx, const u8 *dst,
 
376
                                           const u8 *data, size_t data_len)
 
377
{
 
378
        struct hostapd_data *hapd = ctx;
 
379
        int res;
 
380
        struct ieee80211_mgmt *m;
 
381
        size_t mlen;
 
382
        struct sta_info *sta;
 
383
 
 
384
        sta = ap_get_sta(hapd, dst);
 
385
        if (sta == NULL || sta->wpa_sm == NULL)
 
386
                return -1;
 
387
 
 
388
        m = os_zalloc(sizeof(*m) + data_len);
 
389
        if (m == NULL)
 
390
                return -1;
 
391
        mlen = ((u8 *) &m->u - (u8 *) m) + data_len;
 
392
        m->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
 
393
                                        WLAN_FC_STYPE_ACTION);
 
394
        os_memcpy(m->da, dst, ETH_ALEN);
 
395
        os_memcpy(m->sa, hapd->own_addr, ETH_ALEN);
 
396
        os_memcpy(m->bssid, hapd->own_addr, ETH_ALEN);
 
397
        os_memcpy(&m->u, data, data_len);
 
398
 
 
399
        res = hapd->drv.send_mgmt_frame(hapd, (u8 *) m, mlen);
 
400
        os_free(m);
 
401
        return res;
 
402
}
 
403
 
 
404
 
 
405
static struct wpa_state_machine *
 
406
hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr)
 
407
{
 
408
        struct hostapd_data *hapd = ctx;
 
409
        struct sta_info *sta;
 
410
 
 
411
        sta = ap_sta_add(hapd, sta_addr);
 
412
        if (sta == NULL)
 
413
                return NULL;
 
414
        if (sta->wpa_sm) {
 
415
                sta->auth_alg = WLAN_AUTH_FT;
 
416
                return sta->wpa_sm;
 
417
        }
 
418
 
 
419
        sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr);
 
420
        if (sta->wpa_sm == NULL) {
 
421
                ap_free_sta(hapd, sta);
 
422
                return NULL;
 
423
        }
 
424
        sta->auth_alg = WLAN_AUTH_FT;
 
425
 
 
426
        return sta->wpa_sm;
 
427
}
 
428
 
 
429
 
 
430
static void hostapd_rrb_receive(void *ctx, const u8 *src_addr, const u8 *buf,
 
431
                                size_t len)
 
432
{
 
433
        struct hostapd_data *hapd = ctx;
 
434
        wpa_ft_rrb_rx(hapd->wpa_auth, src_addr, buf, len);
 
435
}
 
436
 
 
437
#endif /* CONFIG_IEEE80211R */
 
438
 
 
439
 
 
440
int hostapd_setup_wpa(struct hostapd_data *hapd)
 
441
{
 
442
        struct wpa_auth_config _conf;
 
443
        struct wpa_auth_callbacks cb;
 
444
        const u8 *wpa_ie;
 
445
        size_t wpa_ie_len;
 
446
 
 
447
        hostapd_wpa_auth_conf(hapd->conf, &_conf);
 
448
        os_memset(&cb, 0, sizeof(cb));
 
449
        cb.ctx = hapd;
 
450
        cb.logger = hostapd_wpa_auth_logger;
 
451
        cb.disconnect = hostapd_wpa_auth_disconnect;
 
452
        cb.mic_failure_report = hostapd_wpa_auth_mic_failure_report;
 
453
        cb.set_eapol = hostapd_wpa_auth_set_eapol;
 
454
        cb.get_eapol = hostapd_wpa_auth_get_eapol;
 
455
        cb.get_psk = hostapd_wpa_auth_get_psk;
 
456
        cb.get_msk = hostapd_wpa_auth_get_msk;
 
457
        cb.set_key = hostapd_wpa_auth_set_key;
 
458
        cb.get_seqnum = hostapd_wpa_auth_get_seqnum;
 
459
        cb.send_eapol = hostapd_wpa_auth_send_eapol;
 
460
        cb.for_each_sta = hostapd_wpa_auth_for_each_sta;
 
461
        cb.for_each_auth = hostapd_wpa_auth_for_each_auth;
 
462
        cb.send_ether = hostapd_wpa_auth_send_ether;
 
463
#ifdef CONFIG_IEEE80211R
 
464
        cb.send_ft_action = hostapd_wpa_auth_send_ft_action;
 
465
        cb.add_sta = hostapd_wpa_auth_add_sta;
 
466
#endif /* CONFIG_IEEE80211R */
 
467
        hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb);
 
468
        if (hapd->wpa_auth == NULL) {
 
469
                wpa_printf(MSG_ERROR, "WPA initialization failed.");
 
470
                return -1;
 
471
        }
 
472
 
 
473
        if (hostapd_set_privacy(hapd, 1)) {
 
474
                wpa_printf(MSG_ERROR, "Could not set PrivacyInvoked "
 
475
                           "for interface %s", hapd->conf->iface);
 
476
                return -1;
 
477
        }
 
478
 
 
479
        wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
 
480
        if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) {
 
481
                wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
 
482
                           "the kernel driver.");
 
483
                return -1;
 
484
        }
 
485
 
 
486
        if (rsn_preauth_iface_init(hapd)) {
 
487
                wpa_printf(MSG_ERROR, "Initialization of RSN "
 
488
                           "pre-authentication failed.");
 
489
                return -1;
 
490
        }
 
491
 
 
492
#ifdef CONFIG_IEEE80211R
 
493
        if (!hostapd_drv_none(hapd)) {
 
494
                hapd->l2 = l2_packet_init(hapd->conf->bridge[0] ?
 
495
                                          hapd->conf->bridge :
 
496
                                          hapd->conf->iface, NULL, ETH_P_RRB,
 
497
                                          hostapd_rrb_receive, hapd, 0);
 
498
                if (hapd->l2 == NULL &&
 
499
                    (hapd->driver == NULL ||
 
500
                     hapd->driver->send_ether == NULL)) {
 
501
                        wpa_printf(MSG_ERROR, "Failed to open l2_packet "
 
502
                                   "interface");
 
503
                        return -1;
 
504
                }
 
505
        }
 
506
#endif /* CONFIG_IEEE80211R */
 
507
 
 
508
        return 0;
 
509
 
 
510
}
 
511
 
 
512
 
 
513
void hostapd_reconfig_wpa(struct hostapd_data *hapd)
 
514
{
 
515
        struct wpa_auth_config wpa_auth_conf;
 
516
        hostapd_wpa_auth_conf(hapd->conf, &wpa_auth_conf);
 
517
        wpa_reconfig(hapd->wpa_auth, &wpa_auth_conf);
 
518
}
 
519
 
 
520
 
 
521
void hostapd_deinit_wpa(struct hostapd_data *hapd)
 
522
{
 
523
        rsn_preauth_iface_deinit(hapd);
 
524
        if (hapd->wpa_auth) {
 
525
                wpa_deinit(hapd->wpa_auth);
 
526
                hapd->wpa_auth = NULL;
 
527
 
 
528
                if (hostapd_set_privacy(hapd, 0)) {
 
529
                        wpa_printf(MSG_DEBUG, "Could not disable "
 
530
                                   "PrivacyInvoked for interface %s",
 
531
                                   hapd->conf->iface);
 
532
                }
 
533
 
 
534
                if (hostapd_set_generic_elem(hapd, (u8 *) "", 0)) {
 
535
                        wpa_printf(MSG_DEBUG, "Could not remove generic "
 
536
                                   "information element from interface %s",
 
537
                                   hapd->conf->iface);
 
538
                }
 
539
        }
 
540
        ieee802_1x_deinit(hapd);
 
541
 
 
542
#ifdef CONFIG_IEEE80211R
 
543
        l2_packet_deinit(hapd->l2);
 
544
#endif /* CONFIG_IEEE80211R */
 
545
}