From 4ecb6dd16b33a3220df12892f52ad2a7647d77a5 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 25 Aug 2020 15:53:08 +0300 Subject: [PATCH] DPP2: Controller support in hostapd Extend hostapd support for DPP Controller to cover the DPP_CONTROLLER_* cases that were previously implemented only in wpa_supplicant. This allows hostapd/AP to be provisioned using DPP over TCP. Signed-off-by: Jouni Malinen --- hostapd/ctrl_iface.c | 8 +++++++ src/ap/dpp_hostapd.c | 39 +++++++++++++++++++++++++++++++++ src/ap/dpp_hostapd.h | 1 + src/common/dpp.h | 4 ++++ src/common/dpp_tcp.c | 15 ++++++++++--- wpa_supplicant/dpp_supplicant.c | 4 ++++ 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index ae63acd47..5b71a7bc4 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -3768,6 +3768,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, if (hostapd_dpp_pkex_remove(hapd, buf + 16) < 0) reply_len = -1; #ifdef CONFIG_DPP2 + } else if (os_strncmp(buf, "DPP_CONTROLLER_START ", 21) == 0) { + if (hostapd_dpp_controller_start(hapd, buf + 20) < 0) + reply_len = -1; + } else if (os_strcmp(buf, "DPP_CONTROLLER_START") == 0) { + if (hostapd_dpp_controller_start(hapd, NULL) < 0) + reply_len = -1; + } else if (os_strcmp(buf, "DPP_CONTROLLER_STOP") == 0) { + dpp_controller_stop(hapd->iface->interfaces->dpp); } else if (os_strncmp(buf, "DPP_CHIRP ", 10) == 0) { if (hostapd_dpp_chirp(hapd, buf + 9) < 0) reply_len = -1; diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index c886103fb..bf62e63be 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -2222,6 +2222,45 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd) #ifdef CONFIG_DPP2 +int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd) +{ + struct dpp_controller_config config; + const char *pos; + + os_memset(&config, 0, sizeof(config)); + config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR; + config.netrole = DPP_NETROLE_AP; + config.msg_ctx = hapd->msg_ctx; + config.cb_ctx = hapd; + config.process_conf_obj = hostapd_dpp_process_conf_obj; + if (cmd) { + pos = os_strstr(cmd, " tcp_port="); + if (pos) { + pos += 10; + config.tcp_port = atoi(pos); + } + + pos = os_strstr(cmd, " role="); + if (pos) { + pos += 6; + if (os_strncmp(pos, "configurator", 12) == 0) + config.allowed_roles = DPP_CAPAB_CONFIGURATOR; + else if (os_strncmp(pos, "enrollee", 8) == 0) + config.allowed_roles = DPP_CAPAB_ENROLLEE; + else if (os_strncmp(pos, "either", 6) == 0) + config.allowed_roles = DPP_CAPAB_CONFIGURATOR | + DPP_CAPAB_ENROLLEE; + else + return -1; + } + + config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL; + } + config.configurator_params = hapd->dpp_configurator_params; + return dpp_controller_start(hapd->iface->interfaces->dpp, &config); +} + + static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx); static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx) diff --git a/src/ap/dpp_hostapd.h b/src/ap/dpp_hostapd.h index 7e74185ca..264d3e4c0 100644 --- a/src/ap/dpp_hostapd.h +++ b/src/ap/dpp_hostapd.h @@ -41,6 +41,7 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd); void hostapd_dpp_init_global(struct hapd_interfaces *ifaces); void hostapd_dpp_deinit_global(struct hapd_interfaces *ifaces); +int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd); int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd); void hostapd_dpp_chirp_stop(struct hostapd_data *hapd); void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi); diff --git a/src/common/dpp.h b/src/common/dpp.h index b3d505cc7..ee88560c7 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -386,6 +386,10 @@ struct dpp_controller_config { int tcp_port; u8 allowed_roles; int qr_mutual; + enum dpp_netrole netrole; + void *msg_ctx; + void *cb_ctx; + int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth); }; #ifdef CONFIG_TESTING_OPTIONS diff --git a/src/common/dpp_tcp.c b/src/common/dpp_tcp.c index e243a6d44..5bd17cdb0 100644 --- a/src/common/dpp_tcp.c +++ b/src/common/dpp_tcp.c @@ -69,6 +69,10 @@ struct dpp_controller { int sock; struct dl_list conn; /* struct dpp_connection */ char *configurator_params; + enum dpp_netrole netrole; + void *msg_ctx; + void *cb_ctx; + int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth); }; static void dpp_controller_rx(int sd, void *eloop_ctx, void *sock_ctx); @@ -1500,10 +1504,11 @@ static void dpp_controller_tcp_cb(int sd, void *eloop_ctx, void *sock_ctx) conn->global = ctrl->global; conn->ctrl = ctrl; - conn->msg_ctx = ctrl->global->msg_ctx; - conn->cb_ctx = ctrl->global->cb_ctx; - conn->process_conf_obj = ctrl->global->process_conf_obj; + conn->msg_ctx = ctrl->msg_ctx; + conn->cb_ctx = ctrl->cb_ctx; + conn->process_conf_obj = ctrl->process_conf_obj; conn->sock = fd; + conn->netrole = ctrl->netrole; if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) { wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s", @@ -1628,6 +1633,10 @@ int dpp_controller_start(struct dpp_global *dpp, dl_list_init(&ctrl->conn); ctrl->allowed_roles = config->allowed_roles; ctrl->qr_mutual = config->qr_mutual; + ctrl->netrole = config->netrole; + ctrl->msg_ctx = config->msg_ctx; + ctrl->cb_ctx = config->cb_ctx; + ctrl->process_conf_obj = config->process_conf_obj; ctrl->sock = socket(AF_INET, SOCK_STREAM, 0); if (ctrl->sock < 0) diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index 4f7546e27..df6ddfc5b 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -3337,6 +3337,10 @@ int wpas_dpp_controller_start(struct wpa_supplicant *wpa_s, const char *cmd) os_memset(&config, 0, sizeof(config)); config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR; + config.netrole = DPP_NETROLE_STA; + config.msg_ctx = wpa_s; + config.cb_ctx = wpa_s; + config.process_conf_obj = wpas_dpp_process_conf_obj; if (cmd) { pos = os_strstr(cmd, " tcp_port="); if (pos) {