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