diff options
Diffstat (limited to 'hostapd/ctrl_iface.c')
-rw-r--r-- | hostapd/ctrl_iface.c | 153 |
1 files changed, 125 insertions, 28 deletions
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 75f12e543f210..e4b16e61af0ec 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -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; } |