]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - hostapd/ctrl_iface.c
macsec: Add configuration parameters for hostapd
[thirdparty/hostap.git] / hostapd / ctrl_iface.c
index 75f12e543f210ddb369f5bfa34db2654d9cf15bf..e4b16e61af0ecc6042a1432593d52b59f760bd34 100644 (file)
@@ -883,7 +883,7 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
                /* TODO: TSF configurable/learnable */
                bss_term_dur[0] = 4; /* Subelement ID */
                bss_term_dur[1] = 10; /* Length */
-               os_memset(bss_term_dur, 2, 8);
+               os_memset(&bss_term_dur[2], 0, 8);
                end = os_strchr(pos, ',');
                if (end == NULL) {
                        wpa_printf(MSG_DEBUG, "Invalid bss_term data");
@@ -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)
@@ -2826,6 +2883,34 @@ static int hostapd_ctrl_iface_acl_add_mac(struct mac_acl_entry **acl, int *num,
 }
 
 
+static int hostapd_ctrl_iface_get_capability(struct hostapd_data *hapd,
+                                            const char *field, char *buf,
+                                            size_t buflen)
+{
+       wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s'", field);
+
+#ifdef CONFIG_DPP
+       if (os_strcmp(field, "dpp") == 0) {
+               int res;
+
+#ifdef CONFIG_DPP2
+               res = os_snprintf(buf, buflen, "DPP=2");
+#else /* CONFIG_DPP2 */
+               res = os_snprintf(buf, buflen, "DPP=1");
+#endif /* CONFIG_DPP2 */
+               if (os_snprintf_error(buflen, res))
+                       return -1;
+               return res;
+       }
+#endif /* CONFIG_DPP */
+
+       wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
+                  field);
+
+       return -1;
+}
+
+
 static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                                              char *buf, char *reply,
                                              int reply_size,
@@ -3013,6 +3098,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;
@@ -3182,7 +3270,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                                reply_len = -1;
                }
        } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GEN ", 18) == 0) {
-               res = hostapd_dpp_bootstrap_gen(hapd, buf + 18);
+               res = dpp_bootstrap_gen(hapd->iface->interfaces->dpp, buf + 18);
                if (res < 0) {
                        reply_len = -1;
                } else {
@@ -3191,12 +3279,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                                reply_len = -1;
                }
        } else if (os_strncmp(buf, "DPP_BOOTSTRAP_REMOVE ", 21) == 0) {
-               if (hostapd_dpp_bootstrap_remove(hapd, buf + 21) < 0)
+               if (dpp_bootstrap_remove(hapd->iface->interfaces->dpp,
+                                        buf + 21) < 0)
                        reply_len = -1;
        } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GET_URI ", 22) == 0) {
                const char *uri;
 
-               uri = hostapd_dpp_bootstrap_get_uri(hapd, atoi(buf + 22));
+               uri = dpp_bootstrap_get_uri(hapd->iface->interfaces->dpp,
+                                           atoi(buf + 22));
                if (!uri) {
                        reply_len = -1;
                } else {
@@ -3205,8 +3295,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                                reply_len = -1;
                }
        } else if (os_strncmp(buf, "DPP_BOOTSTRAP_INFO ", 19) == 0) {
-               reply_len = hostapd_dpp_bootstrap_info(hapd, atoi(buf + 19),
-                                                      reply, reply_size);
+               reply_len = dpp_bootstrap_info(hapd->iface->interfaces->dpp,
+                                              atoi(buf + 19),
+                       reply, reply_size);
        } else if (os_strncmp(buf, "DPP_AUTH_INIT ", 14) == 0) {
                if (hostapd_dpp_auth_init(hapd, buf + 13) < 0)
                        reply_len = -1;
@@ -3217,7 +3308,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                hostapd_dpp_stop(hapd);
                hostapd_dpp_listen_stop(hapd);
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_ADD", 20) == 0) {
-               res = hostapd_dpp_configurator_add(hapd, buf + 20);
+               res = dpp_configurator_add(hapd->iface->interfaces->dpp,
+                                          buf + 20);
                if (res < 0) {
                        reply_len = -1;
                } else {
@@ -3226,15 +3318,17 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                                reply_len = -1;
                }
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
-               if (hostapd_dpp_configurator_remove(hapd, buf + 24) < 0)
+               if (dpp_configurator_remove(hapd->iface->interfaces->dpp,
+                                           buf + 24) < 0)
                        reply_len = -1;
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) {
-               if (hostapd_dpp_configurator_sign(hapd, buf + 22) < 0)
+               if (hostapd_dpp_configurator_sign(hapd, buf + 21) < 0)
                        reply_len = -1;
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_GET_KEY ", 25) == 0) {
-               reply_len = hostapd_dpp_configurator_get_key(hapd,
-                                                            atoi(buf + 25),
-                                                            reply, reply_size);
+               reply_len = dpp_configurator_get_key_id(
+                       hapd->iface->interfaces->dpp,
+                       atoi(buf + 25),
+                       reply, reply_size);
        } else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
                res = hostapd_dpp_pkex_add(hapd, buf + 12);
                if (res < 0) {
@@ -3253,6 +3347,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                if (radius_server_dac_request(hapd->radius_srv, buf + 12) < 0)
                        reply_len = -1;
 #endif /* RADIUS_SERVER */
+       } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
+               reply_len = hostapd_ctrl_iface_get_capability(
+                       hapd, buf + 15, reply, reply_size);
        } else {
                os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
                reply_len = 16;
@@ -3506,18 +3603,18 @@ fail:
        }
 
        if (hapd->conf->ctrl_interface_gid_set &&
-           chown(hapd->conf->ctrl_interface, -1,
-                 hapd->conf->ctrl_interface_gid) < 0) {
-               wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
+           lchown(hapd->conf->ctrl_interface, -1,
+                  hapd->conf->ctrl_interface_gid) < 0) {
+               wpa_printf(MSG_ERROR, "lchown[ctrl_interface]: %s",
                           strerror(errno));
                return -1;
        }
 
        if (!hapd->conf->ctrl_interface_gid_set &&
            hapd->iface->interfaces->ctrl_iface_group &&
-           chown(hapd->conf->ctrl_interface, -1,
-                 hapd->iface->interfaces->ctrl_iface_group) < 0) {
-               wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
+           lchown(hapd->conf->ctrl_interface, -1,
+                  hapd->iface->interfaces->ctrl_iface_group) < 0) {
+               wpa_printf(MSG_ERROR, "lchown[ctrl_interface]: %s",
                           strerror(errno));
                return -1;
        }
@@ -3590,16 +3687,16 @@ fail:
        }
 
        if (hapd->conf->ctrl_interface_gid_set &&
-           chown(fname, -1, hapd->conf->ctrl_interface_gid) < 0) {
-               wpa_printf(MSG_ERROR, "chown[ctrl_interface/ifname]: %s",
+           lchown(fname, -1, hapd->conf->ctrl_interface_gid) < 0) {
+               wpa_printf(MSG_ERROR, "lchown[ctrl_interface/ifname]: %s",
                           strerror(errno));
                goto fail;
        }
 
        if (!hapd->conf->ctrl_interface_gid_set &&
            hapd->iface->interfaces->ctrl_iface_group &&
-           chown(fname, -1, hapd->iface->interfaces->ctrl_iface_group) < 0) {
-               wpa_printf(MSG_ERROR, "chown[ctrl_interface/ifname]: %s",
+           lchown(fname, -1, hapd->iface->interfaces->ctrl_iface_group) < 0) {
+               wpa_printf(MSG_ERROR, "lchown[ctrl_interface/ifname]: %s",
                           strerror(errno));
                goto fail;
        }
@@ -3733,7 +3830,7 @@ static void hostapd_ctrl_iface_flush(struct hapd_interfaces *interfaces)
 #endif /* CONFIG_TESTING_OPTIONS */
 
 #ifdef CONFIG_DPP
-       hostapd_dpp_deinit_global(interfaces);
+       dpp_global_clear(interfaces->dpp);
 #endif /* CONFIG_DPP */
 }
 
@@ -4273,9 +4370,9 @@ fail:
                        goto fail;
                }
        } else if (interface->ctrl_iface_group &&
-                  chown(interface->global_iface_path, -1,
-                        interface->ctrl_iface_group) < 0) {
-               wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
+                  lchown(interface->global_iface_path, -1,
+                         interface->ctrl_iface_group) < 0) {
+               wpa_printf(MSG_ERROR, "lchown[ctrl_interface]: %s",
                           strerror(errno));
                goto fail;
        }
@@ -4332,8 +4429,8 @@ fail:
        }
 
        if (interface->ctrl_iface_group &&
-           chown(fname, -1, interface->ctrl_iface_group) < 0) {
-               wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
+           lchown(fname, -1, interface->ctrl_iface_group) < 0) {
+               wpa_printf(MSG_ERROR, "lchown[ctrl_interface]: %s",
                           strerror(errno));
                goto fail;
        }