Rekeying a pairwise key using only keyid 0 (PTK0 rekeys) has many broken implementations and should be avoided for both security and usability reasons. Add the new configuration option "wpa_deny_ptk0_rekey" - defaulting to replace any PTK0 rekey attempt with a fast reconnect. Signed-off-by: Alexander Wetzel <alexander@xxxxxxxxxxxxxx> --- src/eapol_supp/eapol_supp_sm.c | 15 +++++++++++++++ src/eapol_supp/eapol_supp_sm.h | 8 ++++++++ src/rsn_supp/wpa.c | 18 ++++++++++++++++++ src/rsn_supp/wpa.h | 5 ++++- src/rsn_supp/wpa_i.h | 7 +++++++ wpa_supplicant/ap.c | 1 + wpa_supplicant/config.c | 2 ++ wpa_supplicant/config_file.c | 1 + wpa_supplicant/config_ssid.h | 11 +++++++++++ wpa_supplicant/events.c | 16 ++++++++++------ wpa_supplicant/ibss_rsn.c | 9 ++++++++- wpa_supplicant/notify.c | 10 ++++++++++ wpa_supplicant/notify.h | 1 + wpa_supplicant/wpa_cli.c | 5 +++-- wpa_supplicant/wpa_supplicant.c | 26 +++++++++++++++++++++++++- wpa_supplicant/wpa_supplicant.conf | 25 +++++++++++++++++++++++++ wpa_supplicant/wpa_supplicant_i.h | 3 +++ wpa_supplicant/wpas_glue.c | 17 +++++++++++++++++ 18 files changed, 169 insertions(+), 11 deletions(-) diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c index f1ca0a859..90a551200 100644 --- a/src/eapol_supp/eapol_supp_sm.c +++ b/src/eapol_supp/eapol_supp_sm.c @@ -200,6 +200,17 @@ static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx) } +static int eapol_sm_confirm_auth(struct eapol_sm *sm) +{ + if (!sm->ctx->confirm_auth_cb) + return 0; + + wpa_printf(MSG_DEBUG, + "EAPOL: Confirm planned PTK key install or trigger reconnect"); + return sm->ctx->confirm_auth_cb(sm->ctx->ctx); +} + + static void eapol_enable_timer_tick(struct eapol_sm *sm) { if (sm->timer_tick_enabled) @@ -316,6 +327,10 @@ SM_STATE(SUPP_PAE, AUTHENTICATED) SM_STATE(SUPP_PAE, RESTART) { + if (eapol_sm_confirm_auth(sm)) + /* Don't process restart, we are already reconnecting */ + return; + SM_ENTRY(SUPP_PAE, RESTART); sm->eapRestart = TRUE; if (sm->altAccept) { diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h index c9d7522d5..3511c12d5 100644 --- a/src/eapol_supp/eapol_supp_sm.h +++ b/src/eapol_supp/eapol_supp_sm.h @@ -298,6 +298,14 @@ struct eapol_ctx { * @len: Length of anonymous identity in octets */ void (*set_anon_id)(void *ctx, const u8 *id, size_t len); + + /** + * confirm_auth_cb - Callback confirming if we can install a new PTK + * Triggers a reconnect when the check fails. + * @ctx: Callback context (ctx) + * Returns: 0 when authentication can continue, -1 when reconnecting + */ + int (*confirm_auth_cb)(void *ctx); }; diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index adcda3443..e8931ff08 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -183,6 +183,14 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise) int key_info, ver; u8 bssid[ETH_ALEN], *rbuf, *key_mic, *mic; + if (pairwise && sm->wpa_deny_ptk0_rekey && + wpa_sm_get_state(sm) == WPA_COMPLETED) { + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, + "WPA: PTK0 rekey not allowed, reconnecting"); + wpa_sm_reconnect(sm); + return; + } + if (wpa_use_akm_defined(sm->key_mgmt)) ver = WPA_KEY_INFO_TYPE_AKM_DEFINED; else if (wpa_key_mgmt_ft(sm->key_mgmt) || @@ -607,6 +615,13 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, "found (msg 1 of 4)"); return; } + if (sm->wpa_deny_ptk0_rekey && + wpa_sm_get_state(sm) == WPA_COMPLETED) { + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, + "WPA: PTK0 rekey not allowed, reconnecting"); + wpa_sm_reconnect(sm); + return; + } wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE); wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way " @@ -3043,6 +3058,9 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, case WPA_PARAM_PAIRWISE: sm->pairwise_cipher = value; break; + case WPA_PARAM_DENY_PTK0_REKEY: + sm->wpa_deny_ptk0_rekey = value; + break; case WPA_PARAM_GROUP: sm->group_cipher = value; break; diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index f1fbb1bb5..ef77475cb 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -26,7 +26,8 @@ struct wpa_sm_ctx { void (*set_state)(void *ctx, enum wpa_states state); enum wpa_states (*get_state)(void *ctx); - void (*deauthenticate)(void * ctx, u16 reason_code); + void (*deauthenticate)(void *ctx, u16 reason_code); + void (*reconnect)(void *ctx); int (*set_key)(void *ctx, enum wpa_alg alg, const u8 *addr, int key_idx, int set_tx, const u8 *seq, size_t seq_len, @@ -100,6 +101,7 @@ enum wpa_sm_conf_params { WPA_PARAM_MFP, WPA_PARAM_OCV, WPA_PARAM_SAE_PWE, + WPA_PARAM_DENY_PTK0_REKEY }; struct rsn_supp_config { @@ -111,6 +113,7 @@ struct rsn_supp_config { const u8 *ssid; size_t ssid_len; int wpa_ptk_rekey; + int wpa_deny_ptk0_rekey; int p2p; int wpa_rsc_relaxation; const u8 *fils_cache_id; diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 2a433425c..8faaa85a3 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -61,6 +61,7 @@ struct wpa_sm { u8 ssid[32]; size_t ssid_len; int wpa_ptk_rekey; + int wpa_deny_ptk0_rekey:1; int p2p; int wpa_rsc_relaxation; @@ -195,6 +196,12 @@ static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, u16 reason_code) sm->ctx->deauthenticate(sm->ctx->ctx, reason_code); } +static inline void wpa_sm_reconnect(struct wpa_sm *sm) +{ + WPA_ASSERT(sm->ctx->reconnect); + sm->ctx->reconnect(sm->ctx->ctx); +} + static inline int wpa_sm_set_key(struct wpa_sm *sm, enum wpa_alg alg, const u8 *addr, int key_idx, int set_tx, const u8 *seq, size_t seq_len, diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index e552306d7..004d86bc3 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -349,6 +349,7 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, bss->isolate = !wpa_s->conf->p2p_intra_bss; bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk; + bss->wpa_deny_ptk0_rekey = ssid->wpa_deny_ptk0_rekey; if (ssid->p2p_group) { os_memcpy(bss->ip_addr_go, wpa_s->p2pdev->conf->ip_addr_go, 4); diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 3b37d152d..02d5f0b07 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2495,6 +2495,7 @@ static const struct parse_data ssid_fields[] = { { INT(dot11MeshHoldingTimeout) }, #endif /* CONFIG_MESH */ { INT(wpa_ptk_rekey) }, + { INT_RANGE(wpa_deny_ptk0_rekey, 0, 2) }, { INT(group_rekey) }, { STR(bgscan) }, { INT_RANGE(ignore_broadcast_ssid, 0, 2) }, @@ -3016,6 +3017,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid) { ssid->proto = DEFAULT_PROTO; ssid->pairwise_cipher = DEFAULT_PAIRWISE; + ssid->wpa_deny_ptk0_rekey = PTK0_REKEY_ALLOW_NEVER; ssid->group_cipher = DEFAULT_GROUP; ssid->key_mgmt = DEFAULT_KEY_MGMT; ssid->bg_scan_period = DEFAULT_BG_SCAN_PERIOD; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 2a0c7803e..16b5251d0 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -900,6 +900,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INT_DEF(mesh_rssi_threshold, DEFAULT_MESH_RSSI_THRESHOLD); #endif /* CONFIG_MESH */ INT(wpa_ptk_rekey); + INT(wpa_deny_ptk0_rekey); INT(group_rekey); INT(ignore_broadcast_ssid); #ifdef CONFIG_DPP diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 98db1fe1a..f4bbb7882 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -553,6 +553,17 @@ struct wpa_ssid { */ int wpa_ptk_rekey; + /** wpa_deny_ptk0_rekey - Control PTK0 rekeying + * + * Rekeying a pairwise key using only keyid 0 (PTK0 rekeys) has many + * broken implementations and should only be used when known to be safe. + * + * 0 = always rekey when configured/instructed (old behavior) + * 1 = only rekey when local driver is able to do it bug free + * 2 = never allow PTK0 rekeys (default) + */ + int wpa_deny_ptk0_rekey; + /** * group_rekey - Group rekeying time in seconds * diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index d75a50eaf..4b02c2b2c 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3214,8 +3214,9 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, if (wpa_s->wpa_state == WPA_COMPLETED && wpa_s->current_ssid && wpa_s->current_ssid->mode == WPAS_MODE_INFRA && - !locally_generated && - disconnect_reason_recoverable(reason_code)) { + (wpa_s->own_reconnect_req || + (!locally_generated && + disconnect_reason_recoverable(reason_code)))) { /* * It looks like the AP has dropped association with * us, but could allow us to get back in. Try to @@ -3224,11 +3225,12 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, */ fast_reconnect = wpa_s->current_bss; fast_reconnect_ssid = wpa_s->current_ssid; - } else if (wpa_s->wpa_state >= WPA_ASSOCIATING) + } else if (wpa_s->wpa_state >= WPA_ASSOCIATING) { wpa_supplicant_req_scan(wpa_s, 0, 100000); - else + } else { wpa_dbg(wpa_s, MSG_DEBUG, "Do not request new " "immediate scan"); + } } else { wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect disabled: do not " "try to re-connect"); @@ -3270,15 +3272,16 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, fast_reconnect->ssid_len) && !wpas_temp_disabled(wpa_s, fast_reconnect_ssid) && !wpa_is_bss_tmp_disallowed(wpa_s, fast_reconnect)) { -#ifndef CONFIG_NO_SCAN_PROCESSING wpa_dbg(wpa_s, MSG_DEBUG, "Try to reconnect to the same BSS"); if (wpa_supplicant_connect(wpa_s, fast_reconnect, fast_reconnect_ssid) < 0) { +#ifndef CONFIG_NO_SCAN_PROCESSING /* Recover through full scan */ wpa_supplicant_req_scan(wpa_s, 0, 100000); - } #endif /* CONFIG_NO_SCAN_PROCESSING */ + } } else if (fast_reconnect) { +#ifndef CONFIG_NO_SCAN_PROCESSING /* * Could not reconnect to the same BSS due to network being * disabled. Use a new scan to match the alternative behavior @@ -3286,6 +3289,7 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, * way that enforces disabled network rules. */ wpa_supplicant_req_scan(wpa_s, 0, 100000); +#endif /* CONFIG_NO_SCAN_PROCESSING */ } } diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c index 48dd66b12..93a683551 100644 --- a/wpa_supplicant/ibss_rsn.c +++ b/wpa_supplicant/ibss_rsn.c @@ -194,7 +194,13 @@ static void supp_cancel_auth_timeout(void *ctx) } -static void supp_deauthenticate(void * ctx, u16 reason_code) +static void supp_deauthenticate(void *ctx, u16 reason_code) +{ + wpa_printf(MSG_DEBUG, "SUPP: %s (TODO)", __func__); +} + + +static void supp_reconnect(void *ctx) { wpa_printf(MSG_DEBUG, "SUPP: %s (TODO)", __func__); } @@ -219,6 +225,7 @@ static int ibss_rsn_supp_init(struct ibss_rsn_peer *peer, const u8 *own_addr, ctx->mlme_setprotection = supp_mlme_setprotection; ctx->cancel_auth_timeout = supp_cancel_auth_timeout; ctx->deauthenticate = supp_deauthenticate; + ctx->reconnect = supp_reconnect; peer->supp = wpa_sm_init(ctx); if (peer->supp == NULL) { wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_init() failed"); diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index 0ba1e144c..6758e6cf0 100644 --- a/wpa_supplicant/notify.c +++ b/wpa_supplicant/notify.c @@ -851,6 +851,16 @@ void wpas_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code) wpa_msg(wpa_s, MSG_ERROR, WPA_EVENT_EAP_ERROR_CODE "%d", error_code); } +int wpas_notify_eap_auth_start(struct wpa_supplicant *wpa_s) +{ + if (!wpa_s->new_connection && wpa_s->deny_ptk0_rekey) { + wpa_msg(wpa_s, MSG_WARNING, + "WPA: PTK0 rekey not allowed, reconnecting"); + wpa_supplicant_reconnect(wpa_s); + return -1; + } + return 0; +} void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h index e843aa124..bc9a022e5 100644 --- a/wpa_supplicant/notify.h +++ b/wpa_supplicant/notify.h @@ -140,6 +140,7 @@ void wpas_notify_preq(struct wpa_supplicant *wpa_s, void wpas_notify_eap_status(struct wpa_supplicant *wpa_s, const char *status, const char *parameter); void wpas_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code); +int wpas_notify_eap_auth_start(struct wpa_supplicant *wpa_s); void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); void wpas_notify_network_type_changed(struct wpa_supplicant *wpa_s, diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 6d3f56a87..63c681ffa 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1440,8 +1440,9 @@ static const char *network_fields[] = { "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout", "dot11MeshHoldingTimeout", #endif /* CONFIG_MESH */ - "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid", - "enable_edmg", "edmg_channel", + "wpa_ptk_rekey", + "wpa_deny_ptk0_rekey", "bgscan", + "ignore_broadcast_ssid", "enable_edmg", "edmg_channel", #ifdef CONFIG_P2P "go_p2p_dev_addr", "p2p_client_list", "psk_list", #endif /* CONFIG_P2P */ diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 08b140312..e6460fa4a 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1271,6 +1271,22 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, int sel, proto; const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen; + if (ssid->mode == WPAS_MODE_IBSS) { + wpa_msg(wpa_s, MSG_INFO, + "PTK rekey not supported, ignoring PTK0 rekey setting"); + } else if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED) && + (ssid->wpa_deny_ptk0_rekey == PTK0_REKEY_ALLOW_NEVER || + (ssid->wpa_deny_ptk0_rekey == PTK0_REKEY_ALLOW_LOCAL_OK && + !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAFE_PTK0_REKEYS)))) { + wpa_msg(wpa_s, MSG_INFO, "Disable PTK0 rekey support"); + wpa_s->deny_ptk0_rekey = 1; + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DENY_PTK0_REKEY, 1); + } else { + wpa_dbg(wpa_s, MSG_DEBUG, "Support PTK0 rekey"); + wpa_s->deny_ptk0_rekey = 0; + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DENY_PTK0_REKEY, 0); + } + if (bss) { bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); @@ -2044,6 +2060,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, int rand_style; wpa_s->own_disconnect_req = 0; + wpa_s->own_reconnect_req = 0; /* * If we are starting a new connection, any previously pending EAPOL @@ -3830,6 +3847,13 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, wpa_supplicant_clear_connection(wpa_s, addr); } +void wpa_supplicant_reconnect(struct wpa_supplicant *wpa_s) +{ + wpa_s->own_reconnect_req = 1; + wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED); + +} + static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { @@ -7069,7 +7093,7 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid) * There is no point in blacklisting the AP if this event is * generated based on local request to disconnect. */ - if (wpa_s->own_disconnect_req) { + if (wpa_s->own_disconnect_req || wpa_s->own_reconnect_req) { wpa_s->own_disconnect_req = 0; wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure due to local request to disconnect"); diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 328f91a97..2665a8d11 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -1102,6 +1102,31 @@ fast_reauth=1 # wpa_ptk_rekey: Maximum lifetime for PTK in seconds. This can be used to # enforce rekeying of PTK to mitigate some attacks against TKIP deficiencies. # +# wpa_deny_ptk0_rekey: Control PTK0 rekeying. +# Rekeying the PTK without using "Extended Key ID for Individually Addressed +# Frames" can - depending on the cards/drivers - reduce both the security and +# the stability of connections. Both ends can freeze the connection or even leak +# the PTK by repeating MPDU's without encryption. To avoid the issues +# wpa_supplicant is now by default replacing all PTK rekeys using only keyid 0 +# (PTK0 rekeys) with disconnects. +# This is a regression for setups able to rekey the PTK and actually do so. +# +# Eap reauthentication depends on replacing the PTK and is therefore just +# another way to rekey the PTK and affected by the setting, too. +# +# Unfortunately there is no way to detect if a remote stations can safely rekey +# the PTK and the default is therefore to replace all those rekeys with a +# disconnect when not two keyids (Extended Key ID for Individually Addressed +# Frames) are available for it. +# +# If you are sure your cards/drivers don't need the workaround the old behavior +# can be restored by setting wpa_deny_ptk0_rekey = 0. +# +# Available options: +# 0 = always rekey when configured/instructed (old behavior) +# 1 = only rekey when local driver is able to do it bug free +# 2 = never allow problematic PTK0 rekeys (default) +# # group_rekey: Group rekeying time in seconds. This value, if non-zero, is used # as the dot11RSNAConfigGroupRekeyTime parameter when operating in # Authenticator role in IBSS, or in AP and mesh modes. diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index b8313f935..4e7faa246 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -553,6 +553,7 @@ struct wpa_supplicant { /* Selected configuration (based on Beacon/ProbeResp WPA IE) */ int pairwise_cipher; + int deny_ptk0_rekey; int group_cipher; int key_mgmt; int wpa_proto; @@ -1072,6 +1073,7 @@ struct wpa_supplicant { unsigned int wmm_ac_supported:1; unsigned int ext_work_in_progress:1; unsigned int own_disconnect_req:1; + unsigned int own_reconnect_req:1; unsigned int ignore_post_flush_scan_res:1; #define MAC_ADDR_RAND_SCAN BIT(0) @@ -1326,6 +1328,7 @@ const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s); void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s); void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, u16 reason_code); +void wpa_supplicant_reconnect(struct wpa_supplicant *wpa_s); struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s); int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id); diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index d80b8f28d..1f78e2d93 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -476,6 +476,12 @@ static void _wpa_supplicant_deauthenticate(void *wpa_s, u16 reason_code) } +static void _wpa_supplicant_reconnect(void *wpa_s) +{ + wpa_supplicant_reconnect(wpa_s); +} + + static void * wpa_supplicant_get_network_ctx(void *wpa_s) { return wpa_supplicant_get_ssid(wpa_s); @@ -1047,6 +1053,14 @@ static void wpa_supplicant_eap_error_cb(void *ctx, int error_code) } +static int wpa_supplicant_eap_auth_start_cb(void *ctx) +{ + struct wpa_supplicant *wpa_s = ctx; + + return wpas_notify_eap_auth_start(wpa_s); +} + + static void wpa_supplicant_set_anon_id(void *ctx, const u8 *id, size_t len) { struct wpa_supplicant *wpa_s = ctx; @@ -1125,6 +1139,7 @@ int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s) ctx->cert_in_cb = wpa_s->conf->cert_in_cb; ctx->status_cb = wpa_supplicant_status_cb; ctx->eap_error_cb = wpa_supplicant_eap_error_cb; + ctx->confirm_auth_cb = wpa_supplicant_eap_auth_start_cb; ctx->set_anon_id = wpa_supplicant_set_anon_id; ctx->cb_ctx = wpa_s; wpa_s->eapol = eapol_sm_init(ctx); @@ -1211,6 +1226,7 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) ctx->set_state = _wpa_supplicant_set_state; ctx->get_state = _wpa_supplicant_get_state; ctx->deauthenticate = _wpa_supplicant_deauthenticate; + ctx->reconnect = _wpa_supplicant_reconnect; ctx->set_key = wpa_supplicant_set_key; ctx->get_network_ctx = wpa_supplicant_get_network_ctx; ctx->get_bssid = wpa_supplicant_get_bssid; @@ -1275,6 +1291,7 @@ void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s, conf.ssid = ssid->ssid; conf.ssid_len = ssid->ssid_len; conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey; + conf.wpa_deny_ptk0_rekey = ssid->wpa_deny_ptk0_rekey; #ifdef CONFIG_P2P if (ssid->p2p_group && wpa_s->current_bss && !wpa_s->p2p_disable_ip_addr_req) { -- 2.24.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap