Branch data Line data Source code
1 : : /*
2 : : * hostapd / WPA authenticator glue code
3 : : * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
4 : : *
5 : : * This software may be distributed under the terms of the BSD license.
6 : : * See README for more details.
7 : : */
8 : :
9 : : #include "utils/includes.h"
10 : :
11 : : #include "utils/common.h"
12 : : #include "common/ieee802_11_defs.h"
13 : : #include "common/sae.h"
14 : : #include "eapol_auth/eapol_auth_sm.h"
15 : : #include "eapol_auth/eapol_auth_sm_i.h"
16 : : #include "eap_server/eap.h"
17 : : #include "l2_packet/l2_packet.h"
18 : : #include "hostapd.h"
19 : : #include "ieee802_1x.h"
20 : : #include "preauth_auth.h"
21 : : #include "sta_info.h"
22 : : #include "tkip_countermeasures.h"
23 : : #include "ap_drv_ops.h"
24 : : #include "ap_config.h"
25 : : #include "wpa_auth.h"
26 : : #include "wpa_auth_glue.h"
27 : :
28 : :
29 : 350 : static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
30 : : struct hostapd_config *iconf,
31 : : struct wpa_auth_config *wconf)
32 : : {
33 : 350 : os_memset(wconf, 0, sizeof(*wconf));
34 : 350 : wconf->wpa = conf->wpa;
35 : 350 : wconf->wpa_key_mgmt = conf->wpa_key_mgmt;
36 : 350 : wconf->wpa_pairwise = conf->wpa_pairwise;
37 : 350 : wconf->wpa_group = conf->wpa_group;
38 : 350 : wconf->wpa_group_rekey = conf->wpa_group_rekey;
39 : 350 : wconf->wpa_strict_rekey = conf->wpa_strict_rekey;
40 : 350 : wconf->wpa_gmk_rekey = conf->wpa_gmk_rekey;
41 : 350 : wconf->wpa_ptk_rekey = conf->wpa_ptk_rekey;
42 : 350 : wconf->rsn_pairwise = conf->rsn_pairwise;
43 : 350 : wconf->rsn_preauth = conf->rsn_preauth;
44 : 350 : wconf->eapol_version = conf->eapol_version;
45 : 350 : wconf->peerkey = conf->peerkey;
46 : 350 : wconf->wmm_enabled = conf->wmm_enabled;
47 : 350 : wconf->wmm_uapsd = conf->wmm_uapsd;
48 : 350 : wconf->disable_pmksa_caching = conf->disable_pmksa_caching;
49 : 350 : wconf->okc = conf->okc;
50 : : #ifdef CONFIG_IEEE80211W
51 : 350 : wconf->ieee80211w = conf->ieee80211w;
52 : : #endif /* CONFIG_IEEE80211W */
53 : : #ifdef CONFIG_IEEE80211R
54 : 350 : wconf->ssid_len = conf->ssid.ssid_len;
55 [ - + ]: 350 : if (wconf->ssid_len > SSID_LEN)
56 : 0 : wconf->ssid_len = SSID_LEN;
57 : 350 : os_memcpy(wconf->ssid, conf->ssid.ssid, wconf->ssid_len);
58 : 350 : os_memcpy(wconf->mobility_domain, conf->mobility_domain,
59 : : MOBILITY_DOMAIN_ID_LEN);
60 [ + + ][ + - ]: 350 : if (conf->nas_identifier &&
61 : 65 : os_strlen(conf->nas_identifier) <= FT_R0KH_ID_MAX_LEN) {
62 : 65 : wconf->r0_key_holder_len = os_strlen(conf->nas_identifier);
63 : 65 : os_memcpy(wconf->r0_key_holder, conf->nas_identifier,
64 : : wconf->r0_key_holder_len);
65 : : }
66 : 350 : os_memcpy(wconf->r1_key_holder, conf->r1_key_holder, FT_R1KH_ID_LEN);
67 : 350 : wconf->r0_key_lifetime = conf->r0_key_lifetime;
68 : 350 : wconf->reassociation_deadline = conf->reassociation_deadline;
69 : 350 : wconf->r0kh_list = conf->r0kh_list;
70 : 350 : wconf->r1kh_list = conf->r1kh_list;
71 : 350 : wconf->pmk_r1_push = conf->pmk_r1_push;
72 : 350 : wconf->ft_over_ds = conf->ft_over_ds;
73 : : #endif /* CONFIG_IEEE80211R */
74 : : #ifdef CONFIG_HS20
75 : 350 : wconf->disable_gtk = conf->disable_dgaf;
76 [ + + ]: 350 : if (conf->osen) {
77 : 1 : wconf->disable_gtk = 1;
78 : 1 : wconf->wpa = WPA_PROTO_OSEN;
79 : 1 : wconf->wpa_key_mgmt = WPA_KEY_MGMT_OSEN;
80 : 1 : wconf->wpa_pairwise = 0;
81 : 1 : wconf->wpa_group = WPA_CIPHER_CCMP;
82 : 1 : wconf->rsn_pairwise = WPA_CIPHER_CCMP;
83 : 1 : wconf->rsn_preauth = 0;
84 : 1 : wconf->disable_pmksa_caching = 1;
85 : : #ifdef CONFIG_IEEE80211W
86 : 1 : wconf->ieee80211w = 1;
87 : : #endif /* CONFIG_IEEE80211W */
88 : : }
89 : : #endif /* CONFIG_HS20 */
90 : : #ifdef CONFIG_TESTING_OPTIONS
91 : 350 : wconf->corrupt_gtk_rekey_mic_probability =
92 : 350 : iconf->corrupt_gtk_rekey_mic_probability;
93 : : #endif /* CONFIG_TESTING_OPTIONS */
94 : : #ifdef CONFIG_P2P
95 : 82 : os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4);
96 : 82 : os_memcpy(wconf->ip_addr_mask, conf->ip_addr_mask, 4);
97 : 82 : os_memcpy(wconf->ip_addr_start, conf->ip_addr_start, 4);
98 : 82 : os_memcpy(wconf->ip_addr_end, conf->ip_addr_end, 4);
99 : : #endif /* CONFIG_P2P */
100 : 350 : }
101 : :
102 : :
103 : 3391 : static void hostapd_wpa_auth_logger(void *ctx, const u8 *addr,
104 : : logger_level level, const char *txt)
105 : : {
106 : : #ifndef CONFIG_NO_HOSTAPD_LOGGER
107 : 3391 : struct hostapd_data *hapd = ctx;
108 : : int hlevel;
109 : :
110 [ - + + ]: 3391 : switch (level) {
111 : : case LOGGER_WARNING:
112 : 0 : hlevel = HOSTAPD_LEVEL_WARNING;
113 : 0 : break;
114 : : case LOGGER_INFO:
115 : 411 : hlevel = HOSTAPD_LEVEL_INFO;
116 : 411 : break;
117 : : case LOGGER_DEBUG:
118 : : default:
119 : 2980 : hlevel = HOSTAPD_LEVEL_DEBUG;
120 : 2980 : break;
121 : : }
122 : :
123 : 3391 : hostapd_logger(hapd, addr, HOSTAPD_MODULE_WPA, hlevel, "%s", txt);
124 : : #endif /* CONFIG_NO_HOSTAPD_LOGGER */
125 : 3391 : }
126 : :
127 : :
128 : 7 : static void hostapd_wpa_auth_disconnect(void *ctx, const u8 *addr,
129 : : u16 reason)
130 : : {
131 : 7 : struct hostapd_data *hapd = ctx;
132 : 7 : wpa_printf(MSG_DEBUG, "%s: WPA authenticator requests disconnect: "
133 : : "STA " MACSTR " reason %d",
134 : 42 : __func__, MAC2STR(addr), reason);
135 : 7 : ap_sta_disconnect(hapd, NULL, addr, reason);
136 : 7 : }
137 : :
138 : :
139 : 0 : static int hostapd_wpa_auth_mic_failure_report(void *ctx, const u8 *addr)
140 : : {
141 : 0 : struct hostapd_data *hapd = ctx;
142 : 0 : return michael_mic_failure(hapd, addr, 0);
143 : : }
144 : :
145 : :
146 : 5112 : static void hostapd_wpa_auth_set_eapol(void *ctx, const u8 *addr,
147 : : wpa_eapol_variable var, int value)
148 : : {
149 : 5112 : struct hostapd_data *hapd = ctx;
150 : 5112 : struct sta_info *sta = ap_get_sta(hapd, addr);
151 [ - + ]: 5112 : if (sta == NULL)
152 : 5112 : return;
153 [ + + + + : 5112 : switch (var) {
+ + + +
- ]
154 : : case WPA_EAPOL_portEnabled:
155 : 1134 : ieee802_1x_notify_port_enabled(sta->eapol_sm, value);
156 : 1134 : break;
157 : : case WPA_EAPOL_portValid:
158 : 1140 : ieee802_1x_notify_port_valid(sta->eapol_sm, value);
159 : 1140 : break;
160 : : case WPA_EAPOL_authorized:
161 : 614 : ieee802_1x_set_sta_authorized(hapd, sta, value);
162 : 614 : break;
163 : : case WPA_EAPOL_portControl_Auto:
164 [ + + ]: 396 : if (sta->eapol_sm)
165 : 172 : sta->eapol_sm->portControl = Auto;
166 : 396 : break;
167 : : case WPA_EAPOL_keyRun:
168 [ + - ]: 180 : if (sta->eapol_sm)
169 : 180 : sta->eapol_sm->keyRun = value ? TRUE : FALSE;
170 : 180 : break;
171 : : case WPA_EAPOL_keyAvailable:
172 [ + + ]: 402 : if (sta->eapol_sm)
173 : 180 : sta->eapol_sm->eap_if->eapKeyAvailable =
174 : 180 : value ? TRUE : FALSE;
175 : 402 : break;
176 : : case WPA_EAPOL_keyDone:
177 [ + + ]: 402 : if (sta->eapol_sm)
178 : 180 : sta->eapol_sm->keyDone = value ? TRUE : FALSE;
179 : 402 : break;
180 : : case WPA_EAPOL_inc_EapolFramesTx:
181 [ + + ]: 844 : if (sta->eapol_sm)
182 : 362 : sta->eapol_sm->dot1xAuthEapolFramesTx++;
183 : 844 : break;
184 : : }
185 : : }
186 : :
187 : :
188 : 3389 : static int hostapd_wpa_auth_get_eapol(void *ctx, const u8 *addr,
189 : : wpa_eapol_variable var)
190 : : {
191 : 3389 : struct hostapd_data *hapd = ctx;
192 : 3389 : struct sta_info *sta = ap_get_sta(hapd, addr);
193 [ - + ][ + - ]: 3389 : if (sta == NULL || sta->eapol_sm == NULL)
194 : 0 : return -1;
195 [ + + - ]: 3389 : switch (var) {
196 : : case WPA_EAPOL_keyRun:
197 : 3209 : return sta->eapol_sm->keyRun;
198 : : case WPA_EAPOL_keyAvailable:
199 : 180 : return sta->eapol_sm->eap_if->eapKeyAvailable;
200 : : default:
201 : 3389 : return -1;
202 : : }
203 : : }
204 : :
205 : :
206 : 747 : static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
207 : : const u8 *p2p_dev_addr,
208 : : const u8 *prev_psk)
209 : : {
210 : 747 : struct hostapd_data *hapd = ctx;
211 : 747 : struct sta_info *sta = ap_get_sta(hapd, addr);
212 : : const u8 *psk;
213 : :
214 : : #ifdef CONFIG_SAE
215 [ + + ][ + - ]: 747 : if (sta && sta->auth_alg == WLAN_AUTH_SAE) {
216 [ + - ][ - + ]: 48 : if (!sta->sae || prev_psk)
217 : 0 : return NULL;
218 : 48 : return sta->sae->pmk;
219 : : }
220 : : #endif /* CONFIG_SAE */
221 : :
222 : 699 : psk = hostapd_get_psk(hapd->conf, addr, p2p_dev_addr, prev_psk);
223 : : /*
224 : : * This is about to iterate over all psks, prev_psk gives the last
225 : : * returned psk which should not be returned again.
226 : : * logic list (all hostapd_get_psk; all sta->psk)
227 : : */
228 [ - + ][ # # ]: 699 : if (sta && sta->psk && !psk) {
[ + - ]
229 : : struct hostapd_sta_wpa_psk_short *pos;
230 : 0 : psk = sta->psk->psk;
231 [ # # ]: 0 : for (pos = sta->psk; pos; pos = pos->next) {
232 [ # # ]: 0 : if (pos->psk == prev_psk) {
233 [ # # ]: 0 : psk = pos->next ? pos->next->psk : NULL;
234 : 0 : break;
235 : : }
236 : : }
237 : : }
238 : 747 : return psk;
239 : : }
240 : :
241 : :
242 : 175 : static int hostapd_wpa_auth_get_msk(void *ctx, const u8 *addr, u8 *msk,
243 : : size_t *len)
244 : : {
245 : 175 : struct hostapd_data *hapd = ctx;
246 : : const u8 *key;
247 : : size_t keylen;
248 : : struct sta_info *sta;
249 : :
250 : 175 : sta = ap_get_sta(hapd, addr);
251 [ - + ]: 175 : if (sta == NULL)
252 : 0 : return -1;
253 : :
254 : 175 : key = ieee802_1x_get_key(sta->eapol_sm, &keylen);
255 [ - + ]: 175 : if (key == NULL)
256 : 0 : return -1;
257 : :
258 [ - + ]: 175 : if (keylen > *len)
259 : 0 : keylen = *len;
260 : 175 : os_memcpy(msk, key, keylen);
261 : 175 : *len = keylen;
262 : :
263 : 175 : return 0;
264 : : }
265 : :
266 : :
267 : 3589 : static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
268 : : const u8 *addr, int idx, u8 *key,
269 : : size_t key_len)
270 : : {
271 : 3589 : struct hostapd_data *hapd = ctx;
272 : 3589 : const char *ifname = hapd->conf->iface;
273 : :
274 [ - + ]: 3589 : if (vlan_id > 0) {
275 : 0 : ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id);
276 [ # # ]: 0 : if (ifname == NULL)
277 : 0 : return -1;
278 : : }
279 : :
280 : 3589 : return hostapd_drv_set_key(ifname, hapd, alg, addr, idx, 1, NULL, 0,
281 : : key, key_len);
282 : : }
283 : :
284 : :
285 : 449 : static int hostapd_wpa_auth_get_seqnum(void *ctx, const u8 *addr, int idx,
286 : : u8 *seq)
287 : : {
288 : 449 : struct hostapd_data *hapd = ctx;
289 : 449 : return hostapd_get_seqnum(hapd->conf->iface, hapd, addr, idx, seq);
290 : : }
291 : :
292 : :
293 : 844 : static int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
294 : : const u8 *data, size_t data_len,
295 : : int encrypt)
296 : : {
297 : 844 : struct hostapd_data *hapd = ctx;
298 : : struct sta_info *sta;
299 : 844 : u32 flags = 0;
300 : :
301 : 844 : sta = ap_get_sta(hapd, addr);
302 [ + - ]: 844 : if (sta)
303 : 844 : flags = hostapd_sta_flags_to_drv(sta->flags);
304 : :
305 : 844 : return hostapd_drv_hapd_send_eapol(hapd, addr, data, data_len,
306 : : encrypt, flags);
307 : : }
308 : :
309 : :
310 : 60 : static int hostapd_wpa_auth_for_each_sta(
311 : : void *ctx, int (*cb)(struct wpa_state_machine *sm, void *ctx),
312 : : void *cb_ctx)
313 : : {
314 : 60 : struct hostapd_data *hapd = ctx;
315 : : struct sta_info *sta;
316 : :
317 [ + + ]: 119 : for (sta = hapd->sta_list; sta; sta = sta->next) {
318 [ + - ][ + + ]: 61 : if (sta->wpa_sm && cb(sta->wpa_sm, cb_ctx))
319 : 2 : return 1;
320 : : }
321 : 60 : return 0;
322 : : }
323 : :
324 : :
325 : : struct wpa_auth_iface_iter_data {
326 : : int (*cb)(struct wpa_authenticator *sm, void *ctx);
327 : : void *cb_ctx;
328 : : };
329 : :
330 : 1 : static int wpa_auth_iface_iter(struct hostapd_iface *iface, void *ctx)
331 : : {
332 : 1 : struct wpa_auth_iface_iter_data *data = ctx;
333 : : size_t i;
334 [ + - ]: 1 : for (i = 0; i < iface->num_bss; i++) {
335 [ + - + - ]: 2 : if (iface->bss[i]->wpa_auth &&
336 : 1 : data->cb(iface->bss[i]->wpa_auth, data->cb_ctx))
337 : 1 : return 1;
338 : : }
339 : 1 : return 0;
340 : : }
341 : :
342 : :
343 : 1 : static int hostapd_wpa_auth_for_each_auth(
344 : : void *ctx, int (*cb)(struct wpa_authenticator *sm, void *ctx),
345 : : void *cb_ctx)
346 : : {
347 : 1 : struct hostapd_data *hapd = ctx;
348 : : struct wpa_auth_iface_iter_data data;
349 [ + - ][ - + ]: 1 : if (hapd->iface->interfaces == NULL ||
350 : 1 : hapd->iface->interfaces->for_each_interface == NULL)
351 : 0 : return -1;
352 : 1 : data.cb = cb;
353 : 1 : data.cb_ctx = cb_ctx;
354 : 1 : return hapd->iface->interfaces->for_each_interface(
355 : 1 : hapd->iface->interfaces, wpa_auth_iface_iter, &data);
356 : : }
357 : :
358 : :
359 : : #ifdef CONFIG_IEEE80211R
360 : :
361 : : struct wpa_auth_ft_iface_iter_data {
362 : : struct hostapd_data *src_hapd;
363 : : const u8 *dst;
364 : : const u8 *data;
365 : : size_t data_len;
366 : : };
367 : :
368 : :
369 : 34 : static int hostapd_wpa_auth_ft_iter(struct hostapd_iface *iface, void *ctx)
370 : : {
371 : 34 : struct wpa_auth_ft_iface_iter_data *idata = ctx;
372 : : struct hostapd_data *hapd;
373 : : size_t j;
374 : :
375 [ + + ]: 48 : for (j = 0; j < iface->num_bss; j++) {
376 : 34 : hapd = iface->bss[j];
377 [ + + ]: 34 : if (hapd == idata->src_hapd)
378 : 14 : continue;
379 [ + - ]: 20 : if (os_memcmp(hapd->own_addr, idata->dst, ETH_ALEN) == 0) {
380 : 20 : wpa_printf(MSG_DEBUG, "FT: Send RRB data directly to "
381 : : "locally managed BSS " MACSTR "@%s -> "
382 : : MACSTR "@%s",
383 : 120 : MAC2STR(idata->src_hapd->own_addr),
384 : 20 : idata->src_hapd->conf->iface,
385 : 120 : MAC2STR(hapd->own_addr), hapd->conf->iface);
386 : 20 : wpa_ft_rrb_rx(hapd->wpa_auth,
387 : 20 : idata->src_hapd->own_addr,
388 : : idata->data, idata->data_len);
389 : 20 : return 1;
390 : : }
391 : : }
392 : :
393 : 34 : return 0;
394 : : }
395 : :
396 : : #endif /* CONFIG_IEEE80211R */
397 : :
398 : :
399 : 20 : static int hostapd_wpa_auth_send_ether(void *ctx, const u8 *dst, u16 proto,
400 : : const u8 *data, size_t data_len)
401 : : {
402 : 20 : struct hostapd_data *hapd = ctx;
403 : : struct l2_ethhdr *buf;
404 : : int ret;
405 : :
406 : : #ifdef CONFIG_IEEE80211R
407 [ + - ][ + - ]: 20 : if (proto == ETH_P_RRB && hapd->iface->interfaces &&
[ + - ]
408 : 20 : hapd->iface->interfaces->for_each_interface) {
409 : : int res;
410 : : struct wpa_auth_ft_iface_iter_data idata;
411 : 20 : idata.src_hapd = hapd;
412 : 20 : idata.dst = dst;
413 : 20 : idata.data = data;
414 : 20 : idata.data_len = data_len;
415 : 20 : res = hapd->iface->interfaces->for_each_interface(
416 : 20 : hapd->iface->interfaces, hostapd_wpa_auth_ft_iter,
417 : : &idata);
418 [ + - ]: 20 : if (res == 1)
419 : 20 : return data_len;
420 : : }
421 : : #endif /* CONFIG_IEEE80211R */
422 : :
423 [ # # ][ # # ]: 0 : if (hapd->driver && hapd->driver->send_ether)
424 : 0 : return hapd->driver->send_ether(hapd->drv_priv, dst,
425 : 0 : hapd->own_addr, proto,
426 : : data, data_len);
427 [ # # ]: 0 : if (hapd->l2 == NULL)
428 : 0 : return -1;
429 : :
430 : 0 : buf = os_malloc(sizeof(*buf) + data_len);
431 [ # # ]: 0 : if (buf == NULL)
432 : 0 : return -1;
433 : 0 : os_memcpy(buf->h_dest, dst, ETH_ALEN);
434 : 0 : os_memcpy(buf->h_source, hapd->own_addr, ETH_ALEN);
435 : 0 : buf->h_proto = host_to_be16(proto);
436 : 0 : os_memcpy(buf + 1, data, data_len);
437 : 0 : ret = l2_packet_send(hapd->l2, dst, proto, (u8 *) buf,
438 : : sizeof(*buf) + data_len);
439 : 0 : os_free(buf);
440 : 20 : return ret;
441 : : }
442 : :
443 : :
444 : : #ifdef CONFIG_IEEE80211R
445 : :
446 : 6 : static int hostapd_wpa_auth_send_ft_action(void *ctx, const u8 *dst,
447 : : const u8 *data, size_t data_len)
448 : : {
449 : 6 : struct hostapd_data *hapd = ctx;
450 : : int res;
451 : : struct ieee80211_mgmt *m;
452 : : size_t mlen;
453 : : struct sta_info *sta;
454 : :
455 : 6 : sta = ap_get_sta(hapd, dst);
456 [ - + ][ + - ]: 6 : if (sta == NULL || sta->wpa_sm == NULL)
457 : 0 : return -1;
458 : :
459 : 6 : m = os_zalloc(sizeof(*m) + data_len);
460 [ - + ]: 6 : if (m == NULL)
461 : 0 : return -1;
462 : 6 : mlen = ((u8 *) &m->u - (u8 *) m) + data_len;
463 : 6 : m->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
464 : : WLAN_FC_STYPE_ACTION);
465 : 6 : os_memcpy(m->da, dst, ETH_ALEN);
466 : 6 : os_memcpy(m->sa, hapd->own_addr, ETH_ALEN);
467 : 6 : os_memcpy(m->bssid, hapd->own_addr, ETH_ALEN);
468 : 6 : os_memcpy(&m->u, data, data_len);
469 : :
470 : 6 : res = hostapd_drv_send_mlme(hapd, (u8 *) m, mlen, 0);
471 : 6 : os_free(m);
472 : 6 : return res;
473 : : }
474 : :
475 : :
476 : : static struct wpa_state_machine *
477 : 6 : hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr)
478 : : {
479 : 6 : struct hostapd_data *hapd = ctx;
480 : : struct sta_info *sta;
481 : :
482 [ - + ]: 6 : if (hostapd_add_sta_node(hapd, sta_addr, WLAN_AUTH_FT) < 0)
483 : 0 : return NULL;
484 : :
485 : 6 : sta = ap_sta_add(hapd, sta_addr);
486 [ - + ]: 6 : if (sta == NULL)
487 : 0 : return NULL;
488 [ + + ]: 6 : if (sta->wpa_sm) {
489 : 3 : sta->auth_alg = WLAN_AUTH_FT;
490 : 3 : return sta->wpa_sm;
491 : : }
492 : :
493 : 3 : sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr, NULL);
494 [ - + ]: 3 : if (sta->wpa_sm == NULL) {
495 : 0 : ap_free_sta(hapd, sta);
496 : 0 : return NULL;
497 : : }
498 : 3 : sta->auth_alg = WLAN_AUTH_FT;
499 : :
500 : 6 : return sta->wpa_sm;
501 : : }
502 : :
503 : :
504 : 8 : static void hostapd_rrb_receive(void *ctx, const u8 *src_addr, const u8 *buf,
505 : : size_t len)
506 : : {
507 : 8 : struct hostapd_data *hapd = ctx;
508 : : struct l2_ethhdr *ethhdr;
509 [ - + ]: 8 : if (len < sizeof(*ethhdr))
510 : 8 : return;
511 : 8 : ethhdr = (struct l2_ethhdr *) buf;
512 : 8 : wpa_printf(MSG_DEBUG, "FT: RRB received packet " MACSTR " -> "
513 : 96 : MACSTR, MAC2STR(ethhdr->h_source), MAC2STR(ethhdr->h_dest));
514 : 8 : wpa_ft_rrb_rx(hapd->wpa_auth, ethhdr->h_source, buf + sizeof(*ethhdr),
515 : : len - sizeof(*ethhdr));
516 : : }
517 : :
518 : :
519 : 0 : static int hostapd_wpa_auth_add_tspec(void *ctx, const u8 *sta_addr,
520 : : u8 *tspec_ie, size_t tspec_ielen)
521 : : {
522 : 0 : struct hostapd_data *hapd = ctx;
523 : 0 : return hostapd_add_tspec(hapd, sta_addr, tspec_ie, tspec_ielen);
524 : : }
525 : :
526 : : #endif /* CONFIG_IEEE80211R */
527 : :
528 : :
529 : 348 : int hostapd_setup_wpa(struct hostapd_data *hapd)
530 : : {
531 : : struct wpa_auth_config _conf;
532 : : struct wpa_auth_callbacks cb;
533 : : const u8 *wpa_ie;
534 : : size_t wpa_ie_len;
535 : :
536 : 348 : hostapd_wpa_auth_conf(hapd->conf, hapd->iconf, &_conf);
537 [ + - ]: 348 : if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_EAPOL_TX_STATUS)
538 : 348 : _conf.tx_status = 1;
539 [ + - ]: 348 : if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_MLME)
540 : 348 : _conf.ap_mlme = 1;
541 : 348 : os_memset(&cb, 0, sizeof(cb));
542 : 348 : cb.ctx = hapd;
543 : 348 : cb.logger = hostapd_wpa_auth_logger;
544 : 348 : cb.disconnect = hostapd_wpa_auth_disconnect;
545 : 348 : cb.mic_failure_report = hostapd_wpa_auth_mic_failure_report;
546 : 348 : cb.set_eapol = hostapd_wpa_auth_set_eapol;
547 : 348 : cb.get_eapol = hostapd_wpa_auth_get_eapol;
548 : 348 : cb.get_psk = hostapd_wpa_auth_get_psk;
549 : 348 : cb.get_msk = hostapd_wpa_auth_get_msk;
550 : 348 : cb.set_key = hostapd_wpa_auth_set_key;
551 : 348 : cb.get_seqnum = hostapd_wpa_auth_get_seqnum;
552 : 348 : cb.send_eapol = hostapd_wpa_auth_send_eapol;
553 : 348 : cb.for_each_sta = hostapd_wpa_auth_for_each_sta;
554 : 348 : cb.for_each_auth = hostapd_wpa_auth_for_each_auth;
555 : 348 : cb.send_ether = hostapd_wpa_auth_send_ether;
556 : : #ifdef CONFIG_IEEE80211R
557 : 348 : cb.send_ft_action = hostapd_wpa_auth_send_ft_action;
558 : 348 : cb.add_sta = hostapd_wpa_auth_add_sta;
559 : 348 : cb.add_tspec = hostapd_wpa_auth_add_tspec;
560 : : #endif /* CONFIG_IEEE80211R */
561 : 348 : hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb);
562 [ - + ]: 348 : if (hapd->wpa_auth == NULL) {
563 : 0 : wpa_printf(MSG_ERROR, "WPA initialization failed.");
564 : 0 : return -1;
565 : : }
566 : :
567 [ - + ]: 348 : if (hostapd_set_privacy(hapd, 1)) {
568 : 0 : wpa_printf(MSG_ERROR, "Could not set PrivacyInvoked "
569 : 0 : "for interface %s", hapd->conf->iface);
570 : 0 : return -1;
571 : : }
572 : :
573 : 348 : wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
574 [ - + ]: 348 : if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) {
575 : 0 : wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
576 : : "the kernel driver.");
577 : 0 : return -1;
578 : : }
579 : :
580 [ - + ]: 348 : if (rsn_preauth_iface_init(hapd)) {
581 : 0 : wpa_printf(MSG_ERROR, "Initialization of RSN "
582 : : "pre-authentication failed.");
583 : 0 : return -1;
584 : : }
585 : :
586 : : #ifdef CONFIG_IEEE80211R
587 [ + - ]: 348 : if (!hostapd_drv_none(hapd)) {
588 [ - + ]: 348 : hapd->l2 = l2_packet_init(hapd->conf->bridge[0] ?
589 : 0 : hapd->conf->bridge :
590 : 348 : hapd->conf->iface, NULL, ETH_P_RRB,
591 : : hostapd_rrb_receive, hapd, 1);
592 [ # # ][ - + ]: 348 : if (hapd->l2 == NULL &&
593 [ # # ]: 0 : (hapd->driver == NULL ||
594 : 0 : hapd->driver->send_ether == NULL)) {
595 : 0 : wpa_printf(MSG_ERROR, "Failed to open l2_packet "
596 : : "interface");
597 : 0 : return -1;
598 : : }
599 : : }
600 : : #endif /* CONFIG_IEEE80211R */
601 : :
602 : 348 : return 0;
603 : :
604 : : }
605 : :
606 : :
607 : 2 : void hostapd_reconfig_wpa(struct hostapd_data *hapd)
608 : : {
609 : : struct wpa_auth_config wpa_auth_conf;
610 : 2 : hostapd_wpa_auth_conf(hapd->conf, hapd->iconf, &wpa_auth_conf);
611 : 2 : wpa_reconfig(hapd->wpa_auth, &wpa_auth_conf);
612 : 2 : }
613 : :
614 : :
615 : 429 : void hostapd_deinit_wpa(struct hostapd_data *hapd)
616 : : {
617 : 429 : ieee80211_tkip_countermeasures_deinit(hapd);
618 : 429 : rsn_preauth_iface_deinit(hapd);
619 [ + + ]: 429 : if (hapd->wpa_auth) {
620 : 348 : wpa_deinit(hapd->wpa_auth);
621 : 348 : hapd->wpa_auth = NULL;
622 : :
623 [ - + ]: 348 : if (hostapd_set_privacy(hapd, 0)) {
624 : 0 : wpa_printf(MSG_DEBUG, "Could not disable "
625 : : "PrivacyInvoked for interface %s",
626 : 0 : hapd->conf->iface);
627 : : }
628 : :
629 [ - + ]: 348 : if (hostapd_set_generic_elem(hapd, (u8 *) "", 0)) {
630 : 0 : wpa_printf(MSG_DEBUG, "Could not remove generic "
631 : : "information element from interface %s",
632 : 0 : hapd->conf->iface);
633 : : }
634 : : }
635 : 429 : ieee802_1x_deinit(hapd);
636 : :
637 : : #ifdef CONFIG_IEEE80211R
638 : 429 : l2_packet_deinit(hapd->l2);
639 : 429 : hapd->l2 = NULL;
640 : : #endif /* CONFIG_IEEE80211R */
641 : 429 : }
|