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

« back to all changes in this revision

Viewing changes to wpa_supplicant/wpas_glue.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * WPA Supplicant - Glue code to setup EAPOL and RSN modules
 
3
 * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
 
 
17
#include "common.h"
 
18
#include "eapol_supp/eapol_supp_sm.h"
 
19
#include "wpa.h"
 
20
#include "eloop.h"
 
21
#include "config.h"
 
22
#include "l2_packet/l2_packet.h"
 
23
#include "wpa_common.h"
 
24
#include "wpa_supplicant_i.h"
 
25
#include "pmksa_cache.h"
 
26
#include "mlme.h"
 
27
#include "ieee802_11_defs.h"
 
28
#include "wpa_ctrl.h"
 
29
#include "wpas_glue.h"
 
30
 
 
31
 
 
32
#ifndef CONFIG_NO_CONFIG_BLOBS
 
33
#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
 
34
static void wpa_supplicant_set_config_blob(void *ctx,
 
35
                                           struct wpa_config_blob *blob)
 
36
{
 
37
        struct wpa_supplicant *wpa_s = ctx;
 
38
        wpa_config_set_blob(wpa_s->conf, blob);
 
39
}
 
40
 
 
41
 
 
42
static const struct wpa_config_blob *
 
43
wpa_supplicant_get_config_blob(void *ctx, const char *name)
 
44
{
 
45
        struct wpa_supplicant *wpa_s = ctx;
 
46
        return wpa_config_get_blob(wpa_s->conf, name);
 
47
}
 
48
#endif /* defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) */
 
49
#endif /* CONFIG_NO_CONFIG_BLOBS */
 
50
 
 
51
 
 
52
#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
 
53
static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
 
54
                            const void *data, u16 data_len,
 
55
                            size_t *msg_len, void **data_pos)
 
56
{
 
57
        struct ieee802_1x_hdr *hdr;
 
58
 
 
59
        *msg_len = sizeof(*hdr) + data_len;
 
60
        hdr = os_malloc(*msg_len);
 
61
        if (hdr == NULL)
 
62
                return NULL;
 
63
 
 
64
        hdr->version = wpa_s->conf->eapol_version;
 
65
        hdr->type = type;
 
66
        hdr->length = host_to_be16(data_len);
 
67
 
 
68
        if (data)
 
69
                os_memcpy(hdr + 1, data, data_len);
 
70
        else
 
71
                os_memset(hdr + 1, 0, data_len);
 
72
 
 
73
        if (data_pos)
 
74
                *data_pos = hdr + 1;
 
75
 
 
76
        return (u8 *) hdr;
 
77
}
 
78
 
 
79
 
 
80
/**
 
81
 * wpa_ether_send - Send Ethernet frame
 
82
 * @wpa_s: Pointer to wpa_supplicant data
 
83
 * @dest: Destination MAC address
 
84
 * @proto: Ethertype in host byte order
 
85
 * @buf: Frame payload starting from IEEE 802.1X header
 
86
 * @len: Frame payload length
 
87
 * Returns: >=0 on success, <0 on failure
 
88
 */
 
89
static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
 
90
                          u16 proto, const u8 *buf, size_t len)
 
91
{
 
92
        if (wpa_s->l2) {
 
93
                return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
 
94
        }
 
95
 
 
96
        return wpa_drv_send_eapol(wpa_s, dest, proto, buf, len);
 
97
}
 
98
#endif /* IEEE8021X_EAPOL || !CONFIG_NO_WPA */
 
99
 
 
100
 
 
101
#ifdef IEEE8021X_EAPOL
 
102
 
 
103
/**
 
104
 * wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator
 
105
 * @ctx: Pointer to wpa_supplicant data (wpa_s)
 
106
 * @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*)
 
107
 * @buf: EAPOL payload (after IEEE 802.1X header)
 
108
 * @len: EAPOL payload length
 
109
 * Returns: >=0 on success, <0 on failure
 
110
 *
 
111
 * This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame
 
112
 * to the current Authenticator.
 
113
 */
 
114
static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
 
115
                                     size_t len)
 
116
{
 
117
        struct wpa_supplicant *wpa_s = ctx;
 
118
        u8 *msg, *dst, bssid[ETH_ALEN];
 
119
        size_t msglen;
 
120
        int res;
 
121
 
 
122
        /* TODO: could add l2_packet_sendmsg that allows fragments to avoid
 
123
         * extra copy here */
 
124
 
 
125
        if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK ||
 
126
            wpa_s->key_mgmt == WPA_KEY_MGMT_FT_PSK ||
 
127
            wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
 
128
                /* Current SSID is not using IEEE 802.1X/EAP, so drop possible
 
129
                 * EAPOL frames (mainly, EAPOL-Start) from EAPOL state
 
130
                 * machines. */
 
131
                wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X "
 
132
                           "mode (type=%d len=%lu)", type,
 
133
                           (unsigned long) len);
 
134
                return -1;
 
135
        }
 
136
 
 
137
        if (pmksa_cache_get_current(wpa_s->wpa) &&
 
138
            type == IEEE802_1X_TYPE_EAPOL_START) {
 
139
                /* Trying to use PMKSA caching - do not send EAPOL-Start frames
 
140
                 * since they will trigger full EAPOL authentication. */
 
141
                wpa_printf(MSG_DEBUG, "RSN: PMKSA caching - do not send "
 
142
                           "EAPOL-Start");
 
143
                return -1;
 
144
        }
 
145
 
 
146
        if (os_memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
 
147
        {
 
148
                wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an "
 
149
                           "EAPOL frame");
 
150
                if (wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
 
151
                    os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) !=
 
152
                    0) {
 
153
                        dst = bssid;
 
154
                        wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR
 
155
                                   " from the driver as the EAPOL destination",
 
156
                                   MAC2STR(dst));
 
157
                } else {
 
158
                        dst = wpa_s->last_eapol_src;
 
159
                        wpa_printf(MSG_DEBUG, "Using the source address of the"
 
160
                                   " last received EAPOL frame " MACSTR " as "
 
161
                                   "the EAPOL destination",
 
162
                                   MAC2STR(dst));
 
163
                }
 
164
        } else {
 
165
                /* BSSID was already set (from (Re)Assoc event, so use it as
 
166
                 * the EAPOL destination. */
 
167
                dst = wpa_s->bssid;
 
168
        }
 
169
 
 
170
        msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL);
 
171
        if (msg == NULL)
 
172
                return -1;
 
173
 
 
174
        wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst));
 
175
        wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen);
 
176
        res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen);
 
177
        os_free(msg);
 
178
        return res;
 
179
}
 
180
 
 
181
 
 
182
/**
 
183
 * wpa_eapol_set_wep_key - set WEP key for the driver
 
184
 * @ctx: Pointer to wpa_supplicant data (wpa_s)
 
185
 * @unicast: 1 = individual unicast key, 0 = broadcast key
 
186
 * @keyidx: WEP key index (0..3)
 
187
 * @key: Pointer to key data
 
188
 * @keylen: Key length in bytes
 
189
 * Returns: 0 on success or < 0 on error.
 
190
 */
 
191
static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx,
 
192
                                 const u8 *key, size_t keylen)
 
193
{
 
194
        struct wpa_supplicant *wpa_s = ctx;
 
195
        if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
 
196
                int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 :
 
197
                        WPA_CIPHER_WEP104;
 
198
                if (unicast)
 
199
                        wpa_s->pairwise_cipher = cipher;
 
200
                else
 
201
                        wpa_s->group_cipher = cipher;
 
202
        }
 
203
        return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
 
204
                               unicast ? wpa_s->bssid :
 
205
                               (u8 *) "\xff\xff\xff\xff\xff\xff",
 
206
                               keyidx, unicast, (u8 *) "", 0, key, keylen);
 
207
}
 
208
 
 
209
 
 
210
static void wpa_supplicant_aborted_cached(void *ctx)
 
211
{
 
212
        struct wpa_supplicant *wpa_s = ctx;
 
213
        wpa_sm_aborted_cached(wpa_s->wpa);
 
214
}
 
215
 
 
216
 
 
217
static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, int success,
 
218
                                    void *ctx)
 
219
{
 
220
        struct wpa_supplicant *wpa_s = ctx;
 
221
        int res, pmk_len;
 
222
        u8 pmk[PMK_LEN];
 
223
 
 
224
        wpa_printf(MSG_DEBUG, "EAPOL authentication completed %ssuccessfully",
 
225
                   success ? "" : "un");
 
226
 
 
227
        if (!success || !wpa_s->driver_4way_handshake)
 
228
                return;
 
229
 
 
230
        if (wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
 
231
            wpa_s->key_mgmt != WPA_KEY_MGMT_FT_IEEE8021X)
 
232
                return;
 
233
 
 
234
        wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way "
 
235
                   "handshake");
 
236
 
 
237
        pmk_len = PMK_LEN;
 
238
        res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
 
239
        if (res) {
 
240
                /*
 
241
                 * EAP-LEAP is an exception from other EAP methods: it
 
242
                 * uses only 16-byte PMK.
 
243
                 */
 
244
                res = eapol_sm_get_key(eapol, pmk, 16);
 
245
                pmk_len = 16;
 
246
        }
 
247
 
 
248
        if (res) {
 
249
                wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state "
 
250
                           "machines");
 
251
                return;
 
252
        }
 
253
 
 
254
        if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk,
 
255
                            pmk_len)) {
 
256
                wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
 
257
        }
 
258
 
 
259
        wpa_supplicant_cancel_scan(wpa_s);
 
260
        wpa_supplicant_cancel_auth_timeout(wpa_s);
 
261
        wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
 
262
 
 
263
}
 
264
 
 
265
 
 
266
static void wpa_supplicant_notify_eapol_done(void *ctx)
 
267
{
 
268
        struct wpa_supplicant *wpa_s = ctx;
 
269
        wpa_msg(wpa_s, MSG_DEBUG, "WPA: EAPOL processing complete");
 
270
        if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
 
271
            wpa_s->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
 
272
                wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE);
 
273
        } else {
 
274
                wpa_supplicant_cancel_scan(wpa_s);
 
275
                wpa_supplicant_cancel_auth_timeout(wpa_s);
 
276
                wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
 
277
        }
 
278
}
 
279
 
 
280
#endif /* IEEE8021X_EAPOL */
 
281
 
 
282
 
 
283
#ifndef CONFIG_NO_WPA
 
284
 
 
285
static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
 
286
{
 
287
        size_t i;
 
288
        int ret = 0;
 
289
        struct wpa_scan_res *curr = NULL;
 
290
        struct wpa_ssid *ssid = wpa_s->current_ssid;
 
291
        const u8 *ie;
 
292
 
 
293
        if (wpa_s->scan_res == NULL)
 
294
                return -1;
 
295
 
 
296
        for (i = 0; i < wpa_s->scan_res->num; i++) {
 
297
                struct wpa_scan_res *r = wpa_s->scan_res->res[i];
 
298
                if (os_memcmp(r->bssid, wpa_s->bssid, ETH_ALEN) != 0)
 
299
                        continue;
 
300
                ie = wpa_scan_get_ie(r, WLAN_EID_SSID);
 
301
                if (ssid == NULL ||
 
302
                    ((ie && ie[1] == ssid->ssid_len &&
 
303
                      os_memcmp(ie + 2, ssid->ssid, ssid->ssid_len) == 0) ||
 
304
                     ssid->ssid_len == 0)) {
 
305
                        curr = r;
 
306
                        break;
 
307
                }
 
308
        }
 
309
 
 
310
        if (curr) {
 
311
                ie = wpa_scan_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE);
 
312
                if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
 
313
                        ret = -1;
 
314
 
 
315
                ie = wpa_scan_get_ie(curr, WLAN_EID_RSN);
 
316
                if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
 
317
                        ret = -1;
 
318
        } else {
 
319
                ret = -1;
 
320
        }
 
321
 
 
322
        return ret;
 
323
}
 
324
 
 
325
 
 
326
static int wpa_supplicant_get_beacon_ie(void *ctx)
 
327
{
 
328
        struct wpa_supplicant *wpa_s = ctx;
 
329
        if (wpa_get_beacon_ie(wpa_s) == 0) {
 
330
                return 0;
 
331
        }
 
332
 
 
333
        /* No WPA/RSN IE found in the cached scan results. Try to get updated
 
334
         * scan results from the driver. */
 
335
        if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
 
336
                return -1;
 
337
        }
 
338
 
 
339
        return wpa_get_beacon_ie(wpa_s);
 
340
}
 
341
 
 
342
 
 
343
static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type,
 
344
                             const void *data, u16 data_len,
 
345
                             size_t *msg_len, void **data_pos)
 
346
{
 
347
        return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos);
 
348
}
 
349
 
 
350
 
 
351
static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto,
 
352
                           const u8 *buf, size_t len)
 
353
{
 
354
        return wpa_ether_send(wpa_s, dest, proto, buf, len);
 
355
}
 
356
 
 
357
 
 
358
static void _wpa_supplicant_req_scan(void *wpa_s, int sec, int usec)
 
359
{
 
360
        wpa_supplicant_req_scan(wpa_s, sec, usec);
 
361
}
 
362
 
 
363
 
 
364
static void _wpa_supplicant_cancel_scan(void *wpa_s)
 
365
{
 
366
        wpa_supplicant_cancel_scan(wpa_s);
 
367
}
 
368
 
 
369
 
 
370
static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
 
371
{
 
372
        wpa_supplicant_cancel_auth_timeout(wpa_s);
 
373
}
 
374
 
 
375
 
 
376
static void _wpa_supplicant_set_state(void *wpa_s, wpa_states state)
 
377
{
 
378
        wpa_supplicant_set_state(wpa_s, state);
 
379
}
 
380
 
 
381
 
 
382
/**
 
383
 * wpa_supplicant_get_state - Get the connection state
 
384
 * @wpa_s: Pointer to wpa_supplicant data
 
385
 * Returns: The current connection state (WPA_*)
 
386
 */
 
387
static wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s)
 
388
{
 
389
        return wpa_s->wpa_state;
 
390
}
 
391
 
 
392
 
 
393
static wpa_states _wpa_supplicant_get_state(void *wpa_s)
 
394
{
 
395
        return wpa_supplicant_get_state(wpa_s);
 
396
}
 
397
 
 
398
 
 
399
static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code)
 
400
{
 
401
        wpa_supplicant_disassociate(wpa_s, reason_code);
 
402
}
 
403
 
 
404
 
 
405
static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code)
 
406
{
 
407
        wpa_supplicant_deauthenticate(wpa_s, reason_code);
 
408
}
 
409
 
 
410
 
 
411
static void * wpa_supplicant_get_network_ctx(void *wpa_s)
 
412
{
 
413
        return wpa_supplicant_get_ssid(wpa_s);
 
414
}
 
415
 
 
416
 
 
417
static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid)
 
418
{
 
419
        struct wpa_supplicant *wpa_s = ctx;
 
420
        if (wpa_s->use_client_mlme) {
 
421
                os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
 
422
                return 0;
 
423
        }
 
424
        return wpa_drv_get_bssid(wpa_s, bssid);
 
425
}
 
426
 
 
427
 
 
428
static int wpa_supplicant_set_key(void *wpa_s, wpa_alg alg,
 
429
                                  const u8 *addr, int key_idx, int set_tx,
 
430
                                  const u8 *seq, size_t seq_len,
 
431
                                  const u8 *key, size_t key_len)
 
432
{
 
433
        return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len,
 
434
                               key, key_len);
 
435
}
 
436
 
 
437
 
 
438
static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr,
 
439
                                             int protection_type,
 
440
                                             int key_type)
 
441
{
 
442
        return wpa_drv_mlme_setprotection(wpa_s, addr, protection_type,
 
443
                                          key_type);
 
444
}
 
445
 
 
446
 
 
447
static int wpa_supplicant_add_pmkid(void *wpa_s,
 
448
                                    const u8 *bssid, const u8 *pmkid)
 
449
{
 
450
        return wpa_drv_add_pmkid(wpa_s, bssid, pmkid);
 
451
}
 
452
 
 
453
 
 
454
static int wpa_supplicant_remove_pmkid(void *wpa_s,
 
455
                                       const u8 *bssid, const u8 *pmkid)
 
456
{
 
457
        return wpa_drv_remove_pmkid(wpa_s, bssid, pmkid);
 
458
}
 
459
 
 
460
 
 
461
#ifdef CONFIG_IEEE80211R
 
462
static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md,
 
463
                                        const u8 *ies, size_t ies_len)
 
464
{
 
465
        struct wpa_supplicant *wpa_s = ctx;
 
466
        if (wpa_s->use_client_mlme)
 
467
                return ieee80211_sta_update_ft_ies(wpa_s, md, ies, ies_len);
 
468
        return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len);
 
469
}
 
470
 
 
471
 
 
472
static int wpa_supplicant_send_ft_action(void *ctx, u8 action,
 
473
                                         const u8 *target_ap,
 
474
                                         const u8 *ies, size_t ies_len)
 
475
{
 
476
        struct wpa_supplicant *wpa_s = ctx;
 
477
        if (wpa_s->use_client_mlme)
 
478
                return ieee80211_sta_send_ft_action(wpa_s, action, target_ap,
 
479
                                                    ies, ies_len);
 
480
        return wpa_drv_send_ft_action(wpa_s, action, target_ap, ies, ies_len);
 
481
}
 
482
#endif /* CONFIG_IEEE80211R */
 
483
 
 
484
#endif /* CONFIG_NO_WPA */
 
485
 
 
486
 
 
487
#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
 
488
static void wpa_supplicant_eap_param_needed(void *ctx, const char *field,
 
489
                                            const char *txt)
 
490
{
 
491
        struct wpa_supplicant *wpa_s = ctx;
 
492
        struct wpa_ssid *ssid = wpa_s->current_ssid;
 
493
        char *buf;
 
494
        size_t buflen;
 
495
        int len;
 
496
 
 
497
        if (ssid == NULL)
 
498
                return;
 
499
 
 
500
        buflen = 100 + os_strlen(txt) + ssid->ssid_len;
 
501
        buf = os_malloc(buflen);
 
502
        if (buf == NULL)
 
503
                return;
 
504
        len = os_snprintf(buf, buflen,
 
505
                          WPA_CTRL_REQ "%s-%d:%s needed for SSID ",
 
506
                          field, ssid->id, txt);
 
507
        if (len < 0 || (size_t) len >= buflen) {
 
508
                os_free(buf);
 
509
                return;
 
510
        }
 
511
        if (ssid->ssid && buflen > len + ssid->ssid_len) {
 
512
                os_memcpy(buf + len, ssid->ssid, ssid->ssid_len);
 
513
                len += ssid->ssid_len;
 
514
                buf[len] = '\0';
 
515
        }
 
516
        buf[buflen - 1] = '\0';
 
517
        wpa_msg(wpa_s, MSG_INFO, "%s", buf);
 
518
        os_free(buf);
 
519
}
 
520
#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
 
521
#define wpa_supplicant_eap_param_needed NULL
 
522
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
 
523
 
 
524
 
 
525
int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
 
526
{
 
527
#ifdef IEEE8021X_EAPOL
 
528
        struct eapol_ctx *ctx;
 
529
        ctx = os_zalloc(sizeof(*ctx));
 
530
        if (ctx == NULL) {
 
531
                wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context.");
 
532
                return -1;
 
533
        }
 
534
 
 
535
        ctx->ctx = wpa_s;
 
536
        ctx->msg_ctx = wpa_s;
 
537
        ctx->eapol_send_ctx = wpa_s;
 
538
        ctx->preauth = 0;
 
539
        ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done;
 
540
        ctx->eapol_send = wpa_supplicant_eapol_send;
 
541
        ctx->set_wep_key = wpa_eapol_set_wep_key;
 
542
        ctx->set_config_blob = wpa_supplicant_set_config_blob;
 
543
        ctx->get_config_blob = wpa_supplicant_get_config_blob;
 
544
        ctx->aborted_cached = wpa_supplicant_aborted_cached;
 
545
#ifdef EAP_TLS_OPENSSL
 
546
        ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
 
547
        ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
 
548
        ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
 
549
#endif /* EAP_TLS_OPENSSL */
 
550
        ctx->eap_param_needed = wpa_supplicant_eap_param_needed;
 
551
        ctx->cb = wpa_supplicant_eapol_cb;
 
552
        ctx->cb_ctx = wpa_s;
 
553
        wpa_s->eapol = eapol_sm_init(ctx);
 
554
        if (wpa_s->eapol == NULL) {
 
555
                os_free(ctx);
 
556
                wpa_printf(MSG_ERROR, "Failed to initialize EAPOL state "
 
557
                           "machines.");
 
558
                return -1;
 
559
        }
 
560
#endif /* IEEE8021X_EAPOL */
 
561
 
 
562
        return 0;
 
563
}
 
564
 
 
565
 
 
566
int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
 
567
{
 
568
#ifndef CONFIG_NO_WPA
 
569
        struct wpa_sm_ctx *ctx;
 
570
        ctx = os_zalloc(sizeof(*ctx));
 
571
        if (ctx == NULL) {
 
572
                wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
 
573
                return -1;
 
574
        }
 
575
 
 
576
        ctx->ctx = wpa_s;
 
577
        ctx->set_state = _wpa_supplicant_set_state;
 
578
        ctx->get_state = _wpa_supplicant_get_state;
 
579
        ctx->req_scan = _wpa_supplicant_req_scan;
 
580
        ctx->cancel_scan = _wpa_supplicant_cancel_scan;
 
581
        ctx->deauthenticate = _wpa_supplicant_deauthenticate;
 
582
        ctx->disassociate = _wpa_supplicant_disassociate;
 
583
        ctx->set_key = wpa_supplicant_set_key;
 
584
        ctx->get_network_ctx = wpa_supplicant_get_network_ctx;
 
585
        ctx->get_bssid = wpa_supplicant_get_bssid;
 
586
        ctx->ether_send = _wpa_ether_send;
 
587
        ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie;
 
588
        ctx->alloc_eapol = _wpa_alloc_eapol;
 
589
        ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout;
 
590
        ctx->add_pmkid = wpa_supplicant_add_pmkid;
 
591
        ctx->remove_pmkid = wpa_supplicant_remove_pmkid;
 
592
#ifndef CONFIG_NO_CONFIG_BLOBS
 
593
        ctx->set_config_blob = wpa_supplicant_set_config_blob;
 
594
        ctx->get_config_blob = wpa_supplicant_get_config_blob;
 
595
#endif /* CONFIG_NO_CONFIG_BLOBS */
 
596
        ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection;
 
597
#ifdef CONFIG_IEEE80211R
 
598
        ctx->update_ft_ies = wpa_supplicant_update_ft_ies;
 
599
        ctx->send_ft_action = wpa_supplicant_send_ft_action;
 
600
#endif /* CONFIG_IEEE80211R */
 
601
 
 
602
        wpa_s->wpa = wpa_sm_init(ctx);
 
603
        if (wpa_s->wpa == NULL) {
 
604
                wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
 
605
                           "machine");
 
606
                return -1;
 
607
        }
 
608
#endif /* CONFIG_NO_WPA */
 
609
 
 
610
        return 0;
 
611
}
 
612
 
 
613
 
 
614
void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
 
615
                                        struct wpa_ssid *ssid)
 
616
{
 
617
        struct rsn_supp_config conf;
 
618
        if (ssid) {
 
619
                os_memset(&conf, 0, sizeof(conf));
 
620
                conf.peerkey_enabled = ssid->peerkey;
 
621
                conf.allowed_pairwise_cipher = ssid->pairwise_cipher;
 
622
                conf.eap_workaround = ssid->eap_workaround;
 
623
                conf.eap_conf_ctx = &ssid->eap;
 
624
                conf.ssid = ssid->ssid;
 
625
                conf.ssid_len = ssid->ssid_len;
 
626
        }
 
627
        wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
 
628
}