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