]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/hostapd/ieee802_1x.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / contrib / hostapd / ieee802_1x.c
1 /*
2  * hostapd / IEEE 802.1X Authenticator
3  * Copyright (c) 2002-2006, 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  * $FreeBSD$
15  */
16
17 #include "includes.h"
18 #include <assert.h>
19
20 #include "hostapd.h"
21 #include "ieee802_1x.h"
22 #include "accounting.h"
23 #include "radius.h"
24 #include "radius_client.h"
25 #include "eapol_sm.h"
26 #include "md5.h"
27 #include "rc4.h"
28 #include "eloop.h"
29 #include "sta_info.h"
30 #include "wpa.h"
31 #include "preauth.h"
32 #include "pmksa_cache.h"
33 #include "driver.h"
34 #include "hw_features.h"
35 #include "eap.h"
36
37
38 static void ieee802_1x_new_auth_session(struct hostapd_data *hapd,
39                                         struct sta_info *sta);
40
41
42 static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta,
43                             u8 type, u8 *data, size_t datalen)
44 {
45         u8 *buf;
46         struct ieee802_1x_hdr *xhdr;
47         size_t len;
48         int encrypt = 0;
49
50         len = sizeof(*xhdr) + datalen;
51         buf = wpa_zalloc(len);
52         if (buf == NULL) {
53                 printf("malloc() failed for ieee802_1x_send(len=%lu)\n",
54                        (unsigned long) len);
55                 return;
56         }
57
58 #if 0
59         /* TODO:
60          * According to IEEE 802.1aa/D4 EAPOL-Key should be sent before any
61          * remaining EAP frames, if possible. This would allow rest of the
62          * frames to be encrypted. This code could be used to request
63          * encryption from the kernel driver. */
64         if (sta->eapol_sm &&
65             sta->eapol_sm->be_auth.state == BE_AUTH_SUCCESS &&
66             sta->eapol_sm->keyTxEnabled)
67                 encrypt = 1;
68 #endif
69
70         xhdr = (struct ieee802_1x_hdr *) buf;
71         xhdr->version = hapd->conf->eapol_version;
72         xhdr->type = type;
73         xhdr->length = htons(datalen);
74
75         if (datalen > 0 && data != NULL)
76                 memcpy(xhdr + 1, data, datalen);
77
78         if (wpa_auth_pairwise_set(sta->wpa_sm))
79                 encrypt = 1;
80         if (sta->flags & WLAN_STA_PREAUTH) {
81                 rsn_preauth_send(hapd, sta, buf, len);
82         } else {
83                 hostapd_send_eapol(hapd, sta->addr, buf, len, encrypt);
84         }
85
86         free(buf);
87 }
88
89
90 void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
91                                    struct sta_info *sta, int authorized)
92 {
93         int res;
94
95         if (sta->flags & WLAN_STA_PREAUTH)
96                 return;
97
98         if (authorized) {
99                 sta->flags |= WLAN_STA_AUTHORIZED;
100                 res = hostapd_sta_set_flags(hapd, sta->addr,
101                                             WLAN_STA_AUTHORIZED, ~0);
102                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
103                                HOSTAPD_LEVEL_DEBUG, "authorizing port");
104         } else {
105                 sta->flags &= ~WLAN_STA_AUTHORIZED;
106                 res = hostapd_sta_set_flags(hapd, sta->addr,
107                                             0, ~WLAN_STA_AUTHORIZED);
108                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
109                                HOSTAPD_LEVEL_DEBUG, "unauthorizing port");
110         }
111
112         if (res && errno != ENOENT) {
113                 printf("Could not set station " MACSTR " flags for kernel "
114                        "driver (errno=%d).\n", MAC2STR(sta->addr), errno);
115         }
116
117         if (authorized)
118                 accounting_sta_start(hapd, sta);
119 }
120
121
122 static void ieee802_1x_eap_timeout(void *eloop_ctx, void *timeout_ctx)
123 {
124         struct sta_info *sta = eloop_ctx;
125         struct eapol_state_machine *sm = sta->eapol_sm;
126         if (sm == NULL)
127                 return;
128         hostapd_logger(sm->hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
129                        HOSTAPD_LEVEL_DEBUG, "EAP timeout");
130         sm->eapTimeout = TRUE;
131         eapol_sm_step(sm);
132 }
133
134
135 void ieee802_1x_request_identity(struct hostapd_data *hapd,
136                                  struct sta_info *sta)
137 {
138         u8 *buf;
139         struct eap_hdr *eap;
140         int tlen;
141         u8 *pos;
142         struct eapol_state_machine *sm = sta->eapol_sm;
143
144         if (hapd->conf->eap_server) {
145                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
146                               "IEEE 802.1X: Integrated EAP server in "
147                               "use - do not generate EAP-Request/Identity\n");
148                 return;
149         }
150
151         if (sm == NULL || !sm->eapRestart)
152                 return;
153
154         ieee802_1x_new_auth_session(hapd, sta);
155
156         tlen = sizeof(*eap) + 1 + hapd->conf->eap_req_id_text_len;
157
158         buf = wpa_zalloc(tlen);
159         if (buf == NULL) {
160                 printf("Could not allocate memory for identity request\n");
161                 return;
162         }
163
164         eap = (struct eap_hdr *) buf;
165         eap->code = EAP_CODE_REQUEST;
166         eap->identifier = ++sm->currentId;
167         eap->length = htons(tlen);
168         pos = (u8 *) (eap + 1);
169         *pos++ = EAP_TYPE_IDENTITY;
170         if (hapd->conf->eap_req_id_text) {
171                 memcpy(pos, hapd->conf->eap_req_id_text,
172                        hapd->conf->eap_req_id_text_len);
173         }
174
175         sm->eapReq = TRUE;
176         free(sm->last_eap_radius);
177         sm->last_eap_radius = buf;
178         sm->last_eap_radius_len = tlen;
179
180         eloop_cancel_timeout(ieee802_1x_eap_timeout, sta, NULL);
181         eloop_register_timeout(30, 0, ieee802_1x_eap_timeout, sta, NULL);
182         sm->eapTimeout = FALSE;
183
184         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
185                       "IEEE 802.1X: Generated EAP Request-Identity for " MACSTR
186                       " (identifier %d, timeout 30)\n", MAC2STR(sta->addr),
187                       eap->identifier);
188
189         sm->eapRestart = FALSE;
190 }
191
192
193 void ieee802_1x_tx_canned_eap(struct hostapd_data *hapd, struct sta_info *sta,
194                               int success)
195 {
196         struct eap_hdr eap;
197         struct eapol_state_machine *sm = sta->eapol_sm;
198
199         memset(&eap, 0, sizeof(eap));
200
201         eap.code = success ? EAP_CODE_SUCCESS : EAP_CODE_FAILURE;
202         eap.identifier = 1;
203         if (sm && sm->last_eap_radius) {
204                 struct eap_hdr *hdr = (struct eap_hdr *) sm->last_eap_radius;
205                 eap.identifier = hdr->identifier + 1;
206         }
207         eap.length = htons(sizeof(eap));
208
209         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
210                       "IEEE 802.1X: Sending canned EAP packet %s to " MACSTR
211                       " (identifier %d)\n", success ? "SUCCESS" : "FAILURE",
212                       MAC2STR(sta->addr), eap.identifier);
213         ieee802_1x_send(hapd, sta, IEEE802_1X_TYPE_EAP_PACKET, (u8 *) &eap,
214                         sizeof(eap));
215         if (sm)
216                 sm->dot1xAuthEapolFramesTx++;
217 }
218
219
220 void ieee802_1x_tx_req(struct hostapd_data *hapd, struct sta_info *sta)
221 {
222         struct eap_hdr *eap;
223         struct eapol_state_machine *sm = sta->eapol_sm;
224         u8 *type;
225         if (sm == NULL)
226                 return;
227
228         if (sm->last_eap_radius == NULL) {
229                 printf("Error: TxReq called for station " MACSTR ", but there "
230                        "is no EAP request from the authentication server\n",
231                        MAC2STR(sm->addr));
232                 return;
233         }
234
235         eap = (struct eap_hdr *) sm->last_eap_radius;
236         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
237                       "IEEE 802.1X: Sending EAP Packet to " MACSTR
238                       " (identifier %d)\n", MAC2STR(sm->addr),
239                       eap->identifier);
240         sm->currentId = eap->identifier;
241         ieee802_1x_send(hapd, sta, IEEE802_1X_TYPE_EAP_PACKET,
242                         sm->last_eap_radius, sm->last_eap_radius_len);
243         sm->dot1xAuthEapolFramesTx++;
244         type = (u8 *) (eap + 1);
245         if (sm->last_eap_radius_len > sizeof(*eap) &&
246             *type == EAP_TYPE_IDENTITY)
247                 sm->dot1xAuthEapolReqIdFramesTx++;
248         else
249                 sm->dot1xAuthEapolReqFramesTx++;
250 }
251
252
253 static void ieee802_1x_tx_key_one(struct hostapd_data *hapd,
254                                   struct sta_info *sta,
255                                   int idx, int broadcast,
256                                   u8 *key_data, size_t key_len)
257 {
258         u8 *buf, *ekey;
259         struct ieee802_1x_hdr *hdr;
260         struct ieee802_1x_eapol_key *key;
261         size_t len, ekey_len;
262         struct eapol_state_machine *sm = sta->eapol_sm;
263
264         if (sm == NULL)
265                 return;
266
267         len = sizeof(*key) + key_len;
268         buf = wpa_zalloc(sizeof(*hdr) + len);
269         if (buf == NULL)
270                 return;
271
272         hdr = (struct ieee802_1x_hdr *) buf;
273         key = (struct ieee802_1x_eapol_key *) (hdr + 1);
274         key->type = EAPOL_KEY_TYPE_RC4;
275         key->key_length = htons(key_len);
276         wpa_get_ntp_timestamp(key->replay_counter);
277
278         if (hostapd_get_rand(key->key_iv, sizeof(key->key_iv))) {
279                 printf("Could not get random numbers\n");
280                 free(buf);
281                 return;
282         }
283
284         key->key_index = idx | (broadcast ? 0 : BIT(7));
285         if (hapd->conf->eapol_key_index_workaround) {
286                 /* According to some information, WinXP Supplicant seems to
287                  * interpret bit7 as an indication whether the key is to be
288                  * activated, so make it possible to enable workaround that
289                  * sets this bit for all keys. */
290                 key->key_index |= BIT(7);
291         }
292
293         /* Key is encrypted using "Key-IV + sm->eapol_key_crypt" as the
294          * RC4-key */
295         memcpy((u8 *) (key + 1), key_data, key_len);
296         ekey_len = sizeof(key->key_iv) + sm->eapol_key_crypt_len;
297         ekey = malloc(ekey_len);
298         if (ekey == NULL) {
299                 printf("Could not encrypt key\n");
300                 free(buf);
301                 return;
302         }
303         memcpy(ekey, key->key_iv, sizeof(key->key_iv));
304         memcpy(ekey + sizeof(key->key_iv), sm->eapol_key_crypt,
305                sm->eapol_key_crypt_len);
306         rc4((u8 *) (key + 1), key_len, ekey, ekey_len);
307         free(ekey);
308
309         /* This header is needed here for HMAC-MD5, but it will be regenerated
310          * in ieee802_1x_send() */
311         hdr->version = hapd->conf->eapol_version;
312         hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
313         hdr->length = htons(len);
314         hmac_md5(sm->eapol_key_sign, sm->eapol_key_sign_len,
315                  buf, sizeof(*hdr) + len,
316                  key->key_signature);
317
318         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
319                       "IEEE 802.1X: Sending EAPOL-Key to " MACSTR
320                       " (%s index=%d)\n", MAC2STR(sm->addr),
321                       broadcast ? "broadcast" : "unicast", idx);
322         ieee802_1x_send(hapd, sta, IEEE802_1X_TYPE_EAPOL_KEY, (u8 *) key, len);
323         if (sta->eapol_sm)
324                 sta->eapol_sm->dot1xAuthEapolFramesTx++;
325         free(buf);
326 }
327
328
329 static struct hostapd_wep_keys *
330 ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname)
331 {
332         struct hostapd_wep_keys *key;
333
334         key = wpa_zalloc(sizeof(*key));
335         if (key == NULL)
336                 return NULL;
337
338         key->default_len = hapd->conf->default_wep_key_len;
339
340         if (key->idx >= hapd->conf->broadcast_key_idx_max ||
341             key->idx < hapd->conf->broadcast_key_idx_min)
342                 key->idx = hapd->conf->broadcast_key_idx_min;
343         else
344                 key->idx++;
345
346         if (!key->key[key->idx])
347                 key->key[key->idx] = malloc(key->default_len);
348         if (key->key[key->idx] == NULL ||
349             hostapd_get_rand(key->key[key->idx], key->default_len)) {
350                 printf("Could not generate random WEP key (dynamic VLAN).\n");
351                 free(key->key[key->idx]);
352                 key->key[key->idx] = NULL;
353                 free(key);
354                 return NULL;
355         }
356         key->len[key->idx] = key->default_len;
357
358         if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MINIMAL)) {
359                 printf("%s: Default WEP idx %d for dynamic VLAN\n",
360                        ifname, key->idx);
361                 wpa_hexdump_key(MSG_DEBUG, "Default WEP key (dynamic VLAN)",
362                                 key->key[key->idx], key->len[key->idx]);
363         }
364
365         if (hostapd_set_encryption(ifname, hapd, "WEP", NULL, key->idx,
366                                    key->key[key->idx], key->len[key->idx], 1))
367                 printf("Could not set dynamic VLAN WEP encryption key.\n");
368
369         hostapd_set_ieee8021x(ifname, hapd, 1);
370
371         return key;
372 }
373
374
375 static struct hostapd_wep_keys *
376 ieee802_1x_get_group(struct hostapd_data *hapd, struct hostapd_ssid *ssid,
377                      size_t vlan_id)
378 {
379         const char *ifname;
380
381         if (vlan_id == 0)
382                 return &ssid->wep;
383
384         if (vlan_id <= ssid->max_dyn_vlan_keys && ssid->dyn_vlan_keys &&
385             ssid->dyn_vlan_keys[vlan_id])
386                 return ssid->dyn_vlan_keys[vlan_id];
387
388         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "IEEE 802.1X: Creating new group "
389                       "state machine for VLAN ID %lu\n",
390                       (unsigned long) vlan_id);
391
392         ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id);
393         if (ifname == NULL) {
394                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "IEEE 802.1X: Unknown "
395                               "VLAN ID %lu - cannot create group key state "
396                               "machine\n", (unsigned long) vlan_id);
397                 return NULL;
398         }
399
400         if (ssid->dyn_vlan_keys == NULL) {
401                 int size = (vlan_id + 1) * sizeof(ssid->dyn_vlan_keys[0]);
402                 ssid->dyn_vlan_keys = wpa_zalloc(size);
403                 if (ssid->dyn_vlan_keys == NULL)
404                         return NULL;
405                 ssid->max_dyn_vlan_keys = vlan_id;
406         }
407
408         if (ssid->max_dyn_vlan_keys < vlan_id) {
409                 struct hostapd_wep_keys **na;
410                 int size = (vlan_id + 1) * sizeof(ssid->dyn_vlan_keys[0]);
411                 na = realloc(ssid->dyn_vlan_keys, size);
412                 if (na == NULL)
413                         return NULL;
414                 ssid->dyn_vlan_keys = na;
415                 memset(&ssid->dyn_vlan_keys[ssid->max_dyn_vlan_keys + 1], 0,
416                        (vlan_id - ssid->max_dyn_vlan_keys) *
417                        sizeof(ssid->dyn_vlan_keys[0]));
418                 ssid->max_dyn_vlan_keys = vlan_id;
419         }
420
421         ssid->dyn_vlan_keys[vlan_id] = ieee802_1x_group_alloc(hapd, ifname);
422
423         return ssid->dyn_vlan_keys[vlan_id];
424 }
425
426
427 void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
428 {
429         struct hostapd_wep_keys *key = NULL;
430         struct eapol_state_machine *sm = sta->eapol_sm;
431         int vlan_id;
432
433         if (sm == NULL || !sm->eapol_key_sign || !sm->eapol_key_crypt)
434                 return;
435
436         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
437                       "IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR "\n",
438                       MAC2STR(sta->addr));
439
440         vlan_id = sta->vlan_id;
441         if (vlan_id < 0 || vlan_id > MAX_VLAN_ID)
442                 vlan_id = 0;
443
444         if (vlan_id) {
445                 key = ieee802_1x_get_group(hapd, sta->ssid, vlan_id);
446                 if (key && key->key[key->idx])
447                         ieee802_1x_tx_key_one(hapd, sta, key->idx, 1,
448                                               key->key[key->idx],
449                                               key->len[key->idx]);
450         } else if (hapd->default_wep_key) {
451                 ieee802_1x_tx_key_one(hapd, sta, hapd->default_wep_key_idx, 1,
452                                       hapd->default_wep_key,
453                                       hapd->conf->default_wep_key_len);
454         }
455
456         if (hapd->conf->individual_wep_key_len > 0) {
457                 u8 *ikey;
458                 ikey = malloc(hapd->conf->individual_wep_key_len);
459                 if (ikey == NULL ||
460                     hostapd_get_rand(ikey,
461                                      hapd->conf->individual_wep_key_len)) {
462                         printf("Could not generate random individual WEP "
463                                "key.\n");
464                         free(ikey);
465                         return;
466                 }
467
468                 wpa_hexdump_key(MSG_DEBUG, "Individual WEP key",
469                                 ikey, hapd->conf->individual_wep_key_len);
470
471                 ieee802_1x_tx_key_one(hapd, sta, 0, 0, ikey,
472                                       hapd->conf->individual_wep_key_len);
473
474                 /* TODO: set encryption in TX callback, i.e., only after STA
475                  * has ACKed EAPOL-Key frame */
476                 if (hostapd_set_encryption(hapd->conf->iface, hapd, "WEP",
477                                            sta->addr, 0, ikey,
478                                            hapd->conf->individual_wep_key_len,
479                                            1)) {
480                         printf("Could not set individual WEP encryption.\n");
481                 }
482
483                 free(ikey);
484         }
485 }
486
487
488 const char *radius_mode_txt(struct hostapd_data *hapd)
489 {
490         if (hapd->iface->current_mode == NULL)
491                 return "802.11";
492
493         switch (hapd->iface->current_mode->mode) {
494         case HOSTAPD_MODE_IEEE80211A:
495                 return "802.11a";
496         case HOSTAPD_MODE_IEEE80211G:
497                 return "802.11g";
498         case HOSTAPD_MODE_IEEE80211B:
499         default:
500                 return "802.11b";
501         }
502 }
503
504
505 int radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta)
506 {
507         int i;
508         u8 rate = 0;
509
510         for (i = 0; i < sta->supported_rates_len; i++)
511                 if ((sta->supported_rates[i] & 0x7f) > rate)
512                         rate = sta->supported_rates[i] & 0x7f;
513
514         return rate;
515 }
516
517
518 static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
519                                           struct sta_info *sta,
520                                           u8 *eap, size_t len)
521 {
522         struct radius_msg *msg;
523         char buf[128];
524         struct eapol_state_machine *sm = sta->eapol_sm;
525
526         if (sm == NULL)
527                 return;
528
529         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
530                       "Encapsulating EAP message into a RADIUS packet\n");
531
532         sm->radius_identifier = radius_client_get_id(hapd->radius);
533         msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST,
534                              sm->radius_identifier);
535         if (msg == NULL) {
536                 printf("Could not create net RADIUS packet\n");
537                 return;
538         }
539
540         radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
541
542         if (sm->identity &&
543             !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
544                                  sm->identity, sm->identity_len)) {
545                 printf("Could not add User-Name\n");
546                 goto fail;
547         }
548
549         if (hapd->conf->own_ip_addr.af == AF_INET &&
550             !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
551                                  (u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) {
552                 printf("Could not add NAS-IP-Address\n");
553                 goto fail;
554         }
555
556 #ifdef CONFIG_IPV6
557         if (hapd->conf->own_ip_addr.af == AF_INET6 &&
558             !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS,
559                                  (u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) {
560                 printf("Could not add NAS-IPv6-Address\n");
561                 goto fail;
562         }
563 #endif /* CONFIG_IPV6 */
564
565         if (hapd->conf->nas_identifier &&
566             !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
567                                  (u8 *) hapd->conf->nas_identifier,
568                                  strlen(hapd->conf->nas_identifier))) {
569                 printf("Could not add NAS-Identifier\n");
570                 goto fail;
571         }
572
573         if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
574                 printf("Could not add NAS-Port\n");
575                 goto fail;
576         }
577
578         snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
579                  MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid);
580         buf[sizeof(buf) - 1] = '\0';
581         if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
582                                  (u8 *) buf, strlen(buf))) {
583                 printf("Could not add Called-Station-Id\n");
584                 goto fail;
585         }
586
587         snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
588                  MAC2STR(sta->addr));
589         buf[sizeof(buf) - 1] = '\0';
590         if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
591                                  (u8 *) buf, strlen(buf))) {
592                 printf("Could not add Calling-Station-Id\n");
593                 goto fail;
594         }
595
596         /* TODO: should probably check MTU from driver config; 2304 is max for
597          * IEEE 802.11, but use 1400 to avoid problems with too large packets
598          */
599         if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) {
600                 printf("Could not add Framed-MTU\n");
601                 goto fail;
602         }
603
604         if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
605                                        RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
606                 printf("Could not add NAS-Port-Type\n");
607                 goto fail;
608         }
609
610         if (sta->flags & WLAN_STA_PREAUTH) {
611                 snprintf(buf, sizeof(buf), "IEEE 802.11i Pre-Authentication");
612         } else {
613                 snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s",
614                          radius_sta_rate(hapd, sta) / 2,
615                          (radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
616                          radius_mode_txt(hapd));
617         }
618         buf[sizeof(buf) - 1] = '\0';
619         if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
620                                  (u8 *) buf, strlen(buf))) {
621                 printf("Could not add Connect-Info\n");
622                 goto fail;
623         }
624
625         if (eap && !radius_msg_add_eap(msg, eap, len)) {
626                 printf("Could not add EAP-Message\n");
627                 goto fail;
628         }
629
630         /* State attribute must be copied if and only if this packet is
631          * Access-Request reply to the previous Access-Challenge */
632         if (sm->last_recv_radius && sm->last_recv_radius->hdr->code ==
633             RADIUS_CODE_ACCESS_CHALLENGE) {
634                 int res = radius_msg_copy_attr(msg, sm->last_recv_radius,
635                                                RADIUS_ATTR_STATE);
636                 if (res < 0) {
637                         printf("Could not copy State attribute from previous "
638                                "Access-Challenge\n");
639                         goto fail;
640                 }
641                 if (res > 0) {
642                         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
643                                       "  Copied RADIUS State Attribute\n");
644                 }
645         }
646
647         radius_client_send(hapd->radius, msg, RADIUS_AUTH, sta->addr);
648         return;
649
650  fail:
651         radius_msg_free(msg);
652         free(msg);
653 }
654
655
656 char *eap_type_text(u8 type)
657 {
658         switch (type) {
659         case EAP_TYPE_IDENTITY: return "Identity";
660         case EAP_TYPE_NOTIFICATION: return "Notification";
661         case EAP_TYPE_NAK: return "Nak";
662         case EAP_TYPE_MD5: return "MD5-Challenge";
663         case EAP_TYPE_OTP: return "One-Time Password";
664         case EAP_TYPE_GTC: return "Generic Token Card";
665         case EAP_TYPE_TLS: return "TLS";
666         case EAP_TYPE_TTLS: return "TTLS";
667         case EAP_TYPE_PEAP: return "PEAP";
668         case EAP_TYPE_SIM: return "SIM";
669         case EAP_TYPE_FAST: return "FAST";
670         case EAP_TYPE_SAKE: return "SAKE";
671         case EAP_TYPE_PSK: return "PSK";
672         default: return "Unknown";
673         }
674 }
675
676
677 static void handle_eap_response(struct hostapd_data *hapd,
678                                 struct sta_info *sta, struct eap_hdr *eap,
679                                 u8 *data, size_t len)
680 {
681         u8 type;
682         struct eapol_state_machine *sm = sta->eapol_sm;
683         if (sm == NULL)
684                 return;
685
686         if (eap->identifier != sm->currentId) {
687                 hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
688                                HOSTAPD_LEVEL_DEBUG,
689                                "EAP Identifier of the Response-Identity does "
690                                "not match (was %d, expected %d) - ignored",
691                                eap->identifier, sm->currentId);
692                 return;
693         }
694
695         if (len < 1) {
696                 printf("handle_eap_response: too short response data\n");
697                 return;
698         }
699
700         eloop_cancel_timeout(ieee802_1x_eap_timeout, sta, NULL);
701
702         free(sm->last_eap_supp);
703         sm->last_eap_supp_len = sizeof(*eap) + len;
704         sm->last_eap_supp = (u8 *) malloc(sm->last_eap_supp_len);
705         if (sm->last_eap_supp == NULL) {
706                 printf("Could not alloc memory for last EAP Response\n");
707                 return;
708         }
709         memcpy(sm->last_eap_supp, eap, sizeof(*eap));
710         memcpy(sm->last_eap_supp + sizeof(*eap), data, len);
711
712         sm->eap_type_supp = type = data[0];
713         data++;
714         len--;
715
716         hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
717                        HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d "
718                        "id=%d len=%d) from STA: EAP Response-%s (%d)",
719                        eap->code, eap->identifier, ntohs(eap->length),
720                        eap_type_text(type), type);
721
722         if (type == EAP_TYPE_IDENTITY) {
723                 char *buf, *pos;
724                 size_t i;
725                 buf = malloc(4 * len + 1);
726                 if (buf) {
727                         pos = buf;
728                         for (i = 0; i < len; i++) {
729                                 if (data[i] >= 32 && data[i] < 127)
730                                         *pos++ = data[i];
731                                 else {
732                                         snprintf(pos, 5, "{%02x}", data[i]);
733                                         pos += 4;
734                                 }
735                         }
736                         *pos = '\0';
737                         hostapd_logger(hapd, sm->addr,
738                                        HOSTAPD_MODULE_IEEE8021X,
739                                        HOSTAPD_LEVEL_DEBUG,
740                                        "STA identity '%s'", buf);
741                         free(buf);
742                 }
743
744                 sm->rx_identity = TRUE;
745                 sm->dot1xAuthEapolRespIdFramesRx++;
746
747                 /* Save station identity for future RADIUS packets */
748                 free(sm->identity);
749                 sm->identity = malloc(len + 1);
750                 if (sm->identity) {
751                         memcpy(sm->identity, data, len);
752                         sm->identity[len] = '\0';
753                         sm->identity_len = len;
754                 }
755         } else
756                 sm->dot1xAuthEapolRespFramesRx++;
757
758         sm->eapolEap = TRUE;
759 }
760
761
762 /* Process incoming EAP packet from Supplicant */
763 static void handle_eap(struct hostapd_data *hapd, struct sta_info *sta,
764                        u8 *buf, size_t len)
765 {
766         struct eap_hdr *eap;
767         u16 eap_len;
768
769         if (len < sizeof(*eap)) {
770                 printf("   too short EAP packet\n");
771                 return;
772         }
773
774         eap = (struct eap_hdr *) buf;
775
776         eap_len = ntohs(eap->length);
777         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
778                       "   EAP: code=%d identifier=%d length=%d",
779                       eap->code, eap->identifier, eap_len);
780         if (eap_len < sizeof(*eap)) {
781                 printf("   Invalid EAP length\n");
782                 return;
783         } else if (eap_len > len) {
784                 printf("   Too short frame to contain this EAP packet\n");
785                 return;
786         } else if (eap_len < len) {
787                 printf("   Ignoring %lu extra bytes after EAP packet\n",
788                        (unsigned long) len - eap_len);
789         }
790
791         eap_len -= sizeof(*eap);
792
793         switch (eap->code) {
794         case EAP_CODE_REQUEST:
795                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (request)\n");
796                 return;
797         case EAP_CODE_RESPONSE:
798                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (response)\n");
799                 handle_eap_response(hapd, sta, eap, (u8 *) (eap + 1), eap_len);
800                 break;
801         case EAP_CODE_SUCCESS:
802                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (success)\n");
803                 return;
804         case EAP_CODE_FAILURE:
805                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (failure)\n");
806                 return;
807         default:
808                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (unknown code)\n");
809                 return;
810         }
811 }
812
813
814 /* Process the EAPOL frames from the Supplicant */
815 void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
816                         size_t len)
817 {
818         struct sta_info *sta;
819         struct ieee802_1x_hdr *hdr;
820         struct ieee802_1x_eapol_key *key;
821         u16 datalen;
822         struct rsn_pmksa_cache_entry *pmksa;
823
824         if (!hapd->conf->ieee802_1x && !hapd->conf->wpa)
825                 return;
826
827         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
828                       "IEEE 802.1X: %lu bytes from " MACSTR "\n",
829                       (unsigned long) len, MAC2STR(sa));
830         sta = ap_get_sta(hapd, sa);
831         if (!sta) {
832                 printf("   no station information available\n");
833                 return;
834         }
835
836         if (len < sizeof(*hdr)) {
837                 printf("   too short IEEE 802.1X packet\n");
838                 return;
839         }
840
841         hdr = (struct ieee802_1x_hdr *) buf;
842         datalen = ntohs(hdr->length);
843         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
844                       "   IEEE 802.1X: version=%d type=%d length=%d\n",
845                       hdr->version, hdr->type, datalen);
846
847         if (len - sizeof(*hdr) < datalen) {
848                 printf("   frame too short for this IEEE 802.1X packet\n");
849                 if (sta->eapol_sm)
850                         sta->eapol_sm->dot1xAuthEapLengthErrorFramesRx++;
851                 return;
852         }
853         if (len - sizeof(*hdr) > datalen) {
854                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
855                               "   ignoring %lu extra octets after IEEE 802.1X "
856                               "packet\n",
857                               (unsigned long) len - sizeof(*hdr) - datalen);
858         }
859
860         if (sta->eapol_sm) {
861                 sta->eapol_sm->dot1xAuthLastEapolFrameVersion = hdr->version;
862                 sta->eapol_sm->dot1xAuthEapolFramesRx++;
863         }
864
865         key = (struct ieee802_1x_eapol_key *) (hdr + 1);
866         if (datalen >= sizeof(struct ieee802_1x_eapol_key) &&
867             hdr->type == IEEE802_1X_TYPE_EAPOL_KEY &&
868             (key->type == EAPOL_KEY_TYPE_WPA ||
869              key->type == EAPOL_KEY_TYPE_RSN)) {
870                 wpa_receive(hapd->wpa_auth, sta->wpa_sm, (u8 *) hdr,
871                             sizeof(*hdr) + datalen);
872                 return;
873         }
874
875         if (!hapd->conf->ieee802_1x ||
876             wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_PSK)
877                 return;
878
879         if (!sta->eapol_sm) {
880                 sta->eapol_sm = eapol_sm_alloc(hapd, sta);
881                 if (!sta->eapol_sm)
882                         return;
883         }
884
885         /* since we support version 1, we can ignore version field and proceed
886          * as specified in version 1 standard [IEEE Std 802.1X-2001, 7.5.5] */
887         /* TODO: actually, we are not version 1 anymore.. However, Version 2
888          * does not change frame contents, so should be ok to process frames
889          * more or less identically. Some changes might be needed for
890          * verification of fields. */
891
892         switch (hdr->type) {
893         case IEEE802_1X_TYPE_EAP_PACKET:
894                 handle_eap(hapd, sta, (u8 *) (hdr + 1), datalen);
895                 break;
896
897         case IEEE802_1X_TYPE_EAPOL_START:
898                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
899                                HOSTAPD_LEVEL_DEBUG, "received EAPOL-Start "
900                                "from STA");
901                 pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
902                 if (pmksa) {
903                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
904                                        HOSTAPD_LEVEL_DEBUG, "cached PMKSA "
905                                        "available - ignore it since "
906                                        "STA sent EAPOL-Start");
907                         wpa_auth_sta_clear_pmksa(sta->wpa_sm, pmksa);
908                 }
909                 sta->eapol_sm->eapolStart = TRUE;
910                 sta->eapol_sm->dot1xAuthEapolStartFramesRx++;
911                 wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL);
912                 break;
913
914         case IEEE802_1X_TYPE_EAPOL_LOGOFF:
915                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
916                                HOSTAPD_LEVEL_DEBUG, "received EAPOL-Logoff "
917                                "from STA");
918                 sta->acct_terminate_cause =
919                         RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
920                 sta->eapol_sm->eapolLogoff = TRUE;
921                 sta->eapol_sm->dot1xAuthEapolLogoffFramesRx++;
922                 break;
923
924         case IEEE802_1X_TYPE_EAPOL_KEY:
925                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "   EAPOL-Key\n");
926                 if (!(sta->flags & WLAN_STA_AUTHORIZED)) {
927                         printf("   Dropped key data from unauthorized "
928                                "Supplicant\n");
929                         break;
930                 }
931                 break;
932
933         case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
934                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
935                               "   EAPOL-Encapsulated-ASF-Alert\n");
936                 /* TODO: implement support for this; show data */
937                 break;
938
939         default:
940                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
941                               "   unknown IEEE 802.1X packet type\n");
942                 sta->eapol_sm->dot1xAuthInvalidEapolFramesRx++;
943                 break;
944         }
945
946         eapol_sm_step(sta->eapol_sm);
947 }
948
949
950 void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
951 {
952         struct rsn_pmksa_cache_entry *pmksa;
953         int reassoc = 1;
954
955         if (!hapd->conf->ieee802_1x ||
956             wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_PSK)
957                 return;
958
959         if (sta->eapol_sm == NULL) {
960                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
961                                HOSTAPD_LEVEL_DEBUG, "start authentication");
962                 sta->eapol_sm = eapol_sm_alloc(hapd, sta);
963                 if (sta->eapol_sm == NULL) {
964                         hostapd_logger(hapd, sta->addr,
965                                        HOSTAPD_MODULE_IEEE8021X,
966                                        HOSTAPD_LEVEL_INFO,
967                                        "failed to allocate state machine");
968                         return;
969                 }
970                 reassoc = 0;
971         }
972
973         sta->eapol_sm->portEnabled = TRUE;
974
975         pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
976         if (pmksa) {
977                 int old_vlanid;
978
979                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
980                                HOSTAPD_LEVEL_DEBUG,
981                                "PMK from PMKSA cache - skip IEEE 802.1X/EAP");
982                 /* Setup EAPOL state machines to already authenticated state
983                  * because of existing PMKSA information in the cache. */
984                 sta->eapol_sm->keyRun = TRUE;
985                 sta->eapol_sm->keyAvailable = TRUE;
986                 sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING;
987                 sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS;
988                 sta->eapol_sm->authSuccess = TRUE;
989                 if (sta->eapol_sm->eap)
990                         eap_sm_notify_cached(sta->eapol_sm->eap);
991                 old_vlanid = sta->vlan_id;
992                 pmksa_cache_to_eapol_data(pmksa, sta->eapol_sm);
993                 if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
994                         sta->vlan_id = 0;
995                 ap_sta_bind_vlan(hapd, sta, old_vlanid);
996         } else {
997                 if (reassoc) {
998                         /*
999                          * Force EAPOL state machines to start
1000                          * re-authentication without having to wait for the
1001                          * Supplicant to send EAPOL-Start.
1002                          */
1003                         sta->eapol_sm->reAuthenticate = TRUE;
1004                 }
1005                 eapol_sm_step(sta->eapol_sm);
1006         }
1007 }
1008
1009
1010 void ieee802_1x_free_radius_class(struct radius_class_data *class)
1011 {
1012         size_t i;
1013         if (class == NULL)
1014                 return;
1015         for (i = 0; i < class->count; i++)
1016                 free(class->attr[i].data);
1017         free(class->attr);
1018         class->attr = NULL;
1019         class->count = 0;
1020 }
1021
1022
1023 int ieee802_1x_copy_radius_class(struct radius_class_data *dst,
1024                                  struct radius_class_data *src)
1025 {
1026         size_t i;
1027
1028         if (src->attr == NULL)
1029                 return 0;
1030
1031         dst->attr = wpa_zalloc(src->count * sizeof(struct radius_attr_data));
1032         if (dst->attr == NULL)
1033                 return -1;
1034
1035         dst->count = 0;
1036
1037         for (i = 0; i < src->count; i++) {
1038                 dst->attr[i].data = malloc(src->attr[i].len);
1039                 if (dst->attr[i].data == NULL)
1040                         break;
1041                 dst->count++;
1042                 memcpy(dst->attr[i].data, src->attr[i].data, src->attr[i].len);
1043                 dst->attr[i].len = src->attr[i].len;
1044         }
1045
1046         return 0;
1047 }
1048
1049
1050 void ieee802_1x_free_station(struct sta_info *sta)
1051 {
1052         struct eapol_state_machine *sm = sta->eapol_sm;
1053
1054         eloop_cancel_timeout(ieee802_1x_eap_timeout, sta, NULL);
1055
1056         if (sm == NULL)
1057                 return;
1058
1059         sta->eapol_sm = NULL;
1060
1061         if (sm->last_recv_radius) {
1062                 radius_msg_free(sm->last_recv_radius);
1063                 free(sm->last_recv_radius);
1064         }
1065
1066         free(sm->last_eap_supp);
1067         free(sm->last_eap_radius);
1068         free(sm->identity);
1069         ieee802_1x_free_radius_class(&sm->radius_class);
1070         free(sm->eapol_key_sign);
1071         free(sm->eapol_key_crypt);
1072         eapol_sm_free(sm);
1073 }
1074
1075
1076 static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
1077                                           struct sta_info *sta)
1078 {
1079         u8 *eap;
1080         size_t len;
1081         struct eap_hdr *hdr;
1082         int eap_type = -1;
1083         char buf[64];
1084         struct radius_msg *msg;
1085         struct eapol_state_machine *sm = sta->eapol_sm;
1086
1087         if (sm == NULL || sm->last_recv_radius == NULL) {
1088                 if (sm)
1089                         sm->eapNoReq = TRUE;
1090                 return;
1091         }
1092
1093         msg = sm->last_recv_radius;
1094
1095         eap = radius_msg_get_eap(msg, &len);
1096         if (eap == NULL) {
1097                 /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3:
1098                  * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
1099                  * attribute */
1100                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1101                                HOSTAPD_LEVEL_WARNING, "could not extract "
1102                                "EAP-Message from RADIUS message");
1103                 free(sm->last_eap_radius);
1104                 sm->last_eap_radius = NULL;
1105                 sm->last_eap_radius_len = 0;
1106                 sm->eapNoReq = TRUE;
1107                 return;
1108         }
1109
1110         if (len < sizeof(*hdr)) {
1111                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1112                                HOSTAPD_LEVEL_WARNING, "too short EAP packet "
1113                                "received from authentication server");
1114                 free(eap);
1115                 sm->eapNoReq = TRUE;
1116                 return;
1117         }
1118
1119         if (len > sizeof(*hdr))
1120                 eap_type = eap[sizeof(*hdr)];
1121
1122         hdr = (struct eap_hdr *) eap;
1123         switch (hdr->code) {
1124         case EAP_CODE_REQUEST:
1125                 if (eap_type >= 0)
1126                         sm->eap_type_authsrv = eap_type;
1127                 snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
1128                          eap_type >= 0 ? eap_type_text(eap_type) : "??",
1129                          eap_type);
1130                 break;
1131         case EAP_CODE_RESPONSE:
1132                 snprintf(buf, sizeof(buf), "EAP Response-%s (%d)",
1133                          eap_type >= 0 ? eap_type_text(eap_type) : "??",
1134                          eap_type);
1135                 break;
1136         case EAP_CODE_SUCCESS:
1137                 snprintf(buf, sizeof(buf), "EAP Success");
1138                 break;
1139         case EAP_CODE_FAILURE:
1140                 snprintf(buf, sizeof(buf), "EAP Failure");
1141                 break;
1142         default:
1143                 snprintf(buf, sizeof(buf), "unknown EAP code");
1144                 break;
1145         }
1146         buf[sizeof(buf) - 1] = '\0';
1147         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1148                        HOSTAPD_LEVEL_DEBUG, "decapsulated EAP packet (code=%d "
1149                        "id=%d len=%d) from RADIUS server: %s",
1150                       hdr->code, hdr->identifier, ntohs(hdr->length), buf);
1151         sm->eapReq = TRUE;
1152
1153         free(sm->last_eap_radius);
1154         sm->last_eap_radius = eap;
1155         sm->last_eap_radius_len = len;
1156 }
1157
1158
1159 static void ieee802_1x_get_keys(struct hostapd_data *hapd,
1160                                 struct sta_info *sta, struct radius_msg *msg,
1161                                 struct radius_msg *req,
1162                                 u8 *shared_secret, size_t shared_secret_len)
1163 {
1164         struct radius_ms_mppe_keys *keys;
1165         struct eapol_state_machine *sm = sta->eapol_sm;
1166         if (sm == NULL)
1167                 return;
1168
1169         keys = radius_msg_get_ms_keys(msg, req, shared_secret,
1170                                       shared_secret_len);
1171
1172         if (keys) {
1173                 if (keys->send) {
1174                         wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Send-Key",
1175                                         keys->send, keys->send_len);
1176                 }
1177                 if (keys->recv) {
1178                         wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Recv-Key",
1179                                         keys->recv, keys->recv_len);
1180                 }
1181
1182                 if (keys->send && keys->recv) {
1183                         free(sm->eapol_key_sign);
1184                         free(sm->eapol_key_crypt);
1185                         sm->eapol_key_sign = keys->send;
1186                         sm->eapol_key_sign_len = keys->send_len;
1187                         sm->eapol_key_crypt = keys->recv;
1188                         sm->eapol_key_crypt_len = keys->recv_len;
1189                         if (hapd->default_wep_key ||
1190                             hapd->conf->individual_wep_key_len > 0 ||
1191                             hapd->conf->wpa)
1192                                 sta->eapol_sm->keyAvailable = TRUE;
1193                 } else {
1194                         free(keys->send);
1195                         free(keys->recv);
1196                 }
1197                 free(keys);
1198         }
1199 }
1200
1201
1202 static void ieee802_1x_store_radius_class(struct hostapd_data *hapd,
1203                                           struct sta_info *sta,
1204                                           struct radius_msg *msg)
1205 {
1206         u8 *class;
1207         size_t class_len;
1208         struct eapol_state_machine *sm = sta->eapol_sm;
1209         int count, i;
1210         struct radius_attr_data *nclass;
1211         size_t nclass_count;
1212
1213         if (!hapd->conf->radius->acct_server || hapd->radius == NULL ||
1214             sm == NULL)
1215                 return;
1216
1217         ieee802_1x_free_radius_class(&sm->radius_class);
1218         count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1);
1219         if (count <= 0)
1220                 return;
1221
1222         nclass = wpa_zalloc(count * sizeof(struct radius_attr_data));
1223         if (nclass == NULL)
1224                 return;
1225
1226         nclass_count = 0;
1227
1228         class = NULL;
1229         for (i = 0; i < count; i++) {
1230                 do {
1231                         if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS,
1232                                                     &class, &class_len,
1233                                                     class) < 0) {
1234                                 i = count;
1235                                 break;
1236                         }
1237                 } while (class_len < 1);
1238
1239                 nclass[nclass_count].data = malloc(class_len);
1240                 if (nclass[nclass_count].data == NULL)
1241                         break;
1242
1243                 memcpy(nclass[nclass_count].data, class, class_len);
1244                 nclass[nclass_count].len = class_len;
1245                 nclass_count++;
1246         }
1247
1248         sm->radius_class.attr = nclass;
1249         sm->radius_class.count = nclass_count;
1250         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "IEEE 802.1X: Stored %lu RADIUS "
1251                       "Class attributes for " MACSTR "\n",
1252                       (unsigned long) sm->radius_class.count,
1253                       MAC2STR(sta->addr));
1254 }
1255
1256
1257 /* Update sta->identity based on User-Name attribute in Access-Accept */
1258 static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd,
1259                                            struct sta_info *sta,
1260                                            struct radius_msg *msg)
1261 {
1262         u8 *buf, *identity;
1263         size_t len;
1264         struct eapol_state_machine *sm = sta->eapol_sm;
1265
1266         if (sm == NULL)
1267                 return;
1268
1269         if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &buf, &len,
1270                                     NULL) < 0)
1271                 return;
1272
1273         identity = malloc(len + 1);
1274         if (identity == NULL)
1275                 return;
1276
1277         memcpy(identity, buf, len);
1278         identity[len] = '\0';
1279
1280         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1281                        HOSTAPD_LEVEL_DEBUG, "old identity '%s' updated with "
1282                        "User-Name from Access-Accept '%s'",
1283                        sm->identity ? (char *) sm->identity : "N/A",
1284                        (char *) identity);
1285
1286         free(sm->identity);
1287         sm->identity = identity;
1288         sm->identity_len = len;
1289 }
1290
1291
1292 struct sta_id_search {
1293         u8 identifier;
1294         struct eapol_state_machine *sm;
1295 };
1296
1297
1298 static int ieee802_1x_select_radius_identifier(struct hostapd_data *hapd,
1299                                                struct sta_info *sta,
1300                                                void *ctx)
1301 {
1302         struct sta_id_search *id_search = ctx;
1303         struct eapol_state_machine *sm = sta->eapol_sm;
1304
1305         if (sm && sm->radius_identifier >= 0 &&
1306             sm->radius_identifier == id_search->identifier) {
1307                 id_search->sm = sm;
1308                 return 1;
1309         }
1310         return 0;
1311 }
1312
1313
1314 static struct eapol_state_machine *
1315 ieee802_1x_search_radius_identifier(struct hostapd_data *hapd, u8 identifier)
1316 {
1317         struct sta_id_search id_search;
1318         id_search.identifier = identifier;
1319         id_search.sm = NULL;
1320         ap_for_each_sta(hapd, ieee802_1x_select_radius_identifier, &id_search);
1321         return id_search.sm;
1322 }
1323
1324
1325 /* Process the RADIUS frames from Authentication Server */
1326 static RadiusRxResult
1327 ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
1328                         u8 *shared_secret, size_t shared_secret_len,
1329                         void *data)
1330 {
1331         struct hostapd_data *hapd = data;
1332         struct sta_info *sta;
1333         u32 session_timeout = 0, termination_action, acct_interim_interval;
1334         int session_timeout_set, old_vlanid = 0;
1335         int eap_timeout;
1336         struct eapol_state_machine *sm;
1337         int override_eapReq = 0;
1338
1339         sm = ieee802_1x_search_radius_identifier(hapd, msg->hdr->identifier);
1340         if (sm == NULL) {
1341                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "IEEE 802.1X: Could not "
1342                               "find matching station for this RADIUS "
1343                               "message\n");
1344                 return RADIUS_RX_UNKNOWN;
1345         }
1346         sta = sm->sta;
1347
1348         /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
1349          * present when packet contains an EAP-Message attribute */
1350         if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT &&
1351             radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
1352                                 0) < 0 &&
1353             radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
1354                 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Allowing RADIUS "
1355                               "Access-Reject without Message-Authenticator "
1356                               "since it does not include EAP-Message\n");
1357         } else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
1358                                      req, 1)) {
1359                 printf("Incoming RADIUS packet did not have correct "
1360                        "Message-Authenticator - dropped\n");
1361                 return RADIUS_RX_INVALID_AUTHENTICATOR;
1362         }
1363
1364         if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
1365             msg->hdr->code != RADIUS_CODE_ACCESS_REJECT &&
1366             msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
1367                 printf("Unknown RADIUS message code\n");
1368                 return RADIUS_RX_UNKNOWN;
1369         }
1370
1371         sm->radius_identifier = -1;
1372         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
1373                       "RADIUS packet matching with station " MACSTR "\n",
1374                       MAC2STR(sta->addr));
1375
1376         if (sm->last_recv_radius) {
1377                 radius_msg_free(sm->last_recv_radius);
1378                 free(sm->last_recv_radius);
1379         }
1380
1381         sm->last_recv_radius = msg;
1382
1383         session_timeout_set =
1384                 !radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,
1385                                            &session_timeout);
1386         if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_TERMINATION_ACTION,
1387                                       &termination_action))
1388                 termination_action = RADIUS_TERMINATION_ACTION_DEFAULT;
1389
1390         if (hapd->conf->radius->acct_interim_interval == 0 &&
1391             msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
1392             radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
1393                                       &acct_interim_interval) == 0) {
1394                 if (acct_interim_interval < 60) {
1395                         hostapd_logger(hapd, sta->addr,
1396                                        HOSTAPD_MODULE_IEEE8021X,
1397                                        HOSTAPD_LEVEL_INFO,
1398                                        "ignored too small "
1399                                        "Acct-Interim-Interval %d",
1400                                        acct_interim_interval);
1401                 } else
1402                         sta->acct_interim_interval = acct_interim_interval;
1403         }
1404
1405
1406         switch (msg->hdr->code) {
1407         case RADIUS_CODE_ACCESS_ACCEPT:
1408                 if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
1409                         sta->vlan_id = 0;
1410                 else {
1411                         old_vlanid = sta->vlan_id;
1412                         sta->vlan_id = radius_msg_get_vlanid(msg);
1413                 }
1414                 if (sta->vlan_id > 0 &&
1415                     hostapd_get_vlan_id_ifname(hapd->conf->vlan,
1416                                                sta->vlan_id)) {
1417                         hostapd_logger(hapd, sta->addr,
1418                                        HOSTAPD_MODULE_RADIUS,
1419                                        HOSTAPD_LEVEL_INFO,
1420                                        "VLAN ID %d", sta->vlan_id);
1421                 } else if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_REQUIRED) {
1422                         sta->eapol_sm->authFail = TRUE;
1423                         hostapd_logger(hapd, sta->addr,
1424                                        HOSTAPD_MODULE_IEEE8021X,
1425                                        HOSTAPD_LEVEL_INFO, "authentication "
1426                                        "server did not include required VLAN "
1427                                        "ID in Access-Accept");
1428                         break;
1429                 }
1430
1431                 ap_sta_bind_vlan(hapd, sta, old_vlanid);
1432
1433                 /* RFC 3580, Ch. 3.17 */
1434                 if (session_timeout_set && termination_action ==
1435                     RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) {
1436                         sm->reAuthPeriod = session_timeout;
1437                 } else if (session_timeout_set)
1438                         ap_sta_session_timeout(hapd, sta, session_timeout);
1439
1440                 sm->eapSuccess = TRUE;
1441                 override_eapReq = 1;
1442                 ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret,
1443                                     shared_secret_len);
1444                 ieee802_1x_store_radius_class(hapd, sta, msg);
1445                 ieee802_1x_update_sta_identity(hapd, sta, msg);
1446                 if (sm->keyAvailable &&
1447                     wpa_auth_pmksa_add(sta->wpa_sm, sm->eapol_key_crypt,
1448                                        session_timeout_set ?
1449                                        (int) session_timeout : -1, sm) == 0) {
1450                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
1451                                        HOSTAPD_LEVEL_DEBUG,
1452                                        "Added PMKSA cache entry");
1453                 }
1454                 break;
1455         case RADIUS_CODE_ACCESS_REJECT:
1456                 sm->eapFail = TRUE;
1457                 override_eapReq = 1;
1458                 break;
1459         case RADIUS_CODE_ACCESS_CHALLENGE:
1460                 if (session_timeout_set) {
1461                         /* RFC 2869, Ch. 2.3.2; RFC 3580, Ch. 3.17 */
1462                         eap_timeout = session_timeout;
1463                 } else
1464                         eap_timeout = 30;
1465                 hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
1466                                HOSTAPD_LEVEL_DEBUG,
1467                                "using EAP timeout of %d seconds%s",
1468                                eap_timeout,
1469                                session_timeout_set ? " (from RADIUS)" : "");
1470                 eloop_cancel_timeout(ieee802_1x_eap_timeout, sta, NULL);
1471                 eloop_register_timeout(eap_timeout, 0, ieee802_1x_eap_timeout,
1472                                        sta, NULL);
1473                 sm->eapTimeout = FALSE;
1474                 break;
1475         }
1476
1477         ieee802_1x_decapsulate_radius(hapd, sta);
1478         if (override_eapReq)
1479                 sm->eapReq = FALSE;
1480
1481         eapol_sm_step(sm);
1482
1483         return RADIUS_RX_QUEUED;
1484 }
1485
1486
1487 /* Handler for EAPOL Backend Authentication state machine sendRespToServer.
1488  * Forward the EAP Response from Supplicant to Authentication Server. */
1489 void ieee802_1x_send_resp_to_server(struct hostapd_data *hapd,
1490                                     struct sta_info *sta)
1491 {
1492         struct eapol_state_machine *sm = sta->eapol_sm;
1493         if (sm == NULL)
1494                 return;
1495
1496         if (hapd->conf->eap_server) {
1497                 eap_set_eapRespData(sm->eap, sm->last_eap_supp,
1498                                     sm->last_eap_supp_len);
1499         } else {
1500                 ieee802_1x_encapsulate_radius(hapd, sta, sm->last_eap_supp,
1501                                               sm->last_eap_supp_len);
1502         }
1503 }
1504
1505
1506 void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
1507 {
1508         struct eapol_state_machine *sm = sta->eapol_sm;
1509         if (sm == NULL)
1510                 return;
1511
1512         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1513                        HOSTAPD_LEVEL_DEBUG, "aborting authentication");
1514
1515         if (sm->last_recv_radius) {
1516                 radius_msg_free(sm->last_recv_radius);
1517                 free(sm->last_recv_radius);
1518                 sm->last_recv_radius = NULL;
1519         }
1520         free(sm->last_eap_supp);
1521         sm->last_eap_supp = NULL;
1522         sm->last_eap_supp_len = 0;
1523         free(sm->last_eap_radius);
1524         sm->last_eap_radius = NULL;
1525         sm->last_eap_radius_len = 0;
1526 }
1527
1528
1529 #ifdef HOSTAPD_DUMP_STATE
1530 static void fprint_char(FILE *f, char c)
1531 {
1532         if (c >= 32 && c < 127)
1533                 fprintf(f, "%c", c);
1534         else
1535                 fprintf(f, "<%02x>", c);
1536 }
1537
1538
1539 void ieee802_1x_dump_state(FILE *f, const char *prefix, struct sta_info *sta)
1540 {
1541         struct eapol_state_machine *sm = sta->eapol_sm;
1542         if (sm == NULL)
1543                 return;
1544
1545         fprintf(f, "%sIEEE 802.1X:\n", prefix);
1546
1547         if (sm->identity) {
1548                 size_t i;
1549                 fprintf(f, "%sidentity=", prefix);
1550                 for (i = 0; i < sm->identity_len; i++)
1551                         fprint_char(f, sm->identity[i]);
1552                 fprintf(f, "\n");
1553         }
1554
1555         fprintf(f, "%slast EAP type: Authentication Server: %d (%s) "
1556                 "Supplicant: %d (%s)\n", prefix,
1557                 sm->eap_type_authsrv, eap_type_text(sm->eap_type_authsrv),
1558                 sm->eap_type_supp, eap_type_text(sm->eap_type_supp));
1559
1560         fprintf(f, "%scached_packets=%s%s%s\n", prefix,
1561                 sm->last_recv_radius ? "[RX RADIUS]" : "",
1562                 sm->last_eap_radius ? "[EAP RADIUS]" : "",
1563                 sm->last_eap_supp ? "[EAP SUPPLICANT]" : "");
1564
1565         eapol_sm_dump_state(f, prefix, sm);
1566 }
1567 #endif /* HOSTAPD_DUMP_STATE */
1568
1569
1570 static int ieee802_1x_rekey_broadcast(struct hostapd_data *hapd)
1571 {
1572         if (hapd->conf->default_wep_key_len < 1)
1573                 return 0;
1574
1575         free(hapd->default_wep_key);
1576         hapd->default_wep_key = malloc(hapd->conf->default_wep_key_len);
1577         if (hapd->default_wep_key == NULL ||
1578             hostapd_get_rand(hapd->default_wep_key,
1579                              hapd->conf->default_wep_key_len)) {
1580                 printf("Could not generate random WEP key.\n");
1581                 free(hapd->default_wep_key);
1582                 hapd->default_wep_key = NULL;
1583                 return -1;
1584         }
1585
1586         wpa_hexdump_key(MSG_DEBUG, "IEEE 802.1X: New default WEP key",
1587                         hapd->default_wep_key,
1588                         hapd->conf->default_wep_key_len);
1589
1590         return 0;
1591 }
1592
1593
1594 static int ieee802_1x_sta_key_available(struct hostapd_data *hapd,
1595                                         struct sta_info *sta, void *ctx)
1596 {
1597         if (sta->eapol_sm) {
1598                 sta->eapol_sm->keyAvailable = TRUE;
1599                 eapol_sm_step(sta->eapol_sm);
1600         }
1601         return 0;
1602 }
1603
1604
1605 static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
1606 {
1607         struct hostapd_data *hapd = eloop_ctx;
1608
1609         if (hapd->default_wep_key_idx >= 3)
1610                 hapd->default_wep_key_idx =
1611                         hapd->conf->individual_wep_key_len > 0 ? 1 : 0;
1612         else
1613                 hapd->default_wep_key_idx++;
1614
1615         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "IEEE 802.1X: New default WEP "
1616                       "key index %d\n", hapd->default_wep_key_idx);
1617                       
1618         if (ieee802_1x_rekey_broadcast(hapd)) {
1619                 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
1620                                HOSTAPD_LEVEL_WARNING, "failed to generate a "
1621                                "new broadcast key");
1622                 free(hapd->default_wep_key);
1623                 hapd->default_wep_key = NULL;
1624                 return;
1625         }
1626
1627         /* TODO: Could setup key for RX here, but change default TX keyid only
1628          * after new broadcast key has been sent to all stations. */
1629         if (hostapd_set_encryption(hapd->conf->iface, hapd, "WEP", NULL,
1630                                    hapd->default_wep_key_idx,
1631                                    hapd->default_wep_key,
1632                                    hapd->conf->default_wep_key_len, 1)) {
1633                 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
1634                                HOSTAPD_LEVEL_WARNING, "failed to configure a "
1635                                "new broadcast key");
1636                 free(hapd->default_wep_key);
1637                 hapd->default_wep_key = NULL;
1638                 return;
1639         }
1640
1641         ap_for_each_sta(hapd, ieee802_1x_sta_key_available, NULL);
1642
1643         if (hapd->conf->wep_rekeying_period > 0) {
1644                 eloop_register_timeout(hapd->conf->wep_rekeying_period, 0,
1645                                        ieee802_1x_rekey, hapd, NULL);
1646         }
1647 }
1648
1649
1650 int ieee802_1x_init(struct hostapd_data *hapd)
1651 {
1652         int i;
1653
1654         if ((hapd->conf->ieee802_1x || hapd->conf->wpa) &&
1655             hostapd_set_ieee8021x(hapd->conf->iface, hapd, 1))
1656                 return -1;
1657
1658         if (radius_client_register(hapd->radius, RADIUS_AUTH,
1659                                    ieee802_1x_receive_auth, hapd))
1660                 return -1;
1661
1662         if (hapd->conf->default_wep_key_len) {
1663                 hostapd_set_privacy(hapd, 1);
1664
1665                 for (i = 0; i < 4; i++)
1666                         hostapd_set_encryption(hapd->conf->iface, hapd,
1667                                                "none", NULL, i, NULL, 0, 0);
1668
1669                 ieee802_1x_rekey(hapd, NULL);
1670
1671                 if (hapd->default_wep_key == NULL)
1672                         return -1;
1673         }
1674
1675         return 0;
1676 }
1677
1678
1679 void ieee802_1x_deinit(struct hostapd_data *hapd)
1680 {
1681         eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL);
1682
1683         if (hapd->driver != NULL &&
1684             (hapd->conf->ieee802_1x || hapd->conf->wpa))
1685                 hostapd_set_ieee8021x(hapd->conf->iface, hapd, 0);
1686 }
1687
1688
1689 int ieee802_1x_reconfig(struct hostapd_data *hapd, 
1690                         struct hostapd_config *oldconf,
1691                         struct hostapd_bss_config *oldbss)
1692 {
1693         ieee802_1x_deinit(hapd);
1694         return ieee802_1x_init(hapd);
1695 }
1696
1697
1698 static void ieee802_1x_new_auth_session(struct hostapd_data *hapd,
1699                                         struct sta_info *sta)
1700 {
1701         struct eapol_state_machine *sm = sta->eapol_sm;
1702         if (sm == NULL)
1703                 return;
1704
1705         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
1706                       "IEEE 802.1X: station " MACSTR " - new auth session, "
1707                       "clearing State\n", MAC2STR(sta->addr));
1708
1709         if (sm->last_recv_radius) {
1710                 radius_msg_free(sm->last_recv_radius);
1711                 free(sm->last_recv_radius);
1712                 sm->last_recv_radius = NULL;
1713         }
1714
1715         sm->eapSuccess = FALSE;
1716         sm->eapFail = FALSE;
1717 }
1718
1719
1720 int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta,
1721                          u8 *buf, size_t len, int ack)
1722 {
1723         struct ieee80211_hdr *hdr;
1724         struct ieee802_1x_hdr *xhdr;
1725         struct ieee802_1x_eapol_key *key;
1726         u8 *pos;
1727
1728         if (sta == NULL)
1729                 return -1;
1730         if (len < sizeof(*hdr) + sizeof(rfc1042_header) + 2 + sizeof(*xhdr))
1731                 return 0;
1732
1733         hdr = (struct ieee80211_hdr *) buf;
1734         pos = (u8 *) (hdr + 1);
1735         if (memcmp(pos, rfc1042_header, sizeof(rfc1042_header)) != 0)
1736                 return 0;
1737         pos += sizeof(rfc1042_header);
1738         if (((pos[0] << 8) | pos[1]) != ETH_P_PAE)
1739                 return 0;
1740         pos += 2;
1741
1742         xhdr = (struct ieee802_1x_hdr *) pos;
1743         pos += sizeof(*xhdr);
1744
1745         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "IEEE 802.1X: " MACSTR
1746                       " TX status - version=%d type=%d length=%d - ack=%d\n",
1747                       MAC2STR(sta->addr), xhdr->version, xhdr->type,
1748                       ntohs(xhdr->length), ack);
1749
1750         /* EAPOL EAP-Packet packets are eventually re-sent by either Supplicant
1751          * or Authenticator state machines, but EAPOL-Key packets are not
1752          * retransmitted in case of failure. Try to re-sent failed EAPOL-Key
1753          * packets couple of times because otherwise STA keys become
1754          * unsynchronized with AP. */
1755         if (xhdr->type == IEEE802_1X_TYPE_EAPOL_KEY && !ack &&
1756             pos + sizeof(*key) <= buf + len) {
1757                 key = (struct ieee802_1x_eapol_key *) pos;
1758                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1759                                HOSTAPD_LEVEL_DEBUG, "did not Ack EAPOL-Key "
1760                                "frame (%scast index=%d)",
1761                                key->key_index & BIT(7) ? "uni" : "broad",
1762                                key->key_index & ~BIT(7));
1763                 /* TODO: re-send EAPOL-Key couple of times (with short delay
1764                  * between them?). If all attempt fail, report error and
1765                  * deauthenticate STA so that it will get new keys when
1766                  * authenticating again (e.g., after returning in range).
1767                  * Separate limit/transmit state needed both for unicast and
1768                  * broadcast keys(?) */
1769         }
1770         /* TODO: could move unicast key configuration from ieee802_1x_tx_key()
1771          * to here and change the key only if the EAPOL-Key packet was Acked.
1772          */
1773
1774         return 1;
1775 }
1776
1777
1778 u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len)
1779 {
1780         if (sm == NULL || sm->identity == NULL)
1781                 return NULL;
1782
1783         *len = sm->identity_len;
1784         return sm->identity;
1785 }
1786
1787
1788 u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
1789                                  int idx)
1790 {
1791         if (sm == NULL || sm->radius_class.attr == NULL ||
1792             idx >= (int) sm->radius_class.count)
1793                 return NULL;
1794
1795         *len = sm->radius_class.attr[idx].len;
1796         return sm->radius_class.attr[idx].data;
1797 }
1798
1799
1800 u8 * ieee802_1x_get_key_crypt(struct eapol_state_machine *sm, size_t *len)
1801 {
1802         if (sm == NULL)
1803                 return NULL;
1804
1805         *len = sm->eapol_key_crypt_len;
1806         return sm->eapol_key_crypt;
1807 }
1808
1809
1810 void ieee802_1x_notify_port_enabled(struct eapol_state_machine *sm,
1811                                     int enabled)
1812 {
1813         if (sm == NULL)
1814                 return;
1815         sm->portEnabled = enabled ? TRUE : FALSE;
1816         eapol_sm_step(sm);
1817 }
1818
1819
1820 void ieee802_1x_notify_port_valid(struct eapol_state_machine *sm,
1821                                   int valid)
1822 {
1823         if (sm == NULL)
1824                 return;
1825         sm->portValid = valid ? TRUE : FALSE;
1826         eapol_sm_step(sm);
1827 }
1828
1829
1830 void ieee802_1x_notify_pre_auth(struct eapol_state_machine *sm, int pre_auth)
1831 {
1832         if (sm == NULL)
1833                 return;
1834         if (pre_auth)
1835                 sm->flags |= EAPOL_SM_PREAUTH;
1836         else
1837                 sm->flags &= ~EAPOL_SM_PREAUTH;
1838 }
1839
1840
1841 static const char * bool_txt(Boolean bool)
1842 {
1843         return bool ? "TRUE" : "FALSE";
1844 }
1845
1846
1847 int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
1848 {
1849         /* TODO */
1850         return 0;
1851 }
1852
1853
1854 int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
1855                            char *buf, size_t buflen)
1856 {
1857         int len = 0, ret;
1858         struct eapol_state_machine *sm = sta->eapol_sm;
1859
1860         if (sm == NULL)
1861                 return 0;
1862
1863         ret = snprintf(buf + len, buflen - len,
1864                        "dot1xPaePortNumber=%d\n"
1865                        "dot1xPaePortProtocolVersion=%d\n"
1866                        "dot1xPaePortCapabilities=1\n"
1867                        "dot1xPaePortInitialize=%d\n"
1868                        "dot1xPaePortReauthenticate=FALSE\n",
1869                        sta->aid,
1870                        EAPOL_VERSION,
1871                        sm->initialize);
1872         if (ret < 0 || (size_t) ret >= buflen - len)
1873                 return len;
1874         len += ret;
1875
1876         /* dot1xAuthConfigTable */
1877         ret = snprintf(buf + len, buflen - len,
1878                        "dot1xAuthPaeState=%d\n"
1879                        "dot1xAuthBackendAuthState=%d\n"
1880                        "dot1xAuthAdminControlledDirections=%d\n"
1881                        "dot1xAuthOperControlledDirections=%d\n"
1882                        "dot1xAuthAuthControlledPortStatus=%d\n"
1883                        "dot1xAuthAuthControlledPortControl=%d\n"
1884                        "dot1xAuthQuietPeriod=%u\n"
1885                        "dot1xAuthServerTimeout=%u\n"
1886                        "dot1xAuthReAuthPeriod=%u\n"
1887                        "dot1xAuthReAuthEnabled=%s\n"
1888                        "dot1xAuthKeyTxEnabled=%s\n",
1889                        sm->auth_pae_state + 1,
1890                        sm->be_auth_state + 1,
1891                        sm->adminControlledDirections,
1892                        sm->operControlledDirections,
1893                        sm->authPortStatus,
1894                        sm->portControl,
1895                        sm->quietPeriod,
1896                        sm->serverTimeout,
1897                        sm->reAuthPeriod,
1898                        bool_txt(sm->reAuthEnabled),
1899                        bool_txt(sm->keyTxEnabled));
1900         if (ret < 0 || (size_t) ret >= buflen - len)
1901                 return len;
1902         len += ret;
1903
1904         /* dot1xAuthStatsTable */
1905         ret = snprintf(buf + len, buflen - len,
1906                        "dot1xAuthEapolFramesRx=%u\n"
1907                        "dot1xAuthEapolFramesTx=%u\n"
1908                        "dot1xAuthEapolStartFramesRx=%u\n"
1909                        "dot1xAuthEapolLogoffFramesRx=%u\n"
1910                        "dot1xAuthEapolRespIdFramesRx=%u\n"
1911                        "dot1xAuthEapolRespFramesRx=%u\n"
1912                        "dot1xAuthEapolReqIdFramesTx=%u\n"
1913                        "dot1xAuthEapolReqFramesTx=%u\n"
1914                        "dot1xAuthInvalidEapolFramesRx=%u\n"
1915                        "dot1xAuthEapLengthErrorFramesRx=%u\n"
1916                        "dot1xAuthLastEapolFrameVersion=%u\n"
1917                        "dot1xAuthLastEapolFrameSource=" MACSTR "\n",
1918                        sm->dot1xAuthEapolFramesRx,
1919                        sm->dot1xAuthEapolFramesTx,
1920                        sm->dot1xAuthEapolStartFramesRx,
1921                        sm->dot1xAuthEapolLogoffFramesRx,
1922                        sm->dot1xAuthEapolRespIdFramesRx,
1923                        sm->dot1xAuthEapolRespFramesRx,
1924                        sm->dot1xAuthEapolReqIdFramesTx,
1925                        sm->dot1xAuthEapolReqFramesTx,
1926                        sm->dot1xAuthInvalidEapolFramesRx,
1927                        sm->dot1xAuthEapLengthErrorFramesRx,
1928                        sm->dot1xAuthLastEapolFrameVersion,
1929                        MAC2STR(sm->addr));
1930         if (ret < 0 || (size_t) ret >= buflen - len)
1931                 return len;
1932         len += ret;
1933
1934         /* dot1xAuthDiagTable */
1935         ret = snprintf(buf + len, buflen - len,
1936                        "dot1xAuthEntersConnecting=%u\n"
1937                        "dot1xAuthEapLogoffsWhileConnecting=%u\n"
1938                        "dot1xAuthEntersAuthenticating=%u\n"
1939                        "dot1xAuthAuthSuccessesWhileAuthenticating=%u\n"
1940                        "dot1xAuthAuthTimeoutsWhileAuthenticating=%u\n"
1941                        "dot1xAuthAuthFailWhileAuthenticating=%u\n"
1942                        "dot1xAuthAuthEapStartsWhileAuthenticating=%u\n"
1943                        "dot1xAuthAuthEapLogoffWhileAuthenticating=%u\n"
1944                        "dot1xAuthAuthReauthsWhileAuthenticated=%u\n"
1945                        "dot1xAuthAuthEapStartsWhileAuthenticated=%u\n"
1946                        "dot1xAuthAuthEapLogoffWhileAuthenticated=%u\n"
1947                        "dot1xAuthBackendResponses=%u\n"
1948                        "dot1xAuthBackendAccessChallenges=%u\n"
1949                        "dot1xAuthBackendOtherRequestsToSupplicant=%u\n"
1950                        "dot1xAuthBackendAuthSuccesses=%u\n"
1951                        "dot1xAuthBackendAuthFails=%u\n",
1952                        sm->authEntersConnecting,
1953                        sm->authEapLogoffsWhileConnecting,
1954                        sm->authEntersAuthenticating,
1955                        sm->authAuthSuccessesWhileAuthenticating,
1956                        sm->authAuthTimeoutsWhileAuthenticating,
1957                        sm->authAuthFailWhileAuthenticating,
1958                        sm->authAuthEapStartsWhileAuthenticating,
1959                        sm->authAuthEapLogoffWhileAuthenticating,
1960                        sm->authAuthReauthsWhileAuthenticated,
1961                        sm->authAuthEapStartsWhileAuthenticated,
1962                        sm->authAuthEapLogoffWhileAuthenticated,
1963                        sm->backendResponses,
1964                        sm->backendAccessChallenges,
1965                        sm->backendOtherRequestsToSupplicant,
1966                        sm->backendAuthSuccesses,
1967                        sm->backendAuthFails);
1968         if (ret < 0 || (size_t) ret >= buflen - len)
1969                 return len;
1970         len += ret;
1971
1972         /* dot1xAuthSessionStatsTable */
1973         ret = snprintf(buf + len, buflen - len,
1974                        /* TODO: dot1xAuthSessionOctetsRx */
1975                        /* TODO: dot1xAuthSessionOctetsTx */
1976                        /* TODO: dot1xAuthSessionFramesRx */
1977                        /* TODO: dot1xAuthSessionFramesTx */
1978                        "dot1xAuthSessionId=%08X-%08X\n"
1979                        "dot1xAuthSessionAuthenticMethod=%d\n"
1980                        "dot1xAuthSessionTime=%u\n"
1981                        "dot1xAuthSessionTerminateCause=999\n"
1982                        "dot1xAuthSessionUserName=%s\n",
1983                        sta->acct_session_id_hi, sta->acct_session_id_lo,
1984                        wpa_auth_sta_key_mgmt(sta->wpa_sm) ==
1985                        WPA_KEY_MGMT_IEEE8021X ? 1 : 2,
1986                        (unsigned int) (time(NULL) - sta->acct_session_start),
1987                        sm->identity);
1988         if (ret < 0 || (size_t) ret >= buflen - len)
1989                 return len;
1990         len += ret;
1991
1992         return len;
1993 }
1994
1995
1996 void ieee802_1x_finished(struct hostapd_data *hapd, struct sta_info *sta,
1997                          int success)
1998 {
1999         u8 *key;
2000         size_t len;
2001         /* TODO: get PMKLifetime from WPA parameters */
2002         static const int dot11RSNAConfigPMKLifetime = 43200;
2003
2004         key = ieee802_1x_get_key_crypt(sta->eapol_sm, &len);
2005         if (success && key &&
2006             wpa_auth_pmksa_add(sta->wpa_sm, key, dot11RSNAConfigPMKLifetime,
2007                                sta->eapol_sm) == 0) {
2008                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
2009                                HOSTAPD_LEVEL_DEBUG,
2010                                "Added PMKSA cache entry (IEEE 802.1X)");
2011         }
2012 }