From 6e80a7a5c10b1290142aecf778ae9c2f8b09c9ee Mon Sep 17 00:00:00 2001 From: Michael Belyaev Date: Wed, 23 Sep 2020 16:57:56 +0300 Subject: [PATCH] Allow RSN IE override in association request. Set LINK_STATE_UP earlier to allow transmission of 802.1X authentication packets. WPA2 Enterprise works --- AirportItlwm/AirportSTAIOCTL.cpp | 24 +++++++++++++++++--- include/Airport/apple80211_ioctl.h | 4 +++- itl80211/openbsd/net80211/ieee80211_output.c | 20 ++++++++++++++-- itl80211/openbsd/net80211/ieee80211_proto.c | 4 ++++ itl80211/openbsd/net80211/ieee80211_var.h | 3 +++ 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/AirportItlwm/AirportSTAIOCTL.cpp b/AirportItlwm/AirportSTAIOCTL.cpp index d0c7fb220..0bb22cb6e 100644 --- a/AirportItlwm/AirportSTAIOCTL.cpp +++ b/AirportItlwm/AirportSTAIOCTL.cpp @@ -540,14 +540,25 @@ getRSN_IE(OSObject *object, struct apple80211_rsn_ie_data *data) return kIOReturnError; } data->version = APPLE80211_VERSION; - data->len = 2 + ic->ic_bss->ni_rsnie[1]; - memcpy(data->ie, ic->ic_bss->ni_rsnie, data->len); + if (ic->ic_rsn_ie_override[1] > 0) { + data->len = 2 + ic->ic_rsn_ie_override[1]; + memcpy(data->ie, ic->ic_rsn_ie_override, data->len); + } + else { + data->len = 2 + ic->ic_bss->ni_rsnie[1]; + memcpy(data->ie, ic->ic_bss->ni_rsnie, data->len); + } return kIOReturnSuccess; } IOReturn AirportItlwm:: setRSN_IE(OSObject *object, struct apple80211_rsn_ie_data *data) { + struct ieee80211com *ic = fHalService->get80211Controller(); + static_assert(sizeof(ic->ic_rsn_ie_override) == APPLE80211_MAX_RSN_IE_LEN, "Max RSN IE length mismatch"); + memcpy(ic->ic_rsn_ie_override, data->ie, APPLE80211_MAX_RSN_IE_LEN); + if (ic->ic_state == IEEE80211_S_RUN && ic->ic_bss != nullptr) + ieee80211_save_ie(data->ie, &ic->ic_bss->ni_rsnie); return kIOReturnSuccess; } @@ -634,6 +645,13 @@ setASSOCIATE(OSObject *object, XYLog("%s [%s]\n", __FUNCTION__, ad->ad_ssid); this->current_authtype_lower = ad->ad_auth_lower; this->current_authtype_upper = ad->ad_auth_upper; + + apple80211_rsn_ie_data rsn_ie_data; + rsn_ie_data.version = APPLE80211_VERSION; + rsn_ie_data.len = ad->ad_rsn_ie[1] + 2; + memcpy(rsn_ie_data.ie, ad->ad_rsn_ie, rsn_ie_data.len); + setRSN_IE(object, &rsn_ie_data); + associateSSID(ad->ad_ssid, ad->ad_ssid_len, ad->ad_bssid, ad->ad_auth_lower, ad->ad_auth_upper, ad->ad_key.key, ad->ad_key.key_len, ad->ad_key.key_index); return kIOReturnSuccess; } @@ -659,7 +677,7 @@ IOReturn AirportItlwm::setDISASSOCIATE(OSObject *object) ieee80211_del_ess(ic, nullptr, 0, 1); ieee80211_deselect_ess(ic); - // ic->ic_rsn_ie_override[1] = 0; + ic->ic_rsn_ie_override[1] = 0; ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); return kIOReturnSuccess; } diff --git a/include/Airport/apple80211_ioctl.h b/include/Airport/apple80211_ioctl.h index dfd9a9900..1f8e6326c 100644 --- a/include/Airport/apple80211_ioctl.h +++ b/include/Airport/apple80211_ioctl.h @@ -557,11 +557,13 @@ struct apple80211_assoc_data u_int8_t ad_ssid[ APPLE80211_MAX_SSID_LEN ]; struct ether_addr ad_bssid; // prefer over ssid if not zeroed struct apple80211_key ad_key; - u_int16_t ad_rsn_ie_len; + u_int8_t unknown[82]; u_int8_t ad_rsn_ie[ APPLE80211_MAX_RSN_IE_LEN ]; u_int32_t ad_flags; // apple80211_assoc_flags }; +static_assert(offsetof(apple80211_assoc_data, ad_rsn_ie) == 206, "offsetof(apple80211_assoc_data, ad_rsn_ie)"); + struct apple80211_deauth_data { u_int32_t version; diff --git a/itl80211/openbsd/net80211/ieee80211_output.c b/itl80211/openbsd/net80211/ieee80211_output.c index 1820e5783..d414171b7 100644 --- a/itl80211/openbsd/net80211/ieee80211_output.c +++ b/itl80211/openbsd/net80211/ieee80211_output.c @@ -1445,13 +1445,29 @@ ieee80211_get_assoc_req(struct ieee80211com *ic, struct ieee80211_node *ni, if (rs->rs_nrates > IEEE80211_RATE_SIZE) frm = ieee80211_add_xrates(frm, rs); if ((ic->ic_flags & IEEE80211_F_RSNON) && - (ni->ni_rsnprotos & IEEE80211_PROTO_RSN)) + (ni->ni_rsnprotos & IEEE80211_PROTO_RSN)) { +#ifdef AIRPORT + if (ic->ic_rsn_ie_override[1] > 0) { + memcpy(frm, ic->ic_rsn_ie_override, 2 + ic->ic_rsn_ie_override[1]); + frm += 2 + ic->ic_rsn_ie_override[1]; + } + else +#endif frm = ieee80211_add_rsn(frm, ic, ni); + } if (ni->ni_flags & IEEE80211_NODE_QOS) frm = ieee80211_add_qos_capability(frm, ic); if ((ic->ic_flags & IEEE80211_F_RSNON) && - (ni->ni_rsnprotos & IEEE80211_PROTO_WPA)) + (ni->ni_rsnprotos & IEEE80211_PROTO_WPA)) { +#ifdef AIRPORT + if (ic->ic_rsn_ie_override[1] > 0) { + memcpy(frm, ic->ic_rsn_ie_override, 2 + ic->ic_rsn_ie_override[1]); + frm += 2 + ic->ic_rsn_ie_override[1]; + } + else +#endif frm = ieee80211_add_wpa(frm, ic, ni); + } if (ic->ic_flags & IEEE80211_F_HTON) { frm = ieee80211_add_htcaps(frm, ic); frm = ieee80211_add_wme_info(frm, ic); diff --git a/itl80211/openbsd/net80211/ieee80211_proto.c b/itl80211/openbsd/net80211/ieee80211_proto.c index 3829eef0c..ef01f8884 100644 --- a/itl80211/openbsd/net80211/ieee80211_proto.c +++ b/itl80211/openbsd/net80211/ieee80211_proto.c @@ -1272,7 +1272,11 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, (ni->ni_flags & IEEE80211_NODE_HT) ? " HT enabled" : ""); } +#ifdef AIRPORT + { +#else if (!(ic->ic_flags & IEEE80211_F_RSNON)) { +#endif /* * NB: When RSN is enabled, we defer setting * the link up until the port is valid. diff --git a/itl80211/openbsd/net80211/ieee80211_var.h b/itl80211/openbsd/net80211/ieee80211_var.h index 3f0d51013..4433db9ec 100644 --- a/itl80211/openbsd/net80211/ieee80211_var.h +++ b/itl80211/openbsd/net80211/ieee80211_var.h @@ -479,6 +479,9 @@ struct ieee80211com { u_int8_t ic_des_essid[IEEE80211_NWID_LEN]; struct ieee80211_channel *ic_des_chan; /* desired channel */ u_int8_t ic_des_bssid[IEEE80211_ADDR_LEN]; +#ifdef AIRPORT + u_int8_t ic_rsn_ie_override[257]; +#endif struct ieee80211_key ic_nw_keys[IEEE80211_GROUP_NKID]; int ic_def_txkey; /* group data key index */ #define ic_wep_txkey ic_def_txkey