From 8cd635c895029020fc6766559bf7b0873f86a748 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 9 Sep 2024 12:30:49 +0200 Subject: [PATCH] hostapd: fix radius rate limit while roaming Fixes: WIFI-14054 Signed-off-by: John Crispin --- .../hostapd/patches/751-wispr-ft.patch | 79 ++++++++++--------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/feeds/ipq807x_v5.4/hostapd/patches/751-wispr-ft.patch b/feeds/ipq807x_v5.4/hostapd/patches/751-wispr-ft.patch index 9090c2faa..f51bafb2d 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/751-wispr-ft.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/751-wispr-ft.patch @@ -119,7 +119,7 @@ static size_t wpa_ft_vlan_lin(const struct vlan_description *vlan, u8 *start, u8 *endpos) -@@ -430,10 +438,47 @@ static size_t wpa_ft_vlan_lin(const stru +@@ -430,10 +438,48 @@ static size_t wpa_ft_vlan_lin(const stru } @@ -141,13 +141,14 @@ + return tlv_len; + hdr = (struct ft_rrb_tlv *) pos; + hdr->type = host_to_le16(FT_RRB_RATE_LIMIT); -+ hdr->len = host_to_le16(sizeof(le16)); ++ hdr->len = host_to_le16(2 * sizeof(le32)); + pos = start + tlv_len; + + tlv_len += sizeof(u32); + if (start + tlv_len > endpos) + return tlv_len; + WPA_PUT_LE32(pos, rate->rx); ++ pos = start + tlv_len; + tlv_len += sizeof(u32); + if (start + tlv_len > endpos) + return tlv_len; @@ -168,7 +169,7 @@ { u8 *pos, *endpos; size_t tlv_len; -@@ -441,6 +486,7 @@ static int wpa_ft_rrb_lin(const struct t +@@ -441,6 +487,7 @@ static int wpa_ft_rrb_lin(const struct t tlv_len = wpa_ft_tlv_len(tlvs1); tlv_len += wpa_ft_tlv_len(tlvs2); tlv_len += wpa_ft_vlan_len(vlan); @@ -176,7 +177,7 @@ *plain_len = tlv_len; *plain = os_zalloc(tlv_len); -@@ -454,6 +500,7 @@ static int wpa_ft_rrb_lin(const struct t +@@ -454,6 +501,7 @@ static int wpa_ft_rrb_lin(const struct t pos += wpa_ft_tlv_lin(tlvs1, pos, endpos); pos += wpa_ft_tlv_lin(tlvs2, pos, endpos); pos += wpa_ft_vlan_lin(vlan, pos, endpos); @@ -184,7 +185,7 @@ /* sanity check */ if (pos != endpos) { -@@ -522,7 +569,8 @@ static int wpa_ft_rrb_build(const u8 *ke +@@ -522,7 +570,8 @@ static int wpa_ft_rrb_build(const u8 *ke const struct tlv_list *tlvs_auth, const struct vlan_description *vlan, const u8 *src_addr, u8 type, @@ -194,7 +195,7 @@ { u8 *plain = NULL, *auth = NULL, *pos, *tmp; size_t plain_len = 0, auth_len = 0; -@@ -530,10 +578,10 @@ static int wpa_ft_rrb_build(const u8 *ke +@@ -530,10 +579,10 @@ static int wpa_ft_rrb_build(const u8 *ke size_t pad_len = 0; *packet = NULL; @@ -207,7 +208,7 @@ goto out; *packet_len = sizeof(u16) + auth_len + plain_len; -@@ -696,6 +744,24 @@ static int wpa_ft_get_vlan(struct wpa_au +@@ -696,6 +745,24 @@ static int wpa_ft_get_vlan(struct wpa_au } @@ -232,7 +233,7 @@ static int wpa_ft_set_identity(struct wpa_authenticator *wpa_auth, const u8 *sta_addr, const u8 *identity, size_t identity_len) -@@ -991,7 +1057,7 @@ wpa_ft_rrb_seq_req(struct wpa_authentica +@@ -991,7 +1058,7 @@ wpa_ft_rrb_seq_req(struct wpa_authentica if (wpa_ft_rrb_build(key, key_len, NULL, NULL, seq_req_auth, NULL, wpa_auth->addr, FT_PACKET_R0KH_R1KH_SEQ_REQ, @@ -241,7 +242,7 @@ item = NULL; /* some other seq resp might still accept this */ goto err; } -@@ -1174,6 +1240,7 @@ struct wpa_ft_pmk_r0_sa { +@@ -1174,6 +1241,7 @@ struct wpa_ft_pmk_r0_sa { u8 spa[ETH_ALEN]; int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */ struct vlan_description *vlan; @@ -249,7 +250,7 @@ os_time_t expiration; /* 0 for no expiration */ u8 *identity; size_t identity_len; -@@ -1192,6 +1259,7 @@ struct wpa_ft_pmk_r1_sa { +@@ -1192,6 +1260,7 @@ struct wpa_ft_pmk_r1_sa { u8 spa[ETH_ALEN]; int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */ struct vlan_description *vlan; @@ -257,7 +258,7 @@ u8 *identity; size_t identity_len; u8 *radius_cui; -@@ -1220,6 +1288,7 @@ static void wpa_ft_free_pmk_r0(struct wp +@@ -1220,6 +1289,7 @@ static void wpa_ft_free_pmk_r0(struct wp os_memset(r0->pmk_r0, 0, PMK_LEN_MAX); os_free(r0->vlan); @@ -265,7 +266,7 @@ os_free(r0->identity); os_free(r0->radius_cui); os_free(r0); -@@ -1273,6 +1342,7 @@ static void wpa_ft_free_pmk_r1(struct wp +@@ -1273,6 +1343,7 @@ static void wpa_ft_free_pmk_r1(struct wp eloop_cancel_timeout(wpa_ft_expire_pmk_r1, r1, NULL); os_memset(r1->pmk_r1, 0, PMK_LEN_MAX); @@ -273,7 +274,7 @@ os_free(r1->vlan); os_free(r1->identity); os_free(r1->radius_cui); -@@ -1326,7 +1396,8 @@ static int wpa_ft_store_pmk_r0(struct wp +@@ -1326,7 +1397,8 @@ static int wpa_ft_store_pmk_r0(struct wp const struct vlan_description *vlan, int expires_in, int session_timeout, const u8 *identity, size_t identity_len, @@ -283,7 +284,7 @@ { struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache; struct wpa_ft_pmk_r0_sa *r0; -@@ -1354,6 +1425,14 @@ static int wpa_ft_store_pmk_r0(struct wp +@@ -1354,6 +1426,14 @@ static int wpa_ft_store_pmk_r0(struct wp } *r0->vlan = *vlan; } @@ -298,7 +299,7 @@ if (identity) { r0->identity = os_malloc(identity_len); if (r0->identity) { -@@ -1413,7 +1492,8 @@ static int wpa_ft_store_pmk_r1(struct wp +@@ -1413,7 +1493,8 @@ static int wpa_ft_store_pmk_r1(struct wp const struct vlan_description *vlan, int expires_in, int session_timeout, const u8 *identity, size_t identity_len, @@ -308,7 +309,7 @@ { struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache; int max_expires_in = wpa_auth->conf.r1_max_key_lifetime; -@@ -1443,6 +1523,14 @@ static int wpa_ft_store_pmk_r1(struct wp +@@ -1443,6 +1524,14 @@ static int wpa_ft_store_pmk_r1(struct wp } *r1->vlan = *vlan; } @@ -323,7 +324,7 @@ if (identity) { r1->identity = os_malloc(identity_len); if (r1->identity) { -@@ -1479,7 +1567,7 @@ int wpa_ft_fetch_pmk_r1(struct wpa_authe +@@ -1479,7 +1568,7 @@ int wpa_ft_fetch_pmk_r1(struct wpa_authe struct vlan_description *vlan, const u8 **identity, size_t *identity_len, const u8 **radius_cui, size_t *radius_cui_len, @@ -332,7 +333,7 @@ { struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache; struct wpa_ft_pmk_r1_sa *r1; -@@ -1499,6 +1587,12 @@ int wpa_ft_fetch_pmk_r1(struct wpa_authe +@@ -1499,6 +1588,12 @@ int wpa_ft_fetch_pmk_r1(struct wpa_authe *vlan = *r1->vlan; if (vlan && !r1->vlan) os_memset(vlan, 0, sizeof(*vlan)); @@ -345,7 +346,7 @@ if (identity && identity_len) { *identity = r1->identity; *identity_len = r1->identity_len; -@@ -2025,7 +2119,7 @@ static int wpa_ft_pull_pmk_r1(struct wpa +@@ -2025,7 +2120,7 @@ static int wpa_ft_pull_pmk_r1(struct wpa if (wpa_ft_rrb_build(key, key_len, req_enc, NULL, req_auth, NULL, sm->wpa_auth->addr, FT_PACKET_R0KH_R1KH_PULL, @@ -354,7 +355,7 @@ return -1; ft_pending_req_ies = wpabuf_alloc_copy(ies, ies_len); -@@ -2054,6 +2148,7 @@ int wpa_ft_store_pmk_fils(struct wpa_sta +@@ -2054,6 +2149,7 @@ int wpa_ft_store_pmk_fils(struct wpa_sta { int expires_in = sm->wpa_auth->conf.r0_key_lifetime; struct vlan_description vlan; @@ -362,7 +363,7 @@ const u8 *identity, *radius_cui; size_t identity_len, radius_cui_len; int session_timeout; -@@ -2065,6 +2160,7 @@ int wpa_ft_store_pmk_fils(struct wpa_sta +@@ -2065,6 +2161,7 @@ int wpa_ft_store_pmk_fils(struct wpa_sta MAC2STR(sm->addr)); return -1; } @@ -370,7 +371,7 @@ identity_len = wpa_ft_get_identity(sm->wpa_auth, sm->addr, &identity); radius_cui_len = wpa_ft_get_radius_cui(sm->wpa_auth, sm->addr, -@@ -2074,7 +2170,7 @@ int wpa_ft_store_pmk_fils(struct wpa_sta +@@ -2074,7 +2171,7 @@ int wpa_ft_store_pmk_fils(struct wpa_sta return wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_len, pmk_r0_name, sm->pairwise, &vlan, expires_in, session_timeout, identity, identity_len, @@ -379,7 +380,7 @@ } -@@ -2095,6 +2191,7 @@ int wpa_auth_derive_ptk_ft(struct wpa_st +@@ -2095,6 +2192,7 @@ int wpa_auth_derive_ptk_ft(struct wpa_st int psk_local = sm->wpa_auth->conf.ft_psk_generate_local; int expires_in = sm->wpa_auth->conf.r0_key_lifetime; struct vlan_description vlan; @@ -387,7 +388,7 @@ const u8 *identity, *radius_cui; size_t identity_len, radius_cui_len; int session_timeout; -@@ -2119,6 +2216,8 @@ int wpa_auth_derive_ptk_ft(struct wpa_st +@@ -2119,6 +2217,8 @@ int wpa_auth_derive_ptk_ft(struct wpa_st return -1; } @@ -396,7 +397,7 @@ identity_len = wpa_ft_get_identity(sm->wpa_auth, sm->addr, &identity); radius_cui_len = wpa_ft_get_radius_cui(sm->wpa_auth, sm->addr, &radius_cui); -@@ -2134,7 +2233,7 @@ int wpa_auth_derive_ptk_ft(struct wpa_st +@@ -2134,7 +2234,7 @@ int wpa_auth_derive_ptk_ft(struct wpa_st pmk_r0_name, sm->pairwise, &vlan, expires_in, session_timeout, identity, identity_len, @@ -405,7 +406,7 @@ if (wpa_derive_pmk_r1(pmk_r0, pmk_r0_len, pmk_r0_name, r1kh, sm->addr, pmk_r1, sm->pmk_r1_name) < 0) -@@ -2143,7 +2242,8 @@ int wpa_auth_derive_ptk_ft(struct wpa_st +@@ -2143,7 +2243,8 @@ int wpa_auth_derive_ptk_ft(struct wpa_st wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, pmk_r1_len, sm->pmk_r1_name, sm->pairwise, &vlan, expires_in, session_timeout, identity, @@ -415,7 +416,7 @@ return wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce, sm->addr, sm->wpa_auth->addr, sm->pmk_r1_name, -@@ -2986,7 +3086,8 @@ static int wpa_ft_local_derive_pmk_r1(st +@@ -2986,7 +3087,8 @@ static int wpa_ft_local_derive_pmk_r1(st const u8 **identity, size_t *identity_len, const u8 **radius_cui, size_t *radius_cui_len, @@ -425,7 +426,7 @@ { struct wpa_auth_config *conf = &wpa_auth->conf; const struct wpa_ft_pmk_r0_sa *r0; -@@ -3023,7 +3124,8 @@ static int wpa_ft_local_derive_pmk_r1(st +@@ -3023,7 +3125,8 @@ static int wpa_ft_local_derive_pmk_r1(st pmk_r1_name, sm->pairwise, r0->vlan, expires_in, session_timeout, r0->identity, r0->identity_len, @@ -435,7 +436,7 @@ *out_pairwise = sm->pairwise; if (vlan) { -@@ -3033,6 +3135,13 @@ static int wpa_ft_local_derive_pmk_r1(st +@@ -3033,6 +3136,13 @@ static int wpa_ft_local_derive_pmk_r1(st os_memset(vlan, 0, sizeof(*vlan)); } @@ -449,7 +450,7 @@ if (identity && identity_len) { *identity = r0->identity; *identity_len = r0->identity_len; -@@ -3063,6 +3172,7 @@ static int wpa_ft_process_auth_req(struc +@@ -3063,6 +3173,7 @@ static int wpa_ft_process_auth_req(struc u8 *pos, *end; int pairwise, session_timeout = 0; struct vlan_description vlan; @@ -457,7 +458,7 @@ const u8 *identity, *radius_cui; size_t identity_len = 0, radius_cui_len = 0; int use_sha384; -@@ -3152,7 +3262,7 @@ static int wpa_ft_process_auth_req(struc +@@ -3152,7 +3263,7 @@ static int wpa_ft_process_auth_req(struc } else if (wpa_ft_fetch_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1_name, pmk_r1, &pmk_r1_len, &pairwise, &vlan, &identity, &identity_len, &radius_cui, @@ -466,7 +467,7 @@ wpa_printf(MSG_DEBUG, "FT: No PMK-R1 available in local cache for the requested PMKR1Name"); if (wpa_ft_local_derive_pmk_r1(sm->wpa_auth, sm, -@@ -3161,7 +3271,7 @@ static int wpa_ft_process_auth_req(struc +@@ -3161,7 +3272,7 @@ static int wpa_ft_process_auth_req(struc pmk_r1_name, pmk_r1, &pairwise, &vlan, &identity, &identity_len, &radius_cui, &radius_cui_len, @@ -475,7 +476,7 @@ wpa_printf(MSG_DEBUG, "FT: Generated PMK-R1 based on local PMK-R0"); goto pmk_r1_derived; -@@ -3219,6 +3329,7 @@ pmk_r1_derived: +@@ -3219,6 +3330,7 @@ pmk_r1_derived: wpa_printf(MSG_DEBUG, "FT: Failed to configure VLAN"); return WLAN_STATUS_UNSPECIFIED_FAILURE; } @@ -483,7 +484,7 @@ if (wpa_ft_set_identity(sm->wpa_auth, sm->addr, identity, identity_len) < 0 || wpa_ft_set_radius_cui(sm->wpa_auth, sm->addr, -@@ -3791,7 +3902,7 @@ static int wpa_ft_rrb_build_r0(const u8 +@@ -3791,7 +3903,7 @@ static int wpa_ft_rrb_build_r0(const u8 ret = wpa_ft_rrb_build(key, key_len, tlvs, sess_tlv, tlv_auth, pmk_r0->vlan, src_addr, type, @@ -492,7 +493,7 @@ forced_memzero(pmk_r1, sizeof(pmk_r1)); -@@ -3931,7 +4042,7 @@ static int wpa_ft_rrb_rx_pull(struct wpa +@@ -3931,7 +4043,7 @@ static int wpa_ft_rrb_rx_pull(struct wpa ret = wpa_ft_rrb_build(key, key_len, resp, NULL, resp_auth, NULL, wpa_auth->addr, FT_PACKET_R0KH_R1KH_RESP, @@ -501,7 +502,7 @@ } else { ret = wpa_ft_rrb_build_r0(key, key_len, resp, r0, f_r1kh_id, f_s1kh_id, resp_auth, wpa_auth->addr, -@@ -3983,11 +4094,15 @@ static int wpa_ft_rrb_rx_r1(struct wpa_a +@@ -3983,11 +4095,15 @@ static int wpa_ft_rrb_rx_r1(struct wpa_a size_t f_expires_in_len; size_t f_identity_len, f_radius_cui_len; size_t f_session_timeout_len; @@ -517,7 +518,7 @@ size_t pmk_r1_len; RRB_GET_AUTH(FT_RRB_R0KH_ID, r0kh_id, msgtype, -1); -@@ -4096,6 +4211,13 @@ static int wpa_ft_rrb_rx_r1(struct wpa_a +@@ -4096,6 +4212,13 @@ static int wpa_ft_rrb_rx_r1(struct wpa_a wpa_printf(MSG_DEBUG, "FT: vlan %d%s", le_to_host16(vlan.untagged), vlan.tagged[0] ? "+" : ""); @@ -531,7 +532,7 @@ RRB_GET_OPTIONAL(FT_RRB_IDENTITY, identity, msgtype, -1); if (f_identity) wpa_hexdump_ascii(MSG_DEBUG, "FT: Identity", f_identity, -@@ -4118,7 +4240,7 @@ static int wpa_ft_rrb_rx_r1(struct wpa_a +@@ -4118,7 +4241,7 @@ static int wpa_ft_rrb_rx_r1(struct wpa_a f_pmk_r1_name, pairwise, &vlan, expires_in, session_timeout, f_identity, f_identity_len, f_radius_cui, @@ -540,7 +541,7 @@ goto out; ret = 0; -@@ -4431,7 +4553,7 @@ static int wpa_ft_rrb_rx_seq_req(struct +@@ -4431,7 +4554,7 @@ static int wpa_ft_rrb_rx_seq_req(struct if (wpa_ft_rrb_build(key, key_len, NULL, NULL, seq_resp_auth, NULL, wpa_auth->addr, FT_PACKET_R0KH_R1KH_SEQ_RESP,