From: Jouni Malinen Date: Sat, 23 Jul 2022 14:41:00 +0000 (+0300) Subject: DPP: Allow Relay connections to Controllers to be added and removed X-Git-Tag: hostap_2_11~1810 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bfe3cfc382d6e25a69d093a49a3a9fc1415e3752;p=thirdparty%2Fhostap.git DPP: Allow Relay connections to Controllers to be added and removed The new control interface commands "DPP_RELAY_ADD_CONTROLLER " and "DPP_RELAY_REMOVE_CONTROLLER " can now be used to dynamically add and remove connections to Controllers for the cases where the connection is initialized through a DPP Public Action frame (i.e., Controller as the Responder). Signed-off-by: Jouni Malinen --- diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index a976e8fca..32ab3019f 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -3673,6 +3673,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, reply_len = -1; } else if (os_strcmp(buf, "DPP_STOP_CHIRP") == 0) { hostapd_dpp_chirp_stop(hapd); + } else if (os_strncmp(buf, "DPP_RELAY_ADD_CONTROLLER ", 25) == 0) { + if (hostapd_dpp_add_controller(hapd, buf + 25) < 0) + reply_len = -1; + } else if (os_strncmp(buf, "DPP_RELAY_REMOVE_CONTROLLER ", 28) == 0) { + hostapd_dpp_remove_controller(hapd, buf + 28); #endif /* CONFIG_DPP2 */ #ifdef CONFIG_DPP3 } else if (os_strcmp(buf, "DPP_PUSH_BUTTON") == 0) { diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index c1732ca40..a92ae0d79 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -21,6 +21,7 @@ #include "gas_query_ap.h" #include "gas_serv.h" #include "wpa_auth.h" +#include "beacon.h" #include "dpp_hostapd.h" @@ -3375,6 +3376,65 @@ static int hostapd_dpp_add_controllers(struct hostapd_data *hapd) } +#ifdef CONFIG_DPP2 + +int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd) +{ + struct dpp_relay_config config; + struct hostapd_ip_addr addr; + u8 pkhash[SHA256_MAC_LEN]; + char *pos, *tmp; + int ret = -1; + bool prev_state, new_state; + struct dpp_global *dpp = hapd->iface->interfaces->dpp; + + tmp = os_strdup(cmd); + if (!tmp) + goto fail; + pos = os_strchr(tmp, ' '); + if (!pos) + goto fail; + pos++; + if (hostapd_parse_ip_addr(tmp, &addr) < 0 || + hexstr2bin(pos, pkhash, SHA256_MAC_LEN) < 0) + goto fail; + + os_memset(&config, 0, sizeof(config)); + config.msg_ctx = hapd->msg_ctx; + config.cb_ctx = hapd; + config.tx = hostapd_dpp_relay_tx; + config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx; + config.ipaddr = &addr; + config.pkhash = pkhash; + prev_state = dpp_relay_controller_available(dpp); + ret = dpp_relay_add_controller(dpp, &config); + new_state = dpp_relay_controller_available(dpp); + if (new_state != prev_state) + ieee802_11_update_beacons(hapd->iface); +fail: + os_free(tmp); + return ret; +} + + +void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd) +{ + struct hostapd_ip_addr addr; + bool prev_state, new_state; + struct dpp_global *dpp = hapd->iface->interfaces->dpp; + + if (hostapd_parse_ip_addr(cmd, &addr) < 0) + return; + prev_state = dpp_relay_controller_available(dpp); + dpp_relay_remove_controller(dpp, &addr); + new_state = dpp_relay_controller_available(dpp); + if (new_state != prev_state) + ieee802_11_update_beacons(hapd->iface); +} + +#endif /* CONFIG_DPP2 */ + + int hostapd_dpp_init(struct hostapd_data *hapd) { hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE; diff --git a/src/ap/dpp_hostapd.h b/src/ap/dpp_hostapd.h index d462a1a6a..55f1fce22 100644 --- a/src/ap/dpp_hostapd.h +++ b/src/ap/dpp_hostapd.h @@ -48,5 +48,7 @@ void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi); int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd); void hostapd_dpp_push_button_stop(struct hostapd_data *hapd); bool hostapd_dpp_configurator_connectivity(struct hostapd_data *hapd); +int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd); +void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd); #endif /* DPP_HOSTAPD_H */ diff --git a/src/common/dpp.h b/src/common/dpp.h index 3b5f08967..ea91ece48 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -749,6 +749,8 @@ struct dpp_configurator * dpp_configurator_find_kid(struct dpp_global *dpp, const u8 *kid); int dpp_relay_add_controller(struct dpp_global *dpp, struct dpp_relay_config *config); +void dpp_relay_remove_controller(struct dpp_global *dpp, + const struct hostapd_ip_addr *addr); int dpp_relay_listen(struct dpp_global *dpp, int port, struct dpp_relay_config *config); void dpp_relay_stop_listen(struct dpp_global *dpp); diff --git a/src/common/dpp_tcp.c b/src/common/dpp_tcp.c index 6c5f3bf83..e16d9b09b 100644 --- a/src/common/dpp_tcp.c +++ b/src/common/dpp_tcp.c @@ -139,6 +139,7 @@ int dpp_relay_add_controller(struct dpp_global *dpp, struct dpp_relay_config *config) { struct dpp_relay_controller *ctrl; + char txt[100]; if (!dpp) return -1; @@ -154,6 +155,8 @@ int dpp_relay_add_controller(struct dpp_global *dpp, ctrl->cb_ctx = config->cb_ctx; ctrl->tx = config->tx; ctrl->gas_resp_tx = config->gas_resp_tx; + wpa_printf(MSG_DEBUG, "DPP: Add Relay connection to Controller %s", + hostapd_ip_txt(&ctrl->ipaddr, txt, sizeof(txt))); dl_list_add(&dpp->controllers, &ctrl->list); return 0; } @@ -2344,6 +2347,10 @@ void dpp_tcp_init_flush(struct dpp_global *dpp) static void dpp_relay_controller_free(struct dpp_relay_controller *ctrl) { struct dpp_connection *conn, *tmp; + char txt[100]; + + wpa_printf(MSG_DEBUG, "DPP: Remove Relay connection to Controller %s", + hostapd_ip_txt(&ctrl->ipaddr, txt, sizeof(txt))); dl_list_for_each_safe(conn, tmp, &ctrl->conn, struct dpp_connection, list) @@ -2372,6 +2379,31 @@ void dpp_relay_flush_controllers(struct dpp_global *dpp) } +void dpp_relay_remove_controller(struct dpp_global *dpp, + const struct hostapd_ip_addr *addr) +{ + struct dpp_relay_controller *ctrl; + + if (!dpp) + return; + + dl_list_for_each(ctrl, &dpp->controllers, struct dpp_relay_controller, + list) { + if (hostapd_ip_equal(&ctrl->ipaddr, addr)) { + dl_list_del(&ctrl->list); + dpp_relay_controller_free(ctrl); + return; + } + } + + if (dpp->tmp_controller && + hostapd_ip_equal(&dpp->tmp_controller->ipaddr, addr)) { + dpp_relay_controller_free(dpp->tmp_controller); + dpp->tmp_controller = NULL; + } +} + + static void dpp_relay_tcp_cb(int sd, void *eloop_ctx, void *sock_ctx) { struct dpp_global *dpp = eloop_ctx;