Line data Source code
1 : /*
2 : * wpa_supplicant - IBSS RSN
3 : * Copyright (c) 2009-2013, Jouni Malinen <j@w1.fi>
4 : *
5 : * This software may be distributed under the terms of the BSD license.
6 : * See README for more details.
7 : */
8 :
9 : #include "includes.h"
10 :
11 : #include "common.h"
12 : #include "common/wpa_ctrl.h"
13 : #include "utils/eloop.h"
14 : #include "l2_packet/l2_packet.h"
15 : #include "rsn_supp/wpa.h"
16 : #include "rsn_supp/wpa_ie.h"
17 : #include "ap/wpa_auth.h"
18 : #include "wpa_supplicant_i.h"
19 : #include "driver_i.h"
20 : #include "common/ieee802_11_defs.h"
21 : #include "ibss_rsn.h"
22 :
23 :
24 : static void ibss_rsn_auth_timeout(void *eloop_ctx, void *timeout_ctx);
25 :
26 :
27 408 : static struct ibss_rsn_peer * ibss_rsn_get_peer(struct ibss_rsn *ibss_rsn,
28 : const u8 *addr)
29 : {
30 : struct ibss_rsn_peer *peer;
31 :
32 527 : for (peer = ibss_rsn->peers; peer; peer = peer->next)
33 475 : if (os_memcmp(addr, peer->addr, ETH_ALEN) == 0)
34 356 : break;
35 408 : return peer;
36 : }
37 :
38 :
39 25 : static void ibss_rsn_free(struct ibss_rsn_peer *peer)
40 : {
41 25 : eloop_cancel_timeout(ibss_rsn_auth_timeout, peer, NULL);
42 25 : wpa_auth_sta_deinit(peer->auth);
43 25 : wpa_sm_deinit(peer->supp);
44 25 : os_free(peer);
45 25 : }
46 :
47 :
48 67 : static void supp_set_state(void *ctx, enum wpa_states state)
49 : {
50 67 : struct ibss_rsn_peer *peer = ctx;
51 67 : peer->supp_state = state;
52 67 : }
53 :
54 :
55 1 : static enum wpa_states supp_get_state(void *ctx)
56 : {
57 1 : struct ibss_rsn_peer *peer = ctx;
58 1 : return peer->supp_state;
59 : }
60 :
61 :
62 37 : static int supp_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *buf,
63 : size_t len)
64 : {
65 37 : struct ibss_rsn_peer *peer = ctx;
66 37 : struct wpa_supplicant *wpa_s = peer->ibss_rsn->wpa_s;
67 :
68 259 : wpa_printf(MSG_DEBUG, "SUPP: %s(dest=" MACSTR " proto=0x%04x "
69 : "len=%lu)",
70 222 : __func__, MAC2STR(dest), proto, (unsigned long) len);
71 :
72 37 : if (wpa_s->l2)
73 37 : return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
74 :
75 0 : return -1;
76 : }
77 :
78 :
79 38 : static u8 * supp_alloc_eapol(void *ctx, u8 type, const void *data,
80 : u16 data_len, size_t *msg_len, void **data_pos)
81 : {
82 : struct ieee802_1x_hdr *hdr;
83 :
84 38 : wpa_printf(MSG_DEBUG, "SUPP: %s(type=%d data_len=%d)",
85 : __func__, type, data_len);
86 :
87 38 : *msg_len = sizeof(*hdr) + data_len;
88 38 : hdr = os_malloc(*msg_len);
89 38 : if (hdr == NULL)
90 1 : return NULL;
91 :
92 37 : hdr->version = 2;
93 37 : hdr->type = type;
94 37 : hdr->length = host_to_be16(data_len);
95 :
96 37 : if (data)
97 0 : os_memcpy(hdr + 1, data, data_len);
98 : else
99 37 : os_memset(hdr + 1, 0, data_len);
100 :
101 37 : if (data_pos)
102 37 : *data_pos = hdr + 1;
103 :
104 37 : return (u8 *) hdr;
105 : }
106 :
107 :
108 14 : static int supp_get_beacon_ie(void *ctx)
109 : {
110 14 : struct ibss_rsn_peer *peer = ctx;
111 :
112 14 : wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
113 : /* TODO: get correct RSN IE */
114 14 : return wpa_sm_set_ap_rsn_ie(peer->supp,
115 : (u8 *) "\x30\x14\x01\x00"
116 : "\x00\x0f\xac\x04"
117 : "\x01\x00\x00\x0f\xac\x04"
118 : "\x01\x00\x00\x0f\xac\x02"
119 : "\x00\x00", 22);
120 : }
121 :
122 :
123 70 : static void ibss_check_rsn_completed(struct ibss_rsn_peer *peer)
124 : {
125 70 : struct wpa_supplicant *wpa_s = peer->ibss_rsn->wpa_s;
126 :
127 70 : if ((peer->authentication_status &
128 : (IBSS_RSN_SET_PTK_SUPP | IBSS_RSN_SET_PTK_AUTH)) !=
129 : (IBSS_RSN_SET_PTK_SUPP | IBSS_RSN_SET_PTK_AUTH))
130 43 : return;
131 27 : if (peer->authentication_status & IBSS_RSN_REPORTED_PTK)
132 13 : return;
133 14 : peer->authentication_status |= IBSS_RSN_REPORTED_PTK;
134 84 : wpa_msg(wpa_s, MSG_INFO, IBSS_RSN_COMPLETED MACSTR,
135 84 : MAC2STR(peer->addr));
136 : }
137 :
138 :
139 29 : static int supp_set_key(void *ctx, enum wpa_alg alg,
140 : const u8 *addr, int key_idx, int set_tx,
141 : const u8 *seq, size_t seq_len,
142 : const u8 *key, size_t key_len)
143 : {
144 29 : struct ibss_rsn_peer *peer = ctx;
145 :
146 174 : wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d "
147 : "set_tx=%d)",
148 174 : __func__, alg, MAC2STR(addr), key_idx, set_tx);
149 29 : wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len);
150 29 : wpa_hexdump_key(MSG_DEBUG, "SUPP: set_key - key", key, key_len);
151 :
152 29 : if (key_idx == 0) {
153 14 : peer->authentication_status |= IBSS_RSN_SET_PTK_SUPP;
154 14 : ibss_check_rsn_completed(peer);
155 : /*
156 : * In IBSS RSN, the pairwise key from the 4-way handshake
157 : * initiated by the peer with highest MAC address is used.
158 : */
159 14 : if (os_memcmp(peer->ibss_rsn->wpa_s->own_addr, peer->addr,
160 : ETH_ALEN) > 0) {
161 7 : wpa_printf(MSG_DEBUG, "SUPP: Do not use this PTK");
162 7 : return 0;
163 : }
164 : }
165 :
166 22 : if (is_broadcast_ether_addr(addr))
167 15 : addr = peer->addr;
168 22 : return wpa_drv_set_key(peer->ibss_rsn->wpa_s, alg, addr, key_idx,
169 : set_tx, seq, seq_len, key, key_len);
170 : }
171 :
172 :
173 23 : static void * supp_get_network_ctx(void *ctx)
174 : {
175 23 : struct ibss_rsn_peer *peer = ctx;
176 23 : return wpa_supplicant_get_ssid(peer->ibss_rsn->wpa_s);
177 : }
178 :
179 :
180 28 : static int supp_mlme_setprotection(void *ctx, const u8 *addr,
181 : int protection_type, int key_type)
182 : {
183 168 : wpa_printf(MSG_DEBUG, "SUPP: %s(addr=" MACSTR " protection_type=%d "
184 : "key_type=%d)",
185 168 : __func__, MAC2STR(addr), protection_type, key_type);
186 28 : return 0;
187 : }
188 :
189 :
190 15 : static void supp_cancel_auth_timeout(void *ctx)
191 : {
192 15 : wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
193 15 : }
194 :
195 :
196 1 : static void supp_deauthenticate(void * ctx, int reason_code)
197 : {
198 1 : wpa_printf(MSG_DEBUG, "SUPP: %s (TODO)", __func__);
199 1 : }
200 :
201 :
202 25 : static int ibss_rsn_supp_init(struct ibss_rsn_peer *peer, const u8 *own_addr,
203 : const u8 *psk)
204 : {
205 25 : struct wpa_sm_ctx *ctx = os_zalloc(sizeof(*ctx));
206 25 : if (ctx == NULL)
207 1 : return -1;
208 :
209 24 : ctx->ctx = peer;
210 24 : ctx->msg_ctx = peer->ibss_rsn->wpa_s;
211 24 : ctx->set_state = supp_set_state;
212 24 : ctx->get_state = supp_get_state;
213 24 : ctx->ether_send = supp_ether_send;
214 24 : ctx->get_beacon_ie = supp_get_beacon_ie;
215 24 : ctx->alloc_eapol = supp_alloc_eapol;
216 24 : ctx->set_key = supp_set_key;
217 24 : ctx->get_network_ctx = supp_get_network_ctx;
218 24 : ctx->mlme_setprotection = supp_mlme_setprotection;
219 24 : ctx->cancel_auth_timeout = supp_cancel_auth_timeout;
220 24 : ctx->deauthenticate = supp_deauthenticate;
221 24 : peer->supp = wpa_sm_init(ctx);
222 24 : if (peer->supp == NULL) {
223 1 : wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_init() failed");
224 1 : os_free(ctx);
225 1 : return -1;
226 : }
227 :
228 23 : wpa_sm_set_own_addr(peer->supp, own_addr);
229 23 : wpa_sm_set_param(peer->supp, WPA_PARAM_RSN_ENABLED, 1);
230 23 : wpa_sm_set_param(peer->supp, WPA_PARAM_PROTO, WPA_PROTO_RSN);
231 23 : wpa_sm_set_param(peer->supp, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP);
232 23 : wpa_sm_set_param(peer->supp, WPA_PARAM_GROUP, WPA_CIPHER_CCMP);
233 23 : wpa_sm_set_param(peer->supp, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK);
234 23 : wpa_sm_set_pmk(peer->supp, psk, PMK_LEN, NULL, NULL);
235 :
236 23 : peer->supp_ie_len = sizeof(peer->supp_ie);
237 23 : if (wpa_sm_set_assoc_wpa_ie_default(peer->supp, peer->supp_ie,
238 : &peer->supp_ie_len) < 0) {
239 1 : wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_set_assoc_wpa_ie_default()"
240 : " failed");
241 1 : return -1;
242 : }
243 :
244 22 : wpa_sm_notify_assoc(peer->supp, peer->addr);
245 :
246 22 : return 0;
247 : }
248 :
249 :
250 142 : static void auth_logger(void *ctx, const u8 *addr, logger_level level,
251 : const char *txt)
252 : {
253 142 : if (addr)
254 846 : wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " - %s",
255 846 : MAC2STR(addr), txt);
256 : else
257 1 : wpa_printf(MSG_DEBUG, "AUTH: %s", txt);
258 142 : }
259 :
260 :
261 54 : static const u8 * auth_get_psk(void *ctx, const u8 *addr,
262 : const u8 *p2p_dev_addr, const u8 *prev_psk)
263 : {
264 54 : struct ibss_rsn *ibss_rsn = ctx;
265 324 : wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
266 324 : __func__, MAC2STR(addr), prev_psk);
267 54 : if (prev_psk)
268 0 : return NULL;
269 54 : return ibss_rsn->psk;
270 : }
271 :
272 :
273 44 : static int auth_send_eapol(void *ctx, const u8 *addr, const u8 *data,
274 : size_t data_len, int encrypt)
275 : {
276 44 : struct ibss_rsn *ibss_rsn = ctx;
277 44 : struct wpa_supplicant *wpa_s = ibss_rsn->wpa_s;
278 :
279 264 : wpa_printf(MSG_DEBUG, "AUTH: %s(addr=" MACSTR " data_len=%lu "
280 : "encrypt=%d)",
281 264 : __func__, MAC2STR(addr), (unsigned long) data_len, encrypt);
282 :
283 44 : if (wpa_s->l2)
284 44 : return l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data,
285 : data_len);
286 :
287 0 : return -1;
288 : }
289 :
290 :
291 75 : static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
292 : const u8 *addr, int idx, u8 *key, size_t key_len)
293 : {
294 75 : struct ibss_rsn *ibss_rsn = ctx;
295 : u8 seq[6];
296 :
297 75 : os_memset(seq, 0, sizeof(seq));
298 :
299 75 : if (addr) {
300 450 : wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR
301 : " key_idx=%d)",
302 450 : __func__, alg, MAC2STR(addr), idx);
303 : } else {
304 0 : wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)",
305 : __func__, alg, idx);
306 : }
307 75 : wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len);
308 :
309 75 : if (idx == 0) {
310 56 : if (addr) {
311 : struct ibss_rsn_peer *peer;
312 56 : peer = ibss_rsn_get_peer(ibss_rsn, addr);
313 56 : if (peer) {
314 56 : peer->authentication_status |=
315 : IBSS_RSN_SET_PTK_AUTH;
316 56 : ibss_check_rsn_completed(peer);
317 : }
318 : }
319 : /*
320 : * In IBSS RSN, the pairwise key from the 4-way handshake
321 : * initiated by the peer with highest MAC address is used.
322 : */
323 112 : if (addr == NULL ||
324 56 : os_memcmp(ibss_rsn->wpa_s->own_addr, addr, ETH_ALEN) < 0) {
325 32 : wpa_printf(MSG_DEBUG, "AUTH: Do not use this PTK");
326 32 : return 0;
327 : }
328 : }
329 :
330 43 : return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
331 : 1, seq, 6, key, key_len);
332 : }
333 :
334 :
335 2 : static void ibss_rsn_disconnect(void *ctx, const u8 *addr, u16 reason)
336 : {
337 2 : struct ibss_rsn *ibss_rsn = ctx;
338 2 : wpa_drv_sta_deauth(ibss_rsn->wpa_s, addr, reason);
339 2 : }
340 :
341 :
342 1 : static int auth_for_each_sta(void *ctx, int (*cb)(struct wpa_state_machine *sm,
343 : void *ctx),
344 : void *cb_ctx)
345 : {
346 1 : struct ibss_rsn *ibss_rsn = ctx;
347 : struct ibss_rsn_peer *peer;
348 :
349 1 : wpa_printf(MSG_DEBUG, "AUTH: for_each_sta");
350 :
351 2 : for (peer = ibss_rsn->peers; peer; peer = peer->next) {
352 1 : if (peer->auth && cb(peer->auth, cb_ctx))
353 0 : return 1;
354 : }
355 :
356 1 : return 0;
357 : }
358 :
359 :
360 36 : static void ibss_set_sta_authorized(struct ibss_rsn *ibss_rsn,
361 : struct ibss_rsn_peer *peer, int authorized)
362 : {
363 : int res;
364 :
365 36 : if (authorized) {
366 14 : res = wpa_drv_sta_set_flags(ibss_rsn->wpa_s, peer->addr,
367 : WPA_STA_AUTHORIZED,
368 : WPA_STA_AUTHORIZED, ~0);
369 84 : wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " authorizing port",
370 84 : MAC2STR(peer->addr));
371 : } else {
372 22 : res = wpa_drv_sta_set_flags(ibss_rsn->wpa_s, peer->addr,
373 : 0, 0, ~WPA_STA_AUTHORIZED);
374 132 : wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " unauthorizing port",
375 132 : MAC2STR(peer->addr));
376 : }
377 :
378 36 : if (res && errno != ENOENT) {
379 28 : wpa_printf(MSG_DEBUG, "Could not set station " MACSTR " flags "
380 : "for kernel driver (errno=%d)",
381 28 : MAC2STR(peer->addr), errno);
382 : }
383 36 : }
384 :
385 :
386 206 : static void auth_set_eapol(void *ctx, const u8 *addr,
387 : wpa_eapol_variable var, int value)
388 : {
389 206 : struct ibss_rsn *ibss_rsn = ctx;
390 206 : struct ibss_rsn_peer *peer = ibss_rsn_get_peer(ibss_rsn, addr);
391 :
392 206 : if (peer == NULL)
393 206 : return;
394 :
395 206 : switch (var) {
396 : case WPA_EAPOL_authorized:
397 36 : ibss_set_sta_authorized(ibss_rsn, peer, value);
398 36 : break;
399 : default:
400 : /* do not handle any other event */
401 170 : wpa_printf(MSG_DEBUG, "AUTH: eapol event not handled %d", var);
402 170 : break;
403 : }
404 : }
405 :
406 :
407 10 : static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
408 : const u8 *own_addr, struct wpa_ssid *ssid)
409 : {
410 : struct wpa_auth_config conf;
411 : struct wpa_auth_callbacks cb;
412 :
413 10 : wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine");
414 :
415 10 : os_memset(&conf, 0, sizeof(conf));
416 10 : conf.wpa = 2;
417 10 : conf.wpa_key_mgmt = WPA_KEY_MGMT_PSK;
418 10 : conf.wpa_pairwise = WPA_CIPHER_CCMP;
419 10 : conf.rsn_pairwise = WPA_CIPHER_CCMP;
420 10 : conf.wpa_group = WPA_CIPHER_CCMP;
421 10 : conf.eapol_version = 2;
422 10 : conf.wpa_group_rekey = ssid->group_rekey ? ssid->group_rekey : 600;
423 :
424 10 : os_memset(&cb, 0, sizeof(cb));
425 10 : cb.ctx = ibss_rsn;
426 10 : cb.logger = auth_logger;
427 10 : cb.set_eapol = auth_set_eapol;
428 10 : cb.send_eapol = auth_send_eapol;
429 10 : cb.get_psk = auth_get_psk;
430 10 : cb.set_key = auth_set_key;
431 10 : cb.for_each_sta = auth_for_each_sta;
432 10 : cb.disconnect = ibss_rsn_disconnect;
433 :
434 10 : ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
435 10 : if (ibss_rsn->auth_group == NULL) {
436 1 : wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
437 1 : return -1;
438 : }
439 :
440 9 : wpa_init_keys(ibss_rsn->auth_group);
441 :
442 9 : return 0;
443 : }
444 :
445 :
446 22 : static int ibss_rsn_auth_init(struct ibss_rsn *ibss_rsn,
447 : struct ibss_rsn_peer *peer)
448 : {
449 22 : peer->auth = wpa_auth_sta_init(ibss_rsn->auth_group, peer->addr, NULL);
450 22 : if (peer->auth == NULL) {
451 1 : wpa_printf(MSG_DEBUG, "AUTH: wpa_auth_sta_init() failed");
452 1 : return -1;
453 : }
454 :
455 : /* TODO: get peer RSN IE with Probe Request */
456 21 : if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth,
457 : (u8 *) "\x30\x14\x01\x00"
458 : "\x00\x0f\xac\x04"
459 : "\x01\x00\x00\x0f\xac\x04"
460 : "\x01\x00\x00\x0f\xac\x02"
461 : "\x00\x00", 22, NULL, 0) !=
462 : WPA_IE_OK) {
463 1 : wpa_printf(MSG_DEBUG, "AUTH: wpa_validate_wpa_ie() failed");
464 1 : return -1;
465 : }
466 :
467 20 : if (wpa_auth_sm_event(peer->auth, WPA_ASSOC))
468 0 : return -1;
469 :
470 20 : if (wpa_auth_sta_associated(ibss_rsn->auth_group, peer->auth))
471 0 : return -1;
472 :
473 20 : return 0;
474 : }
475 :
476 :
477 27 : static int ibss_rsn_send_auth(struct ibss_rsn *ibss_rsn, const u8 *da, int seq)
478 : {
479 : struct ieee80211_mgmt auth;
480 27 : const size_t auth_length = IEEE80211_HDRLEN + sizeof(auth.u.auth);
481 27 : struct wpa_supplicant *wpa_s = ibss_rsn->wpa_s;
482 :
483 27 : if (wpa_s->driver->send_frame == NULL)
484 0 : return -1;
485 :
486 27 : os_memset(&auth, 0, sizeof(auth));
487 :
488 27 : auth.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
489 : WLAN_FC_STYPE_AUTH);
490 27 : os_memcpy(auth.da, da, ETH_ALEN);
491 27 : os_memcpy(auth.sa, wpa_s->own_addr, ETH_ALEN);
492 27 : os_memcpy(auth.bssid, wpa_s->bssid, ETH_ALEN);
493 :
494 27 : auth.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
495 27 : auth.u.auth.auth_transaction = host_to_le16(seq);
496 27 : auth.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);
497 :
498 162 : wpa_printf(MSG_DEBUG, "RSN: IBSS TX Auth frame (SEQ %d) to " MACSTR,
499 162 : seq, MAC2STR(da));
500 :
501 27 : return wpa_s->driver->send_frame(wpa_s->drv_priv, (u8 *) &auth,
502 : auth_length, 0);
503 : }
504 :
505 :
506 60 : static int ibss_rsn_is_auth_started(struct ibss_rsn_peer * peer)
507 : {
508 60 : return peer->authentication_status &
509 : (IBSS_RSN_AUTH_BY_US | IBSS_RSN_AUTH_EAPOL_BY_US);
510 : }
511 :
512 :
513 : static struct ibss_rsn_peer *
514 27 : ibss_rsn_peer_init(struct ibss_rsn *ibss_rsn, const u8 *addr)
515 : {
516 : struct ibss_rsn_peer *peer;
517 27 : if (ibss_rsn == NULL)
518 0 : return NULL;
519 :
520 27 : peer = ibss_rsn_get_peer(ibss_rsn, addr);
521 27 : if (peer) {
522 0 : wpa_printf(MSG_DEBUG, "RSN: IBSS Supplicant for peer "MACSTR
523 0 : " already running", MAC2STR(addr));
524 0 : return peer;
525 : }
526 :
527 162 : wpa_printf(MSG_DEBUG, "RSN: Starting IBSS Supplicant for peer "MACSTR,
528 162 : MAC2STR(addr));
529 :
530 27 : peer = os_zalloc(sizeof(*peer));
531 27 : if (peer == NULL) {
532 2 : wpa_printf(MSG_DEBUG, "RSN: Could not allocate memory.");
533 2 : return NULL;
534 : }
535 :
536 25 : peer->ibss_rsn = ibss_rsn;
537 25 : os_memcpy(peer->addr, addr, ETH_ALEN);
538 25 : peer->authentication_status = IBSS_RSN_AUTH_NOT_AUTHENTICATED;
539 :
540 25 : if (ibss_rsn_supp_init(peer, ibss_rsn->wpa_s->own_addr,
541 25 : ibss_rsn->psk) < 0) {
542 3 : ibss_rsn_free(peer);
543 3 : return NULL;
544 : }
545 :
546 22 : peer->next = ibss_rsn->peers;
547 22 : ibss_rsn->peers = peer;
548 :
549 22 : return peer;
550 : }
551 :
552 :
553 1 : static void ibss_rsn_auth_timeout(void *eloop_ctx, void *timeout_ctx)
554 : {
555 1 : struct ibss_rsn_peer *peer = eloop_ctx;
556 :
557 : /*
558 : * Assume peer does not support Authentication exchange or the frame was
559 : * lost somewhere - start EAPOL Authenticator.
560 : */
561 6 : wpa_printf(MSG_DEBUG,
562 : "RSN: Timeout on waiting Authentication frame response from "
563 6 : MACSTR " - start authenticator", MAC2STR(peer->addr));
564 :
565 1 : peer->authentication_status |= IBSS_RSN_AUTH_BY_US;
566 1 : ibss_rsn_auth_init(peer->ibss_rsn, peer);
567 1 : }
568 :
569 :
570 17 : int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr)
571 : {
572 : struct ibss_rsn_peer *peer;
573 : int res;
574 :
575 17 : if (!ibss_rsn)
576 1 : return -1;
577 :
578 : /* if the peer already exists, exit immediately */
579 16 : peer = ibss_rsn_get_peer(ibss_rsn, addr);
580 16 : if (peer)
581 2 : return 0;
582 :
583 14 : peer = ibss_rsn_peer_init(ibss_rsn, addr);
584 14 : if (peer == NULL)
585 0 : return -1;
586 :
587 : /* Open Authentication: send first Authentication frame */
588 14 : res = ibss_rsn_send_auth(ibss_rsn, addr, 1);
589 14 : if (res) {
590 : /*
591 : * The driver may not support Authentication frame exchange in
592 : * IBSS. Ignore authentication and go through EAPOL exchange.
593 : */
594 0 : peer->authentication_status |= IBSS_RSN_AUTH_BY_US;
595 0 : return ibss_rsn_auth_init(ibss_rsn, peer);
596 : } else {
597 14 : os_get_reltime(&peer->own_auth_tx);
598 14 : eloop_register_timeout(1, 0, ibss_rsn_auth_timeout, peer, NULL);
599 : }
600 :
601 14 : return 0;
602 : }
603 :
604 :
605 31 : static int ibss_rsn_peer_authenticated(struct ibss_rsn *ibss_rsn,
606 : struct ibss_rsn_peer *peer, int reason)
607 : {
608 : int already_started;
609 :
610 31 : if (ibss_rsn == NULL || peer == NULL)
611 0 : return -1;
612 :
613 31 : already_started = ibss_rsn_is_auth_started(peer);
614 31 : peer->authentication_status |= reason;
615 :
616 31 : if (already_started) {
617 60 : wpa_printf(MSG_DEBUG, "RSN: IBSS Authenticator already "
618 60 : "started for peer " MACSTR, MAC2STR(peer->addr));
619 10 : return 0;
620 : }
621 :
622 126 : wpa_printf(MSG_DEBUG, "RSN: Starting IBSS Authenticator "
623 126 : "for now-authenticated peer " MACSTR, MAC2STR(peer->addr));
624 :
625 21 : return ibss_rsn_auth_init(ibss_rsn, peer);
626 : }
627 :
628 :
629 4 : void ibss_rsn_stop(struct ibss_rsn *ibss_rsn, const u8 *peermac)
630 : {
631 : struct ibss_rsn_peer *peer, *prev;
632 :
633 4 : if (ibss_rsn == NULL)
634 4 : return;
635 :
636 4 : if (peermac == NULL) {
637 : /* remove all peers */
638 0 : wpa_printf(MSG_DEBUG, "%s: Remove all peers", __func__);
639 0 : peer = ibss_rsn->peers;
640 0 : while (peer) {
641 0 : prev = peer;
642 0 : peer = peer->next;
643 0 : ibss_rsn_free(prev);
644 0 : ibss_rsn->peers = peer;
645 : }
646 : } else {
647 : /* remove specific peer */
648 24 : wpa_printf(MSG_DEBUG, "%s: Remove specific peer " MACSTR,
649 24 : __func__, MAC2STR(peermac));
650 :
651 10 : for (prev = NULL, peer = ibss_rsn->peers; peer != NULL;
652 2 : prev = peer, peer = peer->next) {
653 6 : if (os_memcmp(peermac, peer->addr, ETH_ALEN) == 0) {
654 4 : if (prev == NULL)
655 2 : ibss_rsn->peers = peer->next;
656 : else
657 2 : prev->next = peer->next;
658 4 : ibss_rsn_free(peer);
659 4 : wpa_printf(MSG_DEBUG, "%s: Successfully "
660 : "removed a specific peer",
661 : __func__);
662 4 : break;
663 : }
664 : }
665 : }
666 : }
667 :
668 :
669 11 : struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s,
670 : struct wpa_ssid *ssid)
671 : {
672 : struct ibss_rsn *ibss_rsn;
673 :
674 11 : ibss_rsn = os_zalloc(sizeof(*ibss_rsn));
675 11 : if (ibss_rsn == NULL)
676 1 : return NULL;
677 10 : ibss_rsn->wpa_s = wpa_s;
678 :
679 10 : if (ibss_rsn_auth_init_group(ibss_rsn, wpa_s->own_addr, ssid) < 0) {
680 1 : ibss_rsn_deinit(ibss_rsn);
681 1 : return NULL;
682 : }
683 :
684 9 : return ibss_rsn;
685 : }
686 :
687 :
688 16660 : void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn)
689 : {
690 : struct ibss_rsn_peer *peer, *prev;
691 :
692 16660 : if (ibss_rsn == NULL)
693 33310 : return;
694 :
695 10 : peer = ibss_rsn->peers;
696 38 : while (peer) {
697 18 : prev = peer;
698 18 : peer = peer->next;
699 18 : ibss_rsn_free(prev);
700 : }
701 :
702 10 : if (ibss_rsn->auth_group)
703 9 : wpa_deinit(ibss_rsn->auth_group);
704 10 : os_free(ibss_rsn);
705 :
706 : }
707 :
708 :
709 82 : static int ibss_rsn_eapol_dst_supp(const u8 *buf, size_t len)
710 : {
711 : const struct ieee802_1x_hdr *hdr;
712 : const struct wpa_eapol_key *key;
713 : u16 key_info;
714 : size_t plen;
715 :
716 : /* TODO: Support other EAPOL packets than just EAPOL-Key */
717 :
718 82 : if (len < sizeof(*hdr) + sizeof(*key))
719 1 : return -1;
720 :
721 81 : hdr = (const struct ieee802_1x_hdr *) buf;
722 81 : key = (const struct wpa_eapol_key *) (hdr + 1);
723 81 : plen = be_to_host16(hdr->length);
724 :
725 81 : if (hdr->version < EAPOL_VERSION) {
726 : /* TODO: backwards compatibility */
727 : }
728 81 : if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
729 1 : wpa_printf(MSG_DEBUG, "RSN: EAPOL frame (type %u) discarded, "
730 1 : "not a Key frame", hdr->type);
731 1 : return -1;
732 : }
733 80 : if (plen > len - sizeof(*hdr) || plen < sizeof(*key)) {
734 1 : wpa_printf(MSG_DEBUG, "RSN: EAPOL frame payload size %lu "
735 : "invalid (frame size %lu)",
736 : (unsigned long) plen, (unsigned long) len);
737 1 : return -1;
738 : }
739 :
740 79 : if (key->type != EAPOL_KEY_TYPE_RSN) {
741 1 : wpa_printf(MSG_DEBUG, "RSN: EAPOL-Key type (%d) unknown, "
742 1 : "discarded", key->type);
743 1 : return -1;
744 : }
745 :
746 78 : key_info = WPA_GET_BE16(key->key_info);
747 :
748 78 : return !!(key_info & WPA_KEY_INFO_ACK);
749 : }
750 :
751 :
752 72 : static int ibss_rsn_process_rx_eapol(struct ibss_rsn *ibss_rsn,
753 : struct ibss_rsn_peer *peer,
754 : const u8 *buf, size_t len)
755 : {
756 : int supp;
757 : u8 *tmp;
758 :
759 72 : supp = ibss_rsn_eapol_dst_supp(buf, len);
760 72 : if (supp < 0)
761 4 : return -1;
762 :
763 68 : tmp = os_malloc(len);
764 68 : if (tmp == NULL)
765 1 : return -1;
766 67 : os_memcpy(tmp, buf, len);
767 67 : if (supp) {
768 38 : peer->authentication_status |= IBSS_RSN_AUTH_EAPOL_BY_PEER;
769 228 : wpa_printf(MSG_DEBUG, "RSN: IBSS RX EAPOL for Supplicant from "
770 228 : MACSTR, MAC2STR(peer->addr));
771 38 : wpa_sm_rx_eapol(peer->supp, peer->addr, tmp, len);
772 : } else {
773 29 : if (ibss_rsn_is_auth_started(peer) == 0) {
774 0 : wpa_printf(MSG_DEBUG, "RSN: IBSS EAPOL for "
775 : "Authenticator dropped as " MACSTR " is not "
776 0 : "authenticated", MAC2STR(peer->addr));
777 0 : os_free(tmp);
778 0 : return -1;
779 : }
780 :
781 174 : wpa_printf(MSG_DEBUG, "RSN: IBSS RX EAPOL for Authenticator "
782 174 : "from "MACSTR, MAC2STR(peer->addr));
783 29 : wpa_receive(ibss_rsn->auth_group, peer->auth, tmp, len);
784 : }
785 67 : os_free(tmp);
786 :
787 67 : return 1;
788 : }
789 :
790 :
791 77 : int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
792 : const u8 *buf, size_t len)
793 : {
794 : struct ibss_rsn_peer *peer;
795 :
796 77 : if (ibss_rsn == NULL)
797 0 : return -1;
798 :
799 77 : peer = ibss_rsn_get_peer(ibss_rsn, src_addr);
800 77 : if (peer)
801 67 : return ibss_rsn_process_rx_eapol(ibss_rsn, peer, buf, len);
802 :
803 10 : if (ibss_rsn_eapol_dst_supp(buf, len) > 0) {
804 : /*
805 : * Create new IBSS peer based on an EAPOL message from the peer
806 : * Authenticator.
807 : */
808 10 : peer = ibss_rsn_peer_init(ibss_rsn, src_addr);
809 10 : if (peer == NULL)
810 5 : return -1;
811 :
812 : /* assume the peer is authenticated already */
813 30 : wpa_printf(MSG_DEBUG, "RSN: IBSS Not using IBSS Auth for peer "
814 30 : MACSTR, MAC2STR(src_addr));
815 5 : ibss_rsn_peer_authenticated(ibss_rsn, peer,
816 : IBSS_RSN_AUTH_EAPOL_BY_US);
817 :
818 5 : return ibss_rsn_process_rx_eapol(ibss_rsn, ibss_rsn->peers,
819 : buf, len);
820 : }
821 :
822 0 : return 0;
823 : }
824 :
825 9 : void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk)
826 : {
827 9 : if (ibss_rsn == NULL)
828 9 : return;
829 9 : os_memcpy(ibss_rsn->psk, psk, PMK_LEN);
830 : }
831 :
832 :
833 13 : static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn,
834 : struct ibss_rsn_peer *peer,
835 : const u8* addr)
836 : {
837 78 : wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR,
838 78 : MAC2STR(addr));
839 :
840 25 : if (peer &&
841 12 : peer->authentication_status & IBSS_RSN_AUTH_EAPOL_BY_PEER) {
842 3 : if (peer->own_auth_tx.sec) {
843 : struct os_reltime now, diff;
844 3 : os_get_reltime(&now);
845 3 : os_reltime_sub(&now, &peer->own_auth_tx, &diff);
846 3 : if (diff.sec == 0 && diff.usec < 500000) {
847 1 : wpa_printf(MSG_DEBUG, "RSN: Skip IBSS reinit since only %u usec from own Auth frame TX",
848 1 : (int) diff.usec);
849 1 : goto skip_reinit;
850 : }
851 : }
852 : /*
853 : * A peer sent us an Authentication frame even though it already
854 : * started an EAPOL session. We should reinit state machines
855 : * here, but it's much more complicated than just deleting and
856 : * recreating the state machine
857 : */
858 12 : wpa_printf(MSG_DEBUG, "RSN: IBSS Reinitializing station "
859 12 : MACSTR, MAC2STR(addr));
860 :
861 2 : ibss_rsn_stop(ibss_rsn, addr);
862 2 : peer = NULL;
863 : }
864 :
865 12 : if (!peer) {
866 3 : peer = ibss_rsn_peer_init(ibss_rsn, addr);
867 3 : if (!peer)
868 13 : return;
869 :
870 18 : wpa_printf(MSG_DEBUG, "RSN: IBSS Auth started by peer " MACSTR,
871 18 : MAC2STR(addr));
872 : }
873 :
874 : skip_reinit:
875 : /* reply with an Authentication frame now, before sending an EAPOL */
876 13 : ibss_rsn_send_auth(ibss_rsn, addr, 2);
877 : /* no need to start another AUTH challenge in the other way.. */
878 13 : ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_EAPOL_BY_US);
879 : }
880 :
881 :
882 26 : void ibss_rsn_handle_auth(struct ibss_rsn *ibss_rsn, const u8 *auth_frame,
883 : size_t len)
884 : {
885 : const struct ieee80211_mgmt *header;
886 : struct ibss_rsn_peer *peer;
887 : size_t auth_length;
888 :
889 26 : header = (const struct ieee80211_mgmt *) auth_frame;
890 26 : auth_length = IEEE80211_HDRLEN + sizeof(header->u.auth);
891 :
892 26 : if (ibss_rsn == NULL || len < auth_length)
893 0 : return;
894 :
895 52 : if (le_to_host16(header->u.auth.auth_alg) != WLAN_AUTH_OPEN ||
896 26 : le_to_host16(header->u.auth.status_code) != WLAN_STATUS_SUCCESS)
897 0 : return;
898 :
899 26 : peer = ibss_rsn_get_peer(ibss_rsn, header->sa);
900 :
901 26 : switch (le_to_host16(header->u.auth.auth_transaction)) {
902 : case 1:
903 13 : ibss_rsn_handle_auth_1_of_2(ibss_rsn, peer, header->sa);
904 13 : break;
905 : case 2:
906 78 : wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 2) from "
907 78 : MACSTR, MAC2STR(header->sa));
908 13 : if (!peer) {
909 0 : wpa_printf(MSG_DEBUG, "RSN: Received Auth seq 2 from "
910 0 : "unknown STA " MACSTR, MAC2STR(header->sa));
911 0 : break;
912 : }
913 :
914 : /* authentication has been completed */
915 13 : eloop_cancel_timeout(ibss_rsn_auth_timeout, peer, NULL);
916 78 : wpa_printf(MSG_DEBUG, "RSN: IBSS Auth completed with " MACSTR,
917 78 : MAC2STR(header->sa));
918 13 : ibss_rsn_peer_authenticated(ibss_rsn, peer,
919 : IBSS_RSN_AUTH_BY_US);
920 13 : break;
921 : }
922 : }
|