* @temporary_network: Indicates if a temporary network was created to perform
* PASN authentication.
* @password: Password of user requested network.
+ * @comeback_len: Length of the comeback cookie data.
+ * @comeback: Comeback cookie data that may be present in case a temporary
+ * rejection is received from the AP.
+ * @comeback_after: The time after which the STA can try for PASN handshake in
+ * case of temporary rejection.
* @ltf_keyseed_required: Indicates whether LTF keyseed generation is required
* @status: PASN response status, %PASN_STATUS_SUCCESS for successful
* authentication, use %PASN_STATUS_FAILURE if PASN authentication
int group;
bool temporary_network;
char *password;
+ size_t comeback_len;
+ u8 *comeback;
+ u16 comeback_after;
bool ltf_keyseed_required;
enum pasn_status status;
};
wpa_cipher_to_cipher_suite(cipher)))
goto fail;
+ if (params->peer[i].comeback_after &&
+ params->peer[i].comeback_len &&
+ params->peer[i].comeback &&
+ (nla_put_u16(msg,
+ QCA_WLAN_VENDOR_ATTR_PASN_PEER_COMEBACK_AFTER,
+ params->peer[i].comeback_after) ||
+ nla_put(msg, QCA_WLAN_VENDOR_ATTR_PASN_PEER_COOKIE,
+ params->peer[i].comeback_len,
+ params->peer[i].comeback)))
+ goto fail;
+
wpa_printf(MSG_DEBUG,
"nl80211: Own address[%u]: " MACSTR
" Peer address[%u]: " MACSTR
os_memcpy(pw[idx], password, password_len);
event.pasn_auth.peer[idx].password = pw[idx];
}
+ if (cfg[QCA_WLAN_VENDOR_ATTR_PASN_PEER_COOKIE]) {
+ event.pasn_auth.peer[idx].comeback_len =
+ nla_len(cfg[QCA_WLAN_VENDOR_ATTR_PASN_PEER_COOKIE]);
+ event.pasn_auth.peer[idx].comeback =
+ nla_data(cfg[QCA_WLAN_VENDOR_ATTR_PASN_PEER_COOKIE]);
+ }
wpa_printf(MSG_DEBUG, "nl80211: PASN auth action: peer addr "
MACSTR " AKMP 0x%x cipher 0x%x",
struct pasn_auth *pasn_params)
{
struct pasn_peer *peer;
- u8 comeback_len = 0;
- const u8 *comeback = NULL;
struct wpa_ssid *ssid;
if (!pasn_params)
peer->peer_addr, peer->akmp,
peer->cipher, peer->group,
peer->network_id,
- comeback, comeback_len)) {
+ peer->comeback, peer->comeback_len)) {
peer->status = PASN_STATUS_FAILURE;
wpa_msg(wpa_s, MSG_INFO, PASN_AUTH_STATUS MACSTR
" akmp=%s, status=%u",
peer->status);
wpa_s->pasn_count++;
str_clear_free(peer->password);
+ os_free(peer->comeback);
peer->password = NULL;
+ peer->comeback = NULL;
continue;
}
wpa_printf(MSG_DEBUG, "PASN: Sent PASN auth start for " MACSTR,
for (i = 0; i < pasn_params->num_peers; i++) {
peer = &pasn_params->peer[i];
str_clear_free(peer->password);
+ os_free(peer->comeback);
if (peer->temporary_network) {
ssid = wpa_config_get_network(wpa_s->conf,
}
+static void wpas_pasn_store_comeback_data(struct wpa_supplicant *wpa_s,
+ const struct wpabuf *comeback,
+ u16 comeback_after)
+{
+ struct pasn_peer *peer;
+
+ if (!wpa_s->pasn_params)
+ return;
+
+ peer = &wpa_s->pasn_params->peer[wpa_s->pasn_count];
+ if (!peer)
+ return;
+
+ os_free(peer->comeback);
+ peer->comeback = os_zalloc(wpabuf_len(comeback));
+ if (!peer->comeback) {
+ wpa_printf(MSG_ERROR,
+ "PASN: Mem alloc failed for comeback data");
+ return;
+ }
+
+ peer->comeback_len = wpabuf_len(comeback);
+ os_memcpy(peer->comeback, wpabuf_head_u8(comeback), peer->comeback_len);
+ peer->comeback_after = comeback_after;
+}
+
+
int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
const struct ieee80211_mgmt *mgmt, size_t len)
{
forced_memzero(pasn_get_ptk(pasn), sizeof(pasn->ptk));
if (ret == -1) {
+ if (pasn->status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
+ pasn->comeback && wpabuf_len(pasn->comeback))
+ wpas_pasn_store_comeback_data(wpa_s, pasn->comeback,
+ pasn->comeback_after);
wpas_pasn_auth_stop(wpa_s);
wpas_pasn_auth_work_done(wpa_s, PASN_STATUS_FAILURE);
}
return;
}
}
+ if (src->comeback_len && src->comeback) {
+ dst->comeback = os_memdup(src->comeback,
+ src->comeback_len);
+ if (!dst->comeback) {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Mem alloc failed for comeback cookie");
+ return;
+ }
+ dst->comeback_len = src->comeback_len;
+ }
if (!is_zero_ether_addr(src->own_addr)) {
os_memcpy(dst->own_addr, src->own_addr, ETH_ALEN);