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