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