AP: Add wpa_psk_file reloading in runtime
The wpa_psk_file can now be modified and hostapd can be told to re-read it with the control interface RELOAD_WPA_PSK command: $ hostapd_cli reload_wpa_psk It must be noted special care must be taken if WPS is configured (wps_state=2, eap_server=1) because WPS appends PMKs to the wpa_psk_file. Signed-off-by: Michal Kazior <michal@plume.com>
This commit is contained in:
parent
ec5c39a557
commit
83c8608132
2 changed files with 69 additions and 0 deletions
|
@ -1488,6 +1488,63 @@ static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
hostapd_ctrl_iface_kick_mismatch_psk_sta_iter(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, void *ctx)
|
||||
{
|
||||
struct hostapd_wpa_psk *psk;
|
||||
const u8 *pmk;
|
||||
int pmk_len;
|
||||
int pmk_match;
|
||||
int sta_match;
|
||||
int bss_match;
|
||||
int reason;
|
||||
|
||||
pmk = wpa_auth_get_pmk(sta->wpa_sm, &pmk_len);
|
||||
|
||||
for (psk = hapd->conf->ssid.wpa_psk; pmk && psk; psk = psk->next) {
|
||||
pmk_match = PMK_LEN == pmk_len &&
|
||||
os_memcmp(psk->psk, pmk, pmk_len) == 0;
|
||||
sta_match = psk->group == 0 &&
|
||||
os_memcmp(sta->addr, psk->addr, ETH_ALEN) == 0;
|
||||
bss_match = psk->group == 1;
|
||||
|
||||
if (pmk_match && (sta_match || bss_match))
|
||||
return 0;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_INFO, "STA " MACSTR
|
||||
" PSK/passphrase no longer valid - disconnect",
|
||||
MAC2STR(sta->addr));
|
||||
reason = WLAN_REASON_PREV_AUTH_NOT_VALID;
|
||||
hostapd_drv_sta_deauth(hapd, sta->addr, reason);
|
||||
ap_sta_deauthenticate(hapd, sta, reason);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_ctrl_iface_reload_wpa_psk(struct hostapd_data *hapd)
|
||||
{
|
||||
struct hostapd_bss_config *conf = hapd->conf;
|
||||
int err;
|
||||
|
||||
hostapd_config_clear_wpa_psk(&conf->ssid.wpa_psk);
|
||||
|
||||
err = hostapd_setup_wpa_psk(conf);
|
||||
if (err < 0) {
|
||||
wpa_printf(MSG_ERROR, "Reloading WPA-PSK passwords failed: %d",
|
||||
err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ap_for_each_sta(hapd, hostapd_ctrl_iface_kick_mismatch_psk_sta_iter,
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
|
||||
static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)
|
||||
|
@ -3013,6 +3070,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
|
|||
} else if (os_strncmp(buf, "ENABLE", 6) == 0) {
|
||||
if (hostapd_ctrl_iface_enable(hapd->iface))
|
||||
reply_len = -1;
|
||||
} else if (os_strcmp(buf, "RELOAD_WPA_PSK") == 0) {
|
||||
if (hostapd_ctrl_iface_reload_wpa_psk(hapd))
|
||||
reply_len = -1;
|
||||
} else if (os_strncmp(buf, "RELOAD", 6) == 0) {
|
||||
if (hostapd_ctrl_iface_reload(hapd->iface))
|
||||
reply_len = -1;
|
||||
|
|
|
@ -1494,6 +1494,13 @@ static int hostapd_cli_cmd_req_beacon(struct wpa_ctrl *ctrl, int argc,
|
|||
}
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
return wpa_ctrl_command(ctrl, "RELOAD_WPA_PSK");
|
||||
}
|
||||
|
||||
|
||||
struct hostapd_cli_cmd {
|
||||
const char *cmd;
|
||||
int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
|
||||
|
@ -1669,6 +1676,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
|
|||
"<addr> = poll a STA to check connectivity with a QoS null frame" },
|
||||
{ "req_beacon", hostapd_cli_cmd_req_beacon, NULL,
|
||||
"<addr> [req_mode=] <measurement request hexdump> = send a Beacon report request to a station" },
|
||||
{ "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL,
|
||||
"= reload wpa_psk_file only" },
|
||||
{ NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue