]> git.ipfire.org Git - thirdparty/hostap.git/blob - src/ap/ieee802_1x.c
RADIUS: Use more likely unique accounting Acct-{,Multi-}Session-Id
[thirdparty/hostap.git] / src / ap / ieee802_1x.c
1 /*
2 * hostapd / IEEE 802.1X-2004 Authenticator
3 * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "utils/includes.h"
10
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "crypto/md5.h"
14 #include "crypto/crypto.h"
15 #include "crypto/random.h"
16 #include "common/ieee802_11_defs.h"
17 #include "radius/radius.h"
18 #include "radius/radius_client.h"
19 #include "eap_server/eap.h"
20 #include "eap_common/eap_wsc_common.h"
21 #include "eapol_auth/eapol_auth_sm.h"
22 #include "eapol_auth/eapol_auth_sm_i.h"
23 #include "p2p/p2p.h"
24 #include "hostapd.h"
25 #include "accounting.h"
26 #include "sta_info.h"
27 #include "wpa_auth.h"
28 #include "preauth_auth.h"
29 #include "pmksa_cache_auth.h"
30 #include "ap_config.h"
31 #include "ap_drv_ops.h"
32 #include "wps_hostapd.h"
33 #include "hs20.h"
34 #include "ieee802_1x.h"
35
36
37 #ifdef CONFIG_HS20
38 static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx);
39 #endif /* CONFIG_HS20 */
40 static void ieee802_1x_finished(struct hostapd_data *hapd,
41 struct sta_info *sta, int success,
42 int remediation);
43
44
45 static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta,
46 u8 type, const u8 *data, size_t datalen)
47 {
48 u8 *buf;
49 struct ieee802_1x_hdr *xhdr;
50 size_t len;
51 int encrypt = 0;
52
53 len = sizeof(*xhdr) + datalen;
54 buf = os_zalloc(len);
55 if (buf == NULL) {
56 wpa_printf(MSG_ERROR, "malloc() failed for "
57 "ieee802_1x_send(len=%lu)",
58 (unsigned long) len);
59 return;
60 }
61
62 xhdr = (struct ieee802_1x_hdr *) buf;
63 xhdr->version = hapd->conf->eapol_version;
64 xhdr->type = type;
65 xhdr->length = host_to_be16(datalen);
66
67 if (datalen > 0 && data != NULL)
68 os_memcpy(xhdr + 1, data, datalen);
69
70 if (wpa_auth_pairwise_set(sta->wpa_sm))
71 encrypt = 1;
72 #ifdef CONFIG_TESTING_OPTIONS
73 if (hapd->ext_eapol_frame_io) {
74 size_t hex_len = 2 * len + 1;
75 char *hex = os_malloc(hex_len);
76
77 if (hex) {
78 wpa_snprintf_hex(hex, hex_len, buf, len);
79 wpa_msg(hapd->msg_ctx, MSG_INFO,
80 "EAPOL-TX " MACSTR " %s",
81 MAC2STR(sta->addr), hex);
82 os_free(hex);
83 }
84 } else
85 #endif /* CONFIG_TESTING_OPTIONS */
86 if (sta->flags & WLAN_STA_PREAUTH) {
87 rsn_preauth_send(hapd, sta, buf, len);
88 } else {
89 hostapd_drv_hapd_send_eapol(
90 hapd, sta->addr, buf, len,
91 encrypt, hostapd_sta_flags_to_drv(sta->flags));
92 }
93
94 os_free(buf);
95 }
96
97
98 void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
99 struct sta_info *sta, int authorized)
100 {
101 int res;
102
103 if (sta->flags & WLAN_STA_PREAUTH)
104 return;
105
106 if (authorized) {
107 ap_sta_set_authorized(hapd, sta, 1);
108 res = hostapd_set_authorized(hapd, sta, 1);
109 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
110 HOSTAPD_LEVEL_DEBUG, "authorizing port");
111 } else {
112 ap_sta_set_authorized(hapd, sta, 0);
113 res = hostapd_set_authorized(hapd, sta, 0);
114 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
115 HOSTAPD_LEVEL_DEBUG, "unauthorizing port");
116 }
117
118 if (res && errno != ENOENT) {
119 wpa_printf(MSG_DEBUG, "Could not set station " MACSTR
120 " flags for kernel driver (errno=%d).",
121 MAC2STR(sta->addr), errno);
122 }
123
124 if (authorized) {
125 os_get_reltime(&sta->connected_time);
126 accounting_sta_start(hapd, sta);
127 }
128 }
129
130
131 #ifndef CONFIG_FIPS
132 #ifndef CONFIG_NO_RC4
133
134 static void ieee802_1x_tx_key_one(struct hostapd_data *hapd,
135 struct sta_info *sta,
136 int idx, int broadcast,
137 u8 *key_data, size_t key_len)
138 {
139 u8 *buf, *ekey;
140 struct ieee802_1x_hdr *hdr;
141 struct ieee802_1x_eapol_key *key;
142 size_t len, ekey_len;
143 struct eapol_state_machine *sm = sta->eapol_sm;
144
145 if (sm == NULL)
146 return;
147
148 len = sizeof(*key) + key_len;
149 buf = os_zalloc(sizeof(*hdr) + len);
150 if (buf == NULL)
151 return;
152
153 hdr = (struct ieee802_1x_hdr *) buf;
154 key = (struct ieee802_1x_eapol_key *) (hdr + 1);
155 key->type = EAPOL_KEY_TYPE_RC4;
156 WPA_PUT_BE16(key->key_length, key_len);
157 wpa_get_ntp_timestamp(key->replay_counter);
158
159 if (random_get_bytes(key->key_iv, sizeof(key->key_iv))) {
160 wpa_printf(MSG_ERROR, "Could not get random numbers");
161 os_free(buf);
162 return;
163 }
164
165 key->key_index = idx | (broadcast ? 0 : BIT(7));
166 if (hapd->conf->eapol_key_index_workaround) {
167 /* According to some information, WinXP Supplicant seems to
168 * interpret bit7 as an indication whether the key is to be
169 * activated, so make it possible to enable workaround that
170 * sets this bit for all keys. */
171 key->key_index |= BIT(7);
172 }
173
174 /* Key is encrypted using "Key-IV + MSK[0..31]" as the RC4-key and
175 * MSK[32..63] is used to sign the message. */
176 if (sm->eap_if->eapKeyData == NULL || sm->eap_if->eapKeyDataLen < 64) {
177 wpa_printf(MSG_ERROR, "No eapKeyData available for encrypting "
178 "and signing EAPOL-Key");
179 os_free(buf);
180 return;
181 }
182 os_memcpy((u8 *) (key + 1), key_data, key_len);
183 ekey_len = sizeof(key->key_iv) + 32;
184 ekey = os_malloc(ekey_len);
185 if (ekey == NULL) {
186 wpa_printf(MSG_ERROR, "Could not encrypt key");
187 os_free(buf);
188 return;
189 }
190 os_memcpy(ekey, key->key_iv, sizeof(key->key_iv));
191 os_memcpy(ekey + sizeof(key->key_iv), sm->eap_if->eapKeyData, 32);
192 rc4_skip(ekey, ekey_len, 0, (u8 *) (key + 1), key_len);
193 os_free(ekey);
194
195 /* This header is needed here for HMAC-MD5, but it will be regenerated
196 * in ieee802_1x_send() */
197 hdr->version = hapd->conf->eapol_version;
198 hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
199 hdr->length = host_to_be16(len);
200 hmac_md5(sm->eap_if->eapKeyData + 32, 32, buf, sizeof(*hdr) + len,
201 key->key_signature);
202
203 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key to " MACSTR
204 " (%s index=%d)", MAC2STR(sm->addr),
205 broadcast ? "broadcast" : "unicast", idx);
206 ieee802_1x_send(hapd, sta, IEEE802_1X_TYPE_EAPOL_KEY, (u8 *) key, len);
207 if (sta->eapol_sm)
208 sta->eapol_sm->dot1xAuthEapolFramesTx++;
209 os_free(buf);
210 }
211
212
213 static void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
214 {
215 struct eapol_authenticator *eapol = hapd->eapol_auth;
216 struct eapol_state_machine *sm = sta->eapol_sm;
217
218 if (sm == NULL || !sm->eap_if->eapKeyData)
219 return;
220
221 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR,
222 MAC2STR(sta->addr));
223
224 #ifndef CONFIG_NO_VLAN
225 if (sta->vlan_id > 0 && sta->vlan_id <= MAX_VLAN_ID) {
226 wpa_printf(MSG_ERROR, "Using WEP with vlans is not supported.");
227 return;
228 }
229 #endif /* CONFIG_NO_VLAN */
230
231 if (eapol->default_wep_key) {
232 ieee802_1x_tx_key_one(hapd, sta, eapol->default_wep_key_idx, 1,
233 eapol->default_wep_key,
234 hapd->conf->default_wep_key_len);
235 }
236
237 if (hapd->conf->individual_wep_key_len > 0) {
238 u8 *ikey;
239 ikey = os_malloc(hapd->conf->individual_wep_key_len);
240 if (ikey == NULL ||
241 random_get_bytes(ikey, hapd->conf->individual_wep_key_len))
242 {
243 wpa_printf(MSG_ERROR, "Could not generate random "
244 "individual WEP key.");
245 os_free(ikey);
246 return;
247 }
248
249 wpa_hexdump_key(MSG_DEBUG, "Individual WEP key",
250 ikey, hapd->conf->individual_wep_key_len);
251
252 ieee802_1x_tx_key_one(hapd, sta, 0, 0, ikey,
253 hapd->conf->individual_wep_key_len);
254
255 /* TODO: set encryption in TX callback, i.e., only after STA
256 * has ACKed EAPOL-Key frame */
257 if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
258 sta->addr, 0, 1, NULL, 0, ikey,
259 hapd->conf->individual_wep_key_len)) {
260 wpa_printf(MSG_ERROR, "Could not set individual WEP "
261 "encryption.");
262 }
263
264 os_free(ikey);
265 }
266 }
267
268 #endif /* CONFIG_NO_RC4 */
269 #endif /* CONFIG_FIPS */
270
271
272 const char *radius_mode_txt(struct hostapd_data *hapd)
273 {
274 switch (hapd->iface->conf->hw_mode) {
275 case HOSTAPD_MODE_IEEE80211AD:
276 return "802.11ad";
277 case HOSTAPD_MODE_IEEE80211A:
278 return "802.11a";
279 case HOSTAPD_MODE_IEEE80211G:
280 return "802.11g";
281 case HOSTAPD_MODE_IEEE80211B:
282 default:
283 return "802.11b";
284 }
285 }
286
287
288 int radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta)
289 {
290 int i;
291 u8 rate = 0;
292
293 for (i = 0; i < sta->supported_rates_len; i++)
294 if ((sta->supported_rates[i] & 0x7f) > rate)
295 rate = sta->supported_rates[i] & 0x7f;
296
297 return rate;
298 }
299
300
301 #ifndef CONFIG_NO_RADIUS
302 static void ieee802_1x_learn_identity(struct hostapd_data *hapd,
303 struct eapol_state_machine *sm,
304 const u8 *eap, size_t len)
305 {
306 const u8 *identity;
307 size_t identity_len;
308 const struct eap_hdr *hdr = (const struct eap_hdr *) eap;
309
310 if (len <= sizeof(struct eap_hdr) ||
311 (hdr->code == EAP_CODE_RESPONSE &&
312 eap[sizeof(struct eap_hdr)] != EAP_TYPE_IDENTITY) ||
313 (hdr->code == EAP_CODE_INITIATE &&
314 eap[sizeof(struct eap_hdr)] != EAP_ERP_TYPE_REAUTH) ||
315 (hdr->code != EAP_CODE_RESPONSE &&
316 hdr->code != EAP_CODE_INITIATE))
317 return;
318
319 identity = eap_get_identity(sm->eap, &identity_len);
320 if (identity == NULL)
321 return;
322
323 /* Save station identity for future RADIUS packets */
324 os_free(sm->identity);
325 sm->identity = (u8 *) dup_binstr(identity, identity_len);
326 if (sm->identity == NULL) {
327 sm->identity_len = 0;
328 return;
329 }
330
331 sm->identity_len = identity_len;
332 hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
333 HOSTAPD_LEVEL_DEBUG, "STA identity '%s'", sm->identity);
334 sm->dot1xAuthEapolRespIdFramesRx++;
335 }
336
337
338 static int add_common_radius_sta_attr_rsn(struct hostapd_data *hapd,
339 struct hostapd_radius_attr *req_attr,
340 struct sta_info *sta,
341 struct radius_msg *msg)
342 {
343 u32 suite;
344 int ver, val;
345
346 ver = wpa_auth_sta_wpa_version(sta->wpa_sm);
347 val = wpa_auth_get_pairwise(sta->wpa_sm);
348 suite = wpa_cipher_to_suite(ver, val);
349 if (val != -1 &&
350 !hostapd_config_get_radius_attr(req_attr,
351 RADIUS_ATTR_WLAN_PAIRWISE_CIPHER) &&
352 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_PAIRWISE_CIPHER,
353 suite)) {
354 wpa_printf(MSG_ERROR, "Could not add WLAN-Pairwise-Cipher");
355 return -1;
356 }
357
358 suite = wpa_cipher_to_suite(((hapd->conf->wpa & 0x2) ||
359 hapd->conf->osen) ?
360 WPA_PROTO_RSN : WPA_PROTO_WPA,
361 hapd->conf->wpa_group);
362 if (!hostapd_config_get_radius_attr(req_attr,
363 RADIUS_ATTR_WLAN_GROUP_CIPHER) &&
364 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_GROUP_CIPHER,
365 suite)) {
366 wpa_printf(MSG_ERROR, "Could not add WLAN-Group-Cipher");
367 return -1;
368 }
369
370 val = wpa_auth_sta_key_mgmt(sta->wpa_sm);
371 suite = wpa_akm_to_suite(val);
372 if (val != -1 &&
373 !hostapd_config_get_radius_attr(req_attr,
374 RADIUS_ATTR_WLAN_AKM_SUITE) &&
375 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_AKM_SUITE,
376 suite)) {
377 wpa_printf(MSG_ERROR, "Could not add WLAN-AKM-Suite");
378 return -1;
379 }
380
381 #ifdef CONFIG_IEEE80211W
382 if (hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
383 suite = wpa_cipher_to_suite(WPA_PROTO_RSN,
384 hapd->conf->group_mgmt_cipher);
385 if (!hostapd_config_get_radius_attr(
386 req_attr, RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER) &&
387 !radius_msg_add_attr_int32(
388 msg, RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER, suite)) {
389 wpa_printf(MSG_ERROR,
390 "Could not add WLAN-Group-Mgmt-Cipher");
391 return -1;
392 }
393 }
394 #endif /* CONFIG_IEEE80211W */
395
396 return 0;
397 }
398
399
400 static int add_common_radius_sta_attr(struct hostapd_data *hapd,
401 struct hostapd_radius_attr *req_attr,
402 struct sta_info *sta,
403 struct radius_msg *msg)
404 {
405 char buf[128];
406
407 if (!hostapd_config_get_radius_attr(req_attr,
408 RADIUS_ATTR_NAS_PORT) &&
409 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
410 wpa_printf(MSG_ERROR, "Could not add NAS-Port");
411 return -1;
412 }
413
414 os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
415 MAC2STR(sta->addr));
416 buf[sizeof(buf) - 1] = '\0';
417 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
418 (u8 *) buf, os_strlen(buf))) {
419 wpa_printf(MSG_ERROR, "Could not add Calling-Station-Id");
420 return -1;
421 }
422
423 if (sta->flags & WLAN_STA_PREAUTH) {
424 os_strlcpy(buf, "IEEE 802.11i Pre-Authentication",
425 sizeof(buf));
426 } else {
427 os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s",
428 radius_sta_rate(hapd, sta) / 2,
429 (radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
430 radius_mode_txt(hapd));
431 buf[sizeof(buf) - 1] = '\0';
432 }
433 if (!hostapd_config_get_radius_attr(req_attr,
434 RADIUS_ATTR_CONNECT_INFO) &&
435 !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
436 (u8 *) buf, os_strlen(buf))) {
437 wpa_printf(MSG_ERROR, "Could not add Connect-Info");
438 return -1;
439 }
440
441 if (sta->acct_session_id) {
442 os_snprintf(buf, sizeof(buf), "%016lX",
443 (long unsigned int) sta->acct_session_id);
444 if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
445 (u8 *) buf, os_strlen(buf))) {
446 wpa_printf(MSG_ERROR, "Could not add Acct-Session-Id");
447 return -1;
448 }
449 }
450
451 #ifdef CONFIG_IEEE80211R
452 if (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
453 sta->wpa_sm &&
454 (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm)) ||
455 sta->auth_alg == WLAN_AUTH_FT) &&
456 !hostapd_config_get_radius_attr(req_attr,
457 RADIUS_ATTR_MOBILITY_DOMAIN_ID) &&
458 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_MOBILITY_DOMAIN_ID,
459 WPA_GET_BE16(
460 hapd->conf->mobility_domain))) {
461 wpa_printf(MSG_ERROR, "Could not add Mobility-Domain-Id");
462 return -1;
463 }
464 #endif /* CONFIG_IEEE80211R */
465
466 if ((hapd->conf->wpa || hapd->conf->osen) && sta->wpa_sm &&
467 add_common_radius_sta_attr_rsn(hapd, req_attr, sta, msg) < 0)
468 return -1;
469
470 return 0;
471 }
472
473
474 int add_common_radius_attr(struct hostapd_data *hapd,
475 struct hostapd_radius_attr *req_attr,
476 struct sta_info *sta,
477 struct radius_msg *msg)
478 {
479 char buf[128];
480 struct hostapd_radius_attr *attr;
481 int len;
482
483 if (!hostapd_config_get_radius_attr(req_attr,
484 RADIUS_ATTR_NAS_IP_ADDRESS) &&
485 hapd->conf->own_ip_addr.af == AF_INET &&
486 !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
487 (u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) {
488 wpa_printf(MSG_ERROR, "Could not add NAS-IP-Address");
489 return -1;
490 }
491
492 #ifdef CONFIG_IPV6
493 if (!hostapd_config_get_radius_attr(req_attr,
494 RADIUS_ATTR_NAS_IPV6_ADDRESS) &&
495 hapd->conf->own_ip_addr.af == AF_INET6 &&
496 !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS,
497 (u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) {
498 wpa_printf(MSG_ERROR, "Could not add NAS-IPv6-Address");
499 return -1;
500 }
501 #endif /* CONFIG_IPV6 */
502
503 if (!hostapd_config_get_radius_attr(req_attr,
504 RADIUS_ATTR_NAS_IDENTIFIER) &&
505 hapd->conf->nas_identifier &&
506 !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
507 (u8 *) hapd->conf->nas_identifier,
508 os_strlen(hapd->conf->nas_identifier))) {
509 wpa_printf(MSG_ERROR, "Could not add NAS-Identifier");
510 return -1;
511 }
512
513 len = os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":",
514 MAC2STR(hapd->own_addr));
515 os_memcpy(&buf[len], hapd->conf->ssid.ssid,
516 hapd->conf->ssid.ssid_len);
517 len += hapd->conf->ssid.ssid_len;
518 if (!hostapd_config_get_radius_attr(req_attr,
519 RADIUS_ATTR_CALLED_STATION_ID) &&
520 !radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
521 (u8 *) buf, len)) {
522 wpa_printf(MSG_ERROR, "Could not add Called-Station-Id");
523 return -1;
524 }
525
526 if (!hostapd_config_get_radius_attr(req_attr,
527 RADIUS_ATTR_NAS_PORT_TYPE) &&
528 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
529 RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
530 wpa_printf(MSG_ERROR, "Could not add NAS-Port-Type");
531 return -1;
532 }
533
534 #ifdef CONFIG_INTERWORKING
535 if (hapd->conf->interworking &&
536 !is_zero_ether_addr(hapd->conf->hessid)) {
537 os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
538 MAC2STR(hapd->conf->hessid));
539 buf[sizeof(buf) - 1] = '\0';
540 if (!hostapd_config_get_radius_attr(req_attr,
541 RADIUS_ATTR_WLAN_HESSID) &&
542 !radius_msg_add_attr(msg, RADIUS_ATTR_WLAN_HESSID,
543 (u8 *) buf, os_strlen(buf))) {
544 wpa_printf(MSG_ERROR, "Could not add WLAN-HESSID");
545 return -1;
546 }
547 }
548 #endif /* CONFIG_INTERWORKING */
549
550 if (sta && add_common_radius_sta_attr(hapd, req_attr, sta, msg) < 0)
551 return -1;
552
553 for (attr = req_attr; attr; attr = attr->next) {
554 if (!radius_msg_add_attr(msg, attr->type,
555 wpabuf_head(attr->val),
556 wpabuf_len(attr->val))) {
557 wpa_printf(MSG_ERROR, "Could not add RADIUS "
558 "attribute");
559 return -1;
560 }
561 }
562
563 return 0;
564 }
565
566
567 static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
568 struct sta_info *sta,
569 const u8 *eap, size_t len)
570 {
571 struct radius_msg *msg;
572 struct eapol_state_machine *sm = sta->eapol_sm;
573
574 if (sm == NULL)
575 return;
576
577 ieee802_1x_learn_identity(hapd, sm, eap, len);
578
579 wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS "
580 "packet");
581
582 sm->radius_identifier = radius_client_get_id(hapd->radius);
583 msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST,
584 sm->radius_identifier);
585 if (msg == NULL) {
586 wpa_printf(MSG_INFO, "Could not create new RADIUS packet");
587 return;
588 }
589
590 radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
591
592 if (sm->identity &&
593 !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
594 sm->identity, sm->identity_len)) {
595 wpa_printf(MSG_INFO, "Could not add User-Name");
596 goto fail;
597 }
598
599 if (add_common_radius_attr(hapd, hapd->conf->radius_auth_req_attr, sta,
600 msg) < 0)
601 goto fail;
602
603 /* TODO: should probably check MTU from driver config; 2304 is max for
604 * IEEE 802.11, but use 1400 to avoid problems with too large packets
605 */
606 if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
607 RADIUS_ATTR_FRAMED_MTU) &&
608 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) {
609 wpa_printf(MSG_INFO, "Could not add Framed-MTU");
610 goto fail;
611 }
612
613 if (!radius_msg_add_eap(msg, eap, len)) {
614 wpa_printf(MSG_INFO, "Could not add EAP-Message");
615 goto fail;
616 }
617
618 /* State attribute must be copied if and only if this packet is
619 * Access-Request reply to the previous Access-Challenge */
620 if (sm->last_recv_radius &&
621 radius_msg_get_hdr(sm->last_recv_radius)->code ==
622 RADIUS_CODE_ACCESS_CHALLENGE) {
623 int res = radius_msg_copy_attr(msg, sm->last_recv_radius,
624 RADIUS_ATTR_STATE);
625 if (res < 0) {
626 wpa_printf(MSG_INFO, "Could not copy State attribute from previous Access-Challenge");
627 goto fail;
628 }
629 if (res > 0) {
630 wpa_printf(MSG_DEBUG, "Copied RADIUS State Attribute");
631 }
632 }
633
634 if (hapd->conf->radius_request_cui) {
635 const u8 *cui;
636 size_t cui_len;
637 /* Add previously learned CUI or nul CUI to request CUI */
638 if (sm->radius_cui) {
639 cui = wpabuf_head(sm->radius_cui);
640 cui_len = wpabuf_len(sm->radius_cui);
641 } else {
642 cui = (const u8 *) "\0";
643 cui_len = 1;
644 }
645 if (!radius_msg_add_attr(msg,
646 RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
647 cui, cui_len)) {
648 wpa_printf(MSG_ERROR, "Could not add CUI");
649 goto fail;
650 }
651 }
652
653 #ifdef CONFIG_HS20
654 if (hapd->conf->hs20) {
655 u8 ver = 1; /* Release 2 */
656 if (!radius_msg_add_wfa(
657 msg, RADIUS_VENDOR_ATTR_WFA_HS20_AP_VERSION,
658 &ver, 1)) {
659 wpa_printf(MSG_ERROR, "Could not add HS 2.0 AP "
660 "version");
661 goto fail;
662 }
663
664 if (sta->hs20_ie && wpabuf_len(sta->hs20_ie) > 0) {
665 const u8 *pos;
666 u8 buf[3];
667 u16 id;
668 pos = wpabuf_head_u8(sta->hs20_ie);
669 buf[0] = (*pos) >> 4;
670 if (((*pos) & HS20_PPS_MO_ID_PRESENT) &&
671 wpabuf_len(sta->hs20_ie) >= 3)
672 id = WPA_GET_LE16(pos + 1);
673 else
674 id = 0;
675 WPA_PUT_BE16(buf + 1, id);
676 if (!radius_msg_add_wfa(
677 msg,
678 RADIUS_VENDOR_ATTR_WFA_HS20_STA_VERSION,
679 buf, sizeof(buf))) {
680 wpa_printf(MSG_ERROR, "Could not add HS 2.0 "
681 "STA version");
682 goto fail;
683 }
684 }
685 }
686 #endif /* CONFIG_HS20 */
687
688 if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, sta->addr) < 0)
689 goto fail;
690
691 return;
692
693 fail:
694 radius_msg_free(msg);
695 }
696 #endif /* CONFIG_NO_RADIUS */
697
698
699 static void handle_eap_response(struct hostapd_data *hapd,
700 struct sta_info *sta, struct eap_hdr *eap,
701 size_t len)
702 {
703 u8 type, *data;
704 struct eapol_state_machine *sm = sta->eapol_sm;
705 if (sm == NULL)
706 return;
707
708 data = (u8 *) (eap + 1);
709
710 if (len < sizeof(*eap) + 1) {
711 wpa_printf(MSG_INFO, "handle_eap_response: too short response data");
712 return;
713 }
714
715 sm->eap_type_supp = type = data[0];
716
717 hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
718 HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d "
719 "id=%d len=%d) from STA: EAP Response-%s (%d)",
720 eap->code, eap->identifier, be_to_host16(eap->length),
721 eap_server_get_name(0, type), type);
722
723 sm->dot1xAuthEapolRespFramesRx++;
724
725 wpabuf_free(sm->eap_if->eapRespData);
726 sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len);
727 sm->eapolEap = TRUE;
728 }
729
730
731 static void handle_eap_initiate(struct hostapd_data *hapd,
732 struct sta_info *sta, struct eap_hdr *eap,
733 size_t len)
734 {
735 #ifdef CONFIG_ERP
736 u8 type, *data;
737 struct eapol_state_machine *sm = sta->eapol_sm;
738
739 if (sm == NULL)
740 return;
741
742 if (len < sizeof(*eap) + 1) {
743 wpa_printf(MSG_INFO,
744 "handle_eap_initiate: too short response data");
745 return;
746 }
747
748 data = (u8 *) (eap + 1);
749 type = data[0];
750
751 hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
752 HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d "
753 "id=%d len=%d) from STA: EAP Initiate type %u",
754 eap->code, eap->identifier, be_to_host16(eap->length),
755 type);
756
757 wpabuf_free(sm->eap_if->eapRespData);
758 sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len);
759 sm->eapolEap = TRUE;
760 #endif /* CONFIG_ERP */
761 }
762
763
764 /* Process incoming EAP packet from Supplicant */
765 static void handle_eap(struct hostapd_data *hapd, struct sta_info *sta,
766 u8 *buf, size_t len)
767 {
768 struct eap_hdr *eap;
769 u16 eap_len;
770
771 if (len < sizeof(*eap)) {
772 wpa_printf(MSG_INFO, " too short EAP packet");
773 return;
774 }
775
776 eap = (struct eap_hdr *) buf;
777
778 eap_len = be_to_host16(eap->length);
779 wpa_printf(MSG_DEBUG, "EAP: code=%d identifier=%d length=%d",
780 eap->code, eap->identifier, eap_len);
781 if (eap_len < sizeof(*eap)) {
782 wpa_printf(MSG_DEBUG, " Invalid EAP length");
783 return;
784 } else if (eap_len > len) {
785 wpa_printf(MSG_DEBUG, " Too short frame to contain this EAP "
786 "packet");
787 return;
788 } else if (eap_len < len) {
789 wpa_printf(MSG_DEBUG, " Ignoring %lu extra bytes after EAP "
790 "packet", (unsigned long) len - eap_len);
791 }
792
793 switch (eap->code) {
794 case EAP_CODE_REQUEST:
795 wpa_printf(MSG_DEBUG, " (request)");
796 return;
797 case EAP_CODE_RESPONSE:
798 wpa_printf(MSG_DEBUG, " (response)");
799 handle_eap_response(hapd, sta, eap, eap_len);
800 break;
801 case EAP_CODE_SUCCESS:
802 wpa_printf(MSG_DEBUG, " (success)");
803 return;
804 case EAP_CODE_FAILURE:
805 wpa_printf(MSG_DEBUG, " (failure)");
806 return;
807 case EAP_CODE_INITIATE:
808 wpa_printf(MSG_DEBUG, " (initiate)");
809 handle_eap_initiate(hapd, sta, eap, eap_len);
810 break;
811 case EAP_CODE_FINISH:
812 wpa_printf(MSG_DEBUG, " (finish)");
813 break;
814 default:
815 wpa_printf(MSG_DEBUG, " (unknown code)");
816 return;
817 }
818 }
819
820
821 static struct eapol_state_machine *
822 ieee802_1x_alloc_eapol_sm(struct hostapd_data *hapd, struct sta_info *sta)
823 {
824 int flags = 0;
825 if (sta->flags & WLAN_STA_PREAUTH)
826 flags |= EAPOL_SM_PREAUTH;
827 if (sta->wpa_sm) {
828 flags |= EAPOL_SM_USES_WPA;
829 if (wpa_auth_sta_get_pmksa(sta->wpa_sm))
830 flags |= EAPOL_SM_FROM_PMKSA_CACHE;
831 }
832 return eapol_auth_alloc(hapd->eapol_auth, sta->addr, flags,
833 sta->wps_ie, sta->p2p_ie, sta,
834 sta->identity, sta->radius_cui);
835 }
836
837
838 /**
839 * ieee802_1x_receive - Process the EAPOL frames from the Supplicant
840 * @hapd: hostapd BSS data
841 * @sa: Source address (sender of the EAPOL frame)
842 * @buf: EAPOL frame
843 * @len: Length of buf in octets
844 *
845 * This function is called for each incoming EAPOL frame from the interface
846 */
847 void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
848 size_t len)
849 {
850 struct sta_info *sta;
851 struct ieee802_1x_hdr *hdr;
852 struct ieee802_1x_eapol_key *key;
853 u16 datalen;
854 struct rsn_pmksa_cache_entry *pmksa;
855 int key_mgmt;
856
857 if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen &&
858 !hapd->conf->wps_state)
859 return;
860
861 wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR,
862 (unsigned long) len, MAC2STR(sa));
863 sta = ap_get_sta(hapd, sa);
864 if (!sta || (!(sta->flags & (WLAN_STA_ASSOC | WLAN_STA_PREAUTH)) &&
865 !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED))) {
866 wpa_printf(MSG_DEBUG, "IEEE 802.1X data frame from not "
867 "associated/Pre-authenticating STA");
868 return;
869 }
870
871 if (len < sizeof(*hdr)) {
872 wpa_printf(MSG_INFO, " too short IEEE 802.1X packet");
873 return;
874 }
875
876 hdr = (struct ieee802_1x_hdr *) buf;
877 datalen = be_to_host16(hdr->length);
878 wpa_printf(MSG_DEBUG, " IEEE 802.1X: version=%d type=%d length=%d",
879 hdr->version, hdr->type, datalen);
880
881 if (len - sizeof(*hdr) < datalen) {
882 wpa_printf(MSG_INFO, " frame too short for this IEEE 802.1X packet");
883 if (sta->eapol_sm)
884 sta->eapol_sm->dot1xAuthEapLengthErrorFramesRx++;
885 return;
886 }
887 if (len - sizeof(*hdr) > datalen) {
888 wpa_printf(MSG_DEBUG, " ignoring %lu extra octets after "
889 "IEEE 802.1X packet",
890 (unsigned long) len - sizeof(*hdr) - datalen);
891 }
892
893 if (sta->eapol_sm) {
894 sta->eapol_sm->dot1xAuthLastEapolFrameVersion = hdr->version;
895 sta->eapol_sm->dot1xAuthEapolFramesRx++;
896 }
897
898 key = (struct ieee802_1x_eapol_key *) (hdr + 1);
899 if (datalen >= sizeof(struct ieee802_1x_eapol_key) &&
900 hdr->type == IEEE802_1X_TYPE_EAPOL_KEY &&
901 (key->type == EAPOL_KEY_TYPE_WPA ||
902 key->type == EAPOL_KEY_TYPE_RSN)) {
903 wpa_receive(hapd->wpa_auth, sta->wpa_sm, (u8 *) hdr,
904 sizeof(*hdr) + datalen);
905 return;
906 }
907
908 if (!hapd->conf->ieee802_1x && !hapd->conf->osen &&
909 !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) {
910 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore EAPOL message - "
911 "802.1X not enabled and WPS not used");
912 return;
913 }
914
915 key_mgmt = wpa_auth_sta_key_mgmt(sta->wpa_sm);
916 if (key_mgmt != -1 && wpa_key_mgmt_wpa_psk(key_mgmt)) {
917 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore EAPOL message - "
918 "STA is using PSK");
919 return;
920 }
921
922 if (!sta->eapol_sm) {
923 sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta);
924 if (!sta->eapol_sm)
925 return;
926
927 #ifdef CONFIG_WPS
928 if (!hapd->conf->ieee802_1x && hapd->conf->wps_state) {
929 u32 wflags = sta->flags & (WLAN_STA_WPS |
930 WLAN_STA_WPS2 |
931 WLAN_STA_MAYBE_WPS);
932 if (wflags == WLAN_STA_MAYBE_WPS ||
933 wflags == (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) {
934 /*
935 * Delay EAPOL frame transmission until a
936 * possible WPS STA initiates the handshake
937 * with EAPOL-Start. Only allow the wait to be
938 * skipped if the STA is known to support WPS
939 * 2.0.
940 */
941 wpa_printf(MSG_DEBUG, "WPS: Do not start "
942 "EAPOL until EAPOL-Start is "
943 "received");
944 sta->eapol_sm->flags |= EAPOL_SM_WAIT_START;
945 }
946 }
947 #endif /* CONFIG_WPS */
948
949 sta->eapol_sm->eap_if->portEnabled = TRUE;
950 }
951
952 /* since we support version 1, we can ignore version field and proceed
953 * as specified in version 1 standard [IEEE Std 802.1X-2001, 7.5.5] */
954 /* TODO: actually, we are not version 1 anymore.. However, Version 2
955 * does not change frame contents, so should be ok to process frames
956 * more or less identically. Some changes might be needed for
957 * verification of fields. */
958
959 switch (hdr->type) {
960 case IEEE802_1X_TYPE_EAP_PACKET:
961 handle_eap(hapd, sta, (u8 *) (hdr + 1), datalen);
962 break;
963
964 case IEEE802_1X_TYPE_EAPOL_START:
965 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
966 HOSTAPD_LEVEL_DEBUG, "received EAPOL-Start "
967 "from STA");
968 sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START;
969 pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
970 if (pmksa) {
971 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
972 HOSTAPD_LEVEL_DEBUG, "cached PMKSA "
973 "available - ignore it since "
974 "STA sent EAPOL-Start");
975 wpa_auth_sta_clear_pmksa(sta->wpa_sm, pmksa);
976 }
977 sta->eapol_sm->eapolStart = TRUE;
978 sta->eapol_sm->dot1xAuthEapolStartFramesRx++;
979 eap_server_clear_identity(sta->eapol_sm->eap);
980 wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL);
981 break;
982
983 case IEEE802_1X_TYPE_EAPOL_LOGOFF:
984 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
985 HOSTAPD_LEVEL_DEBUG, "received EAPOL-Logoff "
986 "from STA");
987 sta->acct_terminate_cause =
988 RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
989 accounting_sta_stop(hapd, sta);
990 sta->eapol_sm->eapolLogoff = TRUE;
991 sta->eapol_sm->dot1xAuthEapolLogoffFramesRx++;
992 eap_server_clear_identity(sta->eapol_sm->eap);
993 break;
994
995 case IEEE802_1X_TYPE_EAPOL_KEY:
996 wpa_printf(MSG_DEBUG, " EAPOL-Key");
997 if (!ap_sta_is_authorized(sta)) {
998 wpa_printf(MSG_DEBUG, " Dropped key data from "
999 "unauthorized Supplicant");
1000 break;
1001 }
1002 break;
1003
1004 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
1005 wpa_printf(MSG_DEBUG, " EAPOL-Encapsulated-ASF-Alert");
1006 /* TODO: implement support for this; show data */
1007 break;
1008
1009 default:
1010 wpa_printf(MSG_DEBUG, " unknown IEEE 802.1X packet type");
1011 sta->eapol_sm->dot1xAuthInvalidEapolFramesRx++;
1012 break;
1013 }
1014
1015 eapol_auth_step(sta->eapol_sm);
1016 }
1017
1018
1019 /**
1020 * ieee802_1x_new_station - Start IEEE 802.1X authentication
1021 * @hapd: hostapd BSS data
1022 * @sta: The station
1023 *
1024 * This function is called to start IEEE 802.1X authentication when a new
1025 * station completes IEEE 802.11 association.
1026 */
1027 void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
1028 {
1029 struct rsn_pmksa_cache_entry *pmksa;
1030 int reassoc = 1;
1031 int force_1x = 0;
1032 int key_mgmt;
1033
1034 #ifdef CONFIG_WPS
1035 if (hapd->conf->wps_state &&
1036 ((hapd->conf->wpa && (sta->flags & WLAN_STA_MAYBE_WPS)) ||
1037 (sta->flags & WLAN_STA_WPS))) {
1038 /*
1039 * Need to enable IEEE 802.1X/EAPOL state machines for possible
1040 * WPS handshake even if IEEE 802.1X/EAPOL is not used for
1041 * authentication in this BSS.
1042 */
1043 force_1x = 1;
1044 }
1045 #endif /* CONFIG_WPS */
1046
1047 if (!force_1x && !hapd->conf->ieee802_1x && !hapd->conf->osen) {
1048 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore STA - "
1049 "802.1X not enabled or forced for WPS");
1050 /*
1051 * Clear any possible EAPOL authenticator state to support
1052 * reassociation change from WPS to PSK.
1053 */
1054 ieee802_1x_free_station(hapd, sta);
1055 return;
1056 }
1057
1058 key_mgmt = wpa_auth_sta_key_mgmt(sta->wpa_sm);
1059 if (key_mgmt != -1 && wpa_key_mgmt_wpa_psk(key_mgmt)) {
1060 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore STA - using PSK");
1061 /*
1062 * Clear any possible EAPOL authenticator state to support
1063 * reassociation change from WPA-EAP to PSK.
1064 */
1065 ieee802_1x_free_station(hapd, sta);
1066 return;
1067 }
1068
1069 if (sta->eapol_sm == NULL) {
1070 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1071 HOSTAPD_LEVEL_DEBUG, "start authentication");
1072 sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta);
1073 if (sta->eapol_sm == NULL) {
1074 hostapd_logger(hapd, sta->addr,
1075 HOSTAPD_MODULE_IEEE8021X,
1076 HOSTAPD_LEVEL_INFO,
1077 "failed to allocate state machine");
1078 return;
1079 }
1080 reassoc = 0;
1081 }
1082
1083 #ifdef CONFIG_WPS
1084 sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START;
1085 if (!hapd->conf->ieee802_1x && hapd->conf->wps_state &&
1086 !(sta->flags & WLAN_STA_WPS2)) {
1087 /*
1088 * Delay EAPOL frame transmission until a possible WPS STA
1089 * initiates the handshake with EAPOL-Start. Only allow the
1090 * wait to be skipped if the STA is known to support WPS 2.0.
1091 */
1092 wpa_printf(MSG_DEBUG, "WPS: Do not start EAPOL until "
1093 "EAPOL-Start is received");
1094 sta->eapol_sm->flags |= EAPOL_SM_WAIT_START;
1095 }
1096 #endif /* CONFIG_WPS */
1097
1098 sta->eapol_sm->eap_if->portEnabled = TRUE;
1099
1100 #ifdef CONFIG_IEEE80211R
1101 if (sta->auth_alg == WLAN_AUTH_FT) {
1102 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1103 HOSTAPD_LEVEL_DEBUG,
1104 "PMK from FT - skip IEEE 802.1X/EAP");
1105 /* Setup EAPOL state machines to already authenticated state
1106 * because of existing FT information from R0KH. */
1107 sta->eapol_sm->keyRun = TRUE;
1108 sta->eapol_sm->eap_if->eapKeyAvailable = TRUE;
1109 sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING;
1110 sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS;
1111 sta->eapol_sm->authSuccess = TRUE;
1112 sta->eapol_sm->authFail = FALSE;
1113 sta->eapol_sm->portValid = TRUE;
1114 if (sta->eapol_sm->eap)
1115 eap_sm_notify_cached(sta->eapol_sm->eap);
1116 /* TODO: get vlan_id from R0KH using RRB message */
1117 return;
1118 }
1119 #endif /* CONFIG_IEEE80211R */
1120
1121 pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
1122 if (pmksa) {
1123 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1124 HOSTAPD_LEVEL_DEBUG,
1125 "PMK from PMKSA cache - skip IEEE 802.1X/EAP");
1126 /* Setup EAPOL state machines to already authenticated state
1127 * because of existing PMKSA information in the cache. */
1128 sta->eapol_sm->keyRun = TRUE;
1129 sta->eapol_sm->eap_if->eapKeyAvailable = TRUE;
1130 sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING;
1131 sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS;
1132 sta->eapol_sm->authSuccess = TRUE;
1133 sta->eapol_sm->authFail = FALSE;
1134 if (sta->eapol_sm->eap)
1135 eap_sm_notify_cached(sta->eapol_sm->eap);
1136 pmksa_cache_to_eapol_data(pmksa, sta->eapol_sm);
1137 ap_sta_bind_vlan(hapd, sta);
1138 } else {
1139 if (reassoc) {
1140 /*
1141 * Force EAPOL state machines to start
1142 * re-authentication without having to wait for the
1143 * Supplicant to send EAPOL-Start.
1144 */
1145 sta->eapol_sm->reAuthenticate = TRUE;
1146 }
1147 eapol_auth_step(sta->eapol_sm);
1148 }
1149 }
1150
1151
1152 void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta)
1153 {
1154 struct eapol_state_machine *sm = sta->eapol_sm;
1155
1156 #ifdef CONFIG_HS20
1157 eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta);
1158 #endif /* CONFIG_HS20 */
1159
1160 if (sm == NULL)
1161 return;
1162
1163 sta->eapol_sm = NULL;
1164
1165 #ifndef CONFIG_NO_RADIUS
1166 radius_msg_free(sm->last_recv_radius);
1167 radius_free_class(&sm->radius_class);
1168 #endif /* CONFIG_NO_RADIUS */
1169
1170 eapol_auth_free(sm);
1171 }
1172
1173
1174 #ifndef CONFIG_NO_RADIUS
1175 static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
1176 struct sta_info *sta)
1177 {
1178 struct wpabuf *eap;
1179 const struct eap_hdr *hdr;
1180 int eap_type = -1;
1181 char buf[64];
1182 struct radius_msg *msg;
1183 struct eapol_state_machine *sm = sta->eapol_sm;
1184
1185 if (sm == NULL || sm->last_recv_radius == NULL) {
1186 if (sm)
1187 sm->eap_if->aaaEapNoReq = TRUE;
1188 return;
1189 }
1190
1191 msg = sm->last_recv_radius;
1192
1193 eap = radius_msg_get_eap(msg);
1194 if (eap == NULL) {
1195 /* RFC 3579, Chap. 2.6.3:
1196 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
1197 * attribute */
1198 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1199 HOSTAPD_LEVEL_WARNING, "could not extract "
1200 "EAP-Message from RADIUS message");
1201 sm->eap_if->aaaEapNoReq = TRUE;
1202 return;
1203 }
1204
1205 if (wpabuf_len(eap) < sizeof(*hdr)) {
1206 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1207 HOSTAPD_LEVEL_WARNING, "too short EAP packet "
1208 "received from authentication server");
1209 wpabuf_free(eap);
1210 sm->eap_if->aaaEapNoReq = TRUE;
1211 return;
1212 }
1213
1214 if (wpabuf_len(eap) > sizeof(*hdr))
1215 eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)];
1216
1217 hdr = wpabuf_head(eap);
1218 switch (hdr->code) {
1219 case EAP_CODE_REQUEST:
1220 if (eap_type >= 0)
1221 sm->eap_type_authsrv = eap_type;
1222 os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
1223 eap_server_get_name(0, eap_type), eap_type);
1224 break;
1225 case EAP_CODE_RESPONSE:
1226 os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)",
1227 eap_server_get_name(0, eap_type), eap_type);
1228 break;
1229 case EAP_CODE_SUCCESS:
1230 os_strlcpy(buf, "EAP Success", sizeof(buf));
1231 break;
1232 case EAP_CODE_FAILURE:
1233 os_strlcpy(buf, "EAP Failure", sizeof(buf));
1234 break;
1235 default:
1236 os_strlcpy(buf, "unknown EAP code", sizeof(buf));
1237 break;
1238 }
1239 buf[sizeof(buf) - 1] = '\0';
1240 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1241 HOSTAPD_LEVEL_DEBUG, "decapsulated EAP packet (code=%d "
1242 "id=%d len=%d) from RADIUS server: %s",
1243 hdr->code, hdr->identifier, be_to_host16(hdr->length),
1244 buf);
1245 sm->eap_if->aaaEapReq = TRUE;
1246
1247 wpabuf_free(sm->eap_if->aaaEapReqData);
1248 sm->eap_if->aaaEapReqData = eap;
1249 }
1250
1251
1252 static void ieee802_1x_get_keys(struct hostapd_data *hapd,
1253 struct sta_info *sta, struct radius_msg *msg,
1254 struct radius_msg *req,
1255 const u8 *shared_secret,
1256 size_t shared_secret_len)
1257 {
1258 struct radius_ms_mppe_keys *keys;
1259 struct eapol_state_machine *sm = sta->eapol_sm;
1260 if (sm == NULL)
1261 return;
1262
1263 keys = radius_msg_get_ms_keys(msg, req, shared_secret,
1264 shared_secret_len);
1265
1266 if (keys && keys->send && keys->recv) {
1267 size_t len = keys->send_len + keys->recv_len;
1268 wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Send-Key",
1269 keys->send, keys->send_len);
1270 wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Recv-Key",
1271 keys->recv, keys->recv_len);
1272
1273 os_free(sm->eap_if->aaaEapKeyData);
1274 sm->eap_if->aaaEapKeyData = os_malloc(len);
1275 if (sm->eap_if->aaaEapKeyData) {
1276 os_memcpy(sm->eap_if->aaaEapKeyData, keys->recv,
1277 keys->recv_len);
1278 os_memcpy(sm->eap_if->aaaEapKeyData + keys->recv_len,
1279 keys->send, keys->send_len);
1280 sm->eap_if->aaaEapKeyDataLen = len;
1281 sm->eap_if->aaaEapKeyAvailable = TRUE;
1282 }
1283 } else {
1284 wpa_printf(MSG_DEBUG,
1285 "MS-MPPE: 1x_get_keys, could not get keys: %p send: %p recv: %p",
1286 keys, keys ? keys->send : NULL,
1287 keys ? keys->recv : NULL);
1288 }
1289
1290 if (keys) {
1291 os_free(keys->send);
1292 os_free(keys->recv);
1293 os_free(keys);
1294 }
1295 }
1296
1297
1298 static void ieee802_1x_store_radius_class(struct hostapd_data *hapd,
1299 struct sta_info *sta,
1300 struct radius_msg *msg)
1301 {
1302 u8 *attr_class;
1303 size_t class_len;
1304 struct eapol_state_machine *sm = sta->eapol_sm;
1305 int count, i;
1306 struct radius_attr_data *nclass;
1307 size_t nclass_count;
1308
1309 if (!hapd->conf->radius->acct_server || hapd->radius == NULL ||
1310 sm == NULL)
1311 return;
1312
1313 radius_free_class(&sm->radius_class);
1314 count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1);
1315 if (count <= 0)
1316 return;
1317
1318 nclass = os_calloc(count, sizeof(struct radius_attr_data));
1319 if (nclass == NULL)
1320 return;
1321
1322 nclass_count = 0;
1323
1324 attr_class = NULL;
1325 for (i = 0; i < count; i++) {
1326 do {
1327 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS,
1328 &attr_class, &class_len,
1329 attr_class) < 0) {
1330 i = count;
1331 break;
1332 }
1333 } while (class_len < 1);
1334
1335 nclass[nclass_count].data = os_malloc(class_len);
1336 if (nclass[nclass_count].data == NULL)
1337 break;
1338
1339 os_memcpy(nclass[nclass_count].data, attr_class, class_len);
1340 nclass[nclass_count].len = class_len;
1341 nclass_count++;
1342 }
1343
1344 sm->radius_class.attr = nclass;
1345 sm->radius_class.count = nclass_count;
1346 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Stored %lu RADIUS Class "
1347 "attributes for " MACSTR,
1348 (unsigned long) sm->radius_class.count,
1349 MAC2STR(sta->addr));
1350 }
1351
1352
1353 /* Update sta->identity based on User-Name attribute in Access-Accept */
1354 static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd,
1355 struct sta_info *sta,
1356 struct radius_msg *msg)
1357 {
1358 u8 *buf, *identity;
1359 size_t len;
1360 struct eapol_state_machine *sm = sta->eapol_sm;
1361
1362 if (sm == NULL)
1363 return;
1364
1365 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &buf, &len,
1366 NULL) < 0)
1367 return;
1368
1369 identity = (u8 *) dup_binstr(buf, len);
1370 if (identity == NULL)
1371 return;
1372
1373 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1374 HOSTAPD_LEVEL_DEBUG, "old identity '%s' updated with "
1375 "User-Name from Access-Accept '%s'",
1376 sm->identity ? (char *) sm->identity : "N/A",
1377 (char *) identity);
1378
1379 os_free(sm->identity);
1380 sm->identity = identity;
1381 sm->identity_len = len;
1382 }
1383
1384
1385 /* Update CUI based on Chargeable-User-Identity attribute in Access-Accept */
1386 static void ieee802_1x_update_sta_cui(struct hostapd_data *hapd,
1387 struct sta_info *sta,
1388 struct radius_msg *msg)
1389 {
1390 struct eapol_state_machine *sm = sta->eapol_sm;
1391 struct wpabuf *cui;
1392 u8 *buf;
1393 size_t len;
1394
1395 if (sm == NULL)
1396 return;
1397
1398 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
1399 &buf, &len, NULL) < 0)
1400 return;
1401
1402 cui = wpabuf_alloc_copy(buf, len);
1403 if (cui == NULL)
1404 return;
1405
1406 wpabuf_free(sm->radius_cui);
1407 sm->radius_cui = cui;
1408 }
1409
1410
1411 #ifdef CONFIG_HS20
1412
1413 static void ieee802_1x_hs20_sub_rem(struct sta_info *sta, u8 *pos, size_t len)
1414 {
1415 sta->remediation = 1;
1416 os_free(sta->remediation_url);
1417 if (len > 2) {
1418 sta->remediation_url = os_malloc(len);
1419 if (!sta->remediation_url)
1420 return;
1421 sta->remediation_method = pos[0];
1422 os_memcpy(sta->remediation_url, pos + 1, len - 1);
1423 sta->remediation_url[len - 1] = '\0';
1424 wpa_printf(MSG_DEBUG, "HS 2.0: Subscription remediation needed "
1425 "for " MACSTR " - server method %u URL %s",
1426 MAC2STR(sta->addr), sta->remediation_method,
1427 sta->remediation_url);
1428 } else {
1429 sta->remediation_url = NULL;
1430 wpa_printf(MSG_DEBUG, "HS 2.0: Subscription remediation needed "
1431 "for " MACSTR, MAC2STR(sta->addr));
1432 }
1433 /* TODO: assign the STA into remediation VLAN or add filtering */
1434 }
1435
1436
1437 static void ieee802_1x_hs20_deauth_req(struct hostapd_data *hapd,
1438 struct sta_info *sta, u8 *pos,
1439 size_t len)
1440 {
1441 if (len < 3)
1442 return; /* Malformed information */
1443 sta->hs20_deauth_requested = 1;
1444 wpa_printf(MSG_DEBUG, "HS 2.0: Deauthentication request - Code %u "
1445 "Re-auth Delay %u",
1446 *pos, WPA_GET_LE16(pos + 1));
1447 wpabuf_free(sta->hs20_deauth_req);
1448 sta->hs20_deauth_req = wpabuf_alloc(len + 1);
1449 if (sta->hs20_deauth_req) {
1450 wpabuf_put_data(sta->hs20_deauth_req, pos, 3);
1451 wpabuf_put_u8(sta->hs20_deauth_req, len - 3);
1452 wpabuf_put_data(sta->hs20_deauth_req, pos + 3, len - 3);
1453 }
1454 ap_sta_session_timeout(hapd, sta, hapd->conf->hs20_deauth_req_timeout);
1455 }
1456
1457
1458 static void ieee802_1x_hs20_session_info(struct hostapd_data *hapd,
1459 struct sta_info *sta, u8 *pos,
1460 size_t len, int session_timeout)
1461 {
1462 unsigned int swt;
1463 int warning_time, beacon_int;
1464
1465 if (len < 1)
1466 return; /* Malformed information */
1467 os_free(sta->hs20_session_info_url);
1468 sta->hs20_session_info_url = os_malloc(len);
1469 if (sta->hs20_session_info_url == NULL)
1470 return;
1471 swt = pos[0];
1472 os_memcpy(sta->hs20_session_info_url, pos + 1, len - 1);
1473 sta->hs20_session_info_url[len - 1] = '\0';
1474 wpa_printf(MSG_DEBUG, "HS 2.0: Session Information URL='%s' SWT=%u "
1475 "(session_timeout=%d)",
1476 sta->hs20_session_info_url, swt, session_timeout);
1477 if (session_timeout < 0) {
1478 wpa_printf(MSG_DEBUG, "HS 2.0: No Session-Timeout set - ignore session info URL");
1479 return;
1480 }
1481 if (swt == 255)
1482 swt = 1; /* Use one minute as the AP selected value */
1483
1484 if ((unsigned int) session_timeout < swt * 60)
1485 warning_time = 0;
1486 else
1487 warning_time = session_timeout - swt * 60;
1488
1489 beacon_int = hapd->iconf->beacon_int;
1490 if (beacon_int < 1)
1491 beacon_int = 100; /* best guess */
1492 sta->hs20_disassoc_timer = swt * 60 * 1000 / beacon_int * 125 / 128;
1493 if (sta->hs20_disassoc_timer > 65535)
1494 sta->hs20_disassoc_timer = 65535;
1495
1496 ap_sta_session_warning_timeout(hapd, sta, warning_time);
1497 }
1498
1499 #endif /* CONFIG_HS20 */
1500
1501
1502 static void ieee802_1x_check_hs20(struct hostapd_data *hapd,
1503 struct sta_info *sta,
1504 struct radius_msg *msg,
1505 int session_timeout)
1506 {
1507 #ifdef CONFIG_HS20
1508 u8 *buf, *pos, *end, type, sublen;
1509 size_t len;
1510
1511 buf = NULL;
1512 sta->remediation = 0;
1513 sta->hs20_deauth_requested = 0;
1514
1515 for (;;) {
1516 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_VENDOR_SPECIFIC,
1517 &buf, &len, buf) < 0)
1518 break;
1519 if (len < 6)
1520 continue;
1521 pos = buf;
1522 end = buf + len;
1523 if (WPA_GET_BE32(pos) != RADIUS_VENDOR_ID_WFA)
1524 continue;
1525 pos += 4;
1526
1527 type = *pos++;
1528 sublen = *pos++;
1529 if (sublen < 2)
1530 continue; /* invalid length */
1531 sublen -= 2; /* skip header */
1532 if (pos + sublen > end)
1533 continue; /* invalid WFA VSA */
1534
1535 switch (type) {
1536 case RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION:
1537 ieee802_1x_hs20_sub_rem(sta, pos, sublen);
1538 break;
1539 case RADIUS_VENDOR_ATTR_WFA_HS20_DEAUTH_REQ:
1540 ieee802_1x_hs20_deauth_req(hapd, sta, pos, sublen);
1541 break;
1542 case RADIUS_VENDOR_ATTR_WFA_HS20_SESSION_INFO_URL:
1543 ieee802_1x_hs20_session_info(hapd, sta, pos, sublen,
1544 session_timeout);
1545 break;
1546 }
1547 }
1548 #endif /* CONFIG_HS20 */
1549 }
1550
1551
1552 struct sta_id_search {
1553 u8 identifier;
1554 struct eapol_state_machine *sm;
1555 };
1556
1557
1558 static int ieee802_1x_select_radius_identifier(struct hostapd_data *hapd,
1559 struct sta_info *sta,
1560 void *ctx)
1561 {
1562 struct sta_id_search *id_search = ctx;
1563 struct eapol_state_machine *sm = sta->eapol_sm;
1564
1565 if (sm && sm->radius_identifier >= 0 &&
1566 sm->radius_identifier == id_search->identifier) {
1567 id_search->sm = sm;
1568 return 1;
1569 }
1570 return 0;
1571 }
1572
1573
1574 static struct eapol_state_machine *
1575 ieee802_1x_search_radius_identifier(struct hostapd_data *hapd, u8 identifier)
1576 {
1577 struct sta_id_search id_search;
1578 id_search.identifier = identifier;
1579 id_search.sm = NULL;
1580 ap_for_each_sta(hapd, ieee802_1x_select_radius_identifier, &id_search);
1581 return id_search.sm;
1582 }
1583
1584
1585 /**
1586 * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server
1587 * @msg: RADIUS response message
1588 * @req: RADIUS request message
1589 * @shared_secret: RADIUS shared secret
1590 * @shared_secret_len: Length of shared_secret in octets
1591 * @data: Context data (struct hostapd_data *)
1592 * Returns: Processing status
1593 */
1594 static RadiusRxResult
1595 ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
1596 const u8 *shared_secret, size_t shared_secret_len,
1597 void *data)
1598 {
1599 struct hostapd_data *hapd = data;
1600 struct sta_info *sta;
1601 u32 session_timeout = 0, termination_action, acct_interim_interval;
1602 int session_timeout_set, vlan_id = 0;
1603 struct eapol_state_machine *sm;
1604 int override_eapReq = 0;
1605 struct radius_hdr *hdr = radius_msg_get_hdr(msg);
1606
1607 sm = ieee802_1x_search_radius_identifier(hapd, hdr->identifier);
1608 if (sm == NULL) {
1609 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Could not find matching "
1610 "station for this RADIUS message");
1611 return RADIUS_RX_UNKNOWN;
1612 }
1613 sta = sm->sta;
1614
1615 /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
1616 * present when packet contains an EAP-Message attribute */
1617 if (hdr->code == RADIUS_CODE_ACCESS_REJECT &&
1618 radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
1619 0) < 0 &&
1620 radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
1621 wpa_printf(MSG_DEBUG, "Allowing RADIUS Access-Reject without "
1622 "Message-Authenticator since it does not include "
1623 "EAP-Message");
1624 } else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
1625 req, 1)) {
1626 wpa_printf(MSG_INFO, "Incoming RADIUS packet did not have correct Message-Authenticator - dropped");
1627 return RADIUS_RX_INVALID_AUTHENTICATOR;
1628 }
1629
1630 if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
1631 hdr->code != RADIUS_CODE_ACCESS_REJECT &&
1632 hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
1633 wpa_printf(MSG_INFO, "Unknown RADIUS message code");
1634 return RADIUS_RX_UNKNOWN;
1635 }
1636
1637 sm->radius_identifier = -1;
1638 wpa_printf(MSG_DEBUG, "RADIUS packet matching with station " MACSTR,
1639 MAC2STR(sta->addr));
1640
1641 radius_msg_free(sm->last_recv_radius);
1642 sm->last_recv_radius = msg;
1643
1644 session_timeout_set =
1645 !radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,
1646 &session_timeout);
1647 if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_TERMINATION_ACTION,
1648 &termination_action))
1649 termination_action = RADIUS_TERMINATION_ACTION_DEFAULT;
1650
1651 if (hapd->conf->acct_interim_interval == 0 &&
1652 hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
1653 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
1654 &acct_interim_interval) == 0) {
1655 if (acct_interim_interval < 60) {
1656 hostapd_logger(hapd, sta->addr,
1657 HOSTAPD_MODULE_IEEE8021X,
1658 HOSTAPD_LEVEL_INFO,
1659 "ignored too small "
1660 "Acct-Interim-Interval %d",
1661 acct_interim_interval);
1662 } else
1663 sta->acct_interim_interval = acct_interim_interval;
1664 }
1665
1666
1667 switch (hdr->code) {
1668 case RADIUS_CODE_ACCESS_ACCEPT:
1669 if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED)
1670 vlan_id = 0;
1671 #ifndef CONFIG_NO_VLAN
1672 else
1673 vlan_id = radius_msg_get_vlanid(msg);
1674 if (vlan_id > 0 &&
1675 hostapd_vlan_id_valid(hapd->conf->vlan, vlan_id)) {
1676 hostapd_logger(hapd, sta->addr,
1677 HOSTAPD_MODULE_RADIUS,
1678 HOSTAPD_LEVEL_INFO,
1679 "VLAN ID %d", vlan_id);
1680 } else if (vlan_id > 0) {
1681 sta->eapol_sm->authFail = TRUE;
1682 hostapd_logger(hapd, sta->addr,
1683 HOSTAPD_MODULE_RADIUS,
1684 HOSTAPD_LEVEL_INFO,
1685 "Invalid VLAN ID %d received from RADIUS server",
1686 vlan_id);
1687 break;
1688 } else if (hapd->conf->ssid.dynamic_vlan ==
1689 DYNAMIC_VLAN_REQUIRED) {
1690 sta->eapol_sm->authFail = TRUE;
1691 hostapd_logger(hapd, sta->addr,
1692 HOSTAPD_MODULE_IEEE8021X,
1693 HOSTAPD_LEVEL_INFO, "authentication "
1694 "server did not include required VLAN "
1695 "ID in Access-Accept");
1696 break;
1697 }
1698 #endif /* CONFIG_NO_VLAN */
1699
1700 sta->vlan_id = vlan_id;
1701 if ((sta->flags & WLAN_STA_ASSOC) &&
1702 ap_sta_bind_vlan(hapd, sta) < 0)
1703 break;
1704
1705 sta->session_timeout_set = !!session_timeout_set;
1706 sta->session_timeout = session_timeout;
1707
1708 /* RFC 3580, Ch. 3.17 */
1709 if (session_timeout_set && termination_action ==
1710 RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) {
1711 sm->reAuthPeriod = session_timeout;
1712 } else if (session_timeout_set)
1713 ap_sta_session_timeout(hapd, sta, session_timeout);
1714
1715 sm->eap_if->aaaSuccess = TRUE;
1716 override_eapReq = 1;
1717 ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret,
1718 shared_secret_len);
1719 ieee802_1x_store_radius_class(hapd, sta, msg);
1720 ieee802_1x_update_sta_identity(hapd, sta, msg);
1721 ieee802_1x_update_sta_cui(hapd, sta, msg);
1722 ieee802_1x_check_hs20(hapd, sta, msg,
1723 session_timeout_set ?
1724 (int) session_timeout : -1);
1725 break;
1726 case RADIUS_CODE_ACCESS_REJECT:
1727 sm->eap_if->aaaFail = TRUE;
1728 override_eapReq = 1;
1729 break;
1730 case RADIUS_CODE_ACCESS_CHALLENGE:
1731 sm->eap_if->aaaEapReq = TRUE;
1732 if (session_timeout_set) {
1733 /* RFC 2869, Ch. 2.3.2; RFC 3580, Ch. 3.17 */
1734 sm->eap_if->aaaMethodTimeout = session_timeout;
1735 hostapd_logger(hapd, sm->addr,
1736 HOSTAPD_MODULE_IEEE8021X,
1737 HOSTAPD_LEVEL_DEBUG,
1738 "using EAP timeout of %d seconds (from "
1739 "RADIUS)",
1740 sm->eap_if->aaaMethodTimeout);
1741 } else {
1742 /*
1743 * Use dynamic retransmission behavior per EAP
1744 * specification.
1745 */
1746 sm->eap_if->aaaMethodTimeout = 0;
1747 }
1748 break;
1749 }
1750
1751 ieee802_1x_decapsulate_radius(hapd, sta);
1752 if (override_eapReq)
1753 sm->eap_if->aaaEapReq = FALSE;
1754
1755 eapol_auth_step(sm);
1756
1757 return RADIUS_RX_QUEUED;
1758 }
1759 #endif /* CONFIG_NO_RADIUS */
1760
1761
1762 void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
1763 {
1764 struct eapol_state_machine *sm = sta->eapol_sm;
1765 if (sm == NULL)
1766 return;
1767
1768 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
1769 HOSTAPD_LEVEL_DEBUG, "aborting authentication");
1770
1771 #ifndef CONFIG_NO_RADIUS
1772 radius_msg_free(sm->last_recv_radius);
1773 sm->last_recv_radius = NULL;
1774 #endif /* CONFIG_NO_RADIUS */
1775
1776 if (sm->eap_if->eapTimeout) {
1777 /*
1778 * Disconnect the STA since it did not reply to the last EAP
1779 * request and we cannot continue EAP processing (EAP-Failure
1780 * could only be sent if the EAP peer actually replied).
1781 */
1782 wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "EAP Timeout, STA " MACSTR,
1783 MAC2STR(sta->addr));
1784
1785 sm->eap_if->portEnabled = FALSE;
1786 ap_sta_disconnect(hapd, sta, sta->addr,
1787 WLAN_REASON_PREV_AUTH_NOT_VALID);
1788 }
1789 }
1790
1791
1792 static int ieee802_1x_rekey_broadcast(struct hostapd_data *hapd)
1793 {
1794 struct eapol_authenticator *eapol = hapd->eapol_auth;
1795
1796 if (hapd->conf->default_wep_key_len < 1)
1797 return 0;
1798
1799 os_free(eapol->default_wep_key);
1800 eapol->default_wep_key = os_malloc(hapd->conf->default_wep_key_len);
1801 if (eapol->default_wep_key == NULL ||
1802 random_get_bytes(eapol->default_wep_key,
1803 hapd->conf->default_wep_key_len)) {
1804 wpa_printf(MSG_INFO, "Could not generate random WEP key");
1805 os_free(eapol->default_wep_key);
1806 eapol->default_wep_key = NULL;
1807 return -1;
1808 }
1809
1810 wpa_hexdump_key(MSG_DEBUG, "IEEE 802.1X: New default WEP key",
1811 eapol->default_wep_key,
1812 hapd->conf->default_wep_key_len);
1813
1814 return 0;
1815 }
1816
1817
1818 static int ieee802_1x_sta_key_available(struct hostapd_data *hapd,
1819 struct sta_info *sta, void *ctx)
1820 {
1821 if (sta->eapol_sm) {
1822 sta->eapol_sm->eap_if->eapKeyAvailable = TRUE;
1823 eapol_auth_step(sta->eapol_sm);
1824 }
1825 return 0;
1826 }
1827
1828
1829 static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
1830 {
1831 struct hostapd_data *hapd = eloop_ctx;
1832 struct eapol_authenticator *eapol = hapd->eapol_auth;
1833
1834 if (eapol->default_wep_key_idx >= 3)
1835 eapol->default_wep_key_idx =
1836 hapd->conf->individual_wep_key_len > 0 ? 1 : 0;
1837 else
1838 eapol->default_wep_key_idx++;
1839
1840 wpa_printf(MSG_DEBUG, "IEEE 802.1X: New default WEP key index %d",
1841 eapol->default_wep_key_idx);
1842
1843 if (ieee802_1x_rekey_broadcast(hapd)) {
1844 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
1845 HOSTAPD_LEVEL_WARNING, "failed to generate a "
1846 "new broadcast key");
1847 os_free(eapol->default_wep_key);
1848 eapol->default_wep_key = NULL;
1849 return;
1850 }
1851
1852 /* TODO: Could setup key for RX here, but change default TX keyid only
1853 * after new broadcast key has been sent to all stations. */
1854 if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
1855 broadcast_ether_addr,
1856 eapol->default_wep_key_idx, 1, NULL, 0,
1857 eapol->default_wep_key,
1858 hapd->conf->default_wep_key_len)) {
1859 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
1860 HOSTAPD_LEVEL_WARNING, "failed to configure a "
1861 "new broadcast key");
1862 os_free(eapol->default_wep_key);
1863 eapol->default_wep_key = NULL;
1864 return;
1865 }
1866
1867 ap_for_each_sta(hapd, ieee802_1x_sta_key_available, NULL);
1868
1869 if (hapd->conf->wep_rekeying_period > 0) {
1870 eloop_register_timeout(hapd->conf->wep_rekeying_period, 0,
1871 ieee802_1x_rekey, hapd, NULL);
1872 }
1873 }
1874
1875
1876 static void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type,
1877 const u8 *data, size_t datalen)
1878 {
1879 #ifdef CONFIG_WPS
1880 struct sta_info *sta = sta_ctx;
1881
1882 if ((sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) ==
1883 WLAN_STA_MAYBE_WPS) {
1884 const u8 *identity;
1885 size_t identity_len;
1886 struct eapol_state_machine *sm = sta->eapol_sm;
1887
1888 identity = eap_get_identity(sm->eap, &identity_len);
1889 if (identity &&
1890 ((identity_len == WSC_ID_ENROLLEE_LEN &&
1891 os_memcmp(identity, WSC_ID_ENROLLEE,
1892 WSC_ID_ENROLLEE_LEN) == 0) ||
1893 (identity_len == WSC_ID_REGISTRAR_LEN &&
1894 os_memcmp(identity, WSC_ID_REGISTRAR,
1895 WSC_ID_REGISTRAR_LEN) == 0))) {
1896 wpa_printf(MSG_DEBUG, "WPS: WLAN_STA_MAYBE_WPS -> "
1897 "WLAN_STA_WPS");
1898 sta->flags |= WLAN_STA_WPS;
1899 }
1900 }
1901 #endif /* CONFIG_WPS */
1902
1903 ieee802_1x_send(ctx, sta_ctx, type, data, datalen);
1904 }
1905
1906
1907 static void ieee802_1x_aaa_send(void *ctx, void *sta_ctx,
1908 const u8 *data, size_t datalen)
1909 {
1910 #ifndef CONFIG_NO_RADIUS
1911 struct hostapd_data *hapd = ctx;
1912 struct sta_info *sta = sta_ctx;
1913
1914 ieee802_1x_encapsulate_radius(hapd, sta, data, datalen);
1915 #endif /* CONFIG_NO_RADIUS */
1916 }
1917
1918
1919 static void _ieee802_1x_finished(void *ctx, void *sta_ctx, int success,
1920 int preauth, int remediation)
1921 {
1922 struct hostapd_data *hapd = ctx;
1923 struct sta_info *sta = sta_ctx;
1924 if (preauth)
1925 rsn_preauth_finished(hapd, sta, success);
1926 else
1927 ieee802_1x_finished(hapd, sta, success, remediation);
1928 }
1929
1930
1931 static int ieee802_1x_get_eap_user(void *ctx, const u8 *identity,
1932 size_t identity_len, int phase2,
1933 struct eap_user *user)
1934 {
1935 struct hostapd_data *hapd = ctx;
1936 const struct hostapd_eap_user *eap_user;
1937 int i;
1938 int rv = -1;
1939
1940 eap_user = hostapd_get_eap_user(hapd, identity, identity_len, phase2);
1941 if (eap_user == NULL)
1942 goto out;
1943
1944 os_memset(user, 0, sizeof(*user));
1945 user->phase2 = phase2;
1946 for (i = 0; i < EAP_MAX_METHODS; i++) {
1947 user->methods[i].vendor = eap_user->methods[i].vendor;
1948 user->methods[i].method = eap_user->methods[i].method;
1949 }
1950
1951 if (eap_user->password) {
1952 user->password = os_malloc(eap_user->password_len);
1953 if (user->password == NULL)
1954 goto out;
1955 os_memcpy(user->password, eap_user->password,
1956 eap_user->password_len);
1957 user->password_len = eap_user->password_len;
1958 user->password_hash = eap_user->password_hash;
1959 }
1960 user->force_version = eap_user->force_version;
1961 user->macacl = eap_user->macacl;
1962 user->ttls_auth = eap_user->ttls_auth;
1963 user->remediation = eap_user->remediation;
1964 rv = 0;
1965
1966 out:
1967 if (rv)
1968 wpa_printf(MSG_DEBUG, "%s: Failed to find user", __func__);
1969
1970 return rv;
1971 }
1972
1973
1974 static int ieee802_1x_sta_entry_alive(void *ctx, const u8 *addr)
1975 {
1976 struct hostapd_data *hapd = ctx;
1977 struct sta_info *sta;
1978 sta = ap_get_sta(hapd, addr);
1979 if (sta == NULL || sta->eapol_sm == NULL)
1980 return 0;
1981 return 1;
1982 }
1983
1984
1985 static void ieee802_1x_logger(void *ctx, const u8 *addr,
1986 eapol_logger_level level, const char *txt)
1987 {
1988 #ifndef CONFIG_NO_HOSTAPD_LOGGER
1989 struct hostapd_data *hapd = ctx;
1990 int hlevel;
1991
1992 switch (level) {
1993 case EAPOL_LOGGER_WARNING:
1994 hlevel = HOSTAPD_LEVEL_WARNING;
1995 break;
1996 case EAPOL_LOGGER_INFO:
1997 hlevel = HOSTAPD_LEVEL_INFO;
1998 break;
1999 case EAPOL_LOGGER_DEBUG:
2000 default:
2001 hlevel = HOSTAPD_LEVEL_DEBUG;
2002 break;
2003 }
2004
2005 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE8021X, hlevel, "%s",
2006 txt);
2007 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
2008 }
2009
2010
2011 static void ieee802_1x_set_port_authorized(void *ctx, void *sta_ctx,
2012 int authorized)
2013 {
2014 struct hostapd_data *hapd = ctx;
2015 struct sta_info *sta = sta_ctx;
2016 ieee802_1x_set_sta_authorized(hapd, sta, authorized);
2017 }
2018
2019
2020 static void _ieee802_1x_abort_auth(void *ctx, void *sta_ctx)
2021 {
2022 struct hostapd_data *hapd = ctx;
2023 struct sta_info *sta = sta_ctx;
2024 ieee802_1x_abort_auth(hapd, sta);
2025 }
2026
2027
2028 static void _ieee802_1x_tx_key(void *ctx, void *sta_ctx)
2029 {
2030 #ifndef CONFIG_FIPS
2031 #ifndef CONFIG_NO_RC4
2032 struct hostapd_data *hapd = ctx;
2033 struct sta_info *sta = sta_ctx;
2034 ieee802_1x_tx_key(hapd, sta);
2035 #endif /* CONFIG_NO_RC4 */
2036 #endif /* CONFIG_FIPS */
2037 }
2038
2039
2040 static void ieee802_1x_eapol_event(void *ctx, void *sta_ctx,
2041 enum eapol_event type)
2042 {
2043 /* struct hostapd_data *hapd = ctx; */
2044 struct sta_info *sta = sta_ctx;
2045 switch (type) {
2046 case EAPOL_AUTH_SM_CHANGE:
2047 wpa_auth_sm_notify(sta->wpa_sm);
2048 break;
2049 case EAPOL_AUTH_REAUTHENTICATE:
2050 wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL);
2051 break;
2052 }
2053 }
2054
2055
2056 #ifdef CONFIG_ERP
2057
2058 static struct eap_server_erp_key *
2059 ieee802_1x_erp_get_key(void *ctx, const char *keyname)
2060 {
2061 struct hostapd_data *hapd = ctx;
2062 struct eap_server_erp_key *erp;
2063
2064 dl_list_for_each(erp, &hapd->erp_keys, struct eap_server_erp_key,
2065 list) {
2066 if (os_strcmp(erp->keyname_nai, keyname) == 0)
2067 return erp;
2068 }
2069
2070 return NULL;
2071 }
2072
2073
2074 static int ieee802_1x_erp_add_key(void *ctx, struct eap_server_erp_key *erp)
2075 {
2076 struct hostapd_data *hapd = ctx;
2077
2078 dl_list_add(&hapd->erp_keys, &erp->list);
2079 return 0;
2080 }
2081
2082 #endif /* CONFIG_ERP */
2083
2084
2085 int ieee802_1x_init(struct hostapd_data *hapd)
2086 {
2087 int i;
2088 struct eapol_auth_config conf;
2089 struct eapol_auth_cb cb;
2090
2091 dl_list_init(&hapd->erp_keys);
2092
2093 os_memset(&conf, 0, sizeof(conf));
2094 conf.ctx = hapd;
2095 conf.eap_reauth_period = hapd->conf->eap_reauth_period;
2096 conf.wpa = hapd->conf->wpa;
2097 conf.individual_wep_key_len = hapd->conf->individual_wep_key_len;
2098 conf.eap_server = hapd->conf->eap_server;
2099 conf.ssl_ctx = hapd->ssl_ctx;
2100 conf.msg_ctx = hapd->msg_ctx;
2101 conf.eap_sim_db_priv = hapd->eap_sim_db_priv;
2102 conf.eap_req_id_text = hapd->conf->eap_req_id_text;
2103 conf.eap_req_id_text_len = hapd->conf->eap_req_id_text_len;
2104 conf.erp_send_reauth_start = hapd->conf->erp_send_reauth_start;
2105 conf.erp_domain = hapd->conf->erp_domain;
2106 conf.erp = hapd->conf->eap_server_erp;
2107 conf.tls_session_lifetime = hapd->conf->tls_session_lifetime;
2108 conf.pac_opaque_encr_key = hapd->conf->pac_opaque_encr_key;
2109 conf.eap_fast_a_id = hapd->conf->eap_fast_a_id;
2110 conf.eap_fast_a_id_len = hapd->conf->eap_fast_a_id_len;
2111 conf.eap_fast_a_id_info = hapd->conf->eap_fast_a_id_info;
2112 conf.eap_fast_prov = hapd->conf->eap_fast_prov;
2113 conf.pac_key_lifetime = hapd->conf->pac_key_lifetime;
2114 conf.pac_key_refresh_time = hapd->conf->pac_key_refresh_time;
2115 conf.eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind;
2116 conf.tnc = hapd->conf->tnc;
2117 conf.wps = hapd->wps;
2118 conf.fragment_size = hapd->conf->fragment_size;
2119 conf.pwd_group = hapd->conf->pwd_group;
2120 conf.pbc_in_m1 = hapd->conf->pbc_in_m1;
2121 if (hapd->conf->server_id) {
2122 conf.server_id = (const u8 *) hapd->conf->server_id;
2123 conf.server_id_len = os_strlen(hapd->conf->server_id);
2124 } else {
2125 conf.server_id = (const u8 *) "hostapd";
2126 conf.server_id_len = 7;
2127 }
2128
2129 os_memset(&cb, 0, sizeof(cb));
2130 cb.eapol_send = ieee802_1x_eapol_send;
2131 cb.aaa_send = ieee802_1x_aaa_send;
2132 cb.finished = _ieee802_1x_finished;
2133 cb.get_eap_user = ieee802_1x_get_eap_user;
2134 cb.sta_entry_alive = ieee802_1x_sta_entry_alive;
2135 cb.logger = ieee802_1x_logger;
2136 cb.set_port_authorized = ieee802_1x_set_port_authorized;
2137 cb.abort_auth = _ieee802_1x_abort_auth;
2138 cb.tx_key = _ieee802_1x_tx_key;
2139 cb.eapol_event = ieee802_1x_eapol_event;
2140 #ifdef CONFIG_ERP
2141 cb.erp_get_key = ieee802_1x_erp_get_key;
2142 cb.erp_add_key = ieee802_1x_erp_add_key;
2143 #endif /* CONFIG_ERP */
2144
2145 hapd->eapol_auth = eapol_auth_init(&conf, &cb);
2146 if (hapd->eapol_auth == NULL)
2147 return -1;
2148
2149 if ((hapd->conf->ieee802_1x || hapd->conf->wpa) &&
2150 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1))
2151 return -1;
2152
2153 #ifndef CONFIG_NO_RADIUS
2154 if (radius_client_register(hapd->radius, RADIUS_AUTH,
2155 ieee802_1x_receive_auth, hapd))
2156 return -1;
2157 #endif /* CONFIG_NO_RADIUS */
2158
2159 if (hapd->conf->default_wep_key_len) {
2160 for (i = 0; i < 4; i++)
2161 hostapd_drv_set_key(hapd->conf->iface, hapd,
2162 WPA_ALG_NONE, NULL, i, 0, NULL, 0,
2163 NULL, 0);
2164
2165 ieee802_1x_rekey(hapd, NULL);
2166
2167 if (hapd->eapol_auth->default_wep_key == NULL)
2168 return -1;
2169 }
2170
2171 return 0;
2172 }
2173
2174
2175 void ieee802_1x_erp_flush(struct hostapd_data *hapd)
2176 {
2177 struct eap_server_erp_key *erp;
2178
2179 while ((erp = dl_list_first(&hapd->erp_keys, struct eap_server_erp_key,
2180 list)) != NULL) {
2181 dl_list_del(&erp->list);
2182 bin_clear_free(erp, sizeof(*erp));
2183 }
2184 }
2185
2186
2187 void ieee802_1x_deinit(struct hostapd_data *hapd)
2188 {
2189 eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL);
2190
2191 if (hapd->driver && hapd->drv_priv &&
2192 (hapd->conf->ieee802_1x || hapd->conf->wpa))
2193 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
2194
2195 eapol_auth_deinit(hapd->eapol_auth);
2196 hapd->eapol_auth = NULL;
2197
2198 ieee802_1x_erp_flush(hapd);
2199 }
2200
2201
2202 int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta,
2203 const u8 *buf, size_t len, int ack)
2204 {
2205 struct ieee80211_hdr *hdr;
2206 u8 *pos;
2207 const unsigned char rfc1042_hdr[ETH_ALEN] =
2208 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
2209
2210 if (sta == NULL)
2211 return -1;
2212 if (len < sizeof(*hdr) + sizeof(rfc1042_hdr) + 2)
2213 return 0;
2214
2215 hdr = (struct ieee80211_hdr *) buf;
2216 pos = (u8 *) (hdr + 1);
2217 if (os_memcmp(pos, rfc1042_hdr, sizeof(rfc1042_hdr)) != 0)
2218 return 0;
2219 pos += sizeof(rfc1042_hdr);
2220 if (WPA_GET_BE16(pos) != ETH_P_PAE)
2221 return 0;
2222 pos += 2;
2223
2224 return ieee802_1x_eapol_tx_status(hapd, sta, pos, buf + len - pos,
2225 ack);
2226 }
2227
2228
2229 int ieee802_1x_eapol_tx_status(struct hostapd_data *hapd, struct sta_info *sta,
2230 const u8 *buf, int len, int ack)
2231 {
2232 const struct ieee802_1x_hdr *xhdr =
2233 (const struct ieee802_1x_hdr *) buf;
2234 const u8 *pos = buf + sizeof(*xhdr);
2235 struct ieee802_1x_eapol_key *key;
2236
2237 if (len < (int) sizeof(*xhdr))
2238 return 0;
2239 wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR " TX status - version=%d "
2240 "type=%d length=%d - ack=%d",
2241 MAC2STR(sta->addr), xhdr->version, xhdr->type,
2242 be_to_host16(xhdr->length), ack);
2243
2244 if (xhdr->type != IEEE802_1X_TYPE_EAPOL_KEY)
2245 return 0;
2246
2247 if (pos + sizeof(struct wpa_eapol_key) <= buf + len) {
2248 const struct wpa_eapol_key *wpa;
2249 wpa = (const struct wpa_eapol_key *) pos;
2250 if (wpa->type == EAPOL_KEY_TYPE_RSN ||
2251 wpa->type == EAPOL_KEY_TYPE_WPA)
2252 wpa_auth_eapol_key_tx_status(hapd->wpa_auth,
2253 sta->wpa_sm, ack);
2254 }
2255
2256 /* EAPOL EAP-Packet packets are eventually re-sent by either Supplicant
2257 * or Authenticator state machines, but EAPOL-Key packets are not
2258 * retransmitted in case of failure. Try to re-send failed EAPOL-Key
2259 * packets couple of times because otherwise STA keys become
2260 * unsynchronized with AP. */
2261 if (!ack && pos + sizeof(*key) <= buf + len) {
2262 key = (struct ieee802_1x_eapol_key *) pos;
2263 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
2264 HOSTAPD_LEVEL_DEBUG, "did not Ack EAPOL-Key "
2265 "frame (%scast index=%d)",
2266 key->key_index & BIT(7) ? "uni" : "broad",
2267 key->key_index & ~BIT(7));
2268 /* TODO: re-send EAPOL-Key couple of times (with short delay
2269 * between them?). If all attempt fail, report error and
2270 * deauthenticate STA so that it will get new keys when
2271 * authenticating again (e.g., after returning in range).
2272 * Separate limit/transmit state needed both for unicast and
2273 * broadcast keys(?) */
2274 }
2275 /* TODO: could move unicast key configuration from ieee802_1x_tx_key()
2276 * to here and change the key only if the EAPOL-Key packet was Acked.
2277 */
2278
2279 return 1;
2280 }
2281
2282
2283 u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len)
2284 {
2285 if (sm == NULL || sm->identity == NULL)
2286 return NULL;
2287
2288 *len = sm->identity_len;
2289 return sm->identity;
2290 }
2291
2292
2293 u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
2294 int idx)
2295 {
2296 if (sm == NULL || sm->radius_class.attr == NULL ||
2297 idx >= (int) sm->radius_class.count)
2298 return NULL;
2299
2300 *len = sm->radius_class.attr[idx].len;
2301 return sm->radius_class.attr[idx].data;
2302 }
2303
2304
2305 struct wpabuf * ieee802_1x_get_radius_cui(struct eapol_state_machine *sm)
2306 {
2307 if (sm == NULL)
2308 return NULL;
2309 return sm->radius_cui;
2310 }
2311
2312
2313 const u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len)
2314 {
2315 *len = 0;
2316 if (sm == NULL)
2317 return NULL;
2318
2319 *len = sm->eap_if->eapKeyDataLen;
2320 return sm->eap_if->eapKeyData;
2321 }
2322
2323
2324 void ieee802_1x_notify_port_enabled(struct eapol_state_machine *sm,
2325 int enabled)
2326 {
2327 if (sm == NULL)
2328 return;
2329 sm->eap_if->portEnabled = enabled ? TRUE : FALSE;
2330 eapol_auth_step(sm);
2331 }
2332
2333
2334 void ieee802_1x_notify_port_valid(struct eapol_state_machine *sm,
2335 int valid)
2336 {
2337 if (sm == NULL)
2338 return;
2339 sm->portValid = valid ? TRUE : FALSE;
2340 eapol_auth_step(sm);
2341 }
2342
2343
2344 void ieee802_1x_notify_pre_auth(struct eapol_state_machine *sm, int pre_auth)
2345 {
2346 if (sm == NULL)
2347 return;
2348 if (pre_auth)
2349 sm->flags |= EAPOL_SM_PREAUTH;
2350 else
2351 sm->flags &= ~EAPOL_SM_PREAUTH;
2352 }
2353
2354
2355 static const char * bool_txt(Boolean val)
2356 {
2357 return val ? "TRUE" : "FALSE";
2358 }
2359
2360
2361 int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
2362 {
2363 /* TODO */
2364 return 0;
2365 }
2366
2367
2368 int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
2369 char *buf, size_t buflen)
2370 {
2371 int len = 0, ret;
2372 struct eapol_state_machine *sm = sta->eapol_sm;
2373 struct os_reltime diff;
2374 const char *name1;
2375 const char *name2;
2376
2377 if (sm == NULL)
2378 return 0;
2379
2380 ret = os_snprintf(buf + len, buflen - len,
2381 "dot1xPaePortNumber=%d\n"
2382 "dot1xPaePortProtocolVersion=%d\n"
2383 "dot1xPaePortCapabilities=1\n"
2384 "dot1xPaePortInitialize=%d\n"
2385 "dot1xPaePortReauthenticate=FALSE\n",
2386 sta->aid,
2387 EAPOL_VERSION,
2388 sm->initialize);
2389 if (os_snprintf_error(buflen - len, ret))
2390 return len;
2391 len += ret;
2392
2393 /* dot1xAuthConfigTable */
2394 ret = os_snprintf(buf + len, buflen - len,
2395 "dot1xAuthPaeState=%d\n"
2396 "dot1xAuthBackendAuthState=%d\n"
2397 "dot1xAuthAdminControlledDirections=%d\n"
2398 "dot1xAuthOperControlledDirections=%d\n"
2399 "dot1xAuthAuthControlledPortStatus=%d\n"
2400 "dot1xAuthAuthControlledPortControl=%d\n"
2401 "dot1xAuthQuietPeriod=%u\n"
2402 "dot1xAuthServerTimeout=%u\n"
2403 "dot1xAuthReAuthPeriod=%u\n"
2404 "dot1xAuthReAuthEnabled=%s\n"
2405 "dot1xAuthKeyTxEnabled=%s\n",
2406 sm->auth_pae_state + 1,
2407 sm->be_auth_state + 1,
2408 sm->adminControlledDirections,
2409 sm->operControlledDirections,
2410 sm->authPortStatus,
2411 sm->portControl,
2412 sm->quietPeriod,
2413 sm->serverTimeout,
2414 sm->reAuthPeriod,
2415 bool_txt(sm->reAuthEnabled),
2416 bool_txt(sm->keyTxEnabled));
2417 if (os_snprintf_error(buflen - len, ret))
2418 return len;
2419 len += ret;
2420
2421 /* dot1xAuthStatsTable */
2422 ret = os_snprintf(buf + len, buflen - len,
2423 "dot1xAuthEapolFramesRx=%u\n"
2424 "dot1xAuthEapolFramesTx=%u\n"
2425 "dot1xAuthEapolStartFramesRx=%u\n"
2426 "dot1xAuthEapolLogoffFramesRx=%u\n"
2427 "dot1xAuthEapolRespIdFramesRx=%u\n"
2428 "dot1xAuthEapolRespFramesRx=%u\n"
2429 "dot1xAuthEapolReqIdFramesTx=%u\n"
2430 "dot1xAuthEapolReqFramesTx=%u\n"
2431 "dot1xAuthInvalidEapolFramesRx=%u\n"
2432 "dot1xAuthEapLengthErrorFramesRx=%u\n"
2433 "dot1xAuthLastEapolFrameVersion=%u\n"
2434 "dot1xAuthLastEapolFrameSource=" MACSTR "\n",
2435 sm->dot1xAuthEapolFramesRx,
2436 sm->dot1xAuthEapolFramesTx,
2437 sm->dot1xAuthEapolStartFramesRx,
2438 sm->dot1xAuthEapolLogoffFramesRx,
2439 sm->dot1xAuthEapolRespIdFramesRx,
2440 sm->dot1xAuthEapolRespFramesRx,
2441 sm->dot1xAuthEapolReqIdFramesTx,
2442 sm->dot1xAuthEapolReqFramesTx,
2443 sm->dot1xAuthInvalidEapolFramesRx,
2444 sm->dot1xAuthEapLengthErrorFramesRx,
2445 sm->dot1xAuthLastEapolFrameVersion,
2446 MAC2STR(sm->addr));
2447 if (os_snprintf_error(buflen - len, ret))
2448 return len;
2449 len += ret;
2450
2451 /* dot1xAuthDiagTable */
2452 ret = os_snprintf(buf + len, buflen - len,
2453 "dot1xAuthEntersConnecting=%u\n"
2454 "dot1xAuthEapLogoffsWhileConnecting=%u\n"
2455 "dot1xAuthEntersAuthenticating=%u\n"
2456 "dot1xAuthAuthSuccessesWhileAuthenticating=%u\n"
2457 "dot1xAuthAuthTimeoutsWhileAuthenticating=%u\n"
2458 "dot1xAuthAuthFailWhileAuthenticating=%u\n"
2459 "dot1xAuthAuthEapStartsWhileAuthenticating=%u\n"
2460 "dot1xAuthAuthEapLogoffWhileAuthenticating=%u\n"
2461 "dot1xAuthAuthReauthsWhileAuthenticated=%u\n"
2462 "dot1xAuthAuthEapStartsWhileAuthenticated=%u\n"
2463 "dot1xAuthAuthEapLogoffWhileAuthenticated=%u\n"
2464 "dot1xAuthBackendResponses=%u\n"
2465 "dot1xAuthBackendAccessChallenges=%u\n"
2466 "dot1xAuthBackendOtherRequestsToSupplicant=%u\n"
2467 "dot1xAuthBackendAuthSuccesses=%u\n"
2468 "dot1xAuthBackendAuthFails=%u\n",
2469 sm->authEntersConnecting,
2470 sm->authEapLogoffsWhileConnecting,
2471 sm->authEntersAuthenticating,
2472 sm->authAuthSuccessesWhileAuthenticating,
2473 sm->authAuthTimeoutsWhileAuthenticating,
2474 sm->authAuthFailWhileAuthenticating,
2475 sm->authAuthEapStartsWhileAuthenticating,
2476 sm->authAuthEapLogoffWhileAuthenticating,
2477 sm->authAuthReauthsWhileAuthenticated,
2478 sm->authAuthEapStartsWhileAuthenticated,
2479 sm->authAuthEapLogoffWhileAuthenticated,
2480 sm->backendResponses,
2481 sm->backendAccessChallenges,
2482 sm->backendOtherRequestsToSupplicant,
2483 sm->backendAuthSuccesses,
2484 sm->backendAuthFails);
2485 if (os_snprintf_error(buflen - len, ret))
2486 return len;
2487 len += ret;
2488
2489 /* dot1xAuthSessionStatsTable */
2490 os_reltime_age(&sta->acct_session_start, &diff);
2491 ret = os_snprintf(buf + len, buflen - len,
2492 /* TODO: dot1xAuthSessionOctetsRx */
2493 /* TODO: dot1xAuthSessionOctetsTx */
2494 /* TODO: dot1xAuthSessionFramesRx */
2495 /* TODO: dot1xAuthSessionFramesTx */
2496 "dot1xAuthSessionId=%016lX\n"
2497 "dot1xAuthSessionAuthenticMethod=%d\n"
2498 "dot1xAuthSessionTime=%u\n"
2499 "dot1xAuthSessionTerminateCause=999\n"
2500 "dot1xAuthSessionUserName=%s\n",
2501 (long unsigned int) sta->acct_session_id,
2502 (wpa_key_mgmt_wpa_ieee8021x(
2503 wpa_auth_sta_key_mgmt(sta->wpa_sm))) ?
2504 1 : 2,
2505 (unsigned int) diff.sec,
2506 sm->identity);
2507 if (os_snprintf_error(buflen - len, ret))
2508 return len;
2509 len += ret;
2510
2511 if (sm->acct_multi_session_id) {
2512 ret = os_snprintf(buf + len, buflen - len,
2513 "authMultiSessionId=%016lX\n",
2514 (long unsigned int)
2515 sm->acct_multi_session_id);
2516 if (os_snprintf_error(buflen - len, ret))
2517 return len;
2518 len += ret;
2519 }
2520
2521 name1 = eap_server_get_name(0, sm->eap_type_authsrv);
2522 name2 = eap_server_get_name(0, sm->eap_type_supp);
2523 ret = os_snprintf(buf + len, buflen - len,
2524 "last_eap_type_as=%d (%s)\n"
2525 "last_eap_type_sta=%d (%s)\n",
2526 sm->eap_type_authsrv, name1,
2527 sm->eap_type_supp, name2);
2528 if (os_snprintf_error(buflen - len, ret))
2529 return len;
2530 len += ret;
2531
2532 return len;
2533 }
2534
2535
2536 #ifdef CONFIG_HS20
2537 static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx)
2538 {
2539 struct hostapd_data *hapd = eloop_ctx;
2540 struct sta_info *sta = timeout_ctx;
2541
2542 if (sta->remediation) {
2543 wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification to "
2544 MACSTR " to indicate Subscription Remediation",
2545 MAC2STR(sta->addr));
2546 hs20_send_wnm_notification(hapd, sta->addr,
2547 sta->remediation_method,
2548 sta->remediation_url);
2549 os_free(sta->remediation_url);
2550 sta->remediation_url = NULL;
2551 }
2552
2553 if (sta->hs20_deauth_req) {
2554 wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification to "
2555 MACSTR " to indicate imminent deauthentication",
2556 MAC2STR(sta->addr));
2557 hs20_send_wnm_notification_deauth_req(hapd, sta->addr,
2558 sta->hs20_deauth_req);
2559 }
2560 }
2561 #endif /* CONFIG_HS20 */
2562
2563
2564 static void ieee802_1x_finished(struct hostapd_data *hapd,
2565 struct sta_info *sta, int success,
2566 int remediation)
2567 {
2568 const u8 *key;
2569 size_t len;
2570 /* TODO: get PMKLifetime from WPA parameters */
2571 static const int dot11RSNAConfigPMKLifetime = 43200;
2572 unsigned int session_timeout;
2573
2574 #ifdef CONFIG_HS20
2575 if (remediation && !sta->remediation) {
2576 sta->remediation = 1;
2577 os_free(sta->remediation_url);
2578 sta->remediation_url =
2579 os_strdup(hapd->conf->subscr_remediation_url);
2580 sta->remediation_method = 1; /* SOAP-XML SPP */
2581 }
2582
2583 if (success && (sta->remediation || sta->hs20_deauth_req)) {
2584 wpa_printf(MSG_DEBUG, "HS 2.0: Schedule WNM-Notification to "
2585 MACSTR " in 100 ms", MAC2STR(sta->addr));
2586 eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta);
2587 eloop_register_timeout(0, 100000, ieee802_1x_wnm_notif_send,
2588 hapd, sta);
2589 }
2590 #endif /* CONFIG_HS20 */
2591
2592 key = ieee802_1x_get_key(sta->eapol_sm, &len);
2593 if (sta->session_timeout_set)
2594 session_timeout = sta->session_timeout;
2595 else
2596 session_timeout = dot11RSNAConfigPMKLifetime;
2597 if (success && key && len >= PMK_LEN && !sta->remediation &&
2598 !sta->hs20_deauth_requested &&
2599 wpa_auth_pmksa_add(sta->wpa_sm, key, len, session_timeout,
2600 sta->eapol_sm) == 0) {
2601 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
2602 HOSTAPD_LEVEL_DEBUG,
2603 "Added PMKSA cache entry (IEEE 802.1X)");
2604 }
2605
2606 if (!success) {
2607 /*
2608 * Many devices require deauthentication after WPS provisioning
2609 * and some may not be be able to do that themselves, so
2610 * disconnect the client here. In addition, this may also
2611 * benefit IEEE 802.1X/EAPOL authentication cases, too since
2612 * the EAPOL PAE state machine would remain in HELD state for
2613 * considerable amount of time and some EAP methods, like
2614 * EAP-FAST with anonymous provisioning, may require another
2615 * EAPOL authentication to be started to complete connection.
2616 */
2617 wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "IEEE 802.1X: Force "
2618 "disconnection after EAP-Failure");
2619 /* Add a small sleep to increase likelihood of previously
2620 * requested EAP-Failure TX getting out before this should the
2621 * driver reorder operations.
2622 */
2623 os_sleep(0, 10000);
2624 ap_sta_disconnect(hapd, sta, sta->addr,
2625 WLAN_REASON_IEEE_802_1X_AUTH_FAILED);
2626 hostapd_wps_eap_completed(hapd);
2627 }
2628 }