]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP: Add wpa_psk_file reloading in runtime
authorMichal Kazior <michal@plume.com>
Wed, 16 Jan 2019 12:35:20 +0000 (13:35 +0100)
committerJouni Malinen <j@w1.fi>
Sat, 26 Jan 2019 15:52:04 +0000 (17:52 +0200)
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>
hostapd/ctrl_iface.c
hostapd/hostapd_cli.c

index 18621d02c3f4f16c71b291ec4aa06f684d5d43a8..df2524a35b808935cf82afc6de067bf316adf0b6 100644 (file)
@@ -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;
index 3339924ebf26eefb4c87fc6785107afb62faaf22..23c592a6b0a6160e504824f8974d0d2df2794b03 100644 (file)
@@ -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 }
 };