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