aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@codeaurora.org>2019-03-24 20:17:49 (GMT)
committerJouni Malinen <j@w1.fi>2019-04-22 18:08:59 (GMT)
commite00f780e2bdd98d1b7c96876716d8084808e635d (patch)
treeebbc1706542412229becae58c59fb36216c34972
parent88a78bdde4eb245ae1448152dab2ff3a4cf2375f (diff)
downloadhostap-e00f780e2bdd98d1b7c96876716d8084808e635d.zip
hostap-e00f780e2bdd98d1b7c96876716d8084808e635d.tar.gz
hostap-e00f780e2bdd98d1b7c96876716d8084808e635d.tar.bz2
DPP2: hostapd as TCP Relay
The new hostapd configuration parameter dpp_controller can now be used with the following subparameter values: ipaddr=<IP address> pkhash=<hexdump>. This adds a new Controller into the configuration (i.e., more than one can be configured) and all incoming DPP exchanges that match the specified Controller public key hash are relayed to the particular Controller. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
-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 */