aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hostapd/config_file.c35
-rw-r--r--src/ap/ap_config.c17
-rw-r--r--src/ap/ap_config.h10
-rw-r--r--src/ap/dpp_hostapd.c83
-rw-r--r--src/ap/dpp_hostapd.h3
-rw-r--r--src/ap/gas_serv.c9
-rw-r--r--src/ap/gas_serv.h4
7 files changed, 154 insertions, 7 deletions
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 42f3b40..3f61cb6 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2376,6 +2376,36 @@ fail:
#endif /* CONFIG_SAE */
+#ifdef CONFIG_DPP2
+static int hostapd_dpp_controller_parse(struct hostapd_bss_config *bss,
+ const char *pos)
+{
+ struct dpp_controller_conf *conf;
+ char *val;
+
+ conf = os_zalloc(sizeof(*conf));
+ if (!conf)
+ return -1;
+ val = get_param(pos, "ipaddr=");
+ if (!val || hostapd_parse_ip_addr(val, &conf->ipaddr))
+ goto fail;
+ os_free(val);
+ val = get_param(pos, "pkhash=");
+ if (!val || os_strlen(val) != 2 * SHA256_MAC_LEN ||
+ hexstr2bin(val, conf->pkhash, SHA256_MAC_LEN) < 0)
+ goto fail;
+ os_free(val);
+ conf->next = bss->dpp_controller;
+ bss->dpp_controller = conf;
+ return 0;
+fail:
+ os_free(val);
+ os_free(conf);
+ return -1;
+}
+#endif /* CONFIG_DPP2 */
+
+
static int hostapd_config_fill(struct hostapd_config *conf,
struct hostapd_bss_config *bss,
const char *buf, char *pos, int line)
@@ -4298,6 +4328,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "dpp_csign") == 0) {
if (parse_wpabuf_hex(line, buf, &bss->dpp_csign, pos))
return 1;
+#ifdef CONFIG_DPP2
+ } else if (os_strcmp(buf, "dpp_controller") == 0) {
+ if (hostapd_dpp_controller_parse(bss, pos))
+ return 1;
+#endif /* CONFIG_DPP2 */
#endif /* CONFIG_DPP */
#ifdef CONFIG_OWE
} else if (os_strcmp(buf, "owe_transition_bssid") == 0) {
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index e640e99..07b818e 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -559,6 +559,20 @@ static void hostapd_config_free_sae_passwords(struct hostapd_bss_config *conf)
}
+#ifdef CONFIG_DPP2
+static void hostapd_dpp_controller_conf_free(struct dpp_controller_conf *conf)
+{
+ struct dpp_controller_conf *prev;
+
+ while (conf) {
+ prev = conf;
+ conf = conf->next;
+ os_free(prev);
+ }
+}
+#endif /* CONFIG_DPP2 */
+
+
void hostapd_config_free_bss(struct hostapd_bss_config *conf)
{
if (conf == NULL)
@@ -740,6 +754,9 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
os_free(conf->dpp_connector);
wpabuf_free(conf->dpp_netaccesskey);
wpabuf_free(conf->dpp_csign);
+#ifdef CONFIG_DPP2
+ hostapd_dpp_controller_conf_free(conf->dpp_controller);
+#endif /* CONFIG_DPP2 */
#endif /* CONFIG_DPP */
hostapd_config_free_sae_passwords(conf);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 509677a..19eda67 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -15,6 +15,7 @@
#include "common/wpa_common.h"
#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
+#include "crypto/sha256.h"
#include "wps/wps.h"
#include "fst/fst.h"
#include "vlan.h"
@@ -252,6 +253,12 @@ struct sae_password_entry {
int vlan_id;
};
+struct dpp_controller_conf {
+ struct dpp_controller_conf *next;
+ u8 pkhash[SHA256_MAC_LEN];
+ struct hostapd_ip_addr ipaddr;
+};
+
/**
* struct hostapd_bss_config - Per-BSS configuration
*/
@@ -692,6 +699,9 @@ struct hostapd_bss_config {
struct wpabuf *dpp_netaccesskey;
unsigned int dpp_netaccesskey_expiry;
struct wpabuf *dpp_csign;
+#ifdef CONFIG_DPP2
+ struct dpp_controller_conf *dpp_controller;
+#endif /* CONFIG_DPP2 */
#endif /* CONFIG_DPP */
#ifdef CONFIG_OWE
diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
index 75edbc9..697c3ba 100644
--- a/src/ap/dpp_hostapd.c
+++ b/src/ap/dpp_hostapd.c
@@ -16,6 +16,7 @@
#include "hostapd.h"
#include "ap_drv_ops.h"
#include "gas_query_ap.h"
+#include "gas_serv.h"
#include "wpa_auth.h"
#include "dpp_hostapd.h"
@@ -557,6 +558,14 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
* received hash values */
dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
r_bootstrap, &own_bi, &peer_bi);
+#ifdef CONFIG_DPP2
+ if (!own_bi) {
+ if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
+ src, hdr, buf, len, freq, i_bootstrap,
+ r_bootstrap) == 0)
+ return;
+ }
+#endif /* CONFIG_DPP2 */
if (!own_bi) {
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
"No matching own bootstrapping key found - ignore message");
@@ -1357,6 +1366,12 @@ void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
" freq=%u type=%d", MAC2STR(src), freq, type);
+#ifdef CONFIG_DPP2
+ if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
+ src, hdr, buf, len, freq, NULL, NULL) == 0)
+ return;
+#endif /* CONFIG_DPP2 */
+
switch (type) {
case DPP_PA_AUTHENTICATION_REQ:
hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
@@ -1410,7 +1425,8 @@ void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
struct wpabuf *
hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
- const u8 *query, size_t query_len)
+ const u8 *query, size_t query_len,
+ const u8 *data, size_t data_len)
{
struct dpp_authentication *auth = hapd->dpp_auth;
struct wpabuf *resp;
@@ -1418,6 +1434,13 @@ hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
if (!auth || !auth->auth_success ||
os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
+#ifdef CONFIG_DPP2
+ if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
+ data_len) == 0) {
+ /* Response will be forwarded once received over TCP */
+ return NULL;
+ }
+#endif /* CONFIG_DPP2 */
wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
return NULL;
}
@@ -1609,11 +1632,67 @@ void hostapd_dpp_stop(struct hostapd_data *hapd)
}
+#ifdef CONFIG_DPP2
+
+static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
+ const u8 *msg, size_t len)
+{
+ struct hostapd_data *hapd = ctx;
+ u8 *buf;
+
+ wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u",
+ MAC2STR(addr), freq);
+ buf = os_malloc(2 + len);
+ if (!buf)
+ return;
+ buf[0] = WLAN_ACTION_PUBLIC;
+ buf[1] = WLAN_PA_VENDOR_SPECIFIC;
+ os_memcpy(buf + 2, msg, len);
+ hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
+ os_free(buf);
+}
+
+
+static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
+ u8 dialog_token, int prot,
+ struct wpabuf *buf)
+{
+ struct hostapd_data *hapd = ctx;
+
+ gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf);
+}
+
+#endif /* CONFIG_DPP2 */
+
+
+static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
+{
+#ifdef CONFIG_DPP2
+ struct dpp_controller_conf *ctrl;
+ struct dpp_relay_config config;
+
+ os_memset(&config, 0, sizeof(config));
+ config.cb_ctx = hapd;
+ config.tx = hostapd_dpp_relay_tx;
+ config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
+ for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
+ config.ipaddr = &ctrl->ipaddr;
+ config.pkhash = ctrl->pkhash;
+ if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
+ &config) < 0)
+ return -1;
+ }
+#endif /* CONFIG_DPP2 */
+
+ return 0;
+}
+
+
int hostapd_dpp_init(struct hostapd_data *hapd)
{
hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
hapd->dpp_init_done = 1;
- return 0;
+ return hostapd_dpp_add_controllers(hapd);
}
diff --git a/src/ap/dpp_hostapd.h b/src/ap/dpp_hostapd.h
index 449ca16..c1ec5d7 100644
--- a/src/ap/dpp_hostapd.h
+++ b/src/ap/dpp_hostapd.h
@@ -19,7 +19,8 @@ void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
const u8 *data, size_t data_len, int ok);
struct wpabuf *
hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
- const u8 *query, size_t query_len);
+ const u8 *query, size_t query_len,
+ const u8 *data, size_t data_len);
void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok);
int hostapd_dpp_configurator_add(struct hostapd_data *hapd, const char *cmd);
int hostapd_dpp_configurator_remove(struct hostapd_data *hapd, const char *id);
diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
index a7df810..9567e20 100644
--- a/src/ap/gas_serv.c
+++ b/src/ap/gas_serv.c
@@ -1522,9 +1522,9 @@ static void gas_serv_req_local_processing(struct hostapd_data *hapd,
#ifdef CONFIG_DPP
-static void gas_serv_req_dpp_processing(struct hostapd_data *hapd,
- const u8 *sa, u8 dialog_token,
- int prot, struct wpabuf *buf)
+void gas_serv_req_dpp_processing(struct hostapd_data *hapd,
+ const u8 *sa, u8 dialog_token,
+ int prot, struct wpabuf *buf)
{
struct wpabuf *tx_buf;
@@ -1681,7 +1681,8 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
if (dpp) {
struct wpabuf *msg;
- msg = hostapd_dpp_gas_req_handler(hapd, sa, pos, slen);
+ msg = hostapd_dpp_gas_req_handler(hapd, sa, pos, slen,
+ data, len);
if (!msg)
return;
gas_serv_req_dpp_processing(hapd, sa, dialog_token, prot, msg);
diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h
index 2cf1817..1528af4 100644
--- a/src/ap/gas_serv.h
+++ b/src/ap/gas_serv.h
@@ -88,4 +88,8 @@ void gas_serv_dialog_clear(struct gas_dialog_info *dialog);
int gas_serv_init(struct hostapd_data *hapd);
void gas_serv_deinit(struct hostapd_data *hapd);
+void gas_serv_req_dpp_processing(struct hostapd_data *hapd,
+ const u8 *sa, u8 dialog_token,
+ int prot, struct wpabuf *buf);
+
#endif /* GAS_SERV_H */