diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index d46b5c43c..52e9e312d 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -459,7 +459,7 @@ static void eap_erp_remove_keys_realm(struct eap_sm *sm, const char *realm) #endif /* CONFIG_ERP */ -static void eap_peer_erp_free_keys(struct eap_sm *sm) +void eap_peer_erp_free_keys(struct eap_sm *sm) { #ifdef CONFIG_ERP struct eap_erp_key *erp, *tmp; diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h index 0e3569c6b..bc207e74f 100644 --- a/src/eap_peer/eap.h +++ b/src/eap_peer/eap.h @@ -336,6 +336,7 @@ struct ext_password_data; void eap_sm_set_ext_pw_ctx(struct eap_sm *sm, struct ext_password_data *ext); void eap_set_anon_id(struct eap_sm *sm, const u8 *id, size_t len); int eap_peer_was_failure_expected(struct eap_sm *sm); +void eap_peer_erp_free_keys(struct eap_sm *sm); #endif /* IEEE8021X_EAPOL */ diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c index d37511465..895ead679 100644 --- a/src/eapol_supp/eapol_supp_sm.c +++ b/src/eapol_supp/eapol_supp_sm.c @@ -2121,3 +2121,10 @@ int eapol_sm_get_eap_proxy_imsi(struct eapol_sm *sm, char *imsi, size_t *len) return -1; #endif /* CONFIG_EAP_PROXY */ } + + +void eapol_sm_erp_flush(struct eapol_sm *sm) +{ + if (sm) + eap_peer_erp_free_keys(sm->eap); +} diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h index cc3ca67b2..e089e88b5 100644 --- a/src/eapol_supp/eapol_supp_sm.h +++ b/src/eapol_supp/eapol_supp_sm.h @@ -316,6 +316,7 @@ const char * eapol_sm_get_method_name(struct eapol_sm *sm); void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm, struct ext_password_data *ext); int eapol_sm_failed(struct eapol_sm *sm); +void eapol_sm_erp_flush(struct eapol_sm *sm); int eapol_sm_get_eap_proxy_imsi(struct eapol_sm *sm, char *imsi, size_t *len); #else /* IEEE8021X_EAPOL */ static inline struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx) @@ -416,6 +417,9 @@ static inline int eapol_sm_failed(struct eapol_sm *sm) { return 0; } +static inline void eapol_sm_erp_flush(struct eapol_sm *sm) +{ +} #endif /* IEEE8021X_EAPOL */ #endif /* EAPOL_SUPP_SM_H */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 02d429f23..2259a1a82 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -6930,6 +6930,13 @@ static int wpas_ctrl_iface_send_neigbor_rep(struct wpa_supplicant *wpa_s, } +static int wpas_ctrl_iface_erp_flush(struct wpa_supplicant *wpa_s) +{ + eapol_sm_erp_flush(wpa_s->eapol); + return 0; +} + + char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, char *buf, size_t *resp_len) { @@ -7541,6 +7548,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "NEIGHBOR_REP_REQUEST", 20) == 0) { if (wpas_ctrl_iface_send_neigbor_rep(wpa_s, buf + 20)) reply_len = -1; + } else if (os_strcmp(buf, "ERP_FLUSH") == 0) { + wpas_ctrl_iface_erp_flush(wpa_s); } else { os_memcpy(reply, "UNKNOWN COMMAND\n", 16); reply_len = 16; diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index e2ac1e302..778adf9ce 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -2510,6 +2510,12 @@ static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc, } +static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_ctrl_command(ctrl, "ERP_FLUSH"); +} + + enum wpa_cli_cmd_flags { cli_cmd_flag_none = 0x00, cli_cmd_flag_sensitive = 0x01 @@ -3023,6 +3029,8 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { "[ssid=] = Trigger request to AP for neighboring AP report " "(with optional given SSID, default: current SSID)" }, + { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none, + "= flush ERP keys" }, { NULL, NULL, NULL, cli_cmd_flag_none, NULL } };