~ubuntu-branches/ubuntu/precise/wpasupplicant/precise-security

« back to all changes in this revision

Viewing changes to .pc/0004-sme-extend-load-balancing-optimization-in-bss-blacklisting.patch/wpa_supplicant/events.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-10-10 09:23:53 UTC
  • mfrom: (18.1.2 precise-proposed)
  • Revision ID: package-import@ubuntu.com-20141010092353-zo940kiyc1tqwcyi
Tags: 0.7.3-6ubuntu2.3
* SECURITY UPDATE: arbitrary command execution via unsanitized string
  passed to action scripts by wpa_cli
  - debian/patches/CVE-2014-3686.patch: added os_exec() helper to
    src/utils/os.h, src/utils/os_unix.c, src/utils/os_win32.c,
    use instead of system() in wpa_supplicant/wpa_cli.c.
  - CVE-2014-3686

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * WPA Supplicant - Driver event processing
 
3
 * Copyright (c) 2003-2010, 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
 
 
17
#include "common.h"
 
18
#include "eapol_supp/eapol_supp_sm.h"
 
19
#include "rsn_supp/wpa.h"
 
20
#include "eloop.h"
 
21
#include "config.h"
 
22
#include "l2_packet/l2_packet.h"
 
23
#include "wpa_supplicant_i.h"
 
24
#include "driver_i.h"
 
25
#include "pcsc_funcs.h"
 
26
#include "rsn_supp/preauth.h"
 
27
#include "rsn_supp/pmksa_cache.h"
 
28
#include "common/wpa_ctrl.h"
 
29
#include "eap_peer/eap.h"
 
30
#include "ap/hostapd.h"
 
31
#include "notify.h"
 
32
#include "common/ieee802_11_defs.h"
 
33
#include "blacklist.h"
 
34
#include "wpas_glue.h"
 
35
#include "wps_supplicant.h"
 
36
#include "ibss_rsn.h"
 
37
#include "sme.h"
 
38
#include "bgscan.h"
 
39
#include "ap.h"
 
40
#include "bss.h"
 
41
#include "mlme.h"
 
42
#include "scan.h"
 
43
 
 
44
 
 
45
static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
 
46
{
 
47
        struct wpa_ssid *ssid, *old_ssid;
 
48
 
 
49
        if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid)
 
50
                return 0;
 
51
 
 
52
        wpa_printf(MSG_DEBUG, "Select network based on association "
 
53
                   "information");
 
54
        ssid = wpa_supplicant_get_ssid(wpa_s);
 
55
        if (ssid == NULL) {
 
56
                wpa_printf(MSG_INFO, "No network configuration found for the "
 
57
                           "current AP");
 
58
                return -1;
 
59
        }
 
60
 
 
61
        if (ssid->disabled) {
 
62
                wpa_printf(MSG_DEBUG, "Selected network is disabled");
 
63
                return -1;
 
64
        }
 
65
 
 
66
        wpa_printf(MSG_DEBUG, "Network configuration found for the current "
 
67
                   "AP");
 
68
        if (ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X |
 
69
                              WPA_KEY_MGMT_WPA_NONE |
 
70
                              WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_FT_IEEE8021X |
 
71
                              WPA_KEY_MGMT_PSK_SHA256 |
 
72
                              WPA_KEY_MGMT_IEEE8021X_SHA256)) {
 
73
                u8 wpa_ie[80];
 
74
                size_t wpa_ie_len = sizeof(wpa_ie);
 
75
                wpa_supplicant_set_suites(wpa_s, NULL, ssid,
 
76
                                          wpa_ie, &wpa_ie_len);
 
77
        } else {
 
78
                wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
 
79
        }
 
80
 
 
81
        if (wpa_s->current_ssid && wpa_s->current_ssid != ssid)
 
82
                eapol_sm_invalidate_cached_session(wpa_s->eapol);
 
83
        old_ssid = wpa_s->current_ssid;
 
84
        wpa_s->current_ssid = ssid;
 
85
        wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
 
86
        wpa_supplicant_initiate_eapol(wpa_s);
 
87
        if (old_ssid != wpa_s->current_ssid)
 
88
                wpas_notify_network_changed(wpa_s);
 
89
 
 
90
        return 0;
 
91
}
 
92
 
 
93
 
 
94
static void wpa_supplicant_stop_countermeasures(void *eloop_ctx,
 
95
                                                void *sock_ctx)
 
96
{
 
97
        struct wpa_supplicant *wpa_s = eloop_ctx;
 
98
 
 
99
        if (wpa_s->countermeasures) {
 
100
                wpa_s->countermeasures = 0;
 
101
                wpa_drv_set_countermeasures(wpa_s, 0);
 
102
                wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped");
 
103
                wpa_supplicant_req_scan(wpa_s, 0, 0);
 
104
        }
 
105
}
 
106
 
 
107
 
 
108
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
 
109
{
 
110
        int bssid_changed;
 
111
 
 
112
        wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
 
113
        bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
 
114
        os_memset(wpa_s->bssid, 0, ETH_ALEN);
 
115
        os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
 
116
        wpa_s->current_bss = NULL;
 
117
        if (bssid_changed)
 
118
                wpas_notify_bssid_changed(wpa_s);
 
119
 
 
120
        eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
 
121
        eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
 
122
        if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
 
123
                eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
 
124
        wpa_s->ap_ies_from_associnfo = 0;
 
125
}
 
126
 
 
127
 
 
128
static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
 
129
{
 
130
        struct wpa_ie_data ie;
 
131
        int pmksa_set = -1;
 
132
        size_t i;
 
133
 
 
134
        if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
 
135
            ie.pmkid == NULL)
 
136
                return;
 
137
 
 
138
        for (i = 0; i < ie.num_pmkid; i++) {
 
139
                pmksa_set = pmksa_cache_set_current(wpa_s->wpa,
 
140
                                                    ie.pmkid + i * PMKID_LEN,
 
141
                                                    NULL, NULL, 0);
 
142
                if (pmksa_set == 0) {
 
143
                        eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
 
144
                        break;
 
145
                }
 
146
        }
 
147
 
 
148
        wpa_printf(MSG_DEBUG, "RSN: PMKID from assoc IE %sfound from PMKSA "
 
149
                   "cache", pmksa_set == 0 ? "" : "not ");
 
150
}
 
151
 
 
152
 
 
153
static void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s,
 
154
                                                 union wpa_event_data *data)
 
155
{
 
156
        if (data == NULL) {
 
157
                wpa_printf(MSG_DEBUG, "RSN: No data in PMKID candidate event");
 
158
                return;
 
159
        }
 
160
        wpa_printf(MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR
 
161
                   " index=%d preauth=%d",
 
162
                   MAC2STR(data->pmkid_candidate.bssid),
 
163
                   data->pmkid_candidate.index,
 
164
                   data->pmkid_candidate.preauth);
 
165
 
 
166
        pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid,
 
167
                            data->pmkid_candidate.index,
 
168
                            data->pmkid_candidate.preauth);
 
169
}
 
170
 
 
171
 
 
172
static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
 
173
{
 
174
        if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
 
175
            wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
 
176
                return 0;
 
177
 
 
178
#ifdef IEEE8021X_EAPOL
 
179
        if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
 
180
            wpa_s->current_ssid &&
 
181
            !(wpa_s->current_ssid->eapol_flags &
 
182
              (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
 
183
               EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) {
 
184
                /* IEEE 802.1X, but not using dynamic WEP keys (i.e., either
 
185
                 * plaintext or static WEP keys). */
 
186
                return 0;
 
187
        }
 
188
#endif /* IEEE8021X_EAPOL */
 
189
 
 
190
        return 1;
 
191
}
 
192
 
 
193
 
 
194
/**
 
195
 * wpa_supplicant_scard_init - Initialize SIM/USIM access with PC/SC
 
196
 * @wpa_s: pointer to wpa_supplicant data
 
197
 * @ssid: Configuration data for the network
 
198
 * Returns: 0 on success, -1 on failure
 
199
 *
 
200
 * This function is called when starting authentication with a network that is
 
201
 * configured to use PC/SC for SIM/USIM access (EAP-SIM or EAP-AKA).
 
202
 */
 
203
int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
 
204
                              struct wpa_ssid *ssid)
 
205
{
 
206
#ifdef IEEE8021X_EAPOL
 
207
        int aka = 0, sim = 0, type;
 
208
 
 
209
        if (ssid->eap.pcsc == NULL || wpa_s->scard != NULL)
 
210
                return 0;
 
211
 
 
212
        if (ssid->eap.eap_methods == NULL) {
 
213
                sim = 1;
 
214
                aka = 1;
 
215
        } else {
 
216
                struct eap_method_type *eap = ssid->eap.eap_methods;
 
217
                while (eap->vendor != EAP_VENDOR_IETF ||
 
218
                       eap->method != EAP_TYPE_NONE) {
 
219
                        if (eap->vendor == EAP_VENDOR_IETF) {
 
220
                                if (eap->method == EAP_TYPE_SIM)
 
221
                                        sim = 1;
 
222
                                else if (eap->method == EAP_TYPE_AKA)
 
223
                                        aka = 1;
 
224
                        }
 
225
                        eap++;
 
226
                }
 
227
        }
 
228
 
 
229
        if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL)
 
230
                sim = 0;
 
231
        if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL)
 
232
                aka = 0;
 
233
 
 
234
        if (!sim && !aka) {
 
235
                wpa_printf(MSG_DEBUG, "Selected network is configured to use "
 
236
                           "SIM, but neither EAP-SIM nor EAP-AKA are enabled");
 
237
                return 0;
 
238
        }
 
239
 
 
240
        wpa_printf(MSG_DEBUG, "Selected network is configured to use SIM "
 
241
                   "(sim=%d aka=%d) - initialize PCSC", sim, aka);
 
242
        if (sim && aka)
 
243
                type = SCARD_TRY_BOTH;
 
244
        else if (aka)
 
245
                type = SCARD_USIM_ONLY;
 
246
        else
 
247
                type = SCARD_GSM_SIM_ONLY;
 
248
 
 
249
        wpa_s->scard = scard_init(type);
 
250
        if (wpa_s->scard == NULL) {
 
251
                wpa_printf(MSG_WARNING, "Failed to initialize SIM "
 
252
                           "(pcsc-lite)");
 
253
                return -1;
 
254
        }
 
255
        wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
 
256
        eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
 
257
#endif /* IEEE8021X_EAPOL */
 
258
 
 
259
        return 0;
 
260
}
 
261
 
 
262
 
 
263
#ifndef CONFIG_NO_SCAN_PROCESSING
 
264
static int wpa_supplicant_match_privacy(struct wpa_scan_res *bss,
 
265
                                        struct wpa_ssid *ssid)
 
266
{
 
267
        int i, privacy = 0;
 
268
 
 
269
        if (ssid->mixed_cell)
 
270
                return 1;
 
271
 
 
272
#ifdef CONFIG_WPS
 
273
        if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
 
274
                return 1;
 
275
#endif /* CONFIG_WPS */
 
276
 
 
277
        for (i = 0; i < NUM_WEP_KEYS; i++) {
 
278
                if (ssid->wep_key_len[i]) {
 
279
                        privacy = 1;
 
280
                        break;
 
281
                }
 
282
        }
 
283
#ifdef IEEE8021X_EAPOL
 
284
        if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
 
285
            ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
 
286
                                 EAPOL_FLAG_REQUIRE_KEY_BROADCAST))
 
287
                privacy = 1;
 
288
#endif /* IEEE8021X_EAPOL */
 
289
 
 
290
        if (bss->caps & IEEE80211_CAP_PRIVACY)
 
291
                return privacy;
 
292
        return !privacy;
 
293
}
 
294
 
 
295
 
 
296
static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
 
297
                                         struct wpa_ssid *ssid,
 
298
                                         struct wpa_scan_res *bss)
 
299
{
 
300
        struct wpa_ie_data ie;
 
301
        int proto_match = 0;
 
302
        const u8 *rsn_ie, *wpa_ie;
 
303
        int ret;
 
304
 
 
305
        ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
 
306
        if (ret >= 0)
 
307
                return ret;
 
308
 
 
309
        rsn_ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
 
310
        while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
 
311
                proto_match++;
 
312
 
 
313
                if (wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
 
314
                        wpa_printf(MSG_DEBUG, "   skip RSN IE - parse failed");
 
315
                        break;
 
316
                }
 
317
                if (!(ie.proto & ssid->proto)) {
 
318
                        wpa_printf(MSG_DEBUG, "   skip RSN IE - proto "
 
319
                                   "mismatch");
 
320
                        break;
 
321
                }
 
322
 
 
323
                if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
 
324
                        wpa_printf(MSG_DEBUG, "   skip RSN IE - PTK cipher "
 
325
                                   "mismatch");
 
326
                        break;
 
327
                }
 
328
 
 
329
                if (!(ie.group_cipher & ssid->group_cipher)) {
 
330
                        wpa_printf(MSG_DEBUG, "   skip RSN IE - GTK cipher "
 
331
                                   "mismatch");
 
332
                        break;
 
333
                }
 
334
 
 
335
                if (!(ie.key_mgmt & ssid->key_mgmt)) {
 
336
                        wpa_printf(MSG_DEBUG, "   skip RSN IE - key mgmt "
 
337
                                   "mismatch");
 
338
                        break;
 
339
                }
 
340
 
 
341
#ifdef CONFIG_IEEE80211W
 
342
                if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
 
343
                    ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
 
344
                        wpa_printf(MSG_DEBUG, "   skip RSN IE - no mgmt frame "
 
345
                                   "protection");
 
346
                        break;
 
347
                }
 
348
#endif /* CONFIG_IEEE80211W */
 
349
 
 
350
                wpa_printf(MSG_DEBUG, "   selected based on RSN IE");
 
351
                return 1;
 
352
        }
 
353
 
 
354
        wpa_ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
 
355
        while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
 
356
                proto_match++;
 
357
 
 
358
                if (wpa_parse_wpa_ie(wpa_ie, 2 + wpa_ie[1], &ie)) {
 
359
                        wpa_printf(MSG_DEBUG, "   skip WPA IE - parse failed");
 
360
                        break;
 
361
                }
 
362
                if (!(ie.proto & ssid->proto)) {
 
363
                        wpa_printf(MSG_DEBUG, "   skip WPA IE - proto "
 
364
                                   "mismatch");
 
365
                        break;
 
366
                }
 
367
 
 
368
                if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
 
369
                        wpa_printf(MSG_DEBUG, "   skip WPA IE - PTK cipher "
 
370
                                   "mismatch");
 
371
                        break;
 
372
                }
 
373
 
 
374
                if (!(ie.group_cipher & ssid->group_cipher)) {
 
375
                        wpa_printf(MSG_DEBUG, "   skip WPA IE - GTK cipher "
 
376
                                   "mismatch");
 
377
                        break;
 
378
                }
 
379
 
 
380
                if (!(ie.key_mgmt & ssid->key_mgmt)) {
 
381
                        wpa_printf(MSG_DEBUG, "   skip WPA IE - key mgmt "
 
382
                                   "mismatch");
 
383
                        break;
 
384
                }
 
385
 
 
386
                wpa_printf(MSG_DEBUG, "   selected based on WPA IE");
 
387
                return 1;
 
388
        }
 
389
 
 
390
        if (proto_match == 0)
 
391
                wpa_printf(MSG_DEBUG, "   skip - no WPA/RSN proto match");
 
392
 
 
393
        return 0;
 
394
}
 
395
 
 
396
 
 
397
static int freq_allowed(int *freqs, int freq)
 
398
{
 
399
        int i;
 
400
 
 
401
        if (freqs == NULL)
 
402
                return 1;
 
403
 
 
404
        for (i = 0; freqs[i]; i++)
 
405
                if (freqs[i] == freq)
 
406
                        return 1;
 
407
        return 0;
 
408
}
 
409
 
 
410
 
 
411
static struct wpa_bss *
 
412
wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
 
413
                              struct wpa_scan_results *scan_res,
 
414
                              struct wpa_ssid *group,
 
415
                              struct wpa_ssid **selected_ssid)
 
416
{
 
417
        struct wpa_ssid *ssid;
 
418
        struct wpa_scan_res *bss;
 
419
        size_t i;
 
420
        struct wpa_blacklist *e;
 
421
        const u8 *ie;
 
422
 
 
423
        wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP");
 
424
        for (i = 0; i < scan_res->num; i++) {
 
425
                const u8 *ssid_;
 
426
                u8 wpa_ie_len, rsn_ie_len, ssid_len;
 
427
                bss = scan_res->res[i];
 
428
 
 
429
                ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
 
430
                ssid_ = ie ? ie + 2 : (u8 *) "";
 
431
                ssid_len = ie ? ie[1] : 0;
 
432
 
 
433
                ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
 
434
                wpa_ie_len = ie ? ie[1] : 0;
 
435
 
 
436
                ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
 
437
                rsn_ie_len = ie ? ie[1] : 0;
 
438
 
 
439
                wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
 
440
                           "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x",
 
441
                           (int) i, MAC2STR(bss->bssid),
 
442
                           wpa_ssid_txt(ssid_, ssid_len),
 
443
                           wpa_ie_len, rsn_ie_len, bss->caps);
 
444
 
 
445
                e = wpa_blacklist_get(wpa_s, bss->bssid);
 
446
                if (e) {
 
447
                        int limit = 1;
 
448
                        if (wpa_supplicant_enabled_networks(wpa_s->conf) == 1) {
 
449
                                /*
 
450
                                 * When only a single network is enabled, we can
 
451
                                 * trigger blacklisting on the first failure. This
 
452
                                 * should not be done with multiple enabled networks to
 
453
                                 * avoid getting forced to move into a worse ESS on
 
454
                                 * single error if there are no other BSSes of the
 
455
                                 * current ESS.
 
456
                                 */
 
457
                                limit = 0;
 
458
                        }
 
459
                        if (e->count > limit) {
 
460
                                wpa_printf(MSG_DEBUG, "   skip - blacklisted "
 
461
                                           "(count=%d limit=%d)", e->count, limit);
 
462
                                continue;
 
463
                        }
 
464
                }
 
465
 
 
466
                if (ssid_len == 0) {
 
467
                        wpa_printf(MSG_DEBUG, "   skip - SSID not known");
 
468
                        continue;
 
469
                }
 
470
 
 
471
                if (wpa_ie_len == 0 && rsn_ie_len == 0) {
 
472
                        wpa_printf(MSG_DEBUG, "   skip - no WPA/RSN IE");
 
473
                        continue;
 
474
                }
 
475
 
 
476
                for (ssid = group; ssid; ssid = ssid->pnext) {
 
477
                        int check_ssid = 1;
 
478
 
 
479
                        if (ssid->disabled) {
 
480
                                wpa_printf(MSG_DEBUG, "   skip - disabled");
 
481
                                continue;
 
482
                        }
 
483
 
 
484
#ifdef CONFIG_WPS
 
485
                        if (ssid->ssid_len == 0 &&
 
486
                            wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
 
487
                                check_ssid = 0;
 
488
#endif /* CONFIG_WPS */
 
489
 
 
490
                        if (check_ssid &&
 
491
                            (ssid_len != ssid->ssid_len ||
 
492
                             os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
 
493
                                wpa_printf(MSG_DEBUG, "   skip - "
 
494
                                           "SSID mismatch");
 
495
                                continue;
 
496
                        }
 
497
 
 
498
                        if (ssid->bssid_set &&
 
499
                            os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
 
500
                        {
 
501
                                wpa_printf(MSG_DEBUG, "   skip - "
 
502
                                           "BSSID mismatch");
 
503
                                continue;
 
504
                        }
 
505
 
 
506
                        if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
 
507
                                continue;
 
508
 
 
509
                        if (!freq_allowed(ssid->freq_list, bss->freq)) {
 
510
                                wpa_printf(MSG_DEBUG, "   skip - "
 
511
                                           "frequency not allowed");
 
512
                                continue;
 
513
                        }
 
514
 
 
515
                        wpa_printf(MSG_DEBUG, "   selected WPA AP "
 
516
                                   MACSTR " ssid='%s'",
 
517
                                   MAC2STR(bss->bssid),
 
518
                                   wpa_ssid_txt(ssid_, ssid_len));
 
519
                        *selected_ssid = ssid;
 
520
                        return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len);
 
521
                }
 
522
        }
 
523
 
 
524
        return NULL;
 
525
}
 
526
 
 
527
 
 
528
static struct wpa_bss *
 
529
wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
 
530
                                  struct wpa_scan_results *scan_res,
 
531
                                  struct wpa_ssid *group,
 
532
                                  struct wpa_ssid **selected_ssid)
 
533
{
 
534
        struct wpa_ssid *ssid;
 
535
        struct wpa_scan_res *bss;
 
536
        size_t i;
 
537
        struct wpa_blacklist *e;
 
538
        const u8 *ie;
 
539
 
 
540
        wpa_printf(MSG_DEBUG, "Try to find non-WPA AP");
 
541
        for (i = 0; i < scan_res->num; i++) {
 
542
                const u8 *ssid_;
 
543
                u8 wpa_ie_len, rsn_ie_len, ssid_len;
 
544
                bss = scan_res->res[i];
 
545
 
 
546
                ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
 
547
                ssid_ = ie ? ie + 2 : (u8 *) "";
 
548
                ssid_len = ie ? ie[1] : 0;
 
549
 
 
550
                ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
 
551
                wpa_ie_len = ie ? ie[1] : 0;
 
552
 
 
553
                ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
 
554
                rsn_ie_len = ie ? ie[1] : 0;
 
555
 
 
556
                wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
 
557
                           "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x",
 
558
                           (int) i, MAC2STR(bss->bssid),
 
559
                           wpa_ssid_txt(ssid_, ssid_len),
 
560
                           wpa_ie_len, rsn_ie_len, bss->caps);
 
561
 
 
562
                e = wpa_blacklist_get(wpa_s, bss->bssid);
 
563
                if (e && e->count > 1) {
 
564
                        wpa_printf(MSG_DEBUG, "   skip - blacklisted");
 
565
                        continue;
 
566
                }
 
567
 
 
568
                if (ssid_len == 0) {
 
569
                        wpa_printf(MSG_DEBUG, "   skip - SSID not known");
 
570
                        continue;
 
571
                }
 
572
 
 
573
                for (ssid = group; ssid; ssid = ssid->pnext) {
 
574
                        int check_ssid = ssid->ssid_len != 0;
 
575
 
 
576
                        if (ssid->disabled) {
 
577
                                wpa_printf(MSG_DEBUG, "   skip - disabled");
 
578
                                continue;
 
579
                        }
 
580
 
 
581
#ifdef CONFIG_WPS
 
582
                        if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
 
583
                                /* Only allow wildcard SSID match if an AP
 
584
                                 * advertises active WPS operation that matches
 
585
                                 * with our mode. */
 
586
                                check_ssid = 1;
 
587
                                if (ssid->ssid_len == 0 &&
 
588
                                    wpas_wps_ssid_wildcard_ok(wpa_s, ssid,
 
589
                                                              bss))
 
590
                                        check_ssid = 0;
 
591
                        }
 
592
#endif /* CONFIG_WPS */
 
593
 
 
594
                        if (check_ssid &&
 
595
                            (ssid_len != ssid->ssid_len ||
 
596
                             os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
 
597
                                wpa_printf(MSG_DEBUG, "   skip - "
 
598
                                           "SSID mismatch");
 
599
                                continue;
 
600
                        }
 
601
 
 
602
                        if (ssid->bssid_set &&
 
603
                            os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
 
604
                        {
 
605
                                wpa_printf(MSG_DEBUG, "   skip - "
 
606
                                           "BSSID mismatch");
 
607
                                continue;
 
608
                        }
 
609
 
 
610
                        if (!(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
 
611
                            !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
 
612
                            !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA))
 
613
                        {
 
614
                                wpa_printf(MSG_DEBUG, "   skip - "
 
615
                                           "non-WPA network not allowed");
 
616
                                continue;
 
617
                        }
 
618
 
 
619
                        if ((ssid->key_mgmt &
 
620
                             (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK |
 
621
                              WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK |
 
622
                              WPA_KEY_MGMT_IEEE8021X_SHA256 |
 
623
                              WPA_KEY_MGMT_PSK_SHA256)) &&
 
624
                            (wpa_ie_len != 0 || rsn_ie_len != 0)) {
 
625
                                wpa_printf(MSG_DEBUG, "   skip - "
 
626
                                           "WPA network");
 
627
                                continue;
 
628
                        }
 
629
 
 
630
                        if (!wpa_supplicant_match_privacy(bss, ssid)) {
 
631
                                wpa_printf(MSG_DEBUG, "   skip - "
 
632
                                           "privacy mismatch");
 
633
                                continue;
 
634
                        }
 
635
 
 
636
                        if (bss->caps & IEEE80211_CAP_IBSS) {
 
637
                                wpa_printf(MSG_DEBUG, "   skip - "
 
638
                                           "IBSS (adhoc) network");
 
639
                                continue;
 
640
                        }
 
641
 
 
642
                        if (!freq_allowed(ssid->freq_list, bss->freq)) {
 
643
                                wpa_printf(MSG_DEBUG, "   skip - "
 
644
                                           "frequency not allowed");
 
645
                                continue;
 
646
                        }
 
647
 
 
648
                        wpa_printf(MSG_DEBUG, "   selected non-WPA AP "
 
649
                                   MACSTR " ssid='%s'",
 
650
                                   MAC2STR(bss->bssid),
 
651
                                   wpa_ssid_txt(ssid_, ssid_len));
 
652
                        *selected_ssid = ssid;
 
653
                        return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len);
 
654
                }
 
655
        }
 
656
 
 
657
        return NULL;
 
658
}
 
659
 
 
660
 
 
661
static struct wpa_bss *
 
662
wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
 
663
                          struct wpa_scan_results *scan_res,
 
664
                          struct wpa_ssid *group,
 
665
                          struct wpa_ssid **selected_ssid)
 
666
{
 
667
        struct wpa_bss *selected;
 
668
 
 
669
        wpa_printf(MSG_DEBUG, "Selecting BSS from priority group %d",
 
670
                   group->priority);
 
671
 
 
672
        /* First, try to find WPA-enabled AP */
 
673
        selected = wpa_supplicant_select_bss_wpa(wpa_s, scan_res, group,
 
674
                                                 selected_ssid);
 
675
        if (selected)
 
676
                return selected;
 
677
 
 
678
        /* If no WPA-enabled AP found, try to find non-WPA AP, if configuration
 
679
         * allows this. */
 
680
        return wpa_supplicant_select_bss_non_wpa(wpa_s, scan_res, group,
 
681
                                                 selected_ssid);
 
682
}
 
683
 
 
684
 
 
685
static struct wpa_bss *
 
686
wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
 
687
                            struct wpa_scan_results *scan_res,
 
688
                            struct wpa_ssid **selected_ssid)
 
689
{
 
690
        struct wpa_bss *selected = NULL;
 
691
        int prio;
 
692
 
 
693
        while (selected == NULL) {
 
694
                for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
 
695
                        selected = wpa_supplicant_select_bss(
 
696
                                wpa_s, scan_res, wpa_s->conf->pssid[prio],
 
697
                                selected_ssid);
 
698
                        if (selected)
 
699
                                break;
 
700
                }
 
701
 
 
702
                if (selected == NULL && wpa_s->blacklist) {
 
703
                        wpa_printf(MSG_DEBUG, "No APs found - clear blacklist "
 
704
                                   "and try again");
 
705
                        wpa_blacklist_clear(wpa_s);
 
706
                        wpa_s->blacklist_cleared++;
 
707
                } else if (selected == NULL)
 
708
                        break;
 
709
        }
 
710
 
 
711
        return selected;
 
712
}
 
713
 
 
714
 
 
715
static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
 
716
                                        int timeout_sec, int timeout_usec)
 
717
{
 
718
        if (!wpa_supplicant_enabled_networks(wpa_s->conf)) {
 
719
                /*
 
720
                 * No networks are enabled; short-circuit request so
 
721
                 * we don't wait timeout seconds before transitioning
 
722
                 * to INACTIVE state.
 
723
                 */
 
724
                wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
 
725
                return;
 
726
        }
 
727
        wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
 
728
}
 
729
 
 
730
 
 
731
void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
 
732
                            struct wpa_bss *selected,
 
733
                            struct wpa_ssid *ssid)
 
734
{
 
735
        if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
 
736
                wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
 
737
                        "PBC session overlap");
 
738
                wpa_supplicant_req_new_scan(wpa_s, 10, 0);
 
739
                return;
 
740
        }
 
741
 
 
742
        /*
 
743
         * Do not trigger new association unless the BSSID has changed or if
 
744
         * reassociation is requested. If we are in process of associating with
 
745
         * the selected BSSID, do not trigger new attempt.
 
746
         */
 
747
        if (wpa_s->reassociate ||
 
748
            (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
 
749
             (wpa_s->wpa_state != WPA_ASSOCIATING ||
 
750
              os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) !=
 
751
              0))) {
 
752
                if (wpa_supplicant_scard_init(wpa_s, ssid)) {
 
753
                        wpa_supplicant_req_new_scan(wpa_s, 10, 0);
 
754
                        return;
 
755
                }
 
756
                wpa_supplicant_associate(wpa_s, selected, ssid);
 
757
        } else {
 
758
                wpa_printf(MSG_DEBUG, "Already associated with the selected "
 
759
                           "AP");
 
760
        }
 
761
}
 
762
 
 
763
 
 
764
static struct wpa_ssid *
 
765
wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
 
766
{
 
767
        int prio;
 
768
        struct wpa_ssid *ssid;
 
769
 
 
770
        for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
 
771
                for (ssid = wpa_s->conf->pssid[prio]; ssid; ssid = ssid->pnext)
 
772
                {
 
773
                        if (ssid->disabled)
 
774
                                continue;
 
775
                        if (ssid->mode == IEEE80211_MODE_IBSS ||
 
776
                            ssid->mode == IEEE80211_MODE_AP)
 
777
                                return ssid;
 
778
                }
 
779
        }
 
780
        return NULL;
 
781
}
 
782
 
 
783
 
 
784
/* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based
 
785
 * on BSS added and BSS changed events */
 
786
static void wpa_supplicant_rsn_preauth_scan_results(
 
787
        struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res)
 
788
{
 
789
        int i;
 
790
 
 
791
        if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
 
792
                return;
 
793
 
 
794
        for (i = scan_res->num - 1; i >= 0; i--) {
 
795
                const u8 *ssid, *rsn;
 
796
                struct wpa_scan_res *r;
 
797
 
 
798
                r = scan_res->res[i];
 
799
 
 
800
                ssid = wpa_scan_get_ie(r, WLAN_EID_SSID);
 
801
                if (ssid == NULL)
 
802
                        continue;
 
803
 
 
804
                rsn = wpa_scan_get_ie(r, WLAN_EID_RSN);
 
805
                if (rsn == NULL)
 
806
                        continue;
 
807
 
 
808
                rsn_preauth_scan_result(wpa_s->wpa, r->bssid, ssid, rsn);
 
809
        }
 
810
 
 
811
}
 
812
 
 
813
 
 
814
static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
 
815
                                       struct wpa_bss *selected,
 
816
                                       struct wpa_ssid *ssid,
 
817
                                       struct wpa_scan_results *scan_res)
 
818
{
 
819
        size_t i;
 
820
        struct wpa_scan_res *current_bss = NULL;
 
821
        int min_diff;
 
822
 
 
823
        if (wpa_s->reassociate)
 
824
                return 1; /* explicit request to reassociate */
 
825
        if (wpa_s->wpa_state < WPA_ASSOCIATED)
 
826
                return 1; /* we are not associated; continue */
 
827
        if (wpa_s->current_ssid == NULL)
 
828
                return 1; /* unknown current SSID */
 
829
        if (wpa_s->current_ssid != ssid)
 
830
                return 1; /* different network block */
 
831
 
 
832
        for (i = 0; i < scan_res->num; i++) {
 
833
                struct wpa_scan_res *res = scan_res->res[i];
 
834
                const u8 *ie;
 
835
                if (os_memcmp(res->bssid, wpa_s->bssid, ETH_ALEN) != 0)
 
836
                        continue;
 
837
 
 
838
                ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
 
839
                if (ie == NULL)
 
840
                        continue;
 
841
                if (ie[1] != wpa_s->current_ssid->ssid_len ||
 
842
                    os_memcmp(ie + 2, wpa_s->current_ssid->ssid, ie[1]) != 0)
 
843
                        continue;
 
844
                current_bss = res;
 
845
                break;
 
846
        }
 
847
 
 
848
        if (!current_bss)
 
849
                return 1; /* current BSS not seen in scan results */
 
850
 
 
851
        wpa_printf(MSG_DEBUG, "Considering within-ESS reassociation");
 
852
        wpa_printf(MSG_DEBUG, "Current BSS: " MACSTR " level=%d",
 
853
                   MAC2STR(current_bss->bssid), current_bss->level);
 
854
        wpa_printf(MSG_DEBUG, "Selected BSS: " MACSTR " level=%d",
 
855
                   MAC2STR(selected->bssid), selected->level);
 
856
 
 
857
        if (wpa_s->current_ssid->bssid_set &&
 
858
            os_memcmp(selected->bssid, wpa_s->current_ssid->bssid, ETH_ALEN) ==
 
859
            0) {
 
860
                wpa_printf(MSG_DEBUG, "Allow reassociation - selected BSS has "
 
861
                           "preferred BSSID");
 
862
                return 1;
 
863
        }
 
864
 
 
865
        min_diff = 2;
 
866
        if (current_bss->level < 0) {
 
867
                if (current_bss->level < -85)
 
868
                        min_diff = 1;
 
869
                else if (current_bss->level < -80)
 
870
                        min_diff = 2;
 
871
                else if (current_bss->level < -75)
 
872
                        min_diff = 3;
 
873
                else if (current_bss->level < -70)
 
874
                        min_diff = 4;
 
875
                else
 
876
                        min_diff = 5;
 
877
        }
 
878
        if (abs(current_bss->level - selected->level) < min_diff) {
 
879
                wpa_printf(MSG_DEBUG, "Skip roam - too small difference in "
 
880
                           "signal level");
 
881
                return 0;
 
882
        }
 
883
 
 
884
        return 1;
 
885
}
 
886
 
 
887
 
 
888
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 
889
                                              union wpa_event_data *data)
 
890
{
 
891
        struct wpa_bss *selected;
 
892
        struct wpa_ssid *ssid = NULL;
 
893
        struct wpa_scan_results *scan_res;
 
894
        int ap = 0;
 
895
 
 
896
#ifdef CONFIG_AP
 
897
        if (wpa_s->ap_iface)
 
898
                ap = 1;
 
899
#endif /* CONFIG_AP */
 
900
 
 
901
        wpa_supplicant_notify_scanning(wpa_s, 0);
 
902
 
 
903
        scan_res = wpa_supplicant_get_scan_results(wpa_s,
 
904
                                                   data ? &data->scan_info :
 
905
                                                   NULL, 1);
 
906
        if (scan_res == NULL) {
 
907
                if (wpa_s->conf->ap_scan == 2 || ap)
 
908
                        return;
 
909
                wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
 
910
                           "scanning again");
 
911
                wpa_supplicant_req_new_scan(wpa_s, 1, 0);
 
912
                return;
 
913
        }
 
914
 
 
915
        if (wpa_s->scan_res_handler) {
 
916
                wpa_s->scan_res_handler(wpa_s, scan_res);
 
917
                wpa_s->scan_res_handler = NULL;
 
918
                wpa_scan_results_free(scan_res);
 
919
                return;
 
920
        }
 
921
 
 
922
        if (ap) {
 
923
                wpa_printf(MSG_DEBUG, "Ignore scan results in AP mode");
 
924
                wpa_scan_results_free(scan_res);
 
925
                return;
 
926
        }
 
927
 
 
928
        wpa_printf(MSG_DEBUG, "New scan results available");
 
929
        wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
 
930
        wpas_notify_scan_results(wpa_s);
 
931
 
 
932
        wpas_notify_scan_done(wpa_s, 1);
 
933
 
 
934
        if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s))) {
 
935
                wpa_scan_results_free(scan_res);
 
936
                return;
 
937
        }
 
938
 
 
939
        if (wpa_s->disconnected) {
 
940
                wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
 
941
                wpa_scan_results_free(scan_res);
 
942
                return;
 
943
        }
 
944
 
 
945
        if (bgscan_notify_scan(wpa_s) == 1) {
 
946
                wpa_scan_results_free(scan_res);
 
947
                return;
 
948
        }
 
949
 
 
950
        wpa_supplicant_rsn_preauth_scan_results(wpa_s, scan_res);
 
951
 
 
952
        selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid);
 
953
 
 
954
        if (selected) {
 
955
                int skip;
 
956
                skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid,
 
957
                                                    scan_res);
 
958
                wpa_scan_results_free(scan_res);
 
959
                if (skip)
 
960
                        return;
 
961
                wpa_supplicant_connect(wpa_s, selected, ssid);
 
962
        } else {
 
963
                wpa_scan_results_free(scan_res);
 
964
                wpa_printf(MSG_DEBUG, "No suitable network found");
 
965
                ssid = wpa_supplicant_pick_new_network(wpa_s);
 
966
                if (ssid) {
 
967
                        wpa_printf(MSG_DEBUG, "Setup a new network");
 
968
                        wpa_supplicant_associate(wpa_s, NULL, ssid);
 
969
                } else {
 
970
                        int timeout_sec = 5;
 
971
                        int timeout_usec = 0;
 
972
                        wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
 
973
                                                    timeout_usec);
 
974
                }
 
975
        }
 
976
}
 
977
#endif /* CONFIG_NO_SCAN_PROCESSING */
 
978
 
 
979
 
 
980
static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
 
981
                                          union wpa_event_data *data)
 
982
{
 
983
        int l, len, found = 0, wpa_found, rsn_found;
 
984
        const u8 *p;
 
985
 
 
986
        wpa_printf(MSG_DEBUG, "Association info event");
 
987
        if (data->assoc_info.req_ies)
 
988
                wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
 
989
                            data->assoc_info.req_ies_len);
 
990
        if (data->assoc_info.resp_ies)
 
991
                wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies,
 
992
                            data->assoc_info.resp_ies_len);
 
993
        if (data->assoc_info.beacon_ies)
 
994
                wpa_hexdump(MSG_DEBUG, "beacon_ies",
 
995
                            data->assoc_info.beacon_ies,
 
996
                            data->assoc_info.beacon_ies_len);
 
997
        if (data->assoc_info.freq)
 
998
                wpa_printf(MSG_DEBUG, "freq=%u MHz", data->assoc_info.freq);
 
999
 
 
1000
        p = data->assoc_info.req_ies;
 
1001
        l = data->assoc_info.req_ies_len;
 
1002
 
 
1003
        /* Go through the IEs and make a copy of the WPA/RSN IE, if present. */
 
1004
        while (p && l >= 2) {
 
1005
                len = p[1] + 2;
 
1006
                if (len > l) {
 
1007
                        wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
 
1008
                                    p, l);
 
1009
                        break;
 
1010
                }
 
1011
                if ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
 
1012
                     (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
 
1013
                    (p[0] == WLAN_EID_RSN && p[1] >= 2)) {
 
1014
                        if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
 
1015
                                break;
 
1016
                        found = 1;
 
1017
                        wpa_find_assoc_pmkid(wpa_s);
 
1018
                        break;
 
1019
                }
 
1020
                l -= len;
 
1021
                p += len;
 
1022
        }
 
1023
        if (!found && data->assoc_info.req_ies)
 
1024
                wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
 
1025
 
 
1026
#ifdef CONFIG_IEEE80211R
 
1027
#ifdef CONFIG_SME
 
1028
        if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
 
1029
                u8 bssid[ETH_ALEN];
 
1030
                if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
 
1031
                    wpa_ft_validate_reassoc_resp(wpa_s->wpa,
 
1032
                                                 data->assoc_info.resp_ies,
 
1033
                                                 data->assoc_info.resp_ies_len,
 
1034
                                                 bssid) < 0) {
 
1035
                        wpa_printf(MSG_DEBUG, "FT: Validation of "
 
1036
                                   "Reassociation Response failed");
 
1037
                        wpa_supplicant_deauthenticate(
 
1038
                                wpa_s, WLAN_REASON_INVALID_IE);
 
1039
                        return -1;
 
1040
                }
 
1041
        }
 
1042
 
 
1043
        p = data->assoc_info.resp_ies;
 
1044
        l = data->assoc_info.resp_ies_len;
 
1045
 
 
1046
        /* Go through the IEs and make a copy of the MDIE, if present. */
 
1047
        while (p && l >= 2) {
 
1048
                len = p[1] + 2;
 
1049
                if (len > l) {
 
1050
                        wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
 
1051
                                    p, l);
 
1052
                        break;
 
1053
                }
 
1054
                if (p[0] == WLAN_EID_MOBILITY_DOMAIN &&
 
1055
                    p[1] >= MOBILITY_DOMAIN_ID_LEN) {
 
1056
                        wpa_s->sme.ft_used = 1;
 
1057
                        os_memcpy(wpa_s->sme.mobility_domain, p + 2,
 
1058
                                  MOBILITY_DOMAIN_ID_LEN);
 
1059
                        break;
 
1060
                }
 
1061
                l -= len;
 
1062
                p += len;
 
1063
        }
 
1064
#endif /* CONFIG_SME */
 
1065
 
 
1066
        wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
 
1067
                             data->assoc_info.resp_ies_len);
 
1068
#endif /* CONFIG_IEEE80211R */
 
1069
 
 
1070
        /* WPA/RSN IE from Beacon/ProbeResp */
 
1071
        p = data->assoc_info.beacon_ies;
 
1072
        l = data->assoc_info.beacon_ies_len;
 
1073
 
 
1074
        /* Go through the IEs and make a copy of the WPA/RSN IEs, if present.
 
1075
         */
 
1076
        wpa_found = rsn_found = 0;
 
1077
        while (p && l >= 2) {
 
1078
                len = p[1] + 2;
 
1079
                if (len > l) {
 
1080
                        wpa_hexdump(MSG_DEBUG, "Truncated IE in beacon_ies",
 
1081
                                    p, l);
 
1082
                        break;
 
1083
                }
 
1084
                if (!wpa_found &&
 
1085
                    p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
 
1086
                    os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
 
1087
                        wpa_found = 1;
 
1088
                        wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len);
 
1089
                }
 
1090
 
 
1091
                if (!rsn_found &&
 
1092
                    p[0] == WLAN_EID_RSN && p[1] >= 2) {
 
1093
                        rsn_found = 1;
 
1094
                        wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
 
1095
                }
 
1096
 
 
1097
                l -= len;
 
1098
                p += len;
 
1099
        }
 
1100
 
 
1101
        if (!wpa_found && data->assoc_info.beacon_ies)
 
1102
                wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
 
1103
        if (!rsn_found && data->assoc_info.beacon_ies)
 
1104
                wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
 
1105
        if (wpa_found || rsn_found)
 
1106
                wpa_s->ap_ies_from_associnfo = 1;
 
1107
 
 
1108
        wpa_s->assoc_freq = data->assoc_info.freq;
 
1109
 
 
1110
        return 0;
 
1111
}
 
1112
 
 
1113
 
 
1114
static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
 
1115
                                       union wpa_event_data *data)
 
1116
{
 
1117
        u8 bssid[ETH_ALEN];
 
1118
        int ft_completed;
 
1119
        int bssid_changed;
 
1120
        struct wpa_driver_capa capa;
 
1121
 
 
1122
#ifdef CONFIG_AP
 
1123
        if (wpa_s->ap_iface) {
 
1124
                hostapd_notif_assoc(wpa_s->ap_iface->bss[0],
 
1125
                                    data->assoc_info.addr,
 
1126
                                    data->assoc_info.req_ies,
 
1127
                                    data->assoc_info.req_ies_len);
 
1128
                return;
 
1129
        }
 
1130
#endif /* CONFIG_AP */
 
1131
 
 
1132
        ft_completed = wpa_ft_is_completed(wpa_s->wpa);
 
1133
        if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0)
 
1134
                return;
 
1135
 
 
1136
        wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
 
1137
        if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
 
1138
                os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
 
1139
        if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) ||
 
1140
            (wpa_drv_get_bssid(wpa_s, bssid) >= 0 &&
 
1141
             os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)) {
 
1142
                wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
 
1143
                        MACSTR, MAC2STR(bssid));
 
1144
                bssid_changed = os_memcmp(wpa_s->bssid, bssid, ETH_ALEN);
 
1145
                os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
 
1146
                os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
 
1147
                if (bssid_changed)
 
1148
                        wpas_notify_bssid_changed(wpa_s);
 
1149
 
 
1150
                if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) {
 
1151
                        wpa_clear_keys(wpa_s, bssid);
 
1152
                }
 
1153
                if (wpa_supplicant_select_config(wpa_s) < 0) {
 
1154
                        wpa_supplicant_disassociate(
 
1155
                                wpa_s, WLAN_REASON_DEAUTH_LEAVING);
 
1156
                        return;
 
1157
                }
 
1158
                if (wpa_s->current_ssid) {
 
1159
                        struct wpa_bss *bss = NULL;
 
1160
                        struct wpa_ssid *ssid = wpa_s->current_ssid;
 
1161
                        if (ssid->ssid_len > 0)
 
1162
                                bss = wpa_bss_get(wpa_s, bssid,
 
1163
                                                  ssid->ssid, ssid->ssid_len);
 
1164
                        if (!bss)
 
1165
                                bss = wpa_bss_get_bssid(wpa_s, bssid);
 
1166
                        if (bss)
 
1167
                                wpa_s->current_bss = bss;
 
1168
                }
 
1169
        }
 
1170
 
 
1171
#ifdef CONFIG_SME
 
1172
        os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN);
 
1173
        wpa_s->sme.prev_bssid_set = 1;
 
1174
#endif /* CONFIG_SME */
 
1175
 
 
1176
        wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
 
1177
        if (wpa_s->current_ssid) {
 
1178
                /* When using scanning (ap_scan=1), SIM PC/SC interface can be
 
1179
                 * initialized before association, but for other modes,
 
1180
                 * initialize PC/SC here, if the current configuration needs
 
1181
                 * smartcard or SIM/USIM. */
 
1182
                wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid);
 
1183
        }
 
1184
        wpa_sm_notify_assoc(wpa_s->wpa, bssid);
 
1185
        if (wpa_s->l2)
 
1186
                l2_packet_notify_auth_start(wpa_s->l2);
 
1187
 
 
1188
        /*
 
1189
         * Set portEnabled first to FALSE in order to get EAP state machine out
 
1190
         * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE
 
1191
         * state machine may transit to AUTHENTICATING state based on obsolete
 
1192
         * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to
 
1193
         * AUTHENTICATED without ever giving chance to EAP state machine to
 
1194
         * reset the state.
 
1195
         */
 
1196
        if (!ft_completed) {
 
1197
                eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
 
1198
                eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
 
1199
        }
 
1200
        if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed)
 
1201
                eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
 
1202
        /* 802.1X::portControl = Auto */
 
1203
        eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
 
1204
        wpa_s->eapol_received = 0;
 
1205
        if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
 
1206
            wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE ||
 
1207
            (wpa_s->current_ssid &&
 
1208
             wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS)) {
 
1209
                wpa_supplicant_cancel_auth_timeout(wpa_s);
 
1210
                wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
 
1211
        } else if (!ft_completed) {
 
1212
                /* Timeout for receiving the first EAPOL packet */
 
1213
                wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
 
1214
        }
 
1215
        wpa_supplicant_cancel_scan(wpa_s);
 
1216
 
 
1217
        if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
 
1218
            wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
 
1219
                /*
 
1220
                 * We are done; the driver will take care of RSN 4-way
 
1221
                 * handshake.
 
1222
                 */
 
1223
                wpa_supplicant_cancel_auth_timeout(wpa_s);
 
1224
                wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
 
1225
                eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
 
1226
                eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
 
1227
        }
 
1228
 
 
1229
        if (wpa_s->pending_eapol_rx) {
 
1230
                struct os_time now, age;
 
1231
                os_get_time(&now);
 
1232
                os_time_sub(&now, &wpa_s->pending_eapol_rx_time, &age);
 
1233
                if (age.sec == 0 && age.usec < 100000 &&
 
1234
                    os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) ==
 
1235
                    0) {
 
1236
                        wpa_printf(MSG_DEBUG, "Process pending EAPOL frame "
 
1237
                                   "that was received just before association "
 
1238
                                   "notification");
 
1239
                        wpa_supplicant_rx_eapol(
 
1240
                                wpa_s, wpa_s->pending_eapol_rx_src,
 
1241
                                wpabuf_head(wpa_s->pending_eapol_rx),
 
1242
                                wpabuf_len(wpa_s->pending_eapol_rx));
 
1243
                }
 
1244
                wpabuf_free(wpa_s->pending_eapol_rx);
 
1245
                wpa_s->pending_eapol_rx = NULL;
 
1246
        }
 
1247
 
 
1248
#ifdef CONFIG_BGSCAN
 
1249
        if (wpa_s->current_ssid != wpa_s->bgscan_ssid) {
 
1250
                bgscan_deinit(wpa_s);
 
1251
                if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan) {
 
1252
                        if (bgscan_init(wpa_s, wpa_s->current_ssid)) {
 
1253
                                wpa_printf(MSG_DEBUG, "Failed to initialize "
 
1254
                                           "bgscan");
 
1255
                                /*
 
1256
                                 * Live without bgscan; it is only used as a
 
1257
                                 * roaming optimization, so the initial
 
1258
                                 * connection is not affected.
 
1259
                                 */
 
1260
                        } else
 
1261
                                wpa_s->bgscan_ssid = wpa_s->current_ssid;
 
1262
                } else
 
1263
                        wpa_s->bgscan_ssid = NULL;
 
1264
        }
 
1265
#endif /* CONFIG_BGSCAN */
 
1266
 
 
1267
        if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
 
1268
             wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
 
1269
            wpa_s->current_ssid && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
 
1270
            capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE) {
 
1271
                /* Set static WEP keys again */
 
1272
                wpa_set_wep_keys(wpa_s, wpa_s->current_ssid);
 
1273
        }
 
1274
}
 
1275
 
 
1276
 
 
1277
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
 
1278
                                          u16 reason_code)
 
1279
{
 
1280
        const u8 *bssid;
 
1281
#ifdef CONFIG_SME
 
1282
        int authenticating;
 
1283
        u8 prev_pending_bssid[ETH_ALEN];
 
1284
 
 
1285
        authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
 
1286
        os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
 
1287
#endif /* CONFIG_SME */
 
1288
 
 
1289
        if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
 
1290
                /*
 
1291
                 * At least Host AP driver and a Prism3 card seemed to be
 
1292
                 * generating streams of disconnected events when configuring
 
1293
                 * IBSS for WPA-None. Ignore them for now.
 
1294
                 */
 
1295
                wpa_printf(MSG_DEBUG, "Disconnect event - ignore in "
 
1296
                           "IBSS/WPA-None mode");
 
1297
                return;
 
1298
        }
 
1299
 
 
1300
        if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE &&
 
1301
            wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
 
1302
                wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
 
1303
                        "pre-shared key may be incorrect");
 
1304
        }
 
1305
        if (wpa_s->wpa_state >= WPA_ASSOCIATED)
 
1306
                wpa_supplicant_req_scan(wpa_s, 0, 100000);
 
1307
        bssid = wpa_s->bssid;
 
1308
        if (is_zero_ether_addr(bssid))
 
1309
                bssid = wpa_s->pending_bssid;
 
1310
        wpa_blacklist_add(wpa_s, bssid);
 
1311
        wpa_sm_notify_disassoc(wpa_s->wpa);
 
1312
        wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
 
1313
                " reason=%d",
 
1314
                MAC2STR(bssid), reason_code);
 
1315
        if (wpa_supplicant_dynamic_keys(wpa_s)) {
 
1316
                wpa_printf(MSG_DEBUG, "Disconnect event - remove keys");
 
1317
                wpa_s->keys_cleared = 0;
 
1318
                wpa_clear_keys(wpa_s, wpa_s->bssid);
 
1319
        }
 
1320
        wpa_supplicant_mark_disassoc(wpa_s);
 
1321
        bgscan_deinit(wpa_s);
 
1322
        wpa_s->bgscan_ssid = NULL;
 
1323
#ifdef CONFIG_SME
 
1324
        if (authenticating &&
 
1325
            (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) {
 
1326
                /*
 
1327
                 * mac80211-workaround to force deauth on failed auth cmd,
 
1328
                 * requires us to remain in authenticating state to allow the
 
1329
                 * second authentication attempt to be continued properly.
 
1330
                 */
 
1331
                wpa_printf(MSG_DEBUG, "SME: Allow pending authentication to "
 
1332
                           "proceed after disconnection event");
 
1333
                wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
 
1334
                os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN);
 
1335
        }
 
1336
#endif /* CONFIG_SME */
 
1337
}
 
1338
 
 
1339
 
 
1340
#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
 
1341
static void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx,
 
1342
                                                    void *sock_ctx)
 
1343
{
 
1344
        struct wpa_supplicant *wpa_s = eloop_ctx;
 
1345
 
 
1346
        if (!wpa_s->pending_mic_error_report)
 
1347
                return;
 
1348
 
 
1349
        wpa_printf(MSG_DEBUG, "WPA: Sending pending MIC error report");
 
1350
        wpa_sm_key_request(wpa_s->wpa, 1, wpa_s->pending_mic_error_pairwise);
 
1351
        wpa_s->pending_mic_error_report = 0;
 
1352
}
 
1353
#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
 
1354
 
 
1355
 
 
1356
static void
 
1357
wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
 
1358
                                         union wpa_event_data *data)
 
1359
{
 
1360
        int pairwise;
 
1361
        struct os_time t;
 
1362
 
 
1363
        wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
 
1364
        pairwise = (data && data->michael_mic_failure.unicast);
 
1365
        os_get_time(&t);
 
1366
        if ((wpa_s->last_michael_mic_error &&
 
1367
             t.sec - wpa_s->last_michael_mic_error <= 60) ||
 
1368
            wpa_s->pending_mic_error_report) {
 
1369
                if (wpa_s->pending_mic_error_report) {
 
1370
                        /*
 
1371
                         * Send the pending MIC error report immediately since
 
1372
                         * we are going to start countermeasures and AP better
 
1373
                         * do the same.
 
1374
                         */
 
1375
                        wpa_sm_key_request(wpa_s->wpa, 1,
 
1376
                                           wpa_s->pending_mic_error_pairwise);
 
1377
                }
 
1378
 
 
1379
                /* Send the new MIC error report immediately since we are going
 
1380
                 * to start countermeasures and AP better do the same.
 
1381
                 */
 
1382
                wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
 
1383
 
 
1384
                /* initialize countermeasures */
 
1385
                wpa_s->countermeasures = 1;
 
1386
                wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
 
1387
 
 
1388
                /*
 
1389
                 * Need to wait for completion of request frame. We do not get
 
1390
                 * any callback for the message completion, so just wait a
 
1391
                 * short while and hope for the best. */
 
1392
                os_sleep(0, 10000);
 
1393
 
 
1394
                wpa_drv_set_countermeasures(wpa_s, 1);
 
1395
                wpa_supplicant_deauthenticate(wpa_s,
 
1396
                                              WLAN_REASON_MICHAEL_MIC_FAILURE);
 
1397
                eloop_cancel_timeout(wpa_supplicant_stop_countermeasures,
 
1398
                                     wpa_s, NULL);
 
1399
                eloop_register_timeout(60, 0,
 
1400
                                       wpa_supplicant_stop_countermeasures,
 
1401
                                       wpa_s, NULL);
 
1402
                /* TODO: mark the AP rejected for 60 second. STA is
 
1403
                 * allowed to associate with another AP.. */
 
1404
        } else {
 
1405
#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
 
1406
                if (wpa_s->mic_errors_seen) {
 
1407
                        /*
 
1408
                         * Reduce the effectiveness of Michael MIC error
 
1409
                         * reports as a means for attacking against TKIP if
 
1410
                         * more than one MIC failure is noticed with the same
 
1411
                         * PTK. We delay the transmission of the reports by a
 
1412
                         * random time between 0 and 60 seconds in order to
 
1413
                         * force the attacker wait 60 seconds before getting
 
1414
                         * the information on whether a frame resulted in a MIC
 
1415
                         * failure.
 
1416
                         */
 
1417
                        u8 rval[4];
 
1418
                        int sec;
 
1419
 
 
1420
                        if (os_get_random(rval, sizeof(rval)) < 0)
 
1421
                                sec = os_random() % 60;
 
1422
                        else
 
1423
                                sec = WPA_GET_BE32(rval) % 60;
 
1424
                        wpa_printf(MSG_DEBUG, "WPA: Delay MIC error report %d "
 
1425
                                   "seconds", sec);
 
1426
                        wpa_s->pending_mic_error_report = 1;
 
1427
                        wpa_s->pending_mic_error_pairwise = pairwise;
 
1428
                        eloop_cancel_timeout(
 
1429
                                wpa_supplicant_delayed_mic_error_report,
 
1430
                                wpa_s, NULL);
 
1431
                        eloop_register_timeout(
 
1432
                                sec, os_random() % 1000000,
 
1433
                                wpa_supplicant_delayed_mic_error_report,
 
1434
                                wpa_s, NULL);
 
1435
                } else {
 
1436
                        wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
 
1437
                }
 
1438
#else /* CONFIG_DELAYED_MIC_ERROR_REPORT */
 
1439
                wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
 
1440
#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
 
1441
        }
 
1442
        wpa_s->last_michael_mic_error = t.sec;
 
1443
        wpa_s->mic_errors_seen++;
 
1444
}
 
1445
 
 
1446
 
 
1447
#ifdef CONFIG_TERMINATE_ONLASTIF
 
1448
static int any_interfaces(struct wpa_supplicant *head)
 
1449
{
 
1450
        struct wpa_supplicant *wpa_s;
 
1451
 
 
1452
        for (wpa_s = head; wpa_s != NULL; wpa_s = wpa_s->next)
 
1453
                if (!wpa_s->interface_removed)
 
1454
                        return 1;
 
1455
        return 0;
 
1456
}
 
1457
#endif /* CONFIG_TERMINATE_ONLASTIF */
 
1458
 
 
1459
 
 
1460
static void
 
1461
wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
 
1462
                                      union wpa_event_data *data)
 
1463
{
 
1464
        if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
 
1465
                return;
 
1466
 
 
1467
        switch (data->interface_status.ievent) {
 
1468
        case EVENT_INTERFACE_ADDED:
 
1469
                if (!wpa_s->interface_removed)
 
1470
                        break;
 
1471
                wpa_s->interface_removed = 0;
 
1472
                wpa_printf(MSG_DEBUG, "Configured interface was added.");
 
1473
                if (wpa_supplicant_driver_init(wpa_s) < 0) {
 
1474
                        wpa_printf(MSG_INFO, "Failed to initialize the driver "
 
1475
                                   "after interface was added.");
 
1476
                }
 
1477
                break;
 
1478
        case EVENT_INTERFACE_REMOVED:
 
1479
                wpa_printf(MSG_DEBUG, "Configured interface was removed.");
 
1480
                wpa_s->interface_removed = 1;
 
1481
                wpa_supplicant_mark_disassoc(wpa_s);
 
1482
                l2_packet_deinit(wpa_s->l2);
 
1483
                wpa_s->l2 = NULL;
 
1484
#ifdef CONFIG_TERMINATE_ONLASTIF
 
1485
                /* check if last interface */
 
1486
                if (!any_interfaces(wpa_s->global->ifaces))
 
1487
                        eloop_terminate();
 
1488
#endif /* CONFIG_TERMINATE_ONLASTIF */
 
1489
                break;
 
1490
        }
 
1491
}
 
1492
 
 
1493
 
 
1494
#ifdef CONFIG_PEERKEY
 
1495
static void
 
1496
wpa_supplicant_event_stkstart(struct wpa_supplicant *wpa_s,
 
1497
                              union wpa_event_data *data)
 
1498
{
 
1499
        if (data == NULL)
 
1500
                return;
 
1501
        wpa_sm_stkstart(wpa_s->wpa, data->stkstart.peer);
 
1502
}
 
1503
#endif /* CONFIG_PEERKEY */
 
1504
 
 
1505
 
 
1506
#ifdef CONFIG_IEEE80211R
 
1507
static void
 
1508
wpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s,
 
1509
                                 union wpa_event_data *data)
 
1510
{
 
1511
        if (data == NULL)
 
1512
                return;
 
1513
 
 
1514
        if (wpa_ft_process_response(wpa_s->wpa, data->ft_ies.ies,
 
1515
                                    data->ft_ies.ies_len,
 
1516
                                    data->ft_ies.ft_action,
 
1517
                                    data->ft_ies.target_ap,
 
1518
                                    data->ft_ies.ric_ies,
 
1519
                                    data->ft_ies.ric_ies_len) < 0) {
 
1520
                /* TODO: prevent MLME/driver from trying to associate? */
 
1521
        }
 
1522
}
 
1523
#endif /* CONFIG_IEEE80211R */
 
1524
 
 
1525
 
 
1526
#ifdef CONFIG_IBSS_RSN
 
1527
static void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s,
 
1528
                                                union wpa_event_data *data)
 
1529
{
 
1530
        if (data == NULL)
 
1531
                return;
 
1532
        ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer);
 
1533
}
 
1534
#endif /* CONFIG_IBSS_RSN */
 
1535
 
 
1536
 
 
1537
#ifdef CONFIG_IEEE80211R
 
1538
static void ft_rx_action(struct wpa_supplicant *wpa_s, const u8 *data,
 
1539
                         size_t len)
 
1540
{
 
1541
        const u8 *sta_addr, *target_ap_addr;
 
1542
        u16 status;
 
1543
 
 
1544
        wpa_hexdump(MSG_MSGDUMP, "FT: RX Action", data, len);
 
1545
        if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
 
1546
                return; /* only SME case supported for now */
 
1547
        if (len < 1 + 2 * ETH_ALEN + 2)
 
1548
                return;
 
1549
        if (data[0] != 2)
 
1550
                return; /* Only FT Action Response is supported for now */
 
1551
        sta_addr = data + 1;
 
1552
        target_ap_addr = data + 1 + ETH_ALEN;
 
1553
        status = WPA_GET_LE16(data + 1 + 2 * ETH_ALEN);
 
1554
        wpa_printf(MSG_DEBUG, "FT: Received FT Action Response: STA " MACSTR
 
1555
                   " TargetAP " MACSTR " status %u",
 
1556
                   MAC2STR(sta_addr), MAC2STR(target_ap_addr), status);
 
1557
 
 
1558
        if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) {
 
1559
                wpa_printf(MSG_DEBUG, "FT: Foreign STA Address " MACSTR
 
1560
                           " in FT Action Response", MAC2STR(sta_addr));
 
1561
                return;
 
1562
        }
 
1563
 
 
1564
        if (status) {
 
1565
                wpa_printf(MSG_DEBUG, "FT: FT Action Response indicates "
 
1566
                           "failure (status code %d)", status);
 
1567
                /* TODO: report error to FT code(?) */
 
1568
                return;
 
1569
        }
 
1570
 
 
1571
        if (wpa_ft_process_response(wpa_s->wpa, data + 1 + 2 * ETH_ALEN + 2,
 
1572
                                    len - (1 + 2 * ETH_ALEN + 2), 1,
 
1573
                                    target_ap_addr, NULL, 0) < 0)
 
1574
                return;
 
1575
 
 
1576
#ifdef CONFIG_SME
 
1577
        {
 
1578
                struct wpa_bss *bss;
 
1579
                bss = wpa_bss_get_bssid(wpa_s, target_ap_addr);
 
1580
                if (bss)
 
1581
                        wpa_s->sme.freq = bss->freq;
 
1582
                wpa_s->sme.auth_alg = WPA_AUTH_ALG_FT;
 
1583
                sme_associate(wpa_s, WPAS_MODE_INFRA, target_ap_addr,
 
1584
                              WLAN_AUTH_FT);
 
1585
        }
 
1586
#endif /* CONFIG_SME */
 
1587
}
 
1588
#endif /* CONFIG_IEEE80211R */
 
1589
 
 
1590
 
 
1591
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 
1592
                          union wpa_event_data *data)
 
1593
{
 
1594
        struct wpa_supplicant *wpa_s = ctx;
 
1595
        u16 reason_code = 0;
 
1596
 
 
1597
        switch (event) {
 
1598
        case EVENT_AUTH:
 
1599
                sme_event_auth(wpa_s, data);
 
1600
                break;
 
1601
        case EVENT_ASSOC:
 
1602
                wpa_supplicant_event_assoc(wpa_s, data);
 
1603
                break;
 
1604
        case EVENT_DISASSOC:
 
1605
                wpa_printf(MSG_DEBUG, "Disassociation notification");
 
1606
#ifdef CONFIG_AP
 
1607
                if (wpa_s->ap_iface && data && data->disassoc_info.addr) {
 
1608
                        hostapd_notif_disassoc(wpa_s->ap_iface->bss[0],
 
1609
                                               data->disassoc_info.addr);
 
1610
                        break;
 
1611
                }
 
1612
#endif /* CONFIG_AP */
 
1613
                if (data)
 
1614
                        reason_code = data->deauth_info.reason_code;
 
1615
                if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
 
1616
                        sme_event_disassoc(wpa_s, data);
 
1617
                /* fall through */
 
1618
        case EVENT_DEAUTH:
 
1619
                if (event == EVENT_DEAUTH) {
 
1620
                        wpa_printf(MSG_DEBUG, "Deauthentication notification");
 
1621
                        if (data)
 
1622
                                reason_code = data->deauth_info.reason_code;
 
1623
                }
 
1624
#ifdef CONFIG_AP
 
1625
                if (wpa_s->ap_iface && data && data->deauth_info.addr) {
 
1626
                        hostapd_notif_disassoc(wpa_s->ap_iface->bss[0],
 
1627
                                               data->deauth_info.addr);
 
1628
                        break;
 
1629
                }
 
1630
#endif /* CONFIG_AP */
 
1631
                wpa_supplicant_event_disassoc(wpa_s, reason_code);
 
1632
                break;
 
1633
        case EVENT_MICHAEL_MIC_FAILURE:
 
1634
                wpa_supplicant_event_michael_mic_failure(wpa_s, data);
 
1635
                break;
 
1636
#ifndef CONFIG_NO_SCAN_PROCESSING
 
1637
        case EVENT_SCAN_RESULTS:
 
1638
                wpa_supplicant_event_scan_results(wpa_s, data);
 
1639
                break;
 
1640
#endif /* CONFIG_NO_SCAN_PROCESSING */
 
1641
        case EVENT_ASSOCINFO:
 
1642
                wpa_supplicant_event_associnfo(wpa_s, data);
 
1643
                break;
 
1644
        case EVENT_INTERFACE_STATUS:
 
1645
                wpa_supplicant_event_interface_status(wpa_s, data);
 
1646
                break;
 
1647
        case EVENT_PMKID_CANDIDATE:
 
1648
                wpa_supplicant_event_pmkid_candidate(wpa_s, data);
 
1649
                break;
 
1650
#ifdef CONFIG_PEERKEY
 
1651
        case EVENT_STKSTART:
 
1652
                wpa_supplicant_event_stkstart(wpa_s, data);
 
1653
                break;
 
1654
#endif /* CONFIG_PEERKEY */
 
1655
#ifdef CONFIG_IEEE80211R
 
1656
        case EVENT_FT_RESPONSE:
 
1657
                wpa_supplicant_event_ft_response(wpa_s, data);
 
1658
                break;
 
1659
#endif /* CONFIG_IEEE80211R */
 
1660
#ifdef CONFIG_IBSS_RSN
 
1661
        case EVENT_IBSS_RSN_START:
 
1662
                wpa_supplicant_event_ibss_rsn_start(wpa_s, data);
 
1663
                break;
 
1664
#endif /* CONFIG_IBSS_RSN */
 
1665
        case EVENT_ASSOC_REJECT:
 
1666
                sme_event_assoc_reject(wpa_s, data);
 
1667
                break;
 
1668
        case EVENT_AUTH_TIMED_OUT:
 
1669
                sme_event_auth_timed_out(wpa_s, data);
 
1670
                break;
 
1671
        case EVENT_ASSOC_TIMED_OUT:
 
1672
                sme_event_assoc_timed_out(wpa_s, data);
 
1673
                break;
 
1674
#ifdef CONFIG_AP
 
1675
        case EVENT_TX_STATUS:
 
1676
                if (wpa_s->ap_iface == NULL)
 
1677
                        break;
 
1678
                switch (data->tx_status.type) {
 
1679
                case WLAN_FC_TYPE_MGMT:
 
1680
                        ap_mgmt_tx_cb(wpa_s, data->tx_status.data,
 
1681
                                      data->tx_status.data_len,
 
1682
                                      data->tx_status.stype,
 
1683
                                      data->tx_status.ack);
 
1684
                        break;
 
1685
                case WLAN_FC_TYPE_DATA:
 
1686
                        ap_tx_status(wpa_s, data->tx_status.dst,
 
1687
                                     data->tx_status.data,
 
1688
                                     data->tx_status.data_len,
 
1689
                                     data->tx_status.ack);
 
1690
                        break;
 
1691
                }
 
1692
                break;
 
1693
        case EVENT_RX_FROM_UNKNOWN:
 
1694
                if (wpa_s->ap_iface == NULL)
 
1695
                        break;
 
1696
                ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.frame,
 
1697
                                       data->rx_from_unknown.len);
 
1698
                break;
 
1699
        case EVENT_RX_MGMT:
 
1700
                if (wpa_s->ap_iface == NULL)
 
1701
                        break;
 
1702
                ap_mgmt_rx(wpa_s, &data->rx_mgmt);
 
1703
                break;
 
1704
#endif /* CONFIG_AP */
 
1705
        case EVENT_RX_ACTION:
 
1706
                wpa_printf(MSG_DEBUG, "Received Action frame: SA=" MACSTR
 
1707
                           " Category=%u DataLen=%d freq=%d MHz",
 
1708
                           MAC2STR(data->rx_action.sa),
 
1709
                           data->rx_action.category, (int) data->rx_action.len,
 
1710
                           data->rx_action.freq);
 
1711
#ifdef CONFIG_IEEE80211R
 
1712
                if (data->rx_action.category == WLAN_ACTION_FT) {
 
1713
                        ft_rx_action(wpa_s, data->rx_action.data,
 
1714
                                     data->rx_action.len);
 
1715
                        break;
 
1716
                }
 
1717
#endif /* CONFIG_IEEE80211R */
 
1718
                break;
 
1719
#ifdef CONFIG_CLIENT_MLME
 
1720
        case EVENT_MLME_RX: {
 
1721
                struct ieee80211_rx_status rx_status;
 
1722
                os_memset(&rx_status, 0, sizeof(rx_status));
 
1723
                rx_status.freq = data->mlme_rx.freq;
 
1724
                rx_status.channel = data->mlme_rx.channel;
 
1725
                rx_status.ssi = data->mlme_rx.ssi;
 
1726
                ieee80211_sta_rx(wpa_s, data->mlme_rx.buf, data->mlme_rx.len,
 
1727
                                 &rx_status);
 
1728
                break;
 
1729
        }
 
1730
#endif /* CONFIG_CLIENT_MLME */
 
1731
        case EVENT_EAPOL_RX:
 
1732
                wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
 
1733
                                        data->eapol_rx.data,
 
1734
                                        data->eapol_rx.data_len);
 
1735
                break;
 
1736
        case EVENT_SIGNAL_CHANGE:
 
1737
                bgscan_notify_signal_change(
 
1738
                        wpa_s, data->signal_change.above_threshold);
 
1739
                break;
 
1740
        default:
 
1741
                wpa_printf(MSG_INFO, "Unknown event %d", event);
 
1742
                break;
 
1743
        }
 
1744
}