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