aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hostapd/Android.mk1
-rw-r--r--hostapd/Makefile1
-rw-r--r--hostapd/config_file.c21
-rw-r--r--hostapd/ctrl_iface.c273
-rw-r--r--hostapd/hostapd.conf30
-rw-r--r--hostapd/hostapd_cli.c51
-rw-r--r--hostapd/main.c4
-rw-r--r--hs20/client/est.c7
-rw-r--r--hs20/client/osu_client.c4
-rw-r--r--hs20/server/spp_server.c5
-rw-r--r--src/ap/acs.c1
-rw-r--r--src/ap/ap_config.c7
-rw-r--r--src/ap/ap_config.h8
-rw-r--r--src/ap/ap_drv_ops.c122
-rw-r--r--src/ap/ap_drv_ops.h19
-rw-r--r--src/ap/beacon.c69
-rw-r--r--src/ap/ctrl_iface_ap.c59
-rw-r--r--src/ap/dfs.c3
-rw-r--r--src/ap/dhcp_snoop.c8
-rw-r--r--src/ap/dpp_hostapd.c22
-rw-r--r--src/ap/dpp_hostapd.h2
-rw-r--r--src/ap/drv_callbacks.c58
-rw-r--r--src/ap/fils_hlp.c36
-rw-r--r--src/ap/hostapd.c92
-rw-r--r--src/ap/hw_features.c132
-rw-r--r--src/ap/hw_features.h2
-rw-r--r--src/ap/ieee802_11.c185
-rw-r--r--src/ap/ieee802_11.h10
-rw-r--r--src/ap/ieee802_11_auth.c172
-rw-r--r--src/ap/ieee802_11_auth.h17
-rw-r--r--src/ap/ieee802_11_he.c16
-rw-r--r--src/ap/ieee802_11_shared.c7
-rw-r--r--src/ap/ieee802_1x.c14
-rw-r--r--src/ap/neighbor_db.c54
-rw-r--r--src/ap/neighbor_db.h1
-rw-r--r--src/ap/sta_info.c10
-rw-r--r--src/ap/sta_info.h2
-rw-r--r--src/ap/wmm.c10
-rw-r--r--src/ap/wnm_ap.c8
-rw-r--r--src/ap/wpa_auth.c97
-rw-r--r--src/ap/wpa_auth.h9
-rw-r--r--src/ap/wpa_auth_ft.c46
-rw-r--r--src/ap/wpa_auth_glue.c126
-rw-r--r--src/ap/wps_hostapd.c20
-rw-r--r--src/common/common_module_tests.c116
-rw-r--r--src/common/defs.h26
-rw-r--r--src/common/dhcp.h2
-rw-r--r--src/common/dpp.c423
-rw-r--r--src/common/dpp.h10
-rw-r--r--src/common/hw_features_common.c229
-rw-r--r--src/common/hw_features_common.h20
-rw-r--r--src/common/ieee802_11_common.c297
-rw-r--r--src/common/ieee802_11_common.h8
-rw-r--r--src/common/ieee802_11_defs.h7
-rw-r--r--src/common/qca-vendor.h124
-rw-r--r--src/common/sae.c14
-rw-r--r--src/common/wpa_common.c2
-rw-r--r--src/common/wpa_ctrl.h3
-rw-r--r--src/crypto/tls_openssl.c116
-rw-r--r--src/drivers/driver.h237
-rw-r--r--src/drivers/driver_atheros.c13
-rw-r--r--src/drivers/driver_bsd.c12
-rw-r--r--src/drivers/driver_hostap.c24
-rw-r--r--src/drivers/driver_macsec_linux.c6
-rw-r--r--src/drivers/driver_ndis.c14
-rw-r--r--src/drivers/driver_nl80211.c583
-rw-r--r--src/drivers/driver_nl80211.h29
-rw-r--r--src/drivers/driver_nl80211_android.c4
-rw-r--r--src/drivers/driver_nl80211_capa.c14
-rw-r--r--src/drivers/driver_nl80211_event.c78
-rw-r--r--src/drivers/driver_nl80211_monitor.c3
-rw-r--r--src/drivers/driver_nl80211_scan.c14
-rw-r--r--src/drivers/driver_none.c8
-rw-r--r--src/drivers/driver_openbsd.c7
-rw-r--r--src/drivers/driver_privsep.c15
-rw-r--r--src/drivers/driver_wext.c33
-rw-r--r--src/drivers/driver_wext.h4
-rw-r--r--src/drivers/drivers.mak18
-rw-r--r--src/drivers/drivers.mk21
-rw-r--r--src/drivers/nl80211_copy.h34
-rw-r--r--src/eap_common/eap_sim_common.c4
-rw-r--r--src/eap_peer/eap_sim.c17
-rw-r--r--src/eap_peer/tncc.c5
-rw-r--r--src/eap_server/tncs.c5
-rw-r--r--src/l2_packet/l2_packet_linux.c5
-rw-r--r--src/p2p/p2p.c6
-rw-r--r--src/p2p/p2p.h2
-rw-r--r--src/p2p/p2p_go_neg.c9
-rw-r--r--src/radius/radius_client.c6
-rw-r--r--src/rsn_supp/preauth.c17
-rw-r--r--src/rsn_supp/tdls.c7
-rw-r--r--src/rsn_supp/wpa.c33
-rw-r--r--src/rsn_supp/wpa.h3
-rw-r--r--src/rsn_supp/wpa_ft.c11
-rw-r--r--src/rsn_supp/wpa_i.h5
-rw-r--r--src/tls/tlsv1_cred.c8
-rw-r--r--src/utils/base64.c35
-rw-r--r--src/utils/base64.h12
-rw-r--r--src/utils/json.c84
-rw-r--r--src/utils/json.h11
-rw-r--r--src/utils/trace.c11
-rw-r--r--src/utils/utils_module_tests.c37
-rw-r--r--src/utils/wpa_debug.c147
-rw-r--r--src/utils/wpa_debug.h2
-rw-r--r--src/utils/xml_libxml2.c2
-rw-r--r--src/wps/upnp_xml.c2
-rw-r--r--src/wps/wps.h1
-rw-r--r--src/wps/wps_dev_attr.c17
-rw-r--r--src/wps/wps_dev_attr.h1
-rw-r--r--src/wps/wps_er.c4
-rw-r--r--src/wps/wps_registrar.c9
-rw-r--r--src/wps/wps_upnp.c17
-rw-r--r--src/wps/wps_upnp_event.c27
-rw-r--r--src/wps/wps_upnp_i.h9
-rw-r--r--src/wps/wps_upnp_web.c4
-rw-r--r--tests/fuzzing/eap-mschapv2-peer/Makefile20
-rw-r--r--tests/fuzzing/eap-mschapv2-peer/corpus/server.msgbin0 -> 304 bytes
-rw-r--r--tests/fuzzing/eap-mschapv2-peer/eap-mschapv2-peer.c152
-rw-r--r--tests/hwsim/auth_serv/as.conf2
-rw-r--r--tests/hwsim/auth_serv/as2.conf2
-rw-r--r--tests/hwsim/hostapd.py19
-rw-r--r--tests/hwsim/p2p_utils.py20
-rwxr-xr-xtests/hwsim/run-tests.py4
-rwxr-xr-xtests/hwsim/start.sh45
-rw-r--r--tests/hwsim/test_ap_acs.py15
-rw-r--r--tests/hwsim/test_ap_ciphers.py109
-rw-r--r--tests/hwsim/test_ap_eap.py178
-rw-r--r--tests/hwsim/test_ap_ft.py150
-rw-r--r--tests/hwsim/test_ap_hs20.py59
-rw-r--r--tests/hwsim/test_ap_ht.py17
-rw-r--r--tests/hwsim/test_ap_open.py12
-rw-r--r--tests/hwsim/test_ap_pmf.py122
-rw-r--r--tests/hwsim/test_ap_psk.py60
-rw-r--r--tests/hwsim/test_ap_roam.py108
-rw-r--r--tests/hwsim/test_ap_tdls.py8
-rw-r--r--tests/hwsim/test_ap_wps.py47
-rw-r--r--tests/hwsim/test_dfs.py65
-rw-r--r--tests/hwsim/test_dpp.py90
-rw-r--r--tests/hwsim/test_fils.py64
-rw-r--r--tests/hwsim/test_hapd_ctrl.py11
-rw-r--r--tests/hwsim/test_he.py2
-rw-r--r--tests/hwsim/test_ieee8021x.py2
-rw-r--r--tests/hwsim/test_macsec.py99
-rw-r--r--tests/hwsim/test_nfc_wps.py3
-rw-r--r--tests/hwsim/test_oce.py21
-rw-r--r--tests/hwsim/test_ocv.py5
-rw-r--r--tests/hwsim/test_owe.py33
-rw-r--r--tests/hwsim/test_p2p_discovery.py16
-rw-r--r--tests/hwsim/test_pmksa_cache.py1
-rw-r--r--tests/hwsim/test_radius.py15
-rw-r--r--tests/hwsim/test_rrm.py58
-rw-r--r--tests/hwsim/test_sae.py213
-rw-r--r--tests/hwsim/test_scan.py72
-rw-r--r--tests/hwsim/test_sigma_dut.py1075
-rw-r--r--tests/hwsim/test_sta_dynamic.py49
-rw-r--r--tests/hwsim/test_wmediumd.py5
-rw-r--r--tests/hwsim/test_wnm.py32
-rw-r--r--tests/hwsim/test_wpas_mesh.py39
-rw-r--r--tests/hwsim/tshark.py8
-rw-r--r--tests/hwsim/utils.py5
-rwxr-xr-xtests/hwsim/vm/parallel-vm.py315
-rwxr-xr-xtests/hwsim/vm/vm-run.sh10
-rw-r--r--tests/hwsim/wlantest.py34
-rw-r--r--tests/hwsim/wpasupplicant.py18
-rw-r--r--wlantest/process.c5
-rw-r--r--wlantest/rx_ip.c40
-rw-r--r--wlantest/wired.c29
-rw-r--r--wlantest/wlantest.c9
-rw-r--r--wlantest/wlantest.h3
-rw-r--r--wlantest/writepcap.c12
-rw-r--r--wpa_supplicant/Android.mk4
-rw-r--r--wpa_supplicant/Makefile4
-rw-r--r--wpa_supplicant/ap.c3
-rw-r--r--wpa_supplicant/config.c1
-rw-r--r--wpa_supplicant/config.h10
-rw-r--r--wpa_supplicant/config_file.c6
-rw-r--r--wpa_supplicant/ctrl_iface.c215
-rw-r--r--wpa_supplicant/dbus/dbus_new.c48
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers.c11
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_p2p.c8
-rw-r--r--wpa_supplicant/defconfig4
-rw-r--r--wpa_supplicant/dpp_supplicant.c39
-rw-r--r--wpa_supplicant/dpp_supplicant.h1
-rw-r--r--wpa_supplicant/driver_i.h61
-rw-r--r--wpa_supplicant/eapol_test.c2
-rw-r--r--wpa_supplicant/events.c247
-rw-r--r--wpa_supplicant/hs20_supplicant.c2
-rw-r--r--wpa_supplicant/ibss_rsn.c33
-rw-r--r--wpa_supplicant/mesh.c10
-rw-r--r--wpa_supplicant/mesh_mpm.c22
-rw-r--r--wpa_supplicant/mesh_rsn.c10
-rw-r--r--wpa_supplicant/offchannel.c4
-rw-r--r--wpa_supplicant/p2p_supplicant.c198
-rw-r--r--wpa_supplicant/p2p_supplicant.h16
-rw-r--r--wpa_supplicant/preauth_test.c3
-rw-r--r--wpa_supplicant/rrm.c33
-rw-r--r--wpa_supplicant/scan.c72
-rw-r--r--wpa_supplicant/scan.h25
-rw-r--r--wpa_supplicant/sme.c68
-rw-r--r--wpa_supplicant/sme.h6
-rw-r--r--wpa_supplicant/wpa_cli.c46
-rw-r--r--wpa_supplicant/wpa_gui-qt4/peers.cpp4
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpagui.cpp19
-rw-r--r--wpa_supplicant/wpa_passphrase.c8
-rw-r--r--wpa_supplicant/wpa_priv.c21
-rw-r--r--wpa_supplicant/wpa_supplicant.c194
-rw-r--r--wpa_supplicant/wpa_supplicant.conf3
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h26
-rw-r--r--wpa_supplicant/wpas_glue.c21
-rw-r--r--wpa_supplicant/wps_supplicant.c15
210 files changed, 7308 insertions, 2806 deletions
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index a87ac81..82fa3ea 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -145,6 +145,7 @@ OBJS += src/utils/wpa_debug.c
OBJS += src/utils/wpabuf.c
OBJS += src/utils/os_$(CONFIG_OS).c
OBJS += src/utils/ip_addr.c
+OBJS += src/utils/crc32.c
OBJS += src/common/ieee802_11_common.c
OBJS += src/common/wpa_common.c
diff --git a/hostapd/Makefile b/hostapd/Makefile
index 955e278..f1896f2 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -158,6 +158,7 @@ OBJS_c += ../src/utils/wpa_debug.o
OBJS += ../src/utils/wpabuf.o
OBJS += ../src/utils/os_$(CONFIG_OS).o
OBJS += ../src/utils/ip_addr.o
+OBJS += ../src/utils/crc32.o
OBJS += ../src/common/ieee802_11_common.o
OBJS += ../src/common/wpa_common.o
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 40066ad..89e02a5 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3162,6 +3162,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
line);
return 1;
}
+ } else if (os_strcmp(buf, "freqlist") == 0) {
+ if (freq_range_list_parse(&conf->acs_freq_list, pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid frequency list",
+ line);
+ return 1;
+ }
+ conf->acs_freq_list_present = 1;
+ } else if (os_strcmp(buf, "acs_exclude_6ghz_non_psc") == 0) {
+ conf->acs_exclude_6ghz_non_psc = atoi(pos);
} else if (os_strcmp(buf, "beacon_int") == 0) {
int val = atoi(pos);
/* MIB defines range as 1..65535, but very small values
@@ -3753,6 +3762,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "server_id") == 0) {
os_free(bss->server_id);
bss->server_id = os_strdup(pos);
+ } else if (os_strcmp(buf, "wps_application_ext") == 0) {
+ wpabuf_free(bss->wps_application_ext);
+ bss->wps_application_ext = wpabuf_parse_bin(pos);
#ifdef CONFIG_WPS_NFC
} else if (os_strcmp(buf, "wps_nfc_dev_pw_id") == 0) {
bss->wps_nfc_dev_pw_id = atoi(pos);
@@ -4156,6 +4168,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "sae_commit_override") == 0) {
wpabuf_free(bss->sae_commit_override);
bss->sae_commit_override = wpabuf_parse_bin(pos);
+ } else if (os_strcmp(buf, "rsnxe_override_eapol") == 0) {
+ wpabuf_free(bss->rsnxe_override_eapol);
+ bss->rsnxe_override_eapol = wpabuf_parse_bin(pos);
+ } else if (os_strcmp(buf, "gtk_rsc_override") == 0) {
+ wpabuf_free(bss->gtk_rsc_override);
+ bss->gtk_rsc_override = wpabuf_parse_bin(pos);
+ } else if (os_strcmp(buf, "igtk_rsc_override") == 0) {
+ wpabuf_free(bss->igtk_rsc_override);
+ bss->igtk_rsc_override = wpabuf_parse_bin(pos);
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_SAE
} else if (os_strcmp(buf, "sae_password") == 0) {
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 2c44d1e..5eef75b 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -11,7 +11,11 @@
#ifndef CONFIG_NATIVE_WINDOWS
#ifdef CONFIG_TESTING_OPTIONS
+#ifdef __NetBSD__
+#include <net/if_ether.h>
+#else
#include <net/ethernet.h>
+#endif
#include <netinet/ip.h>
#endif /* CONFIG_TESTING_OPTIONS */
@@ -1326,6 +1330,33 @@ static void hostapd_disassoc_deny_mac(struct hostapd_data *hapd)
}
}
+
+static int hostapd_ctrl_iface_set_band(struct hostapd_data *hapd,
+ const char *band)
+{
+ union wpa_event_data event;
+ enum set_band setband;
+
+ if (os_strcmp(band, "AUTO") == 0)
+ setband = WPA_SETBAND_AUTO;
+ else if (os_strcmp(band, "5G") == 0)
+ setband = WPA_SETBAND_5G;
+ else if (os_strcmp(band, "2G") == 0)
+ setband = WPA_SETBAND_2G;
+ else
+ return -1;
+
+ if (hostapd_drv_set_band(hapd, setband) == 0) {
+ os_memset(&event, 0, sizeof(event));
+ event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
+ event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
+ wpa_supplicant_event(hapd, EVENT_CHANNEL_LIST_CHANGED, &event);
+ }
+
+ return 0;
+}
+
+
static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
{
char *value;
@@ -1409,6 +1440,8 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
os_free(hapd->dpp_configurator_params);
hapd->dpp_configurator_params = os_strdup(value);
#endif /* CONFIG_DPP */
+ } else if (os_strcasecmp(cmd, "setband") == 0) {
+ ret = hostapd_ctrl_iface_set_band(hapd, value);
} else {
ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value);
if (ret)
@@ -1629,7 +1662,7 @@ static int hostapd_ctrl_iface_mgmt_tx(struct hostapd_data *hapd, char *cmd)
return -1;
}
- res = hostapd_drv_send_mlme(hapd, buf, len, 0);
+ res = hostapd_drv_send_mlme(hapd, buf, len, 0, NULL, 0, 0);
os_free(buf);
return res;
}
@@ -1828,7 +1861,7 @@ static void hostapd_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf,
{
struct hostapd_data *hapd = ctx;
const struct ether_header *eth;
- struct iphdr ip;
+ struct ip ip;
const u8 *pos;
unsigned int i;
char extra[30];
@@ -1844,14 +1877,14 @@ static void hostapd_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf,
os_memcpy(&ip, eth + 1, sizeof(ip));
pos = &buf[sizeof(*eth) + sizeof(ip)];
- if (ip.ihl != 5 || ip.version != 4 ||
- ntohs(ip.tot_len) > HWSIM_IP_LEN) {
+ if (ip.ip_hl != 5 || ip.ip_v != 4 ||
+ ntohs(ip.ip_len) > HWSIM_IP_LEN) {
wpa_printf(MSG_DEBUG,
"test data: RX - ignore unexpect IP header");
return;
}
- for (i = 0; i < ntohs(ip.tot_len) - sizeof(ip); i++) {
+ for (i = 0; i < ntohs(ip.ip_len) - sizeof(ip); i++) {
if (*pos != (u8) i) {
wpa_printf(MSG_DEBUG,
"test data: RX - ignore mismatching payload");
@@ -1861,8 +1894,8 @@ static void hostapd_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf,
}
extra[0] = '\0';
- if (ntohs(ip.tot_len) != HWSIM_IP_LEN)
- os_snprintf(extra, sizeof(extra), " len=%d", ntohs(ip.tot_len));
+ if (ntohs(ip.ip_len) != HWSIM_IP_LEN)
+ os_snprintf(extra, sizeof(extra), " len=%d", ntohs(ip.ip_len));
wpa_msg(hapd->msg_ctx, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR "%s",
MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost), extra);
}
@@ -1915,7 +1948,7 @@ static int hostapd_ctrl_iface_data_test_tx(struct hostapd_data *hapd, char *cmd)
u8 tos;
u8 buf[2 + HWSIM_PACKETLEN];
struct ether_header *eth;
- struct iphdr *ip;
+ struct ip *ip;
u8 *dpos;
unsigned int i;
size_t send_len = HWSIM_IP_LEN;
@@ -1954,17 +1987,17 @@ static int hostapd_ctrl_iface_data_test_tx(struct hostapd_data *hapd, char *cmd)
os_memcpy(eth->ether_dhost, dst, ETH_ALEN);
os_memcpy(eth->ether_shost, src, ETH_ALEN);
eth->ether_type = htons(ETHERTYPE_IP);
- ip = (struct iphdr *) (eth + 1);
+ ip = (struct ip *) (eth + 1);
os_memset(ip, 0, sizeof(*ip));
- ip->ihl = 5;
- ip->version = 4;
- ip->ttl = 64;
- ip->tos = tos;
- ip->tot_len = htons(send_len);
- ip->protocol = 1;
- ip->saddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 1);
- ip->daddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 2);
- ip->check = ipv4_hdr_checksum(ip, sizeof(*ip));
+ ip->ip_hl = 5;
+ ip->ip_v = 4;
+ ip->ip_ttl = 64;
+ ip->ip_tos = tos;
+ ip->ip_len = htons(send_len);
+ ip->ip_p = 1;
+ ip->ip_src.s_addr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 1);
+ ip->ip_dst.s_addr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 2);
+ ip->ip_sum = ipv4_hdr_checksum(ip, sizeof(*ip));
dpos = (u8 *) (ip + 1);
for (i = 0; i < send_len - sizeof(*ip); i++)
*dpos++ = i;
@@ -2121,17 +2154,19 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
if (hostapd_drv_set_key(hapd->conf->iface, hapd,
hapd->last_igtk_alg,
broadcast_ether_addr,
- hapd->last_igtk_key_idx, 1, NULL, 0,
- zero, hapd->last_igtk_len) < 0)
+ hapd->last_igtk_key_idx, 0, 1, NULL, 0,
+ zero, hapd->last_igtk_len,
+ KEY_FLAG_GROUP_TX_DEFAULT) < 0)
return -1;
/* Set the previously configured key to reset its TSC */
return hostapd_drv_set_key(hapd->conf->iface, hapd,
hapd->last_igtk_alg,
broadcast_ether_addr,
- hapd->last_igtk_key_idx, 1, NULL, 0,
- hapd->last_igtk,
- hapd->last_igtk_len);
+ hapd->last_igtk_key_idx, 0, 1, NULL,
+ 0, hapd->last_igtk,
+ hapd->last_igtk_len,
+ KEY_FLAG_GROUP_TX_DEFAULT);
}
if (is_broadcast_ether_addr(addr)) {
@@ -2145,16 +2180,19 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
if (hostapd_drv_set_key(hapd->conf->iface, hapd,
hapd->last_gtk_alg,
broadcast_ether_addr,
- hapd->last_gtk_key_idx, 1, NULL, 0,
- zero, hapd->last_gtk_len) < 0)
+ hapd->last_gtk_key_idx, 0, 1, NULL, 0,
+ zero, hapd->last_gtk_len,
+ KEY_FLAG_GROUP_TX_DEFAULT) < 0)
return -1;
/* Set the previously configured key to reset its TSC */
return hostapd_drv_set_key(hapd->conf->iface, hapd,
hapd->last_gtk_alg,
broadcast_ether_addr,
- hapd->last_gtk_key_idx, 1, NULL, 0,
- hapd->last_gtk, hapd->last_gtk_len);
+ hapd->last_gtk_key_idx, 0, 1, NULL,
+ 0, hapd->last_gtk,
+ hapd->last_gtk_len,
+ KEY_FLAG_GROUP_TX_DEFAULT);
}
sta = ap_get_sta(hapd, addr);
@@ -2170,14 +2208,16 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
/* First, use a zero key to avoid any possible duplicate key avoidance
* in the driver. */
if (hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
- sta->addr, sta->last_tk_key_idx, 1, NULL, 0,
- zero, sta->last_tk_len) < 0)
+ sta->addr, sta->last_tk_key_idx, 0, 1, NULL, 0,
+ zero, sta->last_tk_len,
+ KEY_FLAG_PAIRWISE_RX_TX) < 0)
return -1;
/* Set the previously configured key to reset its TSC/RSC */
return hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
- sta->addr, sta->last_tk_key_idx, 1, NULL, 0,
- sta->last_tk, sta->last_tk_len);
+ sta->addr, sta->last_tk_key_idx, 0, 1, NULL,
+ 0, sta->last_tk, sta->last_tk_len,
+ KEY_FLAG_PAIRWISE_RX_TX);
}
@@ -2186,11 +2226,12 @@ static int hostapd_ctrl_set_key(struct hostapd_data *hapd, const char *cmd)
u8 addr[ETH_ALEN];
const char *pos = cmd;
enum wpa_alg alg;
+ enum key_flag key_flag;
int idx, set_tx;
u8 seq[6], key[WPA_TK_MAX_LEN];
size_t key_len;
- /* parameters: alg addr idx set_tx seq key */
+ /* parameters: alg addr idx set_tx seq key key_flag */
alg = atoi(pos);
pos = os_strchr(pos, ' ');
@@ -2219,13 +2260,24 @@ static int hostapd_ctrl_set_key(struct hostapd_data *hapd, const char *cmd)
if (*pos != ' ')
return -1;
pos++;
- key_len = os_strlen(pos) / 2;
+ if (!os_strchr(pos, ' '))
+ return -1;
+ key_len = (os_strchr(pos, ' ') - pos) / 2;
if (hexstr2bin(pos, key, key_len) < 0)
return -1;
+ pos += 2 * key_len;
+ if (*pos != ' ')
+ return -1;
+
+ pos++;
+ key_flag = atoi(pos);
+ pos = os_strchr(pos, ' ');
+ if (pos)
+ return -1;
wpa_printf(MSG_INFO, "TESTING: Set key");
- return hostapd_drv_set_key(hapd->conf->iface, hapd, alg, addr, idx,
- set_tx, seq, 6, key, key_len);
+ return hostapd_drv_set_key(hapd->conf->iface, hapd, alg, addr, idx, 0,
+ set_tx, seq, 6, key, key_len, key_flag);
}
@@ -2240,8 +2292,9 @@ static void restore_tk(void *ctx1, void *ctx2)
* in replay protection issues for now since there is no clean way of
* preventing encryption of a single EAPOL frame. */
hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
- sta->addr, sta->last_tk_key_idx, 1, NULL, 0,
- sta->last_tk, sta->last_tk_len);
+ sta->addr, sta->last_tk_key_idx, 0, 1, NULL, 0,
+ sta->last_tk, sta->last_tk_len,
+ KEY_FLAG_PAIRWISE_RX_TX);
}
@@ -2264,8 +2317,8 @@ static int hostapd_ctrl_resend_m1(struct hostapd_data *hapd, const char *cmd)
wpa_printf(MSG_INFO, "TESTING: Clear TK for " MACSTR,
MAC2STR(sta->addr));
hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
- sta->addr, sta->last_tk_key_idx, 0, NULL, 0,
- NULL, 0);
+ sta->addr, sta->last_tk_key_idx, 0, 0, NULL,
+ 0, NULL, 0, KEY_FLAG_PAIRWISE);
}
wpa_printf(MSG_INFO, "TESTING: Send M1 to " MACSTR, MAC2STR(sta->addr));
@@ -2294,8 +2347,8 @@ static int hostapd_ctrl_resend_m3(struct hostapd_data *hapd, const char *cmd)
wpa_printf(MSG_INFO, "TESTING: Clear TK for " MACSTR,
MAC2STR(sta->addr));
hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
- sta->addr, sta->last_tk_key_idx, 0, NULL, 0,
- NULL, 0);
+ sta->addr, sta->last_tk_key_idx, 0, 0, NULL,
+ 0, NULL, 0, KEY_FLAG_PAIRWISE);
}
wpa_printf(MSG_INFO, "TESTING: Send M3 to " MACSTR, MAC2STR(sta->addr));
@@ -2324,8 +2377,8 @@ static int hostapd_ctrl_resend_group_m1(struct hostapd_data *hapd,
wpa_printf(MSG_INFO, "TESTING: Clear TK for " MACSTR,
MAC2STR(sta->addr));
hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
- sta->addr, sta->last_tk_key_idx, 0, NULL, 0,
- NULL, 0);
+ sta->addr, sta->last_tk_key_idx, 0, 0, NULL,
+ 0, NULL, 0, KEY_FLAG_PAIRWISE);
}
wpa_printf(MSG_INFO,
@@ -2678,6 +2731,20 @@ static int hostapd_ctrl_iface_req_beacon(struct hostapd_data *hapd,
}
+static int hostapd_ctrl_iface_show_neighbor(struct hostapd_data *hapd,
+ char *buf, size_t buflen)
+{
+ if (!(hapd->conf->radio_measurements[0] &
+ WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
+ wpa_printf(MSG_ERROR,
+ "CTRL: SHOW_NEIGHBOR: Neighbor report is not enabled");
+ return -1;
+ }
+
+ return hostapd_neighbor_show(hapd, buf, buflen);
+}
+
+
static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
{
struct wpa_ssid_value ssid;
@@ -2784,6 +2851,7 @@ static int hostapd_ctrl_iface_remove_neighbor(struct hostapd_data *hapd,
char *buf)
{
struct wpa_ssid_value ssid;
+ struct wpa_ssid_value *ssidp = NULL;
u8 bssid[ETH_ALEN];
char *tmp;
@@ -2793,13 +2861,16 @@ static int hostapd_ctrl_iface_remove_neighbor(struct hostapd_data *hapd,
}
tmp = os_strstr(buf, "ssid=");
- if (!tmp || ssid_parse(tmp + 5, &ssid)) {
- wpa_printf(MSG_ERROR,
- "CTRL: REMOVE_NEIGHBORr: Bad or missing SSID");
- return -1;
+ if (tmp) {
+ ssidp = &ssid;
+ if (ssid_parse(tmp + 5, &ssid)) {
+ wpa_printf(MSG_ERROR,
+ "CTRL: REMOVE_NEIGHBOR: Bad SSID");
+ return -1;
+ }
}
- return hostapd_neighbor_remove(hapd, bssid, &ssid);
+ return hostapd_neighbor_remove(hapd, bssid, ssidp);
}
@@ -3222,6 +3293,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
} else if (os_strncmp(buf, "SET_NEIGHBOR ", 13) == 0) {
if (hostapd_ctrl_iface_set_neighbor(hapd, buf + 13))
reply_len = -1;
+ } else if (os_strcmp(buf, "SHOW_NEIGHBOR") == 0) {
+ reply_len = hostapd_ctrl_iface_show_neighbor(hapd, reply,
+ reply_size);
} else if (os_strncmp(buf, "REMOVE_NEIGHBOR ", 16) == 0) {
if (hostapd_ctrl_iface_remove_neighbor(hapd, buf + 16))
reply_len = -1;
@@ -3289,6 +3363,15 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
if (os_snprintf_error(reply_size, reply_len))
reply_len = -1;
}
+ } else if (os_strncmp(buf, "DPP_NFC_URI ", 12) == 0) {
+ res = hostapd_dpp_nfc_uri(hapd, buf + 12);
+ if (res < 0) {
+ reply_len = -1;
+ } else {
+ reply_len = os_snprintf(reply, reply_size, "%d", res);
+ if (os_snprintf_error(reply_size, reply_len))
+ reply_len = -1;
+ }
} else if (os_strncmp(buf, "DPP_BOOTSTRAP_GEN ", 18) == 0) {
res = dpp_bootstrap_gen(hapd->iface->interfaces->dpp, buf + 18);
if (res < 0) {
@@ -4364,6 +4447,8 @@ try_again:
return -1;
}
+ wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
+
return 0;
fail:
@@ -4466,6 +4551,8 @@ fail:
eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive,
interface, NULL);
+ wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
+
return 0;
fail:
@@ -4535,37 +4622,48 @@ static int hostapd_ctrl_check_event_enabled(struct wpa_ctrl_dst *dst,
}
-static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
- enum wpa_msg_type type,
- const char *buf, size_t len)
+static void hostapd_ctrl_iface_send_internal(int sock, struct dl_list *ctrl_dst,
+ const char *ifname, int level,
+ const char *buf, size_t len)
{
struct wpa_ctrl_dst *dst, *next;
- struct dl_list *ctrl_dst;
struct msghdr msg;
- int idx;
- struct iovec io[2];
+ int idx, res;
+ struct iovec io[5];
char levelstr[10];
- int s;
- if (type != WPA_MSG_ONLY_GLOBAL) {
- s = hapd->ctrl_sock;
- ctrl_dst = &hapd->ctrl_dst;
- } else {
- s = hapd->iface->interfaces->global_ctrl_sock;
- ctrl_dst = &hapd->iface->interfaces->global_ctrl_dst;
- }
-
- if (s < 0 || dl_list_empty(ctrl_dst))
+ if (sock < 0 || dl_list_empty(ctrl_dst))
return;
- os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
- io[0].iov_base = levelstr;
- io[0].iov_len = os_strlen(levelstr);
- io[1].iov_base = (char *) buf;
- io[1].iov_len = len;
+ res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
+ if (os_snprintf_error(sizeof(levelstr), res))
+ return;
+ idx = 0;
+ if (ifname) {
+#ifdef CONFIG_CTRL_IFACE_UDP
+ io[idx].iov_base = "IFACE=";
+ io[idx].iov_len = 6;
+#else /* CONFIG_CTRL_IFACE_UDP */
+ io[idx].iov_base = "IFNAME=";
+ io[idx].iov_len = 7;
+#endif /* CONFIG_CTRL_IFACE_UDP */
+ idx++;
+ io[idx].iov_base = (char *) ifname;
+ io[idx].iov_len = os_strlen(ifname);
+ idx++;
+ io[idx].iov_base = " ";
+ io[idx].iov_len = 1;
+ idx++;
+ }
+ io[idx].iov_base = levelstr;
+ io[idx].iov_len = os_strlen(levelstr);
+ idx++;
+ io[idx].iov_base = (char *) buf;
+ io[idx].iov_len = len;
+ idx++;
os_memset(&msg, 0, sizeof(msg));
msg.msg_iov = io;
- msg.msg_iovlen = 2;
+ msg.msg_iovlen = idx;
idx = 0;
dl_list_for_each_safe(dst, next, ctrl_dst, struct wpa_ctrl_dst, list) {
@@ -4575,22 +4673,16 @@ static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
&dst->addr, dst->addrlen);
msg.msg_name = &dst->addr;
msg.msg_namelen = dst->addrlen;
- if (sendmsg(s, &msg, 0) < 0) {
+ if (sendmsg(sock, &msg, 0) < 0) {
int _errno = errno;
wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "
"%d - %s",
idx, errno, strerror(errno));
dst->errors++;
if (dst->errors > 10 || _errno == ENOENT) {
- if (type != WPA_MSG_ONLY_GLOBAL)
- hostapd_ctrl_iface_detach(
- hapd, &dst->addr,
- dst->addrlen);
- else
- hostapd_global_ctrl_iface_detach(
- hapd->iface->interfaces,
- &dst->addr,
- dst->addrlen);
+ ctrl_iface_detach(ctrl_dst,
+ &dst->addr,
+ dst->addrlen);
}
} else
dst->errors = 0;
@@ -4599,4 +4691,25 @@ static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
}
}
+
+static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
+ enum wpa_msg_type type,
+ const char *buf, size_t len)
+{
+ if (type != WPA_MSG_NO_GLOBAL) {
+ hostapd_ctrl_iface_send_internal(
+ hapd->iface->interfaces->global_ctrl_sock,
+ &hapd->iface->interfaces->global_ctrl_dst,
+ type != WPA_MSG_PER_INTERFACE ?
+ NULL : hapd->conf->iface,
+ level, buf, len);
+ }
+
+ if (type != WPA_MSG_ONLY_GLOBAL) {
+ hostapd_ctrl_iface_send_internal(
+ hapd->ctrl_sock, &hapd->ctrl_dst,
+ NULL, level, buf, len);
+ }
+}
+
#endif /* CONFIG_NATIVE_WINDOWS */
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 4cbe451..d76a6c7 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -205,11 +205,26 @@ channel=1
#chanlist=100 104 108 112 116
#chanlist=1 6 11-13
+# Frequency list restriction. This option allows hostapd to select one of the
+# provided frequencies when a frequency should be automatically selected.
+# Frequency list can be provided as range using hyphen ('-') or individual
+# frequencies can be specified by comma (',') separated values
+# Default: all frequencies allowed in selected hw_mode
+#freqlist=2437,5945,5965
+#freqlist=2437,5985-6105
+
# Exclude DFS channels from ACS
# This option can be used to exclude all DFS channels from the ACS channel list
# in cases where the driver supports DFS channels.
#acs_exclude_dfs=1
+# Include only preferred scan channels from 6 GHz band for ACS
+# This option can be used to include only preferred scan channels in the 6 GHz
+# band. This can be useful in particular for devices that operate only a 6 GHz
+# BSS without a collocated 2.4/5 GHz BSS.
+# Default behavior is to include all PSC and non-PSC channels.
+#acs_exclude_6ghz_non_psc=1
+
# Beacon interval in kus (1.024 ms) (default: 100; range 15..65535)
beacon_int=100
@@ -1644,6 +1659,12 @@ own_ip_addr=127.0.0.1
# 1 = optional
# 2 = required
#ieee80211w=0
+# The most common configuration options for this based on the PMF (protected
+# management frames) certification program are:
+# PMF enabled: ieee80211w=1 and wpa_key_mgmt=WPA-EAP WPA-EAP-SHA256
+# PMF required: ieee80211w=2 and wpa_key_mgmt=WPA-EAP-SHA256
+# (and similarly for WPA-PSK and WPA-PSK-SHA256 if WPA2-Personal is used)
+# WPA3-Personal-only mode: ieee80211w=2 and wpa_key_mgmt=SAE
# Group management cipher suite
# Default: AES-128-CMAC (BIP)
@@ -2184,6 +2205,13 @@ own_ip_addr=127.0.0.1
#wps_nfc_dh_privkey: Hexdump of DH Private Key
#wps_nfc_dev_pw: Hexdump of Device Password
+# Application Extension attribute for Beacon and Probe Response frames
+# This parameter can be used to add application extension into WPS IE. The
+# contents of this parameter starts with 16-octet (32 hexdump characters) of
+# UUID to identify the specific application and that is followed by the actual
+# application specific data.
+#wps_application_ext=<hexdump>
+
##### Wi-Fi Direct (P2P) ######################################################
# Enable P2P Device management
@@ -2586,7 +2614,7 @@ own_ip_addr=127.0.0.1
# Default is 0 = OCE disabled
#oce=0
-# RSSI-based assocition rejection
+# RSSI-based association rejection
#
# Reject STA association if RSSI is below given threshold (in dBm)
# Allowed range: -60 to -90 dBm; default = 0 (rejection disabled)
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index 42edb7b..440664e 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -54,7 +54,7 @@ static void usage(void)
fprintf(stderr, "%s\n", hostapd_cli_version);
fprintf(stderr,
"\n"
- "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvB] "
+ "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvBr] "
"[-a<path>] \\\n"
" [-P<pid file>] [-G<ping interval>] [command..]\n"
"\n"
@@ -68,6 +68,9 @@ static void usage(void)
" -a<file> run in daemon mode executing the action file "
"based on events\n"
" from hostapd\n"
+ " -r try to reconnect when client socket is "
+ "disconnected.\n"
+ " This is useful only when used with -a.\n"
" -B run a daemon in the background\n"
" -i<ifname> Interface to listen on (default: first "
"interface found in the\n"
@@ -1309,24 +1312,17 @@ static int hostapd_cli_cmd_set_neighbor(struct wpa_ctrl *ctrl, int argc,
}
-static int hostapd_cli_cmd_remove_neighbor(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
+static int hostapd_cli_cmd_show_neighbor(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
{
- char cmd[400];
- int res;
+ return wpa_ctrl_command(ctrl, "SHOW_NEIGHBOR");
+}
- if (argc != 2) {
- printf("Invalid remove_neighbor command: needs 2 arguments\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NEIGHBOR %s %s",
- argv[0], argv[1]);
- if (os_snprintf_error(sizeof(cmd), res)) {
- printf("Too long REMOVE_NEIGHBOR command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
+static int hostapd_cli_cmd_remove_neighbor(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return hostapd_cli_cmd(ctrl, "REMOVE_NEIGHBOR", 1, argc, argv);
}
@@ -1633,8 +1629,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
{ "set_neighbor", hostapd_cli_cmd_set_neighbor, NULL,
"<addr> <ssid=> <nr=> [lci=] [civic=] [stat]\n"
" = add AP to neighbor database" },
+ { "show_neighbor", hostapd_cli_cmd_show_neighbor, NULL,
+ " = show neighbor database entries" },
{ "remove_neighbor", hostapd_cli_cmd_remove_neighbor, NULL,
- "<addr> <ssid=> = remove AP from neighbor database" },
+ "<addr> [ssid=<hex>] = remove AP from neighbor database" },
{ "req_lci", hostapd_cli_cmd_req_lci, hostapd_complete_stations,
"<addr> = send LCI request to a station"},
{ "req_range", hostapd_cli_cmd_req_range, NULL,
@@ -2007,12 +2005,13 @@ int main(int argc, char *argv[])
int warning_displayed = 0;
int c;
int daemonize = 0;
+ int reconnect = 0;
if (os_program_init())
return -1;
for (;;) {
- c = getopt(argc, argv, "a:BhG:i:p:P:s:v");
+ c = getopt(argc, argv, "a:BhG:i:p:P:rs:v");
if (c < 0)
break;
switch (c) {
@@ -2041,6 +2040,9 @@ int main(int argc, char *argv[])
case 'P':
pid_file = optarg;
break;
+ case 'r':
+ reconnect = 1;
+ break;
case 's':
client_socket_dir = optarg;
break;
@@ -2083,8 +2085,7 @@ int main(int argc, char *argv[])
printf("Connection established.\n");
break;
}
-
- if (!interactive) {
+ if (!interactive && !reconnect) {
perror("Failed to connect to hostapd - "
"wpa_ctrl_open");
return -1;
@@ -2102,8 +2103,14 @@ int main(int argc, char *argv[])
return -1;
if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
return -1;
-
- if (interactive)
+ if (reconnect && action_file && ctrl_ifname) {
+ while (!hostapd_cli_quit) {
+ if (ctrl_conn)
+ hostapd_cli_action(ctrl_conn);
+ os_sleep(1, 0);
+ hostapd_cli_reconnect(ctrl_ifname);
+ }
+ } else if (interactive)
hostapd_cli_interactive();
else if (action_file)
hostapd_cli_action(ctrl_conn);
diff --git a/hostapd/main.c b/hostapd/main.c
index 8bfe242..9bca26e 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -260,7 +260,7 @@ hostapd_interface_init(struct hapd_interfaces *interfaces, const char *if_name,
struct hostapd_iface *iface;
int k;
- wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
+ wpa_printf(MSG_DEBUG, "Configuration file: %s", config_fname);
iface = hostapd_init(interfaces, config_fname);
if (!iface)
return NULL;
@@ -768,7 +768,7 @@ int main(int argc, char *argv[])
if (log_file)
wpa_debug_open_file(log_file);
- else
+ if (!log_file && !wpa_debug_syslog)
wpa_debug_setup_stdout();
#ifdef CONFIG_DEBUG_SYSLOG
if (wpa_debug_syslog)
diff --git a/hs20/client/est.c b/hs20/client/est.c
index db65334..97f9132 100644
--- a/hs20/client/est.c
+++ b/hs20/client/est.c
@@ -158,7 +158,7 @@ int est_load_cacerts(struct hs20_osu_client *ctx, const char *url)
return -1;
}
- pkcs7 = base64_decode((unsigned char *) resp, resp_len, &pkcs7_len);
+ pkcs7 = base64_decode(resp, resp_len, &pkcs7_len);
if (pkcs7 && pkcs7_len < resp_len / 2) {
wpa_printf(MSG_INFO, "Too short base64 decode (%u bytes; downloaded %u bytes) - assume this was binary",
(unsigned int) pkcs7_len, (unsigned int) resp_len);
@@ -639,8 +639,7 @@ int est_build_csr(struct hs20_osu_client *ctx, const char *url)
return -1;
}
- attrs = base64_decode((unsigned char *) resp, resp_len,
- &attrs_len);
+ attrs = base64_decode(resp, resp_len, &attrs_len);
os_free(resp);
if (attrs == NULL) {
@@ -734,7 +733,7 @@ int est_simple_enroll(struct hs20_osu_client *ctx, const char *url,
}
wpa_printf(MSG_DEBUG, "EST simpleenroll response: %s", resp);
- pkcs7 = base64_decode((unsigned char *) resp, resp_len, &pkcs7_len);
+ pkcs7 = base64_decode(resp, resp_len, &pkcs7_len);
if (pkcs7 == NULL) {
wpa_printf(MSG_INFO, "EST workaround - Could not decode base64, assume this is DER encoded PKCS7");
pkcs7 = os_malloc(resp_len);
diff --git a/hs20/client/osu_client.c b/hs20/client/osu_client.c
index fd99600..a94f40c 100644
--- a/hs20/client/osu_client.c
+++ b/hs20/client/osu_client.c
@@ -310,7 +310,7 @@ static int download_cert(struct hs20_osu_client *ctx, xml_node_t *params,
size_t len;
u8 digest1[SHA256_MAC_LEN], digest2[SHA256_MAC_LEN];
int res;
- unsigned char *b64;
+ char *b64;
FILE *f;
url_node = get_node(ctx->xml, params, "CertURL");
@@ -364,7 +364,7 @@ static int download_cert(struct hs20_osu_client *ctx, xml_node_t *params,
return -1;
}
- b64 = base64_encode((unsigned char *) cert, len, NULL);
+ b64 = base64_encode(cert, len, NULL);
os_free(cert);
if (b64 == NULL)
return -1;
diff --git a/hs20/server/spp_server.c b/hs20/server/spp_server.c
index 4bef0ff..a50e907 100644
--- a/hs20/server/spp_server.c
+++ b/hs20/server/spp_server.c
@@ -633,7 +633,7 @@ static xml_node_t * build_username_password(struct hs20_svc *ctx,
add_text_node(ctx, node, "Username", user);
- b64 = (char *) base64_encode((unsigned char *) pw, strlen(pw), NULL);
+ b64 = base64_encode(pw, strlen(pw), NULL);
if (b64 == NULL)
return NULL;
len = os_strlen(b64);
@@ -1602,8 +1602,7 @@ static xml_node_t * spp_exec_get_certificate(struct hs20_svc *ctx,
xml_node_create_text(ctx->xml, enroll, ns, "estUserID", user);
- b64 = (char *) base64_encode((unsigned char *) password,
- strlen(password), NULL);
+ b64 = base64_encode(password, strlen(password), NULL);
if (b64 == NULL) {
xml_node_free(ctx->xml, spp_node);
return NULL;
diff --git a/src/ap/acs.c b/src/ap/acs.c
index f12539f..232afa8 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -862,6 +862,7 @@ static void acs_study(struct hostapd_iface *iface)
}
iface->conf->channel = ideal_chan->chan;
+ iface->freq = ideal_chan->freq;
if (iface->conf->ieee80211ac || iface->conf->ieee80211ax)
acs_adjust_center_freq(iface);
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 58fc3e9..cc04144 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -441,7 +441,7 @@ int hostapd_setup_sae_pt(struct hostapd_bss_config *conf)
struct hostapd_ssid *ssid = &conf->ssid;
struct sae_password_entry *pw;
- if (conf->sae_pwe == 0)
+ if (conf->sae_pwe == 0 || !wpa_key_mgmt_sae(conf->wpa_key_mgmt))
return 0; /* PT not needed */
sae_deinit_pt(ssid->pt);
@@ -813,6 +813,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
os_free(conf->upc);
for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
wpabuf_free(conf->wps_vendor_ext[i]);
+ wpabuf_free(conf->wps_application_ext);
wpabuf_free(conf->wps_nfc_dh_pubkey);
wpabuf_free(conf->wps_nfc_dh_privkey);
wpabuf_free(conf->wps_nfc_dev_pw);
@@ -880,6 +881,9 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
#ifdef CONFIG_TESTING_OPTIONS
wpabuf_free(conf->own_ie_override);
wpabuf_free(conf->sae_commit_override);
+ wpabuf_free(conf->rsnxe_override_eapol);
+ wpabuf_free(conf->gtk_rsc_override);
+ wpabuf_free(conf->igtk_rsc_override);
#endif /* CONFIG_TESTING_OPTIONS */
os_free(conf->no_probe_resp_if_seen_on);
@@ -935,6 +939,7 @@ void hostapd_config_free(struct hostapd_config *conf)
os_free(conf->supported_rates);
os_free(conf->basic_rates);
os_free(conf->acs_ch_list.range);
+ os_free(conf->acs_freq_list.range);
os_free(conf->driver_params);
#ifdef CONFIG_ACS
os_free(conf->acs_chan_bias);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 2a0c984..1efdc2b 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -88,6 +88,7 @@ typedef enum hostap_security_policy {
struct hostapd_ssid {
u8 ssid[SSID_MAX_LEN];
size_t ssid_len;
+ u32 short_ssid;
unsigned int ssid_set:1;
unsigned int utf8_ssid:1;
unsigned int wpa_passphrase_set:1;
@@ -497,6 +498,7 @@ struct hostapd_bss_config {
char *model_url;
char *upc;
struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
+ struct wpabuf *wps_application_ext;
int wps_nfc_pw_from_config;
int wps_nfc_dev_pw_id;
struct wpabuf *wps_nfc_dh_pubkey;
@@ -664,6 +666,9 @@ struct hostapd_bss_config {
struct wpabuf *own_ie_override;
int sae_reflection_attack;
struct wpabuf *sae_commit_override;
+ struct wpabuf *rsnxe_override_eapol;
+ struct wpabuf *gtk_rsc_override;
+ struct wpabuf *igtk_rsc_override;
#endif /* CONFIG_TESTING_OPTIONS */
#define MESH_ENABLED BIT(0)
@@ -881,8 +886,11 @@ struct hostapd_config {
u8 edmg_channel;
u8 acs;
struct wpa_freq_range_list acs_ch_list;
+ struct wpa_freq_range_list acs_freq_list;
+ u8 acs_freq_list_present;
int acs_exclude_dfs;
enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
+ int acs_exclude_6ghz_non_psc;
enum {
LONG_PREAMBLE = 0,
SHORT_PREAMBLE = 1
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 204274f..c217d9b 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -10,6 +10,7 @@
#include "utils/common.h"
#include "common/ieee802_11_defs.h"
+#include "common/ieee802_11_common.h"
#include "common/hw_features_common.h"
#include "wps/wps.h"
#include "p2p/p2p.h"
@@ -679,36 +680,41 @@ int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
enum wpa_alg alg, const u8 *addr,
- int key_idx, int set_tx,
+ int key_idx, int vlan_id, int set_tx,
const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
+ const u8 *key, size_t key_len, enum key_flag key_flag)
{
+ struct wpa_driver_set_key_params params;
+
if (hapd->driver == NULL || hapd->driver->set_key == NULL)
return 0;
- return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
- key_idx, set_tx, seq, seq_len, key,
- key_len);
-}
+ os_memset(&params, 0, sizeof(params));
+ params.ifname = ifname;
+ params.alg = alg;
+ params.addr = addr;
+ params.key_idx = key_idx;
+ params.set_tx = set_tx;
+ params.seq = seq;
+ params.seq_len = seq_len;
+ params.key = key;
+ params.key_len = key_len;
+ params.vlan_id = vlan_id;
+ params.key_flag = key_flag;
-int hostapd_drv_send_mlme(struct hostapd_data *hapd,
- const void *msg, size_t len, int noack)
-{
- if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
- return 0;
- return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
- NULL, 0);
+ return hapd->driver->set_key(hapd->drv_priv, &params);
}
-int hostapd_drv_send_mlme_csa(struct hostapd_data *hapd,
- const void *msg, size_t len, int noack,
- const u16 *csa_offs, size_t csa_offs_len)
+int hostapd_drv_send_mlme(struct hostapd_data *hapd,
+ const void *msg, size_t len, int noack,
+ const u16 *csa_offs, size_t csa_offs_len,
+ int no_encrypt)
{
- if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
+ if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
return 0;
return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
- csa_offs, csa_offs_len);
+ csa_offs, csa_offs_len, no_encrypt);
}
@@ -855,10 +861,24 @@ static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
for (i = 0; i < mode->num_channels; i++) {
struct hostapd_channel_data *chan = &mode->channels[i];
- if ((acs_ch_list_all ||
- freq_range_list_includes(&hapd->iface->conf->acs_ch_list,
- chan->chan)) &&
- !(chan->flag & HOSTAPD_CHAN_DISABLED) &&
+ if (!acs_ch_list_all &&
+ (hapd->iface->conf->acs_freq_list.num &&
+ !freq_range_list_includes(
+ &hapd->iface->conf->acs_freq_list,
+ chan->freq)))
+ continue;
+ if (!acs_ch_list_all &&
+ (!hapd->iface->conf->acs_freq_list_present &&
+ hapd->iface->conf->acs_ch_list.num &&
+ !freq_range_list_includes(
+ &hapd->iface->conf->acs_ch_list,
+ chan->chan)))
+ continue;
+ if (is_6ghz_freq(chan->freq) &&
+ hapd->iface->conf->acs_exclude_6ghz_non_psc &&
+ !is_6ghz_psc_frequency(chan->freq))
+ continue;
+ if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
!(hapd->iface->conf->acs_exclude_dfs &&
(chan->flag & HOSTAPD_CHAN_RADAR)))
int_array_add_unique(freq_list, chan->freq);
@@ -884,10 +904,9 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
{
struct drv_acs_params params;
int ret, i, acs_ch_list_all = 0;
- u8 *channels = NULL;
- unsigned int num_channels = 0;
struct hostapd_hw_modes *mode;
int *freq_list = NULL;
+ enum hostapd_hw_mode selected_mode;
if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
return 0;
@@ -899,41 +918,25 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
* If no chanlist config parameter is provided, include all enabled
* channels of the selected hw_mode.
*/
- if (!hapd->iface->conf->acs_ch_list.num)
- acs_ch_list_all = 1;
-
- mode = hapd->iface->current_mode;
- if (mode) {
- channels = os_malloc(mode->num_channels);
- if (channels == NULL)
- return -1;
-
- for (i = 0; i < mode->num_channels; i++) {
- struct hostapd_channel_data *chan = &mode->channels[i];
- if (!acs_ch_list_all &&
- !freq_range_list_includes(
- &hapd->iface->conf->acs_ch_list,
- chan->chan))
- continue;
- if (hapd->iface->conf->acs_exclude_dfs &&
- (chan->flag & HOSTAPD_CHAN_RADAR))
- continue;
- if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) {
- channels[num_channels++] = chan->chan;
- int_array_add_unique(&freq_list, chan->freq);
- }
- }
- } else {
- for (i = 0; i < hapd->iface->num_hw_features; i++) {
- mode = &hapd->iface->hw_features[i];
- hostapd_get_hw_mode_any_channels(hapd, mode,
- acs_ch_list_all,
- &freq_list);
- }
+ if (hapd->iface->conf->acs_freq_list_present)
+ acs_ch_list_all = !hapd->iface->conf->acs_freq_list.num;
+ else
+ acs_ch_list_all = !hapd->iface->conf->acs_ch_list.num;
+
+ if (hapd->iface->current_mode)
+ selected_mode = hapd->iface->current_mode->mode;
+ else
+ selected_mode = HOSTAPD_MODE_IEEE80211ANY;
+
+ for (i = 0; i < hapd->iface->num_hw_features; i++) {
+ mode = &hapd->iface->hw_features[i];
+ if (selected_mode != HOSTAPD_MODE_IEEE80211ANY &&
+ selected_mode != mode->mode)
+ continue;
+ hostapd_get_hw_mode_any_channels(hapd, mode, acs_ch_list_all,
+ &freq_list);
}
- params.ch_list = channels;
- params.ch_list_len = num_channels;
params.freq_list = freq_list;
params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
@@ -958,8 +961,11 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
params.ch_width = 160;
}
+ if (hapd->iface->conf->op_class)
+ params.ch_width = op_class_to_bandwidth(
+ hapd->iface->conf->op_class);
ret = hapd->driver->do_acs(hapd->drv_priv, &params);
- os_free(channels);
+ os_free(freq_list);
return ret;
}
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 79b1302..56d1ad8 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -89,14 +89,13 @@ int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
int hostapd_drv_set_key(const char *ifname,
struct hostapd_data *hapd,
enum wpa_alg alg, const u8 *addr,
- int key_idx, int set_tx,
+ int key_idx, int vlan_id, int set_tx,
const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len);
+ const u8 *key, size_t key_len, enum key_flag key_flag);
int hostapd_drv_send_mlme(struct hostapd_data *hapd,
- const void *msg, size_t len, int noack);
-int hostapd_drv_send_mlme_csa(struct hostapd_data *hapd,
- const void *msg, size_t len, int noack,
- const u16 *csa_offs, size_t csa_offs_len);
+ const void *msg, size_t len, int noack,
+ const u16 *csa_offs, size_t csa_offs_len,
+ int no_encrypt);
int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
const u8 *addr, int reason);
int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
@@ -382,4 +381,12 @@ hostapd_drv_send_external_auth_status(struct hostapd_data *hapd,
return hapd->driver->send_external_auth_status(hapd->drv_priv, params);
}
+static inline int
+hostapd_drv_set_band(struct hostapd_data *hapd, enum set_band band)
+{
+ if (!hapd->driver || !hapd->drv_priv || !hapd->driver->set_band)
+ return -1;
+ return hapd->driver->set_band(hapd->drv_priv, band);
+}
+
#endif /* AP_DRV_OPS */
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 331c09b..29c7e38 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -581,7 +581,9 @@ enum ssid_match_result {
static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
const u8 *ssid, size_t ssid_len,
const u8 *ssid_list,
- size_t ssid_list_len)
+ size_t ssid_list_len,
+ const u8 *short_ssid_list,
+ size_t short_ssid_list_len)
{
const u8 *pos, *end;
int wildcard = 0;
@@ -592,20 +594,30 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
os_memcmp(ssid, hapd->conf->ssid.ssid, ssid_len) == 0)
return EXACT_SSID_MATCH;
- if (ssid_list == NULL)
- return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
+ if (ssid_list) {
+ pos = ssid_list;
+ end = ssid_list + ssid_list_len;
+ while (end - pos >= 2) {
+ if (2 + pos[1] > end - pos)
+ break;
+ if (pos[1] == 0)
+ wildcard = 1;
+ if (pos[1] == hapd->conf->ssid.ssid_len &&
+ os_memcmp(pos + 2, hapd->conf->ssid.ssid,
+ pos[1]) == 0)
+ return EXACT_SSID_MATCH;
+ pos += 2 + pos[1];
+ }
+ }
- pos = ssid_list;
- end = ssid_list + ssid_list_len;
- while (end - pos >= 2) {
- if (2 + pos[1] > end - pos)
- break;
- if (pos[1] == 0)
- wildcard = 1;
- if (pos[1] == hapd->conf->ssid.ssid_len &&
- os_memcmp(pos + 2, hapd->conf->ssid.ssid, pos[1]) == 0)
- return EXACT_SSID_MATCH;
- pos += 2 + pos[1];
+ if (short_ssid_list) {
+ pos = short_ssid_list;
+ end = short_ssid_list + short_ssid_list_len;
+ while (end - pos >= 4) {
+ if (hapd->conf->ssid.short_ssid == WPA_GET_LE32(pos))
+ return EXACT_SSID_MATCH;
+ pos += 4;
+ }
}
return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
@@ -743,11 +755,7 @@ void handle_probe_req(struct hostapd_data *hapd,
int ret;
u16 csa_offs[2];
size_t csa_offs_len;
- u32 session_timeout, acct_interim_interval;
- struct vlan_description vlan_id;
- struct hostapd_sta_wpa_psk_short *psk = NULL;
- char *identity = NULL;
- char *radius_cui = NULL;
+ struct radius_sta rad_info;
if (len < IEEE80211_HDRLEN)
return;
@@ -756,10 +764,8 @@ void handle_probe_req(struct hostapd_data *hapd,
sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
ie_len = len - IEEE80211_HDRLEN;
- ret = ieee802_11_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
- &session_timeout,
- &acct_interim_interval, &vlan_id,
- &psk, &identity, &radius_cui, 1);
+ ret = hostapd_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
+ &rad_info, 1);
if (ret == HOSTAPD_ACL_REJECT) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Ignore Probe Request frame from " MACSTR
@@ -838,7 +844,7 @@ void handle_probe_req(struct hostapd_data *hapd,
#endif /* CONFIG_P2P */
if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
- elems.ssid_list_len == 0) {
+ elems.ssid_list_len == 0 && elems.short_ssid_list_len == 0) {
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
"broadcast SSID ignored", MAC2STR(mgmt->sa));
return;
@@ -870,7 +876,8 @@ void handle_probe_req(struct hostapd_data *hapd,
#endif /* CONFIG_TAXONOMY */
res = ssid_match(hapd, elems.ssid, elems.ssid_len,
- elems.ssid_list, elems.ssid_list_len);
+ elems.ssid_list, elems.ssid_list_len,
+ elems.short_ssid_list, elems.short_ssid_list_len);
if (res == NO_SSID_MATCH) {
if (!(mgmt->da[0] & 0x01)) {
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
@@ -883,6 +890,12 @@ void handle_probe_req(struct hostapd_data *hapd,
return;
}
+ if (hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) {
+ wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
+ "broadcast SSID ignored", MAC2STR(mgmt->sa));
+ return;
+ }
+
#ifdef CONFIG_INTERWORKING
if (hapd->conf->interworking &&
elems.interworking && elems.interworking_len >= 1) {
@@ -987,9 +1000,9 @@ void handle_probe_req(struct hostapd_data *hapd,
hapd->cs_c_off_ecsa_proberesp;
}
- ret = hostapd_drv_send_mlme_csa(hapd, resp, resp_len, noack,
- csa_offs_len ? csa_offs : NULL,
- csa_offs_len);
+ ret = hostapd_drv_send_mlme(hapd, resp, resp_len, noack,
+ csa_offs_len ? csa_offs : NULL,
+ csa_offs_len, 0);
if (ret < 0)
wpa_printf(MSG_INFO, "handle_probe_req: send failed");
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index bde61ee..a54b0ca 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -273,6 +273,36 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
if (!os_snprintf_error(buflen - len, res))
len += res;
}
+
+ if (sta->sae && sta->sae->tmp) {
+ const u8 *pos;
+ unsigned int j, count;
+ struct wpabuf *groups = sta->sae->tmp->peer_rejected_groups;
+
+ res = os_snprintf(buf + len, buflen - len,
+ "sae_rejected_groups=");
+ if (!os_snprintf_error(buflen - len, res))
+ len += res;
+
+ if (groups) {
+ pos = wpabuf_head(groups);
+ count = wpabuf_len(groups) / 2;
+ } else {
+ pos = NULL;
+ count = 0;
+ }
+ for (j = 0; pos && j < count; j++) {
+ res = os_snprintf(buf + len, buflen - len, "%s%d",
+ j == 0 ? "" : " ", WPA_GET_LE16(pos));
+ if (!os_snprintf_error(buflen - len, res))
+ len += res;
+ pos += 2;
+ }
+
+ res = os_snprintf(buf + len, buflen - len, "\n");
+ if (!os_snprintf_error(buflen - len, res))
+ len += res;
+ }
#endif /* CONFIG_SAE */
if (sta->vlan_id > 0) {
@@ -432,9 +462,6 @@ static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
int ret;
u8 *pos;
- if (!hapd->drv_priv || !hapd->driver->send_frame)
- return -1;
-
mgmt = os_zalloc(sizeof(*mgmt) + 100);
if (mgmt == NULL)
return -1;
@@ -468,8 +495,8 @@ static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
pos += 2;
*pos++ = minor_reason_code;
- ret = hapd->driver->send_frame(hapd->drv_priv, (u8 *) mgmt,
- pos - (u8 *) mgmt, 1);
+ ret = hostapd_drv_send_mlme(hapd, mgmt, pos - (u8 *) mgmt, 0, NULL, 0,
+ 0);
os_free(mgmt);
return ret < 0 ? -1 : 0;
@@ -499,8 +526,7 @@ int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
if (pos) {
struct ieee80211_mgmt mgmt;
int encrypt;
- if (!hapd->drv_priv || !hapd->driver->send_frame)
- return -1;
+
pos += 6;
encrypt = atoi(pos);
os_memset(&mgmt, 0, sizeof(mgmt));
@@ -510,10 +536,10 @@ int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
mgmt.u.deauth.reason_code = host_to_le16(reason);
- if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
- IEEE80211_HDRLEN +
- sizeof(mgmt.u.deauth),
- encrypt) < 0)
+ if (hostapd_drv_send_mlme(hapd, (u8 *) &mgmt,
+ IEEE80211_HDRLEN +
+ sizeof(mgmt.u.deauth),
+ 0, NULL, 0, !encrypt) < 0)
return -1;
return 0;
}
@@ -562,8 +588,7 @@ int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
if (pos) {
struct ieee80211_mgmt mgmt;
int encrypt;
- if (!hapd->drv_priv || !hapd->driver->send_frame)
- return -1;
+
pos += 6;
encrypt = atoi(pos);
os_memset(&mgmt, 0, sizeof(mgmt));
@@ -573,10 +598,10 @@ int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
mgmt.u.disassoc.reason_code = host_to_le16(reason);
- if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
- IEEE80211_HDRLEN +
- sizeof(mgmt.u.deauth),
- encrypt) < 0)
+ if (hostapd_drv_send_mlme(hapd, (u8 *) &mgmt,
+ IEEE80211_HDRLEN +
+ sizeof(mgmt.u.deauth),
+ 0, NULL, 0, !encrypt) < 0)
return -1;
return 0;
}
diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index db7130a..f70ecc9 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -673,6 +673,9 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
int res, n_chans, n_chans1, start_chan_idx, start_chan_idx1;
int skip_radar = 0;
+ if (is_6ghz_freq(iface->freq))
+ return 1;
+
if (!iface->current_mode) {
/*
* This can happen with drivers that do not provide mode
diff --git a/src/ap/dhcp_snoop.c b/src/ap/dhcp_snoop.c
index ed37fc8..edc77da 100644
--- a/src/ap/dhcp_snoop.c
+++ b/src/ap/dhcp_snoop.c
@@ -39,22 +39,22 @@ static void handle_dhcp(void *ctx, const u8 *src_addr, const u8 *buf,
const u8 *end, *pos;
int res, msgtype = 0, prefixlen = 32;
u32 subnet_mask = 0;
- u16 tot_len;
+ u16 ip_len;
exten_len = len - ETH_HLEN - (sizeof(*b) - sizeof(b->exten));
if (exten_len < 4)
return;
b = (const struct bootp_pkt *) &buf[ETH_HLEN];
- tot_len = ntohs(b->iph.tot_len);
- if (tot_len > (unsigned int) (len - ETH_HLEN))
+ ip_len = ntohs(b->iph.ip_len);
+ if (ip_len > (unsigned int) (len - ETH_HLEN))
return;
if (WPA_GET_BE32(b->exten) != DHCP_MAGIC)
return;
/* Parse DHCP options */
- end = (const u8 *) b + tot_len;
+ end = (const u8 *) b + ip_len;
pos = &b->exten[4];
while (pos < end && *pos != DHCP_OPT_END) {
const u8 *opt = pos++;
diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
index 085d423..1a3a815 100644
--- a/src/ap/dpp_hostapd.c
+++ b/src/ap/dpp_hostapd.c
@@ -1,6 +1,7 @@
/*
* hostapd / DPP integration
* Copyright (c) 2017, Qualcomm Atheros, Inc.
+ * Copyright (c) 2018-2019, The Linux Foundation
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -62,6 +63,24 @@ int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
}
+/**
+ * hostapd_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
+ * @hapd: Pointer to hostapd_data
+ * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
+ * Returns: Identifier of the stored info or -1 on failure
+ */
+int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd)
+{
+ struct dpp_bootstrap_info *bi;
+
+ bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, cmd);
+ if (!bi)
+ return -1;
+
+ return bi->id;
+}
+
+
static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
void *timeout_ctx)
{
@@ -768,7 +787,8 @@ static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
struct wpabuf *buf;
int res;
- buf = dpp_build_conf_req_helper(auth, hapd->conf->dpp_name, 1,
+ buf = dpp_build_conf_req_helper(auth, hapd->conf->dpp_name,
+ DPP_NETROLE_AP,
hapd->conf->dpp_mud_url, NULL);
if (!buf) {
wpa_printf(MSG_DEBUG,
diff --git a/src/ap/dpp_hostapd.h b/src/ap/dpp_hostapd.h
index c1ec5d7..e151c2f 100644
--- a/src/ap/dpp_hostapd.h
+++ b/src/ap/dpp_hostapd.h
@@ -1,6 +1,7 @@
/*
* hostapd / DPP integration
* Copyright (c) 2017, Qualcomm Atheros, Inc.
+ * Copyright (c) 2018-2019, The Linux Foundation
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -10,6 +11,7 @@
#define DPP_HOSTAPD_H
int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd);
+int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd);
int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd);
int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd);
void hostapd_dpp_listen_stop(struct hostapd_data *hapd);
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index e5ce76d..fdd8455 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -17,6 +17,7 @@
#include "common/wpa_ctrl.h"
#include "common/dpp.h"
#include "common/sae.h"
+#include "common/hw_features_common.h"
#include "crypto/random.h"
#include "p2p/p2p.h"
#include "wps/wps.h"
@@ -935,6 +936,7 @@ void hostapd_acs_channel_selected(struct hostapd_data *hapd,
{
int ret, i;
int err = 0;
+ struct hostapd_channel_data *pri_chan;
if (hapd->iconf->channel) {
wpa_printf(MSG_INFO, "ACS: Channel was already set to %d",
@@ -942,12 +944,20 @@ void hostapd_acs_channel_selected(struct hostapd_data *hapd,
return;
}
+ hapd->iface->freq = acs_res->pri_freq;
+
if (!hapd->iface->current_mode) {
for (i = 0; i < hapd->iface->num_hw_features; i++) {
struct hostapd_hw_modes *mode =
&hapd->iface->hw_features[i];
if (mode->mode == acs_res->hw_mode) {
+ if (hapd->iface->freq > 0 &&
+ !hw_get_chan(mode->mode,
+ hapd->iface->freq,
+ hapd->iface->hw_features,
+ hapd->iface->num_hw_features))
+ continue;
hapd->iface->current_mode = mode;
break;
}
@@ -961,24 +971,33 @@ void hostapd_acs_channel_selected(struct hostapd_data *hapd,
}
}
- hapd->iface->freq = hostapd_hw_get_freq(hapd, acs_res->pri_channel);
-
- if (!acs_res->pri_channel) {
+ if (!acs_res->pri_freq) {
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_WARNING,
"driver switched to bad channel");
err = 1;
goto out;
}
+ pri_chan = hw_get_channel_freq(hapd->iface->current_mode->mode,
+ acs_res->pri_freq, NULL,
+ hapd->iface->hw_features,
+ hapd->iface->num_hw_features);
+ if (!pri_chan) {
+ wpa_printf(MSG_ERROR,
+ "ACS: Could not determine primary channel number from pri_freq %u",
+ acs_res->pri_freq);
+ err = 1;
+ goto out;
+ }
- hapd->iconf->channel = acs_res->pri_channel;
+ hapd->iconf->channel = pri_chan->chan;
hapd->iconf->acs = 1;
- if (acs_res->sec_channel == 0)
+ if (acs_res->sec_freq == 0)
hapd->iconf->secondary_channel = 0;
- else if (acs_res->sec_channel < acs_res->pri_channel)
+ else if (acs_res->sec_freq < acs_res->pri_freq)
hapd->iconf->secondary_channel = -1;
- else if (acs_res->sec_channel > acs_res->pri_channel)
+ else if (acs_res->sec_freq > acs_res->pri_freq)
hapd->iconf->secondary_channel = 1;
else {
wpa_printf(MSG_ERROR, "Invalid secondary channel!");
@@ -991,27 +1010,28 @@ void hostapd_acs_channel_selected(struct hostapd_data *hapd,
hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, 0);
hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, 0);
hostapd_set_oper_chwidth(hapd->iconf, CHANWIDTH_USE_HT);
- if (acs_res->ch_width == 80) {
- hostapd_set_oper_centr_freq_seg0_idx(
- hapd->iconf, acs_res->vht_seg0_center_ch);
- hostapd_set_oper_chwidth(hapd->iconf, CHANWIDTH_80MHZ);
- } else if (acs_res->ch_width == 160) {
- if (acs_res->vht_seg1_center_ch == 0) {
+ if (acs_res->ch_width == 40) {
+ if (is_6ghz_freq(acs_res->pri_freq))
hostapd_set_oper_centr_freq_seg0_idx(
hapd->iconf,
acs_res->vht_seg0_center_ch);
+ } else if (acs_res->ch_width == 80) {
+ hostapd_set_oper_centr_freq_seg0_idx(
+ hapd->iconf, acs_res->vht_seg0_center_ch);
+ if (acs_res->vht_seg1_center_ch == 0) {
hostapd_set_oper_chwidth(hapd->iconf,
- CHANWIDTH_160MHZ);
+ CHANWIDTH_80MHZ);
} else {
- hostapd_set_oper_centr_freq_seg0_idx(
- hapd->iconf,
- acs_res->vht_seg0_center_ch);
+ hostapd_set_oper_chwidth(hapd->iconf,
+ CHANWIDTH_80P80MHZ);
hostapd_set_oper_centr_freq_seg1_idx(
hapd->iconf,
acs_res->vht_seg1_center_ch);
- hostapd_set_oper_chwidth(hapd->iconf,
- CHANWIDTH_80P80MHZ);
}
+ } else if (acs_res->ch_width == 160) {
+ hostapd_set_oper_chwidth(hapd->iconf, CHANWIDTH_160MHZ);
+ hostapd_set_oper_centr_freq_seg0_idx(
+ hapd->iconf, acs_res->vht_seg1_center_ch);
}
}
diff --git a/src/ap/fils_hlp.c b/src/ap/fils_hlp.c
index 6da514a..0310aab 100644
--- a/src/ap/fils_hlp.c
+++ b/src/ap/fils_hlp.c
@@ -158,7 +158,7 @@ static void fils_dhcp_handler(int sd, void *eloop_ctx, void *sock_ctx)
ssize_t res;
u8 msgtype = 0;
int rapid_commit = 0;
- struct iphdr *iph;
+ struct ip *iph;
struct udphdr *udph;
struct wpabuf *resp;
const u8 *rpos;
@@ -259,14 +259,14 @@ static void fils_dhcp_handler(int sd, void *eloop_ctx, void *sock_ctx)
wpabuf_put_data(resp, "\xaa\xaa\x03\x00\x00\x00", 6);
wpabuf_put_be16(resp, ETH_P_IP);
iph = wpabuf_put(resp, sizeof(*iph));
- iph->version = 4;
- iph->ihl = sizeof(*iph) / 4;
- iph->tot_len = htons(sizeof(*iph) + sizeof(*udph) + (end - pos));
- iph->ttl = 1;
- iph->protocol = 17; /* UDP */
- iph->saddr = hapd->conf->dhcp_server.u.v4.s_addr;
- iph->daddr = dhcp->client_ip;
- iph->check = ip_checksum(iph, sizeof(*iph));
+ iph->ip_v = 4;
+ iph->ip_hl = sizeof(*iph) / 4;
+ iph->ip_len = htons(sizeof(*iph) + sizeof(*udph) + (end - pos));
+ iph->ip_ttl = 1;
+ iph->ip_p = 17; /* UDP */
+ iph->ip_src.s_addr = hapd->conf->dhcp_server.u.v4.s_addr;
+ iph->ip_dst.s_addr = dhcp->client_ip;
+ iph->ip_sum = ip_checksum(iph, sizeof(*iph));
udph = wpabuf_put(resp, sizeof(*udph));
udph->uh_sport = htons(DHCP_SERVER_PORT);
udph->uh_dport = htons(DHCP_CLIENT_PORT);
@@ -479,13 +479,13 @@ static int fils_process_hlp_udp(struct hostapd_data *hapd,
struct sta_info *sta, const u8 *dst,
const u8 *pos, size_t len)
{
- const struct iphdr *iph;
+ const struct ip *iph;
const struct udphdr *udph;
u16 sport, dport, ulen;
if (len < sizeof(*iph) + sizeof(*udph))
return 0;
- iph = (const struct iphdr *) pos;
+ iph = (const struct ip *) pos;
udph = (const struct udphdr *) (iph + 1);
sport = ntohs(udph->uh_sport);
dport = ntohs(udph->uh_dport);
@@ -510,24 +510,24 @@ static int fils_process_hlp_ip(struct hostapd_data *hapd,
struct sta_info *sta, const u8 *dst,
const u8 *pos, size_t len)
{
- const struct iphdr *iph;
- u16 tot_len;
+ const struct ip *iph;
+ uint16_t ip_len;
if (len < sizeof(*iph))
return 0;
- iph = (const struct iphdr *) pos;
+ iph = (const struct ip *) pos;
if (ip_checksum(iph, sizeof(*iph)) != 0) {
wpa_printf(MSG_DEBUG,
"FILS: HLP request IPv4 packet had invalid header checksum - dropped");
return 0;
}
- tot_len = ntohs(iph->tot_len);
- if (tot_len > len)
+ ip_len = ntohs(iph->ip_len);
+ if (ip_len > len)
return 0;
wpa_printf(MSG_DEBUG,
"FILS: HLP request IPv4: saddr=%08x daddr=%08x protocol=%u",
- iph->saddr, iph->daddr, iph->protocol);
- switch (iph->protocol) {
+ iph->ip_src.s_addr, iph->ip_dst.s_addr, iph->ip_p);
+ switch (iph->ip_p) {
case 17:
return fils_process_hlp_udp(hapd, sta, dst, pos, len);
}
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 3686438..b87663f 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -13,6 +13,7 @@
#include "utils/common.h"
#include "utils/eloop.h"
+#include "utils/crc32.h"
#include "common/ieee802_11_defs.h"
#include "common/wpa_ctrl.h"
#include "common/hw_features_common.h"
@@ -291,8 +292,8 @@ static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
if (!ifname || !hapd->drv_priv)
return;
for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i,
- 0, NULL, 0, NULL, 0)) {
+ if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 0,
+ 0, NULL, 0, NULL, 0, KEY_FLAG_GROUP)) {
wpa_printf(MSG_DEBUG, "Failed to clear default "
"encryption keys (ifname=%s keyidx=%d)",
ifname, i);
@@ -301,8 +302,8 @@ static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
if (hapd->conf->ieee80211w) {
for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
- NULL, i, 0, NULL,
- 0, NULL, 0)) {
+ NULL, i, 0, 0, NULL,
+ 0, NULL, 0, KEY_FLAG_GROUP)) {
wpa_printf(MSG_DEBUG, "Failed to clear "
"default mgmt encryption keys "
"(ifname=%s keyidx=%d)", ifname, i);
@@ -327,9 +328,10 @@ static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
idx = ssid->wep.idx;
if (ssid->wep.default_len &&
hostapd_drv_set_key(hapd->conf->iface,
- hapd, WPA_ALG_WEP, broadcast_ether_addr, idx,
+ hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 0,
1, NULL, 0, ssid->wep.key[idx],
- ssid->wep.len[idx])) {
+ ssid->wep.len[idx],
+ KEY_FLAG_GROUP_RX_TX_DEFAULT)) {
wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
errors++;
}
@@ -552,10 +554,13 @@ static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
for (i = 0; i < 4; i++) {
if (hapd->conf->ssid.wep.key[i] &&
- hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i,
+ hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 0,
i == hapd->conf->ssid.wep.idx, NULL, 0,
hapd->conf->ssid.wep.key[i],
- hapd->conf->ssid.wep.len[i])) {
+ hapd->conf->ssid.wep.len[i],
+ i == hapd->conf->ssid.wep.idx ?
+ KEY_FLAG_GROUP_RX_TX_DEFAULT :
+ KEY_FLAG_GROUP_RX_TX)) {
wpa_printf(MSG_WARNING, "Could not set WEP "
"encryption.");
return -1;
@@ -1190,8 +1195,14 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
}
+ /*
+ * Short SSID calculation is identical to FCS and it is defined in
+ * IEEE P802.11-REVmd/D3.0, 9.4.2.170.3 (Calculating the Short-SSID).
+ */
+ conf->ssid.short_ssid = crc32(conf->ssid.ssid, conf->ssid.ssid_len);
+
if (!hostapd_drv_none(hapd)) {
- wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR
+ wpa_printf(MSG_DEBUG, "Using interface %s with hwaddr " MACSTR
" and ssid \"%s\"",
conf->iface, MAC2STR(hapd->own_addr),
wpa_ssid_txt(conf->ssid.ssid, conf->ssid.ssid_len));
@@ -1572,6 +1583,51 @@ static int setup_interface(struct hostapd_iface *iface)
}
+static int configured_fixed_chan_to_freq(struct hostapd_iface *iface)
+{
+ int freq, i, j;
+
+ if (!iface->conf->channel)
+ return 0;
+ if (iface->conf->op_class) {
+ freq = ieee80211_chan_to_freq(NULL, iface->conf->op_class,
+ iface->conf->channel);
+ if (freq < 0) {
+ wpa_printf(MSG_INFO,
+ "Could not convert op_class %u channel %u to operating frequency",
+ iface->conf->op_class, iface->conf->channel);
+ return -1;
+ }
+ iface->freq = freq;
+ return 0;
+ }
+
+ /* Old configurations using only 2.4/5/60 GHz bands may not specify the
+ * op_class parameter. Select a matching channel from the configured
+ * mode using the channel parameter for these cases.
+ */
+ for (j = 0; j < iface->num_hw_features; j++) {
+ struct hostapd_hw_modes *mode = &iface->hw_features[j];
+
+ if (iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY &&
+ iface->conf->hw_mode != mode->mode)
+ continue;
+ for (i = 0; i < mode->num_channels; i++) {
+ struct hostapd_channel_data *chan = &mode->channels[i];
+
+ if (chan->chan == iface->conf->channel &&
+ !is_6ghz_freq(chan->freq)) {
+ iface->freq = chan->freq;
+ return 0;
+ }
+ }
+ }
+
+ wpa_printf(MSG_INFO, "Could not determine operating frequency");
+ return -1;
+}
+
+
static int setup_interface2(struct hostapd_iface *iface)
{
iface->wait_channel_update = 0;
@@ -1580,7 +1636,20 @@ static int setup_interface2(struct hostapd_iface *iface)
/* Not all drivers support this yet, so continue without hw
* feature data. */
} else {
- int ret = hostapd_select_hw_mode(iface);
+ int ret;
+
+ ret = configured_fixed_chan_to_freq(iface);
+ if (ret < 0)
+ goto fail;
+
+ if (iface->conf->op_class) {
+ int ch_width;
+
+ ch_width = op_class_to_ch_width(iface->conf->op_class);
+ hostapd_set_oper_chwidth(iface->conf, ch_width);
+ }
+
+ ret = hostapd_select_hw_mode(iface);
if (ret < 0) {
wpa_printf(MSG_ERROR, "Could not select hw_mode and "
"channel. (%d)", ret);
@@ -1864,12 +1933,11 @@ static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
goto fail;
wpa_printf(MSG_DEBUG, "Completing interface initialization");
- if (iface->conf->channel) {
+ if (iface->freq) {
#ifdef NEED_AP_MLME
int res;
#endif /* NEED_AP_MLME */
- iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel);
wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d "
"Frequency: %d MHz",
hostapd_hw_mode_txt(iface->conf->hw_mode),
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 2fefaf8..ba10752 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -227,13 +227,25 @@ int hostapd_prepare_rates(struct hostapd_iface *iface,
#ifdef CONFIG_IEEE80211N
static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface)
{
- int pri_chan, sec_chan;
+ int pri_freq, sec_freq;
+ struct hostapd_channel_data *p_chan, *s_chan;
- pri_chan = iface->conf->channel;
- sec_chan = pri_chan + iface->conf->secondary_channel * 4;
+ pri_freq = iface->freq;
+ sec_freq = pri_freq + iface->conf->secondary_channel * 20;
+
+ if (!iface->current_mode)
+ return 0;
- return allowed_ht40_channel_pair(iface->current_mode, pri_chan,
- sec_chan);
+ p_chan = hw_get_channel_freq(iface->current_mode->mode, pri_freq, NULL,
+ iface->hw_features,
+ iface->num_hw_features);
+
+ s_chan = hw_get_channel_freq(iface->current_mode->mode, sec_freq, NULL,
+ iface->hw_features,
+ iface->num_hw_features);
+
+ return allowed_ht40_channel_pair(iface->current_mode->mode,
+ p_chan, s_chan);
}
@@ -241,9 +253,11 @@ static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface)
{
if (iface->conf->secondary_channel > 0) {
iface->conf->channel += 4;
+ iface->freq += 20;
iface->conf->secondary_channel = -1;
} else {
iface->conf->channel -= 4;
+ iface->freq -= 20;
iface->conf->secondary_channel = 1;
}
}
@@ -252,13 +266,23 @@ static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface)
static int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface,
struct wpa_scan_results *scan_res)
{
- int pri_chan, sec_chan;
+ unsigned int pri_freq, sec_freq;
int res;
+ struct hostapd_channel_data *pri_chan, *sec_chan;
- pri_chan = iface->conf->channel;
- sec_chan = pri_chan + iface->conf->secondary_channel * 4;
+ pri_freq = iface->freq;
+ sec_freq = pri_freq + iface->conf->secondary_channel * 20;
+
+ if (!iface->current_mode)
+ return 0;
+ pri_chan = hw_get_channel_freq(iface->current_mode->mode, pri_freq,
+ NULL, iface->hw_features,
+ iface->num_hw_features);
+ sec_chan = hw_get_channel_freq(iface->current_mode->mode, sec_freq,
+ NULL, iface->hw_features,
+ iface->num_hw_features);
- res = check_40mhz_5g(iface->current_mode, scan_res, pri_chan, sec_chan);
+ res = check_40mhz_5g(scan_res, pri_chan, sec_chan);
if (res == 2) {
if (iface->conf->no_pri_sec_switch) {
@@ -352,7 +376,7 @@ static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface,
if (iface->current_mode == NULL)
return;
- pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
+ pri_freq = iface->freq;
if (iface->conf->secondary_channel > 0)
sec_freq = pri_freq + 20;
else
@@ -397,7 +421,7 @@ static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface,
if (iface->current_mode == NULL)
return;
- pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
+ pri_freq = iface->freq;
if (iface->conf->secondary_channel > 0) {
affected_start = pri_freq - 10;
affected_end = pri_freq + 30;
@@ -670,6 +694,9 @@ int hostapd_check_ht_capab(struct hostapd_iface *iface)
{
#ifdef CONFIG_IEEE80211N
int ret;
+
+ if (is_6ghz_freq(iface->freq))
+ return 0;
if (!iface->conf->ieee80211n)
return 0;
@@ -731,14 +758,15 @@ int hostapd_check_edmg_capab(struct hostapd_iface *iface)
static int hostapd_is_usable_chan(struct hostapd_iface *iface,
- int channel, int primary)
+ int frequency, int primary)
{
struct hostapd_channel_data *chan;
if (!iface->current_mode)
return 0;
- chan = hw_get_channel_chan(iface->current_mode, channel, NULL);
+ chan = hw_get_channel_freq(iface->current_mode->mode, frequency, NULL,
+ iface->hw_features, iface->num_hw_features);
if (!chan)
return 0;
@@ -747,8 +775,8 @@ static int hostapd_is_usable_chan(struct hostapd_iface *iface,
return 1;
wpa_printf(MSG_INFO,
- "Channel %d (%s) not allowed for AP mode, flags: 0x%x%s%s",
- channel, primary ? "primary" : "secondary",
+ "Frequency %d (%s) not allowed for AP mode, flags: 0x%x%s%s",
+ frequency, primary ? "primary" : "secondary",
chan->flag,
chan->flag & HOSTAPD_CHAN_NO_IR ? " NO-IR" : "",
chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : "");
@@ -762,19 +790,28 @@ static int hostapd_is_usable_edmg(struct hostapd_iface *iface)
int num_of_enabled = 0;
int max_contiguous = 0;
struct ieee80211_edmg_config edmg;
+ struct hostapd_channel_data *pri_chan;
if (!iface->conf->enable_edmg)
return 1;
+ if (!iface->current_mode)
+ return 0;
+ pri_chan = hw_get_channel_freq(iface->current_mode->mode,
+ iface->freq, NULL,
+ iface->hw_features,
+ iface->num_hw_features);
hostapd_encode_edmg_chan(iface->conf->enable_edmg,
iface->conf->edmg_channel,
- iface->conf->channel,
+ pri_chan->chan,
&edmg);
- if (!(edmg.channels & BIT(iface->conf->channel - 1)))
+ if (!(edmg.channels & BIT(pri_chan->chan - 1)))
return 0;
/* 60 GHz channels 1..6 */
for (i = 0; i < 6; i++) {
+ int freq = 56160 + 2160 * i;
+
if (edmg.channels & BIT(i)) {
contiguous++;
num_of_enabled++;
@@ -789,7 +826,7 @@ static int hostapd_is_usable_edmg(struct hostapd_iface *iface)
if (num_of_enabled > 4)
return 0;
- if (!hostapd_is_usable_chan(iface, i + 1, 1))
+ if (!hostapd_is_usable_chan(iface, freq, 1))
return 0;
if (contiguous > max_contiguous)
@@ -819,17 +856,23 @@ static int hostapd_is_usable_edmg(struct hostapd_iface *iface)
static int hostapd_is_usable_chans(struct hostapd_iface *iface)
{
- int secondary_chan;
+ int secondary_freq;
struct hostapd_channel_data *pri_chan;
- pri_chan = hw_get_channel_chan(iface->current_mode,
- iface->conf->channel, NULL);
- if (!pri_chan)
+ if (!iface->current_mode)
return 0;
-
- if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1))
+ pri_chan = hw_get_channel_freq(iface->current_mode->mode,
+ iface->freq, NULL,
+ iface->hw_features,
+ iface->num_hw_features);
+ if (!pri_chan) {
+ wpa_printf(MSG_ERROR, "Primary frequency not present");
return 0;
-
+ }
+ if (!hostapd_is_usable_chan(iface, pri_chan->freq, 1)) {
+ wpa_printf(MSG_ERROR, "Primary frequency not allowed");
+ return 0;
+ }
if (!hostapd_is_usable_edmg(iface))
return 0;
@@ -838,19 +881,19 @@ static int hostapd_is_usable_chans(struct hostapd_iface *iface)
if (!iface->conf->ht40_plus_minus_allowed)
return hostapd_is_usable_chan(
- iface, iface->conf->channel +
- iface->conf->secondary_channel * 4, 0);
+ iface,
+ iface->freq + iface->conf->secondary_channel * 20, 0);
/* Both HT40+ and HT40- are set, pick a valid secondary channel */
- secondary_chan = iface->conf->channel + 4;
- if (hostapd_is_usable_chan(iface, secondary_chan, 0) &&
+ secondary_freq = iface->freq + 20;
+ if (hostapd_is_usable_chan(iface, secondary_freq, 0) &&
(pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)) {
iface->conf->secondary_channel = 1;
return 1;
}
- secondary_chan = iface->conf->channel - 4;
- if (hostapd_is_usable_chan(iface, secondary_chan, 0) &&
+ secondary_freq = iface->freq - 20;
+ if (hostapd_is_usable_chan(iface, secondary_freq, 0) &&
(pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40M)) {
iface->conf->secondary_channel = -1;
return 1;
@@ -863,7 +906,7 @@ static int hostapd_is_usable_chans(struct hostapd_iface *iface)
static enum hostapd_chan_status
hostapd_check_chans(struct hostapd_iface *iface)
{
- if (iface->conf->channel) {
+ if (iface->freq) {
if (hostapd_is_usable_chans(iface))
return HOSTAPD_CHAN_VALID;
else
@@ -897,9 +940,9 @@ static void hostapd_notify_bad_chans(struct hostapd_iface *iface)
hostapd_logger(iface->bss[0], NULL,
HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_WARNING,
- "Configured channel (%d) not found from the "
- "channel list of current mode (%d) %s",
+ "Configured channel (%d) or frequency (%d) not found from the channel list of the current mode (%d) %s",
iface->conf->channel,
+ iface->freq,
iface->current_mode->mode,
hostapd_hw_mode_txt(iface->current_mode->mode));
hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
@@ -919,9 +962,7 @@ int hostapd_acs_completed(struct hostapd_iface *iface, int err)
case HOSTAPD_CHAN_VALID:
wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO,
ACS_EVENT_COMPLETED "freq=%d channel=%d",
- hostapd_hw_get_freq(iface->bss[0],
- iface->conf->channel),
- iface->conf->channel);
+ iface->freq, iface->conf->channel);
break;
case HOSTAPD_CHAN_ACS:
wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available");
@@ -961,7 +1002,6 @@ out:
int hostapd_select_hw_mode(struct hostapd_iface *iface)
{
int i;
- int freq = -1;
if (iface->num_hw_features < 1)
return -1;
@@ -978,13 +1018,13 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
}
iface->current_mode = NULL;
- if (iface->conf->channel && iface->conf->op_class)
- freq = ieee80211_chan_to_freq(NULL, iface->conf->op_class,
- iface->conf->channel);
for (i = 0; i < iface->num_hw_features; i++) {
struct hostapd_hw_modes *mode = &iface->hw_features[i];
if (mode->mode == iface->conf->hw_mode) {
- if (freq > 0 && !hw_get_chan(mode, freq))
+ if (iface->freq > 0 &&
+ !hw_get_chan(mode->mode, iface->freq,
+ iface->hw_features,
+ iface->num_hw_features))
continue;
iface->current_mode = mode;
break;
@@ -1048,7 +1088,9 @@ int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
struct hostapd_hw_modes *mode;
if (hapd->iface->current_mode) {
- channel = hw_get_chan(hapd->iface->current_mode, freq);
+ channel = hw_get_chan(hapd->iface->current_mode->mode, freq,
+ hapd->iface->hw_features,
+ hapd->iface->num_hw_features);
if (channel)
return channel;
}
@@ -1059,7 +1101,9 @@ int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
return 0;
for (i = 0; i < hapd->iface->num_hw_features; i++) {
mode = &hapd->iface->hw_features[i];
- channel = hw_get_chan(mode, freq);
+ channel = hw_get_chan(mode->mode, freq,
+ hapd->iface->hw_features,
+ hapd->iface->num_hw_features);
if (channel)
return channel;
}
diff --git a/src/ap/hw_features.h b/src/ap/hw_features.h
index 902a19f..6749319 100644
--- a/src/ap/hw_features.h
+++ b/src/ap/hw_features.h
@@ -49,7 +49,7 @@ static inline int hostapd_select_hw_mode(struct hostapd_iface *iface)
static inline const char * hostapd_hw_mode_txt(int mode)
{
- return NULL;
+ return "UNKNOWN";
}
static inline int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan)
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 92ae026..cd61077 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -98,7 +98,8 @@ u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
num++;
if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
num++;
- if (hapd->conf->sae_pwe == 1)
+ if (hapd->conf->sae_pwe == 1 &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt))
num++;
if (num > 8) {
/* rest of the rates are encoded in Extended supported
@@ -126,7 +127,9 @@ u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
}
- if (hapd->conf->sae_pwe == 1 && count < 8) {
+ if (hapd->conf->sae_pwe == 1 &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
+ count < 8) {
count++;
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
}
@@ -148,7 +151,8 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
num++;
if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
num++;
- if (hapd->conf->sae_pwe == 1)
+ if (hapd->conf->sae_pwe == 1 &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt))
num++;
if (num <= 8)
return eid;
@@ -179,7 +183,8 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
}
- if (hapd->conf->sae_pwe == 1) {
+ if (hapd->conf->sae_pwe == 1 &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt)) {
count++;
if (count > 8)
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
@@ -311,7 +316,7 @@ static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
#endif /* CONFIG_NO_RC4 */
-static int send_auth_reply(struct hostapd_data *hapd,
+static int send_auth_reply(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *dst, const u8 *bssid,
u16 auth_alg, u16 auth_transaction, u16 resp,
const u8 *ies, size_t ies_len, const char *dbg)
@@ -344,7 +349,37 @@ static int send_auth_reply(struct hostapd_data *hapd,
" auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
MAC2STR(dst), auth_alg, auth_transaction,
resp, (unsigned long) ies_len, dbg);
- if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0)
+#ifdef CONFIG_TESTING_OPTIONS
+#ifdef CONFIG_SAE
+ if (hapd->conf->sae_confirm_immediate == 2 &&
+ auth_alg == WLAN_AUTH_SAE) {
+ if (auth_transaction == 1 &&
+ (resp == WLAN_STATUS_SUCCESS ||
+ resp == WLAN_STATUS_SAE_HASH_TO_ELEMENT)) {
+ wpa_printf(MSG_DEBUG,
+ "TESTING: Postpone SAE Commit transmission until Confirm is ready");
+ os_free(sta->sae_postponed_commit);
+ sta->sae_postponed_commit = buf;
+ sta->sae_postponed_commit_len = rlen;
+ return WLAN_STATUS_SUCCESS;
+ }
+
+ if (auth_transaction == 2 && sta && sta->sae_postponed_commit) {
+ wpa_printf(MSG_DEBUG,
+ "TESTING: Send postponed SAE Commit first, immediately followed by SAE Confirm");
+ if (hostapd_drv_send_mlme(hapd,
+ sta->sae_postponed_commit,
+ sta->sae_postponed_commit_len,
+ 0, NULL, 0, 0) < 0)
+ wpa_printf(MSG_INFO, "send_auth_reply: send failed");
+ os_free(sta->sae_postponed_commit);
+ sta->sae_postponed_commit = NULL;
+ sta->sae_postponed_commit_len = 0;
+ }
+ }
+#endif /* CONFIG_SAE */
+#endif /* CONFIG_TESTING_OPTIONS */
+ if (hostapd_drv_send_mlme(hapd, reply, rlen, 0, NULL, 0, 0) < 0)
wpa_printf(MSG_INFO, "send_auth_reply: send failed");
else
reply_res = WLAN_STATUS_SUCCESS;
@@ -364,7 +399,7 @@ static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
struct sta_info *sta;
int reply_res;
- reply_res = send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT,
+ reply_res = send_auth_reply(hapd, NULL, dst, bssid, WLAN_AUTH_FT,
auth_transaction, status, ies, ies_len,
"auth-ft-finish");
@@ -509,7 +544,8 @@ static int auth_sae_send_commit(struct hostapd_data *hapd,
status = (sta->sae->tmp && sta->sae->tmp->h2e) ?
WLAN_STATUS_SAE_HASH_TO_ELEMENT : WLAN_STATUS_SUCCESS;
- reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 1,
+ reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
+ WLAN_AUTH_SAE, 1,
status, wpabuf_head(data),
wpabuf_len(data), "sae-send-commit");
@@ -530,7 +566,8 @@ static int auth_sae_send_confirm(struct hostapd_data *hapd,
if (data == NULL)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
- reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 2,
+ reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
+ WLAN_AUTH_SAE, 2,
WLAN_STATUS_SUCCESS, wpabuf_head(data),
wpabuf_len(data), "sae-send-confirm");
@@ -1098,7 +1135,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
wpa_printf(MSG_DEBUG, "SAE: TESTING - reflection attack");
pos = mgmt->u.auth.variable;
end = ((const u8 *) mgmt) + len;
- send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
+ send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
auth_transaction, resp, pos, end - pos,
"auth-sae-reflection-attack");
goto remove_sta;
@@ -1106,7 +1143,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
if (hapd->conf->sae_commit_override && auth_transaction == 1) {
wpa_printf(MSG_DEBUG, "SAE: TESTING - commit override");
- send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
+ send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
auth_transaction, resp,
wpabuf_head(hapd->conf->sae_commit_override),
wpabuf_len(hapd->conf->sae_commit_override),
@@ -1117,8 +1154,10 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
if (!sta->sae) {
if (auth_transaction != 1 ||
!sae_status_success(hapd, status_code)) {
- resp = -1;
- goto remove_sta;
+ wpa_printf(MSG_DEBUG, "SAE: Unexpected Status Code %u",
+ status_code);
+ resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ goto reply;
}
sta->sae = os_zalloc(sizeof(*sta->sae));
if (!sta->sae) {
@@ -1273,9 +1312,9 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
if (sta->sae->tmp &&
check_sae_rejected_groups(
- hapd, sta->sae->tmp->peer_rejected_groups) < 0) {
+ hapd, sta->sae->tmp->peer_rejected_groups)) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
- goto remove_sta;
+ goto reply;
}
if (!token && use_sae_anti_clogging(hapd) && !allow_reuse) {
@@ -1358,7 +1397,7 @@ reply:
data = wpabuf_alloc_copy(pos, 2);
sae_sme_send_external_auth_status(hapd, sta, resp);
- send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
+ send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
auth_transaction, resp,
data ? wpabuf_head(data) : (u8 *) "",
data ? wpabuf_len(data) : 0, "auth-sae");
@@ -1999,7 +2038,7 @@ static void handle_auth_fils_finish(struct hostapd_data *hapd,
auth_alg = (pub ||
resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) ?
WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
- send_auth_reply(hapd, sta->addr, hapd->own_addr, auth_alg, 2, resp,
+ send_auth_reply(hapd, sta, sta->addr, hapd->own_addr, auth_alg, 2, resp,
data ? wpabuf_head(data) : (u8 *) "",
data ? wpabuf_len(data) : 0, "auth-fils-finish");
wpabuf_free(data);
@@ -2043,28 +2082,18 @@ void ieee802_11_finish_fils_auth(struct hostapd_data *hapd,
#endif /* CONFIG_FILS */
-int
-ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
- const u8 *msg, size_t len, u32 *session_timeout,
- u32 *acct_interim_interval,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui, int is_probe_req)
+static int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
+ const u8 *msg, size_t len,
+ struct radius_sta *info)
{
int res;
- os_memset(vlan_id, 0, sizeof(*vlan_id));
- res = hostapd_allowed_address(hapd, addr, msg, len,
- session_timeout, acct_interim_interval,
- vlan_id, psk, identity, radius_cui,
- is_probe_req);
+ res = hostapd_allowed_address(hapd, addr, msg, len, info, 0);
if (res == HOSTAPD_ACL_REJECT) {
- if (!is_probe_req)
- wpa_printf(MSG_DEBUG,
- "Station " MACSTR
- " not allowed to authenticate",
- MAC2STR(addr));
+ wpa_printf(MSG_DEBUG, "Station " MACSTR
+ " not allowed to authenticate",
+ MAC2STR(addr));
return HOSTAPD_ACL_REJECT;
}
@@ -2084,12 +2113,15 @@ ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
static int
ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
- int res, u32 session_timeout,
- u32 acct_interim_interval,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui)
+ int res, struct radius_sta *info)
{
+ u32 session_timeout = info->session_timeout;
+ u32 acct_interim_interval = info->acct_interim_interval;
+ struct vlan_description *vlan_id = &info->vlan_id;
+ struct hostapd_sta_wpa_psk_short *psk = info->psk;
+ char *identity = info->identity;
+ char *radius_cui = info->radius_cui;
+
if (vlan_id->notempty &&
!hostapd_vlan_valid(hapd->conf->vlan, vlan_id)) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
@@ -2106,20 +2138,22 @@ ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
hostapd_free_psk_list(sta->psk);
- if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
- sta->psk = *psk;
- *psk = NULL;
- } else {
+ if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED)
+ hostapd_copy_psk_list(&sta->psk, psk);
+ else
sta->psk = NULL;
- }
os_free(sta->identity);
- sta->identity = *identity;
- *identity = NULL;
+ if (identity)
+ sta->identity = os_strdup(identity);
+ else
+ sta->identity = NULL;
os_free(sta->radius_cui);
- sta->radius_cui = *radius_cui;
- *radius_cui = NULL;
+ if (radius_cui)
+ sta->radius_cui = os_strdup(radius_cui);
+ else
+ sta->radius_cui = NULL;
if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
sta->acct_interim_interval = acct_interim_interval;
@@ -2147,14 +2181,10 @@ static void handle_auth(struct hostapd_data *hapd,
int res, reply_res;
u16 fc;
const u8 *challenge = NULL;
- u32 session_timeout, acct_interim_interval;
- struct vlan_description vlan_id;
- struct hostapd_sta_wpa_psk_short *psk = NULL;
u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
size_t resp_ies_len = 0;
- char *identity = NULL;
- char *radius_cui = NULL;
u16 seq_ctrl;
+ struct radius_sta rad_info;
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
@@ -2305,10 +2335,8 @@ static void handle_auth(struct hostapd_data *hapd,
}
}
- res = ieee802_11_allowed_address(
- hapd, mgmt->sa, (const u8 *) mgmt, len, &session_timeout,
- &acct_interim_interval, &vlan_id, &psk, &identity, &radius_cui,
- 0);
+ res = ieee802_11_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
+ &rad_info);
if (res == HOSTAPD_ACL_REJECT) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Ignore Authentication frame from " MACSTR
@@ -2391,9 +2419,7 @@ static void handle_auth(struct hostapd_data *hapd,
sta->auth_rssi = rssi;
#endif /* CONFIG_MBO */
- res = ieee802_11_set_radius_info(
- hapd, sta, res, session_timeout, acct_interim_interval,
- &vlan_id, &psk, &identity, &radius_cui);
+ res = ieee802_11_set_radius_info(hapd, sta, res, &rad_info);
if (res) {
wpa_printf(MSG_DEBUG, "ieee802_11_set_radius_info() failed");
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
@@ -2535,11 +2561,7 @@ static void handle_auth(struct hostapd_data *hapd,
}
fail:
- os_free(identity);
- os_free(radius_cui);
- hostapd_free_psk_list(psk);
-
- reply_res = send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
+ reply_res = send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, auth_alg,
auth_transaction + 1, resp, resp_ies,
resp_ies_len, "handle-auth");
@@ -3472,7 +3494,7 @@ static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
reply.u.deauth.reason_code = host_to_le16(reason_code);
- if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0)
+ if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0, NULL, 0, 0) < 0)
wpa_printf(MSG_INFO, "Failed to send deauth: %s",
strerror(errno));
}
@@ -3858,7 +3880,7 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
}
#endif /* CONFIG_FILS */
- if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) {
+ if (hostapd_drv_send_mlme(hapd, reply, send_len, 0, NULL, 0, 0) < 0) {
wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
strerror(errno));
res = WLAN_STATUS_UNSPECIFIED_FAILURE;
@@ -3990,9 +4012,6 @@ static void handle_assoc(struct hostapd_data *hapd,
int left, i;
struct sta_info *sta;
u8 *tmp = NULL;
- struct hostapd_sta_wpa_psk_short *psk = NULL;
- char *identity = NULL;
- char *radius_cui = NULL;
#ifdef CONFIG_FILS
int delay_assoc = 0;
#endif /* CONFIG_FILS */
@@ -4072,13 +4091,11 @@ static void handle_assoc(struct hostapd_data *hapd,
hapd->iface->current_mode->mode ==
HOSTAPD_MODE_IEEE80211AD) {
int acl_res;
- u32 session_timeout, acct_interim_interval;
- struct vlan_description vlan_id;
+ struct radius_sta info;
- acl_res = ieee802_11_allowed_address(
- hapd, mgmt->sa, (const u8 *) mgmt, len,
- &session_timeout, &acct_interim_interval,
- &vlan_id, &psk, &identity, &radius_cui, 0);
+ acl_res = ieee802_11_allowed_address(hapd, mgmt->sa,
+ (const u8 *) mgmt,
+ len, &info);
if (acl_res == HOSTAPD_ACL_REJECT) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Ignore Association Request frame from "
@@ -4103,9 +4120,7 @@ static void handle_assoc(struct hostapd_data *hapd,
}
acl_res = ieee802_11_set_radius_info(
- hapd, sta, acl_res, session_timeout,
- acct_interim_interval, &vlan_id, &psk,
- &identity, &radius_cui);
+ hapd, sta, acl_res, &info);
if (acl_res) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
@@ -4306,9 +4321,6 @@ static void handle_assoc(struct hostapd_data *hapd,
#endif /* CONFIG_FILS */
fail:
- os_free(identity);
- os_free(radius_cui);
- hostapd_free_psk_list(psk);
/*
* In case of a successful response, add the station to the driver.
@@ -4698,7 +4710,7 @@ static int handle_action(struct hostapd_data *hapd,
os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
resp->u.action.category |= 0x80;
- if (hostapd_drv_send_mlme(hapd, resp, len, 0) < 0) {
+ if (hostapd_drv_send_mlme(hapd, resp, len, 0, NULL, 0, 0) < 0) {
wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send "
"Action frame");
}
@@ -4899,8 +4911,11 @@ static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
for (i = 0; i < 4; i++) {
if (ssid->wep.key[i] &&
hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
- i == ssid->wep.idx, NULL, 0,
- ssid->wep.key[i], ssid->wep.len[i])) {
+ 0, i == ssid->wep.idx, NULL, 0,
+ ssid->wep.key[i], ssid->wep.len[i],
+ i == ssid->wep.idx ?
+ KEY_FLAG_GROUP_RX_TX_DEFAULT :
+ KEY_FLAG_GROUP_RX_TX)) {
wpa_printf(MSG_WARNING,
"Could not set WEP keys for WDS interface; %s",
ifname_wds);
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index f592da5..0983d4c 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -16,8 +16,7 @@ struct hostapd_frame_info;
struct ieee80211_ht_capabilities;
struct ieee80211_vht_capabilities;
struct ieee80211_mgmt;
-struct vlan_description;
-struct hostapd_sta_wpa_psk_short;
+struct radius_sta;
enum ieee80211_op_mode;
int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
@@ -180,13 +179,6 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
size_t hostapd_eid_owe_trans_len(struct hostapd_data *hapd);
u8 * hostapd_eid_owe_trans(struct hostapd_data *hapd, u8 *eid, size_t len);
-int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
- const u8 *msg, size_t len, u32 *session_timeout,
- u32 *acct_interim_interval,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui,
- int is_probe_req);
int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth,
int ap_seg1_idx, int *bandwidth, int *seg1_idx);
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index 931d4d0..783ee6d 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -32,12 +32,7 @@ struct hostapd_cached_radius_acl {
macaddr addr;
int accepted; /* HOSTAPD_ACL_* */
struct hostapd_cached_radius_acl *next;
- u32 session_timeout;
- u32 acct_interim_interval;
- struct vlan_description vlan_id;
- struct hostapd_sta_wpa_psk_short *psk;
- char *identity;
- char *radius_cui;
+ struct radius_sta info;
};
@@ -54,9 +49,9 @@ struct hostapd_acl_query_data {
#ifndef CONFIG_NO_RADIUS
static void hostapd_acl_cache_free_entry(struct hostapd_cached_radius_acl *e)
{
- os_free(e->identity);
- os_free(e->radius_cui);
- hostapd_free_psk_list(e->psk);
+ os_free(e->info.identity);
+ os_free(e->info.radius_cui);
+ hostapd_free_psk_list(e->info.psk);
os_free(e);
}
@@ -73,25 +68,8 @@ static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache)
}
-static void copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
- struct hostapd_sta_wpa_psk_short *src)
-{
- if (!psk)
- return;
-
- if (src)
- src->ref++;
-
- *psk = src;
-}
-
-
static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
- u32 *session_timeout,
- u32 *acct_interim_interval,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui)
+ struct radius_sta *out)
{
struct hostapd_cached_radius_acl *entry;
struct os_reltime now;
@@ -105,27 +83,8 @@ static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
if (os_reltime_expired(&now, &entry->timestamp,
RADIUS_ACL_TIMEOUT))
return -1; /* entry has expired */
- if (entry->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT)
- if (session_timeout)
- *session_timeout = entry->session_timeout;
- if (acct_interim_interval)
- *acct_interim_interval =
- entry->acct_interim_interval;
- if (vlan_id)
- *vlan_id = entry->vlan_id;
- copy_psk_list(psk, entry->psk);
- if (identity) {
- if (entry->identity)
- *identity = os_strdup(entry->identity);
- else
- *identity = NULL;
- }
- if (radius_cui) {
- if (entry->radius_cui)
- *radius_cui = os_strdup(entry->radius_cui);
- else
- *radius_cui = NULL;
- }
+ *out = entry->info;
+
return entry->accepted;
}
@@ -238,42 +197,28 @@ int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr,
* @addr: MAC address of the STA
* @msg: Authentication message
* @len: Length of msg in octets
- * @session_timeout: Buffer for returning session timeout (from RADIUS)
- * @acct_interim_interval: Buffer for returning account interval (from RADIUS)
- * @vlan_id: Buffer for returning VLAN ID
- * @psk: Linked list buffer for returning WPA PSK
- * @identity: Buffer for returning identity (from RADIUS)
- * @radius_cui: Buffer for returning CUI (from RADIUS)
+ * @out.session_timeout: Buffer for returning session timeout (from RADIUS)
+ * @out.acct_interim_interval: Buffer for returning account interval (from
+ * RADIUS)
+ * @out.vlan_id: Buffer for returning VLAN ID
+ * @out.psk: Linked list buffer for returning WPA PSK
+ * @out.identity: Buffer for returning identity (from RADIUS)
+ * @out.radius_cui: Buffer for returning CUI (from RADIUS)
* @is_probe_req: Whether this query for a Probe Request frame
* Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING
*
- * The caller is responsible for freeing the returned *identity and *radius_cui
- * values with os_free().
+ * The caller is responsible for properly cloning the returned out->identity and
+ * out->radius_cui and out->psk values.
*/
int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
- const u8 *msg, size_t len, u32 *session_timeout,
- u32 *acct_interim_interval,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui,
+ const u8 *msg, size_t len, struct radius_sta *out,
int is_probe_req)
{
int res;
- if (session_timeout)
- *session_timeout = 0;
- if (acct_interim_interval)
- *acct_interim_interval = 0;
- if (vlan_id)
- os_memset(vlan_id, 0, sizeof(*vlan_id));
- if (psk)
- *psk = NULL;
- if (identity)
- *identity = NULL;
- if (radius_cui)
- *radius_cui = NULL;
-
- res = hostapd_check_acl(hapd, addr, vlan_id);
+ os_memset(out, 0, sizeof(*out));
+
+ res = hostapd_check_acl(hapd, addr, &out->vlan_id);
if (res != HOSTAPD_ACL_PENDING)
return res;
@@ -290,12 +235,10 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
};
if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED)
- vlan_id = NULL;
+ os_memset(&out->vlan_id, 0, sizeof(out->vlan_id));
/* Check whether ACL cache has an entry for this station */
- res = hostapd_acl_cache_get(hapd, addr, session_timeout,
- acct_interim_interval, vlan_id, psk,
- identity, radius_cui);
+ res = hostapd_acl_cache_get(hapd, addr, out);
if (res == HOSTAPD_ACL_ACCEPT ||
res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
return res;
@@ -307,14 +250,6 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
if (os_memcmp(query->addr, addr, ETH_ALEN) == 0) {
/* pending query in RADIUS retransmit queue;
* do not generate a new one */
- if (identity) {
- os_free(*identity);
- *identity = NULL;
- }
- if (radius_cui) {
- os_free(*radius_cui);
- *radius_cui = NULL;
- }
return HOSTAPD_ACL_PENDING;
}
query = query->next;
@@ -488,8 +423,8 @@ static void decode_tunnel_passwords(struct hostapd_data *hapd,
passphraselen);
psk->is_passphrase = 1;
}
- psk->next = cache->psk;
- cache->psk = psk;
+ psk->next = cache->info.psk;
+ cache->info.psk = psk;
psk = NULL;
}
skip:
@@ -518,6 +453,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
struct hostapd_data *hapd = data;
struct hostapd_acl_query_data *query, *prev;
struct hostapd_cached_radius_acl *cache;
+ struct radius_sta *info;
struct radius_hdr *hdr = radius_msg_get_hdr(msg);
query = hapd->acl_queries;
@@ -555,65 +491,66 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
}
os_get_reltime(&cache->timestamp);
os_memcpy(cache->addr, query->addr, sizeof(cache->addr));
+ info = &cache->info;
if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
u8 *buf;
size_t len;
if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,
- &cache->session_timeout) == 0)
+ &info->session_timeout) == 0)
cache->accepted = HOSTAPD_ACL_ACCEPT_TIMEOUT;
else
cache->accepted = HOSTAPD_ACL_ACCEPT;
if (radius_msg_get_attr_int32(
msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
- &cache->acct_interim_interval) == 0 &&
- cache->acct_interim_interval < 60) {
+ &info->acct_interim_interval) == 0 &&
+ info->acct_interim_interval < 60) {
wpa_printf(MSG_DEBUG, "Ignored too small "
"Acct-Interim-Interval %d for STA " MACSTR,
- cache->acct_interim_interval,
+ info->acct_interim_interval,
MAC2STR(query->addr));
- cache->acct_interim_interval = 0;
+ info->acct_interim_interval = 0;
}
if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED)
- cache->vlan_id.notempty = !!radius_msg_get_vlanid(
- msg, &cache->vlan_id.untagged,
- MAX_NUM_TAGGED_VLAN, cache->vlan_id.tagged);
+ info->vlan_id.notempty = !!radius_msg_get_vlanid(
+ msg, &info->vlan_id.untagged,
+ MAX_NUM_TAGGED_VLAN, info->vlan_id.tagged);
decode_tunnel_passwords(hapd, shared_secret, shared_secret_len,
msg, req, cache);
if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME,
&buf, &len, NULL) == 0) {
- cache->identity = os_zalloc(len + 1);
- if (cache->identity)
- os_memcpy(cache->identity, buf, len);
+ info->identity = os_zalloc(len + 1);
+ if (info->identity)
+ os_memcpy(info->identity, buf, len);
}
if (radius_msg_get_attr_ptr(
msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
&buf, &len, NULL) == 0) {
- cache->radius_cui = os_zalloc(len + 1);
- if (cache->radius_cui)
- os_memcpy(cache->radius_cui, buf, len);
+ info->radius_cui = os_zalloc(len + 1);
+ if (info->radius_cui)
+ os_memcpy(info->radius_cui, buf, len);
}
if (hapd->conf->wpa_psk_radius == PSK_RADIUS_REQUIRED &&
- !cache->psk)
+ !info->psk)
cache->accepted = HOSTAPD_ACL_REJECT;
- if (cache->vlan_id.notempty &&
- !hostapd_vlan_valid(hapd->conf->vlan, &cache->vlan_id)) {
+ if (info->vlan_id.notempty &&
+ !hostapd_vlan_valid(hapd->conf->vlan, &info->vlan_id)) {
hostapd_logger(hapd, query->addr,
HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
"Invalid VLAN %d%s received from RADIUS server",
- cache->vlan_id.untagged,
- cache->vlan_id.tagged[0] ? "+" : "");
- os_memset(&cache->vlan_id, 0, sizeof(cache->vlan_id));
+ info->vlan_id.untagged,
+ info->vlan_id.tagged[0] ? "+" : "");
+ os_memset(&info->vlan_id, 0, sizeof(info->vlan_id));
}
if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_REQUIRED &&
- !cache->vlan_id.notempty)
+ !info->vlan_id.notempty)
cache->accepted = HOSTAPD_ACL_REJECT;
} else
cache->accepted = HOSTAPD_ACL_REJECT;
@@ -622,7 +559,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
#ifdef CONFIG_DRIVER_RADIUS_ACL
hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted,
- cache->session_timeout);
+ info->session_timeout);
#else /* CONFIG_DRIVER_RADIUS_ACL */
#ifdef NEED_AP_MLME
/* Re-send original authentication frame for 802.11 processing */
@@ -685,6 +622,19 @@ void hostapd_acl_deinit(struct hostapd_data *hapd)
}
+void hostapd_copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
+ struct hostapd_sta_wpa_psk_short *src)
+{
+ if (!psk)
+ return;
+
+ if (src)
+ src->ref++;
+
+ *psk = src;
+}
+
+
void hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk)
{
if (psk && psk->ref) {
diff --git a/src/ap/ieee802_11_auth.h b/src/ap/ieee802_11_auth.h
index 5aece51..9410f55 100644
--- a/src/ap/ieee802_11_auth.h
+++ b/src/ap/ieee802_11_auth.h
@@ -16,18 +16,25 @@ enum {
HOSTAPD_ACL_ACCEPT_TIMEOUT = 3
};
+struct radius_sta {
+ u32 session_timeout;
+ u32 acct_interim_interval;
+ struct vlan_description vlan_id;
+ struct hostapd_sta_wpa_psk_short *psk;
+ char *identity;
+ char *radius_cui;
+};
+
int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr,
struct vlan_description *vlan_id);
int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
- const u8 *msg, size_t len, u32 *session_timeout,
- u32 *acct_interim_interval,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui,
+ const u8 *msg, size_t len, struct radius_sta *out,
int is_probe_req);
int hostapd_acl_init(struct hostapd_data *hapd);
void hostapd_acl_deinit(struct hostapd_data *hapd);
void hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk);
void hostapd_acl_expire(struct hostapd_data *hapd);
+void hostapd_copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
+ struct hostapd_sta_wpa_psk_short *src);
#endif /* IEEE802_11_AUTH_H */
diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
index abd3940..3e22ce4 100644
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -206,17 +206,25 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid)
if (is_6ghz_op_class(hapd->iconf->op_class)) {
u8 seg0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf);
+ u8 seg1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf);
if (!seg0)
seg0 = hapd->iconf->channel;
params |= HE_OPERATION_6GHZ_OPER_INFO;
+
+ /* 6 GHz Operation Information field */
*pos++ = hapd->iconf->channel; /* Primary Channel */
- *pos++ = center_idx_to_bw_6ghz(seg0); /* Control: Channel Width
- */
- /* Channel Center Freq Seg0/Seg0 */
+
+ /* Control: Channel Width */
+ if (seg1)
+ *pos++ = 3;
+ else
+ *pos++ = center_idx_to_bw_6ghz(seg0);
+
+ /* Channel Center Freq Seg0/Seg1 */
*pos++ = seg0;
- *pos++ = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf);
+ *pos++ = seg1;
/* Minimum Rate */
*pos++ = 6; /* TODO: what should be set here? */
}
diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c
index 0b828e9..ab81d08 100644
--- a/src/ap/ieee802_11_shared.c
+++ b/src/ap/ieee802_11_shared.c
@@ -112,7 +112,8 @@ void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
end += oci_ie_len;
}
#endif /* CONFIG_OCV */
- if (hostapd_drv_send_mlme(hapd, mgmt, end - (u8 *) mgmt, 0) < 0)
+ if (hostapd_drv_send_mlme(hapd, mgmt, end - (u8 *) mgmt, 0, NULL, 0, 0)
+ < 0)
wpa_printf(MSG_INFO, "ieee802_11_send_sa_query_req: send failed");
os_free(mgmt);
@@ -193,7 +194,8 @@ static void ieee802_11_send_sa_query_resp(struct hostapd_data *hapd,
end += oci_ie_len;
}
#endif /* CONFIG_OCV */
- if (hostapd_drv_send_mlme(hapd, resp, end - (u8 *) resp, 0) < 0)
+ if (hostapd_drv_send_mlme(hapd, resp, end - (u8 *) resp, 0, NULL, 0, 0)
+ < 0)
wpa_printf(MSG_INFO, "ieee80211_mgmt_sa_query_request: send failed");
os_free(resp);
@@ -1011,6 +1013,7 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
u8 *pos = eid;
if (!(hapd->conf->wpa & WPA_PROTO_RSN) ||
+ !wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) ||
(hapd->conf->sae_pwe != 1 && hapd->conf->sae_pwe != 2) ||
len < 3)
return pos;
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index d081031..001b261 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -284,8 +284,9 @@ static void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
/* TODO: set encryption in TX callback, i.e., only after STA
* has ACKed EAPOL-Key frame */
if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
- sta->addr, 0, 1, NULL, 0, ikey,
- hapd->conf->individual_wep_key_len)) {
+ sta->addr, 0, 0, 1, NULL, 0, ikey,
+ hapd->conf->individual_wep_key_len,
+ KEY_FLAG_PAIRWISE_RX_TX)) {
wpa_printf(MSG_ERROR,
"Could not set individual WEP encryption");
}
@@ -2177,9 +2178,10 @@ static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
* after new broadcast key has been sent to all stations. */
if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
broadcast_ether_addr,
- eapol->default_wep_key_idx, 1, NULL, 0,
+ eapol->default_wep_key_idx, 0, 1, NULL, 0,
eapol->default_wep_key,
- hapd->conf->default_wep_key_len)) {
+ hapd->conf->default_wep_key_len,
+ KEY_FLAG_GROUP_RX_TX_DEFAULT)) {
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_WARNING,
"failed to configure a new broadcast key");
@@ -2470,8 +2472,8 @@ int ieee802_1x_init(struct hostapd_data *hapd)
if (hapd->conf->default_wep_key_len) {
for (i = 0; i < 4; i++)
hostapd_drv_set_key(hapd->conf->iface, hapd,
- WPA_ALG_NONE, NULL, i, 0, NULL, 0,
- NULL, 0);
+ WPA_ALG_NONE, NULL, i, 0, 0, NULL,
+ 0, NULL, 0, KEY_FLAG_GROUP_RX_TX);
ieee802_1x_rekey(hapd, NULL);
diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
index 5415443..4012ae4 100644
--- a/src/ap/neighbor_db.c
+++ b/src/ap/neighbor_db.c
@@ -34,6 +34,60 @@ hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid,
}
+int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen)
+{
+ struct hostapd_neighbor_entry *nr;
+ char *pos, *end;
+
+ pos = buf;
+ end = buf + buflen;
+
+ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
+ list) {
+ int ret;
+ char nrie[2 * 255 + 1];
+ char lci[2 * 255 + 1];
+ char civic[2 * 255 + 1];
+ char ssid[SSID_MAX_LEN * 2 + 1];
+
+ ssid[0] = '\0';
+ wpa_snprintf_hex(ssid, sizeof(ssid), nr->ssid.ssid,
+ nr->ssid.ssid_len);
+
+ nrie[0] = '\0';
+ if (nr->nr)
+ wpa_snprintf_hex(nrie, sizeof(nrie),
+ wpabuf_head(nr->nr),
+ wpabuf_len(nr->nr));
+
+ lci[0] = '\0';
+ if (nr->lci)
+ wpa_snprintf_hex(lci, sizeof(lci),
+ wpabuf_head(nr->lci),
+ wpabuf_len(nr->lci));
+
+ civic[0] = '\0';
+ if (nr->civic)
+ wpa_snprintf_hex(civic, sizeof(civic),
+ wpabuf_head(nr->civic),
+ wpabuf_len(nr->civic));
+
+ ret = os_snprintf(pos, end - pos, MACSTR
+ " ssid=%s%s%s%s%s%s%s%s\n",
+ MAC2STR(nr->bssid), ssid,
+ nr->nr ? " nr=" : "", nrie,
+ nr->lci ? " lci=" : "", lci,
+ nr->civic ? " civic=" : "", civic,
+ nr->stationary ? " stat" : "");
+ if (os_snprintf_error(end - pos, ret))
+ break;
+ pos += ret;
+ }
+
+ return pos - buf;
+}
+
+
static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
{
wpabuf_free(nr->nr);
diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
index 9c8f4f2..bed0a2f 100644
--- a/src/ap/neighbor_db.h
+++ b/src/ap/neighbor_db.h
@@ -13,6 +13,7 @@
struct hostapd_neighbor_entry *
hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid,
const struct wpa_ssid_value *ssid);
+int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen);
int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
const struct wpa_ssid_value *ssid,
const struct wpabuf *nr, const struct wpabuf *lci,
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index cbb8752..c0503f6 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -373,6 +373,10 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
os_free(sta->ifname_wds);
+#ifdef CONFIG_TESTING_OPTIONS
+ os_free(sta->sae_postponed_commit);
+#endif /* CONFIG_TESTING_OPTIONS */
+
os_free(sta);
}
@@ -586,7 +590,8 @@ static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx)
wpa_printf(MSG_DEBUG, "%s: Session timer for STA " MACSTR,
hapd->conf->iface, MAC2STR(sta->addr));
- if (!(sta->flags & WLAN_STA_AUTH)) {
+ if (!(sta->flags & (WLAN_STA_AUTH | WLAN_STA_ASSOC |
+ WLAN_STA_AUTHORIZED))) {
if (sta->flags & WLAN_STA_GAS) {
wpa_printf(MSG_DEBUG, "GAS: Remove temporary STA "
"entry " MACSTR, MAC2STR(sta->addr));
@@ -1045,7 +1050,8 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta)
if (sta->vlan_id == old_vlanid)
goto skip_counting;
- if (sta->vlan_id > 0 && vlan == NULL) {
+ if (sta->vlan_id > 0 && !vlan &&
+ !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG, "could not find VLAN for "
"binding station to (vlan_id=%d)",
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index de806b4..8ff6ac6 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -276,6 +276,8 @@ struct sta_info {
int last_tk_key_idx;
u8 last_tk[WPA_TK_MAX_LEN];
size_t last_tk_len;
+ u8 *sae_postponed_commit;
+ size_t sae_postponed_commit_len;
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_AIRTIME_POLICY
unsigned int airtime_weight;
diff --git a/src/ap/wmm.c b/src/ap/wmm.c
index dc73493..881fd9f 100644
--- a/src/ap/wmm.c
+++ b/src/ap/wmm.c
@@ -209,7 +209,7 @@ static void wmm_send_action(struct hostapd_data *hapd, const u8 *addr,
os_memcpy(t, tspec, sizeof(struct wmm_tspec_element));
len = ((u8 *) (t + 1)) - buf;
- if (hostapd_drv_send_mlme(hapd, m, len, 0) < 0)
+ if (hostapd_drv_send_mlme(hapd, m, len, 0, NULL, 0, 0) < 0)
wpa_printf(MSG_INFO, "wmm_send_action: send failed");
}
@@ -291,10 +291,11 @@ int wmm_process_tspec(struct wmm_tspec_element *tspec)
static void wmm_addts_req(struct hostapd_data *hapd,
const struct ieee80211_mgmt *mgmt,
- struct wmm_tspec_element *tspec, size_t len)
+ const struct wmm_tspec_element *tspec, size_t len)
{
const u8 *end = ((const u8 *) mgmt) + len;
int res;
+ struct wmm_tspec_element tspec_resp;
if ((const u8 *) (tspec + 1) > end) {
wpa_printf(MSG_DEBUG, "WMM: TSPEC overflow in ADDTS Request");
@@ -306,10 +307,11 @@ static void wmm_addts_req(struct hostapd_data *hapd,
mgmt->u.action.u.wmm_action.dialog_token,
MAC2STR(mgmt->sa));
- res = wmm_process_tspec(tspec);
+ os_memcpy(&tspec_resp, tspec, sizeof(struct wmm_tspec_element));
+ res = wmm_process_tspec(&tspec_resp);
wpa_printf(MSG_DEBUG, "WMM: ADDTS processing result: %d", res);
- wmm_send_action(hapd, mgmt->sa, tspec, WMM_ACTION_CODE_ADDTS_RESP,
+ wmm_send_action(hapd, mgmt->sa, &tspec_resp, WMM_ACTION_CODE_ADDTS_RESP,
mgmt->u.action.u.wmm_action.dialog_token, res);
}
diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
index e4dcfe9..29ca950 100644
--- a/src/ap/wnm_ap.c
+++ b/src/ap/wnm_ap.c
@@ -641,7 +641,7 @@ int wnm_send_disassoc_imminent(struct hostapd_data *hapd,
wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to "
MACSTR, disassoc_timer, MAC2STR(sta->addr));
- if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) {
+ if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) {
wpa_printf(MSG_DEBUG, "Failed to send BSS Transition "
"Management Request frame");
return -1;
@@ -714,7 +714,7 @@ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
os_memcpy(pos, url, url_len);
pos += url_len;
- if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) {
+ if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) {
wpa_printf(MSG_DEBUG, "Failed to send BSS Transition "
"Management Request frame");
return -1;
@@ -790,7 +790,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
mbo_len);
}
- if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) {
+ if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) {
wpa_printf(MSG_DEBUG,
"Failed to send BSS Transition Management Request frame");
os_free(buf);
@@ -834,7 +834,7 @@ int wnm_send_coloc_intf_req(struct hostapd_data *hapd, struct sta_info *sta,
wpa_printf(MSG_DEBUG, "WNM: Sending Collocated Interference Request to "
MACSTR " (dialog_token=%u auto_report=%u timeout=%u)",
MAC2STR(sta->addr), dialog_token, auto_report, timeout);
- if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) {
+ if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) {
wpa_printf(MSG_DEBUG,
"WNM: Failed to send Collocated Interference Request frame");
return -1;
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 7b690d7..423528d 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -136,21 +136,46 @@ static inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth,
static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
int vlan_id,
enum wpa_alg alg, const u8 *addr, int idx,
- u8 *key, size_t key_len)
+ u8 *key, size_t key_len,
+ enum key_flag key_flag)
{
if (wpa_auth->cb->set_key == NULL)
return -1;
return wpa_auth->cb->set_key(wpa_auth->cb_ctx, vlan_id, alg, addr, idx,
- key, key_len);
+ key, key_len, key_flag);
}
static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
const u8 *addr, int idx, u8 *seq)
{
+ int res;
+
if (wpa_auth->cb->get_seqnum == NULL)
return -1;
- return wpa_auth->cb->get_seqnum(wpa_auth->cb_ctx, addr, idx, seq);
+ res = wpa_auth->cb->get_seqnum(wpa_auth->cb_ctx, addr, idx, seq);
+#ifdef CONFIG_TESTING_OPTIONS
+ if (!addr && idx < 4 && wpa_auth->conf.gtk_rsc_override_set) {
+ wpa_printf(MSG_DEBUG,
+ "TESTING: Override GTK RSC %016llx --> %016llx",
+ (long long unsigned) WPA_GET_LE64(seq),
+ (long long unsigned)
+ WPA_GET_LE64(wpa_auth->conf.gtk_rsc_override));
+ os_memcpy(seq, wpa_auth->conf.gtk_rsc_override,
+ WPA_KEY_RSC_LEN);
+ }
+ if (!addr && idx >= 4 && idx <= 5 &&
+ wpa_auth->conf.igtk_rsc_override_set) {
+ wpa_printf(MSG_DEBUG,
+ "TESTING: Override IGTK RSC %016llx --> %016llx",
+ (long long unsigned) WPA_GET_LE64(seq),
+ (long long unsigned)
+ WPA_GET_LE64(wpa_auth->conf.igtk_rsc_override));
+ os_memcpy(seq, wpa_auth->conf.igtk_rsc_override,
+ WPA_KEY_RSC_LEN);
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+ return res;
}
@@ -1714,7 +1739,7 @@ void wpa_remove_ptk(struct wpa_state_machine *sm)
sm->PTK_valid = FALSE;
os_memset(&sm->PTK, 0, sizeof(sm->PTK));
if (wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL,
- 0))
+ 0, KEY_FLAG_PAIRWISE))
wpa_printf(MSG_DEBUG,
"RSN: PTK removal from the driver failed");
sm->pairwise_set = FALSE;
@@ -2169,7 +2194,6 @@ SM_STATE(WPA_PTK, PTKSTART)
wpa_printf(MSG_DEBUG,
"FT: No PMKID in message 1/4 when using FT protocol");
pmkid = NULL;
- pmkid_len = 0;
#endif /* CONFIG_IEEE80211R_AP */
#ifdef CONFIG_SAE
} else if (wpa_key_mgmt_sae(sm->wpa_key_mgmt)) {
@@ -2199,6 +2223,8 @@ SM_STATE(WPA_PTK, PTKSTART)
&pmkid[2 + RSN_SELECTOR_LEN], PMKID_LEN);
}
}
+ if (!pmkid)
+ pmkid_len = 0;
wpa_send_eapol(sm->wpa_auth, sm,
WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE, NULL,
sm->ANonce, pmkid, pmkid_len, 0, 0);
@@ -2746,7 +2772,7 @@ int fils_set_tk(struct wpa_state_machine *sm)
wpa_printf(MSG_DEBUG, "FILS: Configure TK to the driver");
if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
- sm->PTK.tk, klen)) {
+ sm->PTK.tk, klen, KEY_FLAG_PAIRWISE_RX_TX)) {
wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver");
return -1;
}
@@ -3139,11 +3165,12 @@ static int ocv_oci_add(struct wpa_state_machine *sm, u8 **argpos)
SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
{
- u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos, dummy_gtk[32];
+ u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, dummy_gtk[32];
size_t gtk_len, kde_len;
struct wpa_group *gsm = sm->group;
u8 *wpa_ie;
int wpa_ie_len, secure, gtkidx, encr = 0;
+ u8 *wpa_ie_buf = NULL;
SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk);
sm->TimeoutEvt = FALSE;
@@ -3177,6 +3204,35 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
wpa_ie = wpa_ie + wpa_ie[1] + 2;
wpa_ie_len = wpa_ie[1] + 2;
}
+#ifdef CONFIG_TESTING_OPTIONS
+ if (sm->wpa_auth->conf.rsnxe_override_eapol_len) {
+ u8 *obuf = sm->wpa_auth->conf.rsnxe_override_eapol;
+ size_t olen = sm->wpa_auth->conf.rsnxe_override_eapol_len;
+ const u8 *rsnxe;
+
+ wpa_hexdump(MSG_DEBUG,
+ "TESTING: wpa_ie before RSNXE EAPOL override",
+ wpa_ie, wpa_ie_len);
+ wpa_ie_buf = os_malloc(wpa_ie_len + olen);
+ if (!wpa_ie_buf)
+ return;
+ os_memcpy(wpa_ie_buf, wpa_ie, wpa_ie_len);
+ wpa_ie = wpa_ie_buf;
+ rsnxe = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_RSNX);
+ if (rsnxe) {
+ u8 rsnxe_len = 2 + rsnxe[1];
+
+ os_memmove((void *) rsnxe, rsnxe + rsnxe_len,
+ wpa_ie_len - (rsnxe - wpa_ie) - rsnxe_len);
+ wpa_ie_len -= rsnxe_len;
+ }
+ os_memcpy(wpa_ie + wpa_ie_len, obuf, olen);
+ wpa_ie_len += olen;
+ wpa_hexdump(MSG_DEBUG,
+ "TESTING: wpa_ie after RSNXE EAPOL override",
+ wpa_ie, wpa_ie_len);
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
"sending 3/4 msg of 4-Way Handshake");
if (sm->wpa == WPA_VERSION_WPA2) {
@@ -3191,7 +3247,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
* of GTK in the BSS.
*/
if (random_get_bytes(dummy_gtk, gtk_len) < 0)
- return;
+ goto done;
gtk = dummy_gtk;
}
gtkidx = gsm->GN;
@@ -3234,7 +3290,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
#endif /* CONFIG_P2P */
kde = os_malloc(kde_len);
if (kde == NULL)
- return;
+ goto done;
pos = kde;
os_memcpy(pos, wpa_ie, wpa_ie_len);
@@ -3249,8 +3305,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
if (res < 0) {
wpa_printf(MSG_ERROR, "FT: Failed to insert "
"PMKR1Name into RSN IE in EAPOL-Key data");
- os_free(kde);
- return;
+ goto done;
}
pos -= wpa_ie_len;
pos += elen;
@@ -3264,10 +3319,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
gtk, gtk_len);
}
pos = ieee80211w_kde_add(sm, pos);
- if (ocv_oci_add(sm, &pos) < 0) {
- os_free(kde);
- return;
- }
+ if (ocv_oci_add(sm, &pos) < 0)
+ goto done;
#ifdef CONFIG_IEEE80211R_AP
if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
@@ -3293,8 +3346,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
if (res < 0) {
wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE "
"into EAPOL-Key Key Data");
- os_free(kde);
- return;
+ goto done;
}
pos += res;
@@ -3331,7 +3383,9 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL |
WPA_KEY_INFO_KEY_TYPE,
_rsc, sm->ANonce, kde, pos - kde, 0, encr);
+done:
os_free(kde);
+ os_free(wpa_ie_buf);
}
@@ -3343,7 +3397,8 @@ SM_STATE(WPA_PTK, PTKINITDONE)
enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise);
int klen = wpa_cipher_key_len(sm->pairwise);
if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
- sm->PTK.tk, klen)) {
+ sm->PTK.tk, klen,
+ KEY_FLAG_PAIRWISE_RX_TX)) {
wpa_sta_disconnect(sm->wpa_auth, sm->addr,
WLAN_REASON_PREV_AUTH_NOT_VALID);
return;
@@ -3935,7 +3990,8 @@ static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
if (wpa_auth_set_key(wpa_auth, group->vlan_id,
wpa_cipher_to_alg(wpa_auth->conf.wpa_group),
broadcast_ether_addr, group->GN,
- group->GTK[group->GN - 1], group->GTK_len) < 0)
+ group->GTK[group->GN - 1], group->GTK_len,
+ KEY_FLAG_GROUP_TX_DEFAULT) < 0)
ret = -1;
if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
@@ -3948,7 +4004,8 @@ static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
if (ret == 0 &&
wpa_auth_set_key(wpa_auth, group->vlan_id, alg,
broadcast_ether_addr, group->GN_igtk,
- group->IGTK[group->GN_igtk - 4], len) < 0)
+ group->IGTK[group->GN_igtk - 4], len,
+ KEY_FLAG_GROUP_TX_DEFAULT) < 0)
ret = -1;
}
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index f627838..0b4b729 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -219,6 +219,12 @@ struct wpa_auth_config {
double corrupt_gtk_rekey_mic_probability;
u8 own_ie_override[MAX_OWN_IE_OVERRIDE];
size_t own_ie_override_len;
+ u8 rsnxe_override_eapol[MAX_OWN_IE_OVERRIDE];
+ size_t rsnxe_override_eapol_len;
+ u8 gtk_rsc_override[WPA_KEY_RSC_LEN];
+ u8 igtk_rsc_override[WPA_KEY_RSC_LEN];
+ unsigned int gtk_rsc_override_set:1;
+ unsigned int igtk_rsc_override_set:1;
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_P2P
u8 ip_addr_go[4];
@@ -257,7 +263,8 @@ struct wpa_auth_callbacks {
int *vlan_id);
int (*get_msk)(void *ctx, const u8 *addr, u8 *msk, size_t *len);
int (*set_key)(void *ctx, int vlan_id, enum wpa_alg alg,
- const u8 *addr, int idx, u8 *key, size_t key_len);
+ const u8 *addr, int idx, u8 *key, size_t key_len,
+ enum key_flag key_flag);
int (*get_seqnum)(void *ctx, const u8 *addr, int idx, u8 *seq);
int (*send_eapol)(void *ctx, const u8 *addr, const u8 *data,
size_t data_len, int encrypt);
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index a599be2..4628761 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -951,8 +951,9 @@ wpa_ft_rrb_seq_req(struct wpa_authenticator *wpa_auth,
goto err;
}
- wpa_printf(MSG_DEBUG, "FT: Send out sequence number request to " MACSTR,
- MAC2STR(src_addr));
+ wpa_printf(MSG_DEBUG, "FT: Send sequence number request from " MACSTR
+ " to " MACSTR,
+ MAC2STR(wpa_auth->addr), MAC2STR(src_addr));
item = os_zalloc(sizeof(*item));
if (!item)
goto err;
@@ -1997,9 +1998,6 @@ static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm,
key = r0kh->key;
key_len = sizeof(r0kh->key);
- wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull request to remote R0KH "
- "address " MACSTR, MAC2STR(r0kh->addr));
-
if (r0kh->seq->rx.num_last == 0) {
/* A sequence request will be sent out anyway when pull
* response is received. Send it out now to avoid one RTT. */
@@ -2008,6 +2006,10 @@ static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm,
key_len, NULL, 0, NULL, 0, NULL);
}
+ wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull request from " MACSTR
+ " to remote R0KH address " MACSTR,
+ MAC2STR(sm->wpa_auth->addr), MAC2STR(r0kh->addr));
+
if (first &&
random_get_bytes(sm->ft_pending_pull_nonce, FT_RRB_NONCE_LEN) < 0) {
wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
@@ -2620,12 +2622,13 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
int vlan_id,
enum wpa_alg alg, const u8 *addr, int idx,
- u8 *key, size_t key_len)
+ u8 *key, size_t key_len,
+ enum key_flag key_flag)
{
if (wpa_auth->cb->set_key == NULL)
return -1;
return wpa_auth->cb->set_key(wpa_auth->cb_ctx, vlan_id, alg, addr, idx,
- key, key_len);
+ key, key_len, key_flag);
}
@@ -2658,7 +2661,7 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm)
* optimized by adding the STA entry earlier.
*/
if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
- sm->PTK.tk, klen))
+ sm->PTK.tk, klen, KEY_FLAG_PAIRWISE_RX_TX))
return;
/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
@@ -3687,6 +3690,10 @@ static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
goto out;
}
+ wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull response from " MACSTR
+ " to " MACSTR,
+ MAC2STR(wpa_auth->addr), MAC2STR(src_addr));
+
resp[0].type = FT_RRB_S1KH_ID;
resp[0].len = f_s1kh_id_len;
resp[0].data = f_s1kh_id;
@@ -4193,6 +4200,10 @@ static int wpa_ft_rrb_rx_seq_req(struct wpa_authenticator *wpa_auth,
goto out;
}
+ wpa_printf(MSG_DEBUG, "FT: Send sequence number response from " MACSTR
+ " to " MACSTR,
+ MAC2STR(wpa_auth->addr), MAC2STR(src_addr));
+
seq_resp_auth[0].type = FT_RRB_NONCE;
seq_resp_auth[0].len = f_nonce_len;
seq_resp_auth[0].data = f_nonce;
@@ -4452,9 +4463,11 @@ void wpa_ft_rrb_oui_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
size_t alen, elen;
int no_defer = 0;
- wpa_printf(MSG_DEBUG, "FT: RRB-OUI received frame from remote AP "
- MACSTR, MAC2STR(src_addr));
- wpa_printf(MSG_DEBUG, "FT: RRB-OUI frame - oui_suffix=%d", oui_suffix);
+ wpa_printf(MSG_DEBUG, "FT: RRB-OUI(" MACSTR
+ ") received frame from remote AP "
+ MACSTR " oui_suffix=%u dst=" MACSTR,
+ MAC2STR(wpa_auth->addr), MAC2STR(src_addr), oui_suffix,
+ MAC2STR(dst_addr));
wpa_hexdump(MSG_MSGDUMP, "FT: RRB frame payload", data, data_len);
if (is_multicast_ether_addr(src_addr)) {
@@ -4464,13 +4477,8 @@ void wpa_ft_rrb_oui_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
return;
}
- if (is_multicast_ether_addr(dst_addr)) {
- wpa_printf(MSG_DEBUG,
- "FT: RRB-OUI received frame from remote AP " MACSTR
- " to multicast address " MACSTR,
- MAC2STR(src_addr), MAC2STR(dst_addr));
+ if (is_multicast_ether_addr(dst_addr))
no_defer = 1;
- }
if (data_len < sizeof(u16)) {
wpa_printf(MSG_DEBUG, "FT: RRB-OUI frame too short");
@@ -4545,6 +4553,10 @@ static int wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
return -1;
}
+ wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 push from " MACSTR
+ " to remote R0KH address " MACSTR,
+ MAC2STR(wpa_auth->addr), MAC2STR(r1kh->addr));
+
if (wpa_ft_rrb_build_r0(r1kh->key, sizeof(r1kh->key), push, pmk_r0,
r1kh->id, s1kh_id, push_auth, wpa_auth->addr,
FT_PACKET_R0KH_R1KH_PUSH,
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index ddab950..e643046 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -118,6 +118,30 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
wpabuf_head(conf->own_ie_override),
wconf->own_ie_override_len);
}
+ if (conf->rsnxe_override_eapol &&
+ wpabuf_len(conf->rsnxe_override_eapol) <= MAX_OWN_IE_OVERRIDE) {
+ wconf->rsnxe_override_eapol_len =
+ wpabuf_len(conf->rsnxe_override_eapol);
+ os_memcpy(wconf->rsnxe_override_eapol,
+ wpabuf_head(conf->rsnxe_override_eapol),
+ wconf->rsnxe_override_eapol_len);
+ }
+ if (conf->gtk_rsc_override &&
+ wpabuf_len(conf->gtk_rsc_override) > 0 &&
+ wpabuf_len(conf->gtk_rsc_override) <= WPA_KEY_RSC_LEN) {
+ os_memcpy(wconf->gtk_rsc_override,
+ wpabuf_head(conf->gtk_rsc_override),
+ wpabuf_len(conf->gtk_rsc_override));
+ wconf->gtk_rsc_override_set = 1;
+ }
+ if (conf->igtk_rsc_override &&
+ wpabuf_len(conf->igtk_rsc_override) > 0 &&
+ wpabuf_len(conf->igtk_rsc_override) <= WPA_KEY_RSC_LEN) {
+ os_memcpy(wconf->igtk_rsc_override,
+ wpabuf_head(conf->igtk_rsc_override),
+ wpabuf_len(conf->igtk_rsc_override));
+ wconf->igtk_rsc_override_set = 1;
+ }
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_P2P
os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4);
@@ -354,15 +378,19 @@ static int hostapd_wpa_auth_get_msk(void *ctx, const u8 *addr, u8 *msk,
static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
const u8 *addr, int idx, u8 *key,
- size_t key_len)
+ size_t key_len, enum key_flag key_flag)
{
struct hostapd_data *hapd = ctx;
const char *ifname = hapd->conf->iface;
if (vlan_id > 0) {
ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id);
- if (ifname == NULL)
- return -1;
+ if (!ifname) {
+ if (!(hapd->iface->drv_flags &
+ WPA_DRIVER_FLAGS_VLAN_OFFLOAD))
+ return -1;
+ ifname = hapd->conf->iface;
+ }
}
#ifdef CONFIG_TESTING_OPTIONS
@@ -394,8 +422,8 @@ static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
hapd->last_gtk_len = key_len;
}
#endif /* CONFIG_TESTING_OPTIONS */
- return hostapd_drv_set_key(ifname, hapd, alg, addr, idx, 1, NULL, 0,
- key, key_len);
+ return hostapd_drv_set_key(ifname, hapd, alg, addr, idx, vlan_id, 1,
+ NULL, 0, key, key_len, key_flag);
}
@@ -615,10 +643,6 @@ static int hostapd_wpa_auth_send_ether(void *ctx, const u8 *dst, u16 proto,
}
#endif /* CONFIG_IEEE80211R_AP */
- if (hapd->driver && hapd->driver->send_ether)
- return hapd->driver->send_ether(hapd->drv_priv, dst,
- hapd->own_addr, proto,
- data, data_len);
if (hapd->l2 == NULL)
return -1;
@@ -680,6 +704,12 @@ static void hostapd_oui_deliver_later(void *eloop_ctx, void *timeout_ctx)
dl_list_for_each_safe(data, n, &hapd->l2_oui_queue,
struct oui_deliver_later_data, list) {
oui_ctx = hostapd_wpa_get_oui(hapd, data->oui_suffix);
+ wpa_printf(MSG_DEBUG, "RRB(%s): %s src=" MACSTR " dst=" MACSTR
+ " oui_suffix=%u data_len=%u data=%p",
+ hapd->conf->iface, __func__,
+ MAC2STR(data->src_addr), MAC2STR(data->dst_addr),
+ data->oui_suffix, (unsigned int) data->data_len,
+ data);
if (hapd->wpa_auth && oui_ctx) {
eth_p_oui_deliver(oui_ctx, data->src_addr,
data->dst_addr,
@@ -704,16 +734,26 @@ static int hostapd_wpa_auth_oui_iter(struct hostapd_iface *iface, void *ctx)
{
struct wpa_auth_oui_iface_iter_data *idata = ctx;
struct oui_deliver_later_data *data;
- struct hostapd_data *hapd;
+ struct hostapd_data *hapd, *src_hapd = idata->src_hapd;
size_t j;
for (j = 0; j < iface->num_bss; j++) {
hapd = iface->bss[j];
- if (hapd == idata->src_hapd)
- continue;
+ if (hapd == src_hapd)
+ continue; /* don't deliver back to same interface */
+ if (!wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) ||
+ hapd->conf->ssid.ssid_len !=
+ src_hapd->conf->ssid.ssid_len ||
+ os_memcmp(hapd->conf->ssid.ssid,
+ src_hapd->conf->ssid.ssid,
+ hapd->conf->ssid.ssid_len) != 0 ||
+ os_memcmp(hapd->conf->mobility_domain,
+ src_hapd->conf->mobility_domain,
+ MOBILITY_DOMAIN_ID_LEN) != 0)
+ continue; /* no matching FT SSID/mobility domain */
if (!is_multicast_ether_addr(idata->dst_addr) &&
os_memcmp(hapd->own_addr, idata->dst_addr, ETH_ALEN) != 0)
- continue;
+ continue; /* destination address does not match */
/* defer eth_p_oui_deliver until next eloop step as this is
* when it would be triggerd from reading from sock
@@ -725,14 +765,20 @@ static int hostapd_wpa_auth_oui_iter(struct hostapd_iface *iface, void *ctx)
data = os_zalloc(sizeof(*data) + idata->data_len);
if (!data)
return 1;
+ wpa_printf(MSG_DEBUG,
+ "RRB(%s): local delivery to %s dst=" MACSTR
+ " oui_suffix=%u data_len=%u data=%p",
+ src_hapd->conf->iface, hapd->conf->iface,
+ MAC2STR(idata->dst_addr), idata->oui_suffix,
+ (unsigned int) idata->data_len, data);
- os_memcpy(data->src_addr, idata->src_hapd->own_addr, ETH_ALEN);
+ os_memcpy(data->src_addr, src_hapd->own_addr, ETH_ALEN);
os_memcpy(data->dst_addr, idata->dst_addr, ETH_ALEN);
os_memcpy(data + 1, idata->data, idata->data_len);
data->data_len = idata->data_len;
data->oui_suffix = idata->oui_suffix;
- dl_list_add(&hapd->l2_oui_queue, &data->list);
+ dl_list_add_tail(&hapd->l2_oui_queue, &data->list);
if (!eloop_is_timeout_registered(hostapd_oui_deliver_later,
hapd, NULL))
@@ -740,7 +786,11 @@ static int hostapd_wpa_auth_oui_iter(struct hostapd_iface *iface, void *ctx)
hostapd_oui_deliver_later,
hapd, NULL);
- return 1;
+ /* If dst_addr is a multicast address, do not return any
+ * non-zero value here. Otherwise, the iteration of
+ * for_each_interface() will be stopped. */
+ if (!is_multicast_ether_addr(idata->dst_addr))
+ return 1;
}
return 0;
@@ -756,6 +806,10 @@ static int hostapd_wpa_auth_send_oui(void *ctx, const u8 *dst, u8 oui_suffix,
struct hostapd_data *hapd = ctx;
struct eth_p_oui_ctx *oui_ctx;
+ wpa_printf(MSG_DEBUG, "RRB(%s): send to dst=" MACSTR
+ " oui_suffix=%u data_len=%u",
+ hapd->conf->iface, MAC2STR(dst), oui_suffix,
+ (unsigned int) data_len);
#ifdef CONFIG_IEEE80211R_AP
if (hapd->iface->interfaces &&
hapd->iface->interfaces->for_each_interface) {
@@ -799,26 +853,32 @@ static int hostapd_wpa_auth_update_vlan(void *ctx, const u8 *addr, int vlan_id)
#ifndef CONFIG_NO_VLAN
struct hostapd_data *hapd = ctx;
struct sta_info *sta;
- struct vlan_description vlan_desc;
sta = ap_get_sta(hapd, addr);
if (!sta)
return -1;
- os_memset(&vlan_desc, 0, sizeof(vlan_desc));
- vlan_desc.notempty = 1;
- vlan_desc.untagged = vlan_id;
- if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) {
- wpa_printf(MSG_INFO, "Invalid VLAN ID %d in wpa_psk_file",
- vlan_id);
- return -1;
- }
+ if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
+ struct vlan_description vlan_desc;
- if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0) {
- wpa_printf(MSG_INFO,
- "Failed to assign VLAN ID %d from wpa_psk_file to "
- MACSTR, vlan_id, MAC2STR(sta->addr));
- return -1;
+ os_memset(&vlan_desc, 0, sizeof(vlan_desc));
+ vlan_desc.notempty = 1;
+ vlan_desc.untagged = vlan_id;
+ if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) {
+ wpa_printf(MSG_INFO,
+ "Invalid VLAN ID %d in wpa_psk_file",
+ vlan_id);
+ return -1;
+ }
+
+ if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0) {
+ wpa_printf(MSG_INFO,
+ "Failed to assign VLAN ID %d from wpa_psk_file to "
+ MACSTR, vlan_id, MAC2STR(sta->addr));
+ return -1;
+ }
+ } else {
+ sta->vlan_id = vlan_id;
}
wpa_printf(MSG_INFO,
@@ -880,7 +940,7 @@ static int hostapd_wpa_auth_send_ft_action(void *ctx, const u8 *dst,
os_memcpy(m->bssid, hapd->own_addr, ETH_ALEN);
os_memcpy(&m->u, data, data_len);
- res = hostapd_drv_send_mlme(hapd, (u8 *) m, mlen, 0);
+ res = hostapd_drv_send_mlme(hapd, (u8 *) m, mlen, 0, NULL, 0, 0);
os_free(m);
return res;
}
@@ -1344,9 +1404,7 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
hapd->conf->iface;
hapd->l2 = l2_packet_init(ft_iface, NULL, ETH_P_RRB,
hostapd_rrb_receive, hapd, 1);
- if (hapd->l2 == NULL &&
- (hapd->driver == NULL ||
- hapd->driver->send_ether == NULL)) {
+ if (!hapd->l2) {
wpa_printf(MSG_ERROR, "Failed to open l2_packet "
"interface");
return -1;
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index 33caeaf..3ea2228 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -985,6 +985,21 @@ static int hostapd_wps_set_vendor_ext(struct hostapd_data *hapd,
}
+static int hostapd_wps_set_application_ext(struct hostapd_data *hapd,
+ struct wps_context *wps)
+{
+ wpabuf_free(wps->dev.application_ext);
+
+ if (!hapd->conf->wps_application_ext) {
+ wps->dev.application_ext = NULL;
+ return 0;
+ }
+
+ wps->dev.application_ext = wpabuf_dup(hapd->conf->wps_application_ext);
+ return wps->dev.application_ext ? 0 : -1;
+}
+
+
static void hostapd_free_wps(struct wps_context *wps)
{
int i;
@@ -1074,7 +1089,8 @@ int hostapd_init_wps(struct hostapd_data *hapd,
os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type,
WPS_DEV_TYPE_LEN);
- if (hostapd_wps_set_vendor_ext(hapd, wps) < 0)
+ if (hostapd_wps_set_vendor_ext(hapd, wps) < 0 ||
+ hostapd_wps_set_application_ext(hapd, wps) < 0)
goto fail;
wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
@@ -1311,6 +1327,7 @@ void hostapd_update_wps(struct hostapd_data *hapd)
#endif /* CONFIG_WPS_UPNP */
hostapd_wps_set_vendor_ext(hapd, hapd->wps);
+ hostapd_wps_set_application_ext(hapd, hapd->wps);
if (hapd->conf->wps_state)
wps_registrar_update_ie(hapd->wps->registrar);
@@ -1417,6 +1434,7 @@ static int wps_cancel(struct hostapd_data *hapd, void *ctx)
data->count++;
wps_registrar_wps_cancel(hapd->wps->registrar);
ap_for_each_sta(hapd, ap_sta_wps_cancel, NULL);
+ wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_CANCEL);
}
return 0;
diff --git a/src/common/common_module_tests.c b/src/common/common_module_tests.c
index fb0cf43..7694c96 100644
--- a/src/common/common_module_tests.c
+++ b/src/common/common_module_tests.c
@@ -341,71 +341,71 @@ static int sae_tests(void)
struct wpabuf *buf = NULL;
struct crypto_bignum *mask = NULL;
const u8 pwe_19_x[32] = {
- 0x19, 0xd3, 0x37, 0xc9, 0x30, 0x79, 0x2b, 0x47,
- 0x2b, 0x14, 0x5f, 0xc1, 0x5b, 0x98, 0x64, 0x0a,
- 0x0e, 0x7d, 0x3b, 0xb0, 0x7d, 0xc0, 0xad, 0xee,
- 0x6f, 0xc9, 0xdf, 0x75, 0xde, 0xc2, 0xd6, 0x94
+ 0xc9, 0x30, 0x49, 0xb9, 0xe6, 0x40, 0x00, 0xf8,
+ 0x48, 0x20, 0x16, 0x49, 0xe9, 0x99, 0xf2, 0xb5,
+ 0xc2, 0x2d, 0xea, 0x69, 0xb5, 0x63, 0x2c, 0x9d,
+ 0xf4, 0xd6, 0x33, 0xb8, 0xaa, 0x1f, 0x6c, 0x1e
};
const u8 pwe_19_y[32] = {
- 0xb7, 0x8a, 0x02, 0x39, 0x20, 0x29, 0xe7, 0xf4,
- 0x52, 0x41, 0x3d, 0x35, 0x8c, 0x88, 0xd9, 0x16,
- 0xc8, 0x90, 0xba, 0x40, 0xd9, 0x93, 0xe3, 0x2d,
- 0xd0, 0x0f, 0xfb, 0x58, 0xee, 0x62, 0x74, 0x98
+ 0x73, 0x63, 0x4e, 0x94, 0xb5, 0x3d, 0x82, 0xe7,
+ 0x38, 0x3a, 0x8d, 0x25, 0x81, 0x99, 0xd9, 0xdc,
+ 0x1a, 0x5e, 0xe8, 0x26, 0x9d, 0x06, 0x03, 0x82,
+ 0xcc, 0xbf, 0x33, 0xe6, 0x14, 0xff, 0x59, 0xa0
};
const u8 pwe_15[384] = {
- 0x59, 0x00, 0x9a, 0x32, 0xbb, 0x37, 0x84, 0x60,
- 0x27, 0xeb, 0x70, 0x20, 0x57, 0x34, 0xf1, 0xb4,
- 0xde, 0x1b, 0x48, 0xfc, 0x0e, 0xa5, 0xb8, 0x65,
- 0xb1, 0xa0, 0xd4, 0xb9, 0x42, 0x1d, 0x6d, 0xdf,
- 0x8b, 0x86, 0xeb, 0x4a, 0x2c, 0x2e, 0x38, 0x06,
- 0x52, 0xae, 0x67, 0x39, 0xed, 0x7d, 0x0c, 0xd0,
- 0xea, 0x30, 0x6e, 0x50, 0xe7, 0xb1, 0x8d, 0x91,
- 0xf0, 0x05, 0x1f, 0x16, 0xf5, 0x45, 0xa7, 0x37,
- 0x21, 0x0d, 0x8a, 0x69, 0x9a, 0xd1, 0xf1, 0x8c,
- 0x2b, 0xbb, 0xd8, 0x21, 0xa2, 0x8f, 0xcc, 0xd1,
- 0x35, 0x98, 0x66, 0xf3, 0x3c, 0x03, 0xba, 0x70,
- 0x72, 0x4e, 0xe4, 0x23, 0xb5, 0x2e, 0x96, 0x5f,
- 0xdd, 0xd1, 0xae, 0x71, 0xb1, 0xc1, 0x4b, 0x69,
- 0x4e, 0x60, 0x0a, 0x08, 0x02, 0xa1, 0x6e, 0x80,
- 0x68, 0x0a, 0xe7, 0x97, 0x9f, 0x5b, 0xbf, 0xa8,
- 0x77, 0xda, 0x5b, 0x26, 0x13, 0x0a, 0xab, 0x92,
- 0x79, 0x87, 0xa3, 0x85, 0x78, 0x74, 0xae, 0xae,
- 0x01, 0xf0, 0x31, 0x8a, 0xc3, 0x96, 0xce, 0xaa,
- 0x57, 0xbf, 0xb3, 0x57, 0xce, 0x2d, 0x2d, 0x36,
- 0xda, 0x02, 0x5b, 0x12, 0xeb, 0xff, 0x13, 0x00,
- 0x9e, 0xf7, 0xae, 0xe0, 0x47, 0xa4, 0x5d, 0x0a,
- 0x88, 0x65, 0xbc, 0x66, 0x23, 0x3e, 0xf2, 0xf1,
- 0xa0, 0x64, 0x5c, 0x6b, 0xdc, 0x81, 0xe9, 0x3c,
- 0x46, 0x4f, 0x83, 0xcf, 0x9f, 0x55, 0x33, 0x8f,
- 0xaa, 0x60, 0x4b, 0xd7, 0x21, 0x73, 0x6b, 0xdb,
- 0x26, 0xad, 0x2f, 0xb7, 0xe2, 0x42, 0x56, 0x33,
- 0xdb, 0xd6, 0xb2, 0x3a, 0x7d, 0x75, 0x87, 0xda,
- 0x86, 0xc4, 0xe9, 0x41, 0x8d, 0x63, 0x19, 0x8e,
- 0x8b, 0x17, 0x95, 0xfe, 0x2b, 0x96, 0xa0, 0x38,
- 0xf1, 0xe2, 0x1d, 0x42, 0xa9, 0xe3, 0x8a, 0xa1,
- 0x61, 0x62, 0x10, 0xf8, 0xb3, 0xb2, 0x2c, 0x7b,
- 0xdf, 0xba, 0x74, 0xb2, 0x5b, 0xf6, 0xa9, 0xae,
- 0x1d, 0x21, 0x0d, 0xc0, 0x48, 0x20, 0xfc, 0x28,
- 0xf6, 0x22, 0xd2, 0xf6, 0x9c, 0x71, 0x3f, 0x9f,
- 0x32, 0xd6, 0xbb, 0x9b, 0xd3, 0x87, 0x25, 0xcf,
- 0x62, 0xd1, 0x68, 0xba, 0x55, 0x3b, 0x74, 0x2b,
- 0x1d, 0x5a, 0xe4, 0x94, 0x59, 0x3b, 0x13, 0x21,
- 0x15, 0x87, 0x3b, 0x09, 0x0e, 0xcf, 0x35, 0x60,
- 0x04, 0xa8, 0xde, 0xa1, 0x09, 0xca, 0xb8, 0x35,
- 0x1e, 0x16, 0x61, 0xed, 0xa1, 0x1f, 0x8c, 0x92,
- 0x83, 0xa5, 0x27, 0x92, 0xf2, 0x80, 0xc3, 0xcb,
- 0xdd, 0x3c, 0x0c, 0xf5, 0x8d, 0x69, 0xb3, 0xe4,
- 0xd5, 0x49, 0x4d, 0x62, 0xcb, 0xb8, 0xe3, 0x9f,
- 0x89, 0xb5, 0x57, 0xff, 0xef, 0x12, 0x37, 0x05,
- 0xb6, 0x35, 0xe5, 0xc6, 0xd9, 0x23, 0xe2, 0xeb,
- 0xe4, 0x0d, 0x1a, 0x30, 0x8f, 0x73, 0x70, 0x3a,
- 0xef, 0x5a, 0xd1, 0x8c, 0x18, 0x34, 0x1e, 0xf0,
- 0xb9, 0x08, 0x57, 0xab, 0xcb, 0x5c, 0x87, 0x10
+ 0x69, 0x68, 0x73, 0x65, 0x8f, 0x65, 0x31, 0x42,
+ 0x9f, 0x97, 0x39, 0x6f, 0xb8, 0x5f, 0x89, 0xe1,
+ 0xfc, 0xd2, 0xf6, 0x92, 0x19, 0xa9, 0x0e, 0x82,
+ 0x2f, 0xf7, 0xf4, 0xbc, 0x0b, 0xd8, 0xa7, 0x9f,
+ 0xf0, 0x80, 0x35, 0x31, 0x6f, 0xca, 0xe1, 0xa5,
+ 0x39, 0x77, 0xdc, 0x11, 0x2b, 0x0b, 0xfe, 0x2e,
+ 0x6f, 0x65, 0x6d, 0xc7, 0xd4, 0xa4, 0x5b, 0x08,
+ 0x1f, 0xd9, 0xbb, 0xe2, 0x22, 0x85, 0x31, 0x81,
+ 0x79, 0x70, 0xbe, 0xa1, 0x66, 0x58, 0x4a, 0x09,
+ 0x3c, 0x57, 0x34, 0x3c, 0x9d, 0x57, 0x8f, 0x42,
+ 0x58, 0xd0, 0x39, 0x81, 0xdb, 0x8f, 0x79, 0xa2,
+ 0x1b, 0x01, 0xcd, 0x27, 0xc9, 0xae, 0xcf, 0xcb,
+ 0x9c, 0xdb, 0x1f, 0x84, 0xb8, 0x88, 0x4e, 0x8f,
+ 0x50, 0x66, 0xb4, 0x29, 0x83, 0x1e, 0xb9, 0x89,
+ 0x0c, 0xa5, 0x47, 0x21, 0xba, 0x10, 0xd5, 0xaa,
+ 0x1a, 0x80, 0xce, 0xf1, 0x4c, 0xad, 0x16, 0xda,
+ 0x57, 0xb2, 0x41, 0x8a, 0xbe, 0x4b, 0x8c, 0xb0,
+ 0xb2, 0xeb, 0xf7, 0xa8, 0x0e, 0x3e, 0xcf, 0x22,
+ 0x8f, 0xd8, 0xb6, 0xdb, 0x79, 0x9c, 0x9b, 0x80,
+ 0xaf, 0xd7, 0x14, 0xad, 0x51, 0x82, 0xf4, 0x64,
+ 0xb6, 0x3f, 0x4c, 0x6c, 0xe5, 0x3f, 0xaa, 0x6f,
+ 0xbf, 0x3d, 0xc2, 0x3f, 0x77, 0xfd, 0xcb, 0xe1,
+ 0x9c, 0xe3, 0x1e, 0x8a, 0x0e, 0x97, 0xe2, 0x2b,
+ 0xe2, 0xdd, 0x37, 0x39, 0x88, 0xc2, 0x8e, 0xbe,
+ 0xfa, 0xac, 0x3d, 0x5b, 0x62, 0x2e, 0x1e, 0x74,
+ 0xa0, 0x9a, 0xf8, 0xed, 0xfa, 0xe1, 0xce, 0x9c,
+ 0xab, 0xbb, 0xdc, 0x36, 0xb1, 0x28, 0x46, 0x3c,
+ 0x7e, 0xa8, 0xbd, 0xb9, 0x36, 0x4c, 0x26, 0x75,
+ 0xe0, 0x17, 0x73, 0x1f, 0xe0, 0xfe, 0xf6, 0x49,
+ 0xfa, 0xa0, 0x45, 0xf4, 0x44, 0x05, 0x20, 0x27,
+ 0x25, 0xc2, 0x99, 0xde, 0x27, 0x8b, 0x70, 0xdc,
+ 0x54, 0x60, 0x90, 0x02, 0x1e, 0x29, 0x97, 0x9a,
+ 0xc4, 0xe7, 0xb6, 0xf5, 0x8b, 0xae, 0x7c, 0x34,
+ 0xaa, 0xef, 0x9b, 0xc6, 0x30, 0xf2, 0x80, 0x8d,
+ 0x80, 0x78, 0xc2, 0x55, 0x63, 0xa0, 0xa1, 0x38,
+ 0x70, 0xfb, 0xf4, 0x74, 0x8d, 0xcd, 0x87, 0x90,
+ 0xb4, 0x54, 0xc3, 0x75, 0xdf, 0x10, 0xc5, 0xb6,
+ 0xb2, 0x08, 0x59, 0x61, 0xe6, 0x68, 0xa5, 0x82,
+ 0xf8, 0x8f, 0x47, 0x30, 0x43, 0xb4, 0xdc, 0x31,
+ 0xfc, 0xbc, 0x69, 0xe7, 0xb4, 0x94, 0xb0, 0x6a,
+ 0x60, 0x59, 0x80, 0x2e, 0xd3, 0xa4, 0xe8, 0x97,
+ 0xa2, 0xa3, 0xc9, 0x08, 0x4b, 0x27, 0x6c, 0xc1,
+ 0x37, 0xe8, 0xfc, 0x5c, 0xe2, 0x54, 0x30, 0x3e,
+ 0xf8, 0xfe, 0xa2, 0xfc, 0xbb, 0xbd, 0x88, 0x6c,
+ 0x92, 0xa3, 0x2a, 0x40, 0x7a, 0x2c, 0x22, 0x38,
+ 0x8c, 0x86, 0x86, 0xfe, 0xb9, 0xd4, 0x6b, 0xd6,
+ 0x47, 0x88, 0xa7, 0xf6, 0x8e, 0x0f, 0x14, 0xad,
+ 0x1e, 0xac, 0xcf, 0x33, 0x01, 0x99, 0xc1, 0x62
};
int pt_groups[] = { 19, 20, 21, 25, 26, 28, 29, 30, 15, 0 };
struct sae_pt *pt_info, *pt;
- u8 addr1b[ETH_ALEN] = { 0x3b, 0x36, 0xc2, 0x8b, 0x83, 0x03 };
- u8 addr2b[ETH_ALEN] = { 0x58, 0x36, 0xc0, 0x64, 0x2d, 0x31 };
+ const u8 addr1b[ETH_ALEN] = { 0x00, 0x09, 0x5b, 0x66, 0xec, 0x1e };
+ const u8 addr2b[ETH_ALEN] = { 0x00, 0x0b, 0x6b, 0xd9, 0x02, 0x46 };
os_memset(&sae, 0, sizeof(sae));
buf = wpabuf_alloc(1000);
diff --git a/src/common/defs.h b/src/common/defs.h
index 4faf1c8..5e22278 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -416,7 +416,33 @@ enum chan_width {
CHAN_WIDTH_80,
CHAN_WIDTH_80P80,
CHAN_WIDTH_160,
+ CHAN_WIDTH_2160,
+ CHAN_WIDTH_4320,
+ CHAN_WIDTH_6480,
+ CHAN_WIDTH_8640,
CHAN_WIDTH_UNKNOWN
};
+enum key_flag {
+ KEY_FLAG_MODIFY = BIT(0),
+ KEY_FLAG_DEFAULT = BIT(1),
+ KEY_FLAG_RX = BIT(2),
+ KEY_FLAG_TX = BIT(3),
+ KEY_FLAG_GROUP = BIT(4),
+ KEY_FLAG_PAIRWISE = BIT(5),
+ KEY_FLAG_PMK = BIT(6),
+ /* Used flag combinations */
+ KEY_FLAG_RX_TX = KEY_FLAG_RX | KEY_FLAG_TX,
+ KEY_FLAG_GROUP_RX_TX = KEY_FLAG_GROUP | KEY_FLAG_RX_TX,
+ KEY_FLAG_GROUP_RX_TX_DEFAULT = KEY_FLAG_GROUP_RX_TX |
+ KEY_FLAG_DEFAULT,
+ KEY_FLAG_GROUP_RX = KEY_FLAG_GROUP | KEY_FLAG_RX,
+ KEY_FLAG_GROUP_TX_DEFAULT = KEY_FLAG_GROUP | KEY_FLAG_TX |
+ KEY_FLAG_DEFAULT,
+ KEY_FLAG_PAIRWISE_RX_TX = KEY_FLAG_PAIRWISE | KEY_FLAG_RX_TX,
+ KEY_FLAG_PAIRWISE_RX = KEY_FLAG_PAIRWISE | KEY_FLAG_RX,
+ KEY_FLAG_PAIRWISE_RX_TX_MODIFY = KEY_FLAG_PAIRWISE_RX_TX |
+ KEY_FLAG_MODIFY,
+};
+
#endif /* DEFS_H */
diff --git a/src/common/dhcp.h b/src/common/dhcp.h
index e38512c..7dc67d5 100644
--- a/src/common/dhcp.h
+++ b/src/common/dhcp.h
@@ -39,7 +39,7 @@ struct dhcp_data {
} STRUCT_PACKED;
struct bootp_pkt {
- struct iphdr iph;
+ struct ip iph;
struct udphdr udph;
u8 op;
u8 htype;
diff --git a/src/common/dpp.c b/src/common/dpp.c
index ab7072c..8c873fd 100644
--- a/src/common/dpp.c
+++ b/src/common/dpp.c
@@ -33,6 +33,8 @@
#include "dpp.h"
+static const char * dpp_netrole_str(enum dpp_netrole netrole);
+
#ifdef CONFIG_TESTING_OPTIONS
enum dpp_test_behavior dpp_test = DPP_TEST_DISABLED;
u8 dpp_pkex_own_mac_override[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
@@ -830,6 +832,8 @@ const char * dpp_bootstrap_type_txt(enum dpp_bootstrap_type type)
return "QRCODE";
case DPP_BOOTSTRAP_PKEX:
return "PKEX";
+ case DPP_BOOTSTRAP_NFC_URI:
+ return "NFC-URI";
}
return "??";
}
@@ -1007,8 +1011,7 @@ static int dpp_parse_uri_pk(struct dpp_bootstrap_info *bi, const char *info)
if (!end)
return -1;
- data = base64_decode((const unsigned char *) info, end - info,
- &data_len);
+ data = base64_decode(info, end - info, &data_len);
if (!data) {
wpa_printf(MSG_DEBUG,
"DPP: Invalid base64 encoding on URI public-key");
@@ -1182,17 +1185,6 @@ static struct dpp_bootstrap_info * dpp_parse_uri(const char *uri)
}
-struct dpp_bootstrap_info * dpp_parse_qr_code(const char *uri)
-{
- struct dpp_bootstrap_info *bi;
-
- bi = dpp_parse_uri(uri);
- if (bi)
- bi->type = DPP_BOOTSTRAP_QR_CODE;
- return bi;
-}
-
-
static void dpp_debug_print_key(const char *title, EVP_PKEY *key)
{
EC_KEY *eckey;
@@ -1482,7 +1474,7 @@ int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi)
char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
const u8 *privkey, size_t privkey_len)
{
- unsigned char *base64 = NULL;
+ char *base64 = NULL;
char *pos, *end;
size_t len;
struct wpabuf *der = NULL;
@@ -1528,7 +1520,7 @@ char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
der = NULL;
if (!base64)
goto fail;
- pos = (char *) base64;
+ pos = base64;
end = pos + len;
for (;;) {
pos = os_strchr(pos, '\n');
@@ -1536,7 +1528,7 @@ char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
break;
os_memmove(pos, pos + 1, end - pos);
}
- return (char *) base64;
+ return base64;
fail:
os_free(base64);
wpabuf_free(der);
@@ -2541,13 +2533,13 @@ struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth,
struct wpabuf * dpp_build_conf_req_helper(struct dpp_authentication *auth,
- const char *name, int netrole_ap,
+ const char *name,
+ enum dpp_netrole netrole,
const char *mud_url, int *opclasses)
{
- size_t len, nlen;
+ size_t len, name_len;
const char *tech = "infra";
const char *dpp_name;
- char *nbuf;
struct wpabuf *buf, *json;
#ifdef CONFIG_TESTING_OPTIONS
@@ -2560,39 +2552,38 @@ struct wpabuf * dpp_build_conf_req_helper(struct dpp_authentication *auth,
#endif /* CONFIG_TESTING_OPTIONS */
dpp_name = name ? name : "Test";
- len = os_strlen(dpp_name);
- nlen = len * 6 + 1;
- nbuf = os_malloc(nlen);
- if (!nbuf)
- return NULL;
- json_escape_string(nbuf, nlen, dpp_name, len);
+ name_len = os_strlen(dpp_name);
- len = 100 + os_strlen(nbuf) + int_array_len(opclasses) * 4;
+ len = 100 + name_len * 6 + 1 + int_array_len(opclasses) * 4;
if (mud_url && mud_url[0])
len += 10 + os_strlen(mud_url);
json = wpabuf_alloc(len);
- if (!json) {
- os_free(nbuf);
+ if (!json)
return NULL;
- }
- wpabuf_printf(json,
- "{\"name\":\"%s\","
- "\"wi-fi_tech\":\"%s\","
- "\"netRole\":\"%s\"",
- nbuf, tech, netrole_ap ? "ap" : "sta");
- if (mud_url && mud_url[0])
- wpabuf_printf(json, ",\"mudurl\":\"%s\"", mud_url);
+ json_start_object(json, NULL);
+ if (json_add_string_escape(json, "name", dpp_name, name_len) < 0) {
+ wpabuf_free(json);
+ return NULL;
+ }
+ json_value_sep(json);
+ json_add_string(json, "wi-fi_tech", tech);
+ json_value_sep(json);
+ json_add_string(json, "netRole", dpp_netrole_str(netrole));
+ if (mud_url && mud_url[0]) {
+ json_value_sep(json);
+ json_add_string(json, "mudurl", mud_url);
+ }
if (opclasses) {
int i;
- wpabuf_put_str(json, ",\"bandSupport\":[");
+ json_value_sep(json);
+ json_start_array(json, "bandSupport");
for (i = 0; opclasses[i]; i++)
wpabuf_printf(json, "%s%u", i ? "," : "", opclasses[i]);
- wpabuf_put_str(json, "]");
+ json_end_array(json);
}
- wpabuf_put_str(json, "}");
- os_free(nbuf);
+ json_end_object(json);
buf = dpp_build_conf_req(auth, wpabuf_head(json));
wpabuf_free(json);
@@ -4435,6 +4426,16 @@ static int dpp_configuration_parse_helper(struct dpp_authentication *auth,
#endif /* CONFIG_TESTING_OPTIONS */
}
+ pos = os_strstr(cmd, " ssid_charset=");
+ if (pos) {
+ if (conf_ap) {
+ wpa_printf(MSG_INFO,
+ "DPP: ssid64 option (ssid_charset param) not allowed for AP enrollee");
+ goto fail;
+ }
+ conf->ssid_charset = atoi(pos + 14);
+ }
+
pos = os_strstr(cmd, " pass=");
if (pos) {
size_t pass_len;
@@ -4637,7 +4638,6 @@ dpp_build_conf_start(struct dpp_authentication *auth,
struct dpp_configuration *conf, size_t tailroom)
{
struct wpabuf *buf;
- char ssid[6 * sizeof(conf->ssid) + 1];
#ifdef CONFIG_TESTING_OPTIONS
if (auth->discovery_override)
@@ -4647,21 +4647,35 @@ dpp_build_conf_start(struct dpp_authentication *auth,
buf = wpabuf_alloc(200 + tailroom);
if (!buf)
return NULL;
- wpabuf_put_str(buf, "{\"wi-fi_tech\":\"infra\",\"discovery\":");
+ json_start_object(buf, NULL);
+ json_add_string(buf, "wi-fi_tech", "infra");
+ json_value_sep(buf);
#ifdef CONFIG_TESTING_OPTIONS
if (auth->discovery_override) {
wpa_printf(MSG_DEBUG, "DPP: TESTING - discovery override: '%s'",
auth->discovery_override);
+ wpabuf_put_str(buf, "\"discovery\":");
wpabuf_put_str(buf, auth->discovery_override);
- wpabuf_put_u8(buf, ',');
+ json_value_sep(buf);
return buf;
}
#endif /* CONFIG_TESTING_OPTIONS */
- wpabuf_put_str(buf, "{\"ssid\":\"");
- json_escape_string(ssid, sizeof(ssid),
- (const char *) conf->ssid, conf->ssid_len);
- wpabuf_put_str(buf, ssid);
- wpabuf_put_str(buf, "\"},");
+ json_start_object(buf, "discovery");
+ if (((!conf->ssid_charset || auth->peer_version < 2) &&
+ json_add_string_escape(buf, "ssid", conf->ssid,
+ conf->ssid_len) < 0) ||
+ ((conf->ssid_charset && auth->peer_version >= 2) &&
+ json_add_base64url(buf, "ssid64", conf->ssid,
+ conf->ssid_len) < 0)) {
+ wpabuf_free(buf);
+ return NULL;
+ }
+ if (conf->ssid_charset > 0) {
+ json_value_sep(buf);
+ json_add_int(buf, "ssid_charset", conf->ssid_charset);
+ }
+ json_end_object(buf);
+ json_value_sep(buf);
return buf;
}
@@ -4672,37 +4686,32 @@ static int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
{
struct wpabuf *pub;
const u8 *pos;
- char *x = NULL, *y = NULL;
int ret = -1;
pub = dpp_get_pubkey_point(key, 0);
if (!pub)
goto fail;
+
+ json_start_object(buf, name);
+ json_add_string(buf, "kty", "EC");
+ json_value_sep(buf);
+ json_add_string(buf, "crv", curve->jwk_crv);
+ json_value_sep(buf);
pos = wpabuf_head(pub);
- x = (char *) base64_url_encode(pos, curve->prime_len, NULL, 0);
+ if (json_add_base64url(buf, "x", pos, curve->prime_len) < 0)
+ goto fail;
+ json_value_sep(buf);
pos += curve->prime_len;
- y = (char *) base64_url_encode(pos, curve->prime_len, NULL, 0);
- if (!x || !y)
+ if (json_add_base64url(buf, "y", pos, curve->prime_len) < 0)
goto fail;
-
- wpabuf_put_str(buf, "\"");
- wpabuf_put_str(buf, name);
- wpabuf_put_str(buf, "\":{\"kty\":\"EC\",\"crv\":\"");
- wpabuf_put_str(buf, curve->jwk_crv);
- wpabuf_put_str(buf, "\",\"x\":\"");
- wpabuf_put_str(buf, x);
- wpabuf_put_str(buf, "\",\"y\":\"");
- wpabuf_put_str(buf, y);
if (kid) {
- wpabuf_put_str(buf, "\",\"kid\":\"");
- wpabuf_put_str(buf, kid);
+ json_value_sep(buf);
+ json_add_string(buf, "kid", kid);
}
- wpabuf_put_str(buf, "\"}");
+ json_end_object(buf);
ret = 0;
fail:
wpabuf_free(pub);
- os_free(x);
- os_free(y);
return ret;
}
@@ -4711,23 +4720,15 @@ static void dpp_build_legacy_cred_params(struct wpabuf *buf,
struct dpp_configuration *conf)
{
if (conf->passphrase && os_strlen(conf->passphrase) < 64) {
- char pass[63 * 6 + 1];
-
- json_escape_string(pass, sizeof(pass), conf->passphrase,
- os_strlen(conf->passphrase));
- wpabuf_put_str(buf, "\"pass\":\"");
- wpabuf_put_str(buf, pass);
- wpabuf_put_str(buf, "\"");
- os_memset(pass, 0, sizeof(pass));
+ json_add_string_escape(buf, "pass", conf->passphrase,
+ os_strlen(conf->passphrase));
} else if (conf->psk_set) {
char psk[2 * sizeof(conf->psk) + 1];
wpa_snprintf_hex(psk, sizeof(psk),
conf->psk, sizeof(conf->psk));
- wpabuf_put_str(buf, "\"psk_hex\":\"");
- wpabuf_put_str(buf, psk);
- wpabuf_put_str(buf, "\"");
- os_memset(psk, 0, sizeof(psk));
+ json_add_string(buf, "psk_hex", psk);
+ forced_memzero(psk, sizeof(psk));
}
}
@@ -4739,6 +4740,8 @@ static const char * dpp_netrole_str(enum dpp_netrole netrole)
return "sta";
case DPP_NETROLE_AP:
return "ap";
+ case DPP_NETROLE_CONFIGURATOR:
+ return "configurator";
default:
return "??";
}
@@ -4753,7 +4756,7 @@ dpp_build_conf_obj_dpp(struct dpp_authentication *auth,
char *signed1 = NULL, *signed2 = NULL, *signed3 = NULL;
size_t tailroom;
const struct dpp_curve_params *curve;
- char jws_prot_hdr[100];
+ struct wpabuf *jws_prot_hdr;
size_t signed1_len, signed2_len, signed3_len;
struct wpabuf *dppcon = NULL;
unsigned char *signature = NULL;
@@ -4814,15 +4817,21 @@ dpp_build_conf_obj_dpp(struct dpp_authentication *auth,
auth->groups_override);
wpabuf_put_str(dppcon, "\"groups\":");
wpabuf_put_str(dppcon, auth->groups_override);
- wpabuf_put_u8(dppcon, ',');
+ json_value_sep(dppcon);
}
goto skip_groups;
}
#endif /* CONFIG_TESTING_OPTIONS */
- wpabuf_printf(dppcon, "{\"groups\":[{\"groupId\":\"%s\",",
- conf->group_id ? conf->group_id : "*");
- wpabuf_printf(dppcon, "\"netRole\":\"%s\"}],",
- dpp_netrole_str(conf->netrole));
+ json_start_object(dppcon, NULL);
+ json_start_array(dppcon, "groups");
+ json_start_object(dppcon, NULL);
+ json_add_string(dppcon, "groupId",
+ conf->group_id ? conf->group_id : "*");
+ json_value_sep(dppcon);
+ json_add_string(dppcon, "netRole", dpp_netrole_str(conf->netrole));
+ json_end_object(dppcon);
+ json_end_array(dppcon);
+ json_value_sep(dppcon);
#ifdef CONFIG_TESTING_OPTIONS
skip_groups:
#endif /* CONFIG_TESTING_OPTIONS */
@@ -4833,30 +4842,40 @@ skip_groups:
}
if (conf->netaccesskey_expiry) {
struct os_tm tm;
+ char expiry[30];
if (os_gmtime(conf->netaccesskey_expiry, &tm) < 0) {
wpa_printf(MSG_DEBUG,
"DPP: Failed to generate expiry string");
goto fail;
}
- wpabuf_printf(dppcon,
- ",\"expiry\":\"%04u-%02u-%02uT%02u:%02u:%02uZ\"",
- tm.year, tm.month, tm.day,
- tm.hour, tm.min, tm.sec);
- }
- wpabuf_put_u8(dppcon, '}');
+ os_snprintf(expiry, sizeof(expiry),
+ "%04u-%02u-%02uT%02u:%02u:%02uZ",
+ tm.year, tm.month, tm.day,
+ tm.hour, tm.min, tm.sec);
+ json_value_sep(dppcon);
+ json_add_string(dppcon, "expiry", expiry);
+ }
+ json_end_object(dppcon);
wpa_printf(MSG_DEBUG, "DPP: dppCon: %s",
(const char *) wpabuf_head(dppcon));
- os_snprintf(jws_prot_hdr, sizeof(jws_prot_hdr),
- "{\"typ\":\"dppCon\",\"kid\":\"%s\",\"alg\":\"%s\"}",
- auth->conf->kid, curve->jws_alg);
- signed1 = (char *) base64_url_encode((unsigned char *) jws_prot_hdr,
- os_strlen(jws_prot_hdr),
- &signed1_len, 0);
- signed2 = (char *) base64_url_encode(wpabuf_head(dppcon),
- wpabuf_len(dppcon),
- &signed2_len, 0);
+ jws_prot_hdr = wpabuf_alloc(100);
+ if (!jws_prot_hdr)
+ goto fail;
+ json_start_object(jws_prot_hdr, NULL);
+ json_add_string(jws_prot_hdr, "typ", "dppCon");
+ json_value_sep(jws_prot_hdr);
+ json_add_string(jws_prot_hdr, "kid", auth->conf->kid);
+ json_value_sep(jws_prot_hdr);
+ json_add_string(jws_prot_hdr, "alg", curve->jws_alg);
+ json_end_object(jws_prot_hdr);
+ signed1 = base64_url_encode(wpabuf_head(jws_prot_hdr),
+ wpabuf_len(jws_prot_hdr),
+ &signed1_len);
+ wpabuf_free(jws_prot_hdr);
+ signed2 = base64_url_encode(wpabuf_head(dppcon), wpabuf_len(dppcon),
+ &signed2_len);
if (!signed1 || !signed2)
goto fail;
@@ -4906,8 +4925,7 @@ skip_groups:
signature_len = 2 * curve->prime_len;
wpa_hexdump(MSG_DEBUG, "DPP: signedConnector ECDSA signature (raw r,s)",
signature, signature_len);
- signed3 = (char *) base64_url_encode(signature, signature_len,
- &signed3_len, 0);
+ signed3 = base64_url_encode(signature, signature_len, &signed3_len);
if (!signed3)
goto fail;
@@ -4925,10 +4943,12 @@ skip_groups:
akm_str = dpp_akm_selector_str(akm);
else
akm_str = dpp_akm_str(akm);
- wpabuf_printf(buf, "\"cred\":{\"akm\":\"%s\",", akm_str);
+ json_start_object(buf, "cred");
+ json_add_string(buf, "akm", akm_str);
+ json_value_sep(buf);
if (incl_legacy) {
dpp_build_legacy_cred_params(buf, conf);
- wpabuf_put_str(buf, ",");
+ json_value_sep(buf);
}
wpabuf_put_str(buf, "\"signedConnector\":\"");
wpabuf_put_str(buf, signed1);
@@ -4936,14 +4956,16 @@ skip_groups:
wpabuf_put_str(buf, signed2);
wpabuf_put_u8(buf, '.');
wpabuf_put_str(buf, signed3);
- wpabuf_put_str(buf, "\",");
+ wpabuf_put_str(buf, "\"");
+ json_value_sep(buf);
if (dpp_build_jwk(buf, "csign", auth->conf->csign, auth->conf->kid,
curve) < 0) {
wpa_printf(MSG_DEBUG, "DPP: Failed to build csign JWK");
goto fail;
}
- wpabuf_put_str(buf, "}}");
+ json_end_object(buf);
+ json_end_object(buf);
wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Configuration Object",
wpabuf_head(buf), wpabuf_len(buf));
@@ -4980,9 +5002,12 @@ dpp_build_conf_obj_legacy(struct dpp_authentication *auth,
akm_str = dpp_akm_selector_str(conf->akm);
else
akm_str = dpp_akm_str(conf->akm);
- wpabuf_printf(buf, "\"cred\":{\"akm\":\"%s\",", akm_str);
+ json_start_object(buf, "cred");
+ json_add_string(buf, "akm", akm_str);
+ json_value_sep(buf);
dpp_build_legacy_cred_params(buf, conf);
- wpabuf_put_str(buf, "}}");
+ json_end_object(buf);
+ json_end_object(buf);
wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Configuration Object (legacy)",
wpabuf_head(buf), wpabuf_len(buf));
@@ -4992,9 +5017,10 @@ dpp_build_conf_obj_legacy(struct dpp_authentication *auth,
static struct wpabuf *
-dpp_build_conf_obj(struct dpp_authentication *auth, int ap, int idx)
+dpp_build_conf_obj(struct dpp_authentication *auth, enum dpp_netrole netrole,
+ int idx)
{
- struct dpp_configuration *conf;
+ struct dpp_configuration *conf = NULL;
#ifdef CONFIG_TESTING_OPTIONS
if (auth->config_obj_override) {
@@ -5006,17 +5032,22 @@ dpp_build_conf_obj(struct dpp_authentication *auth, int ap, int idx)
}
#endif /* CONFIG_TESTING_OPTIONS */
- if (idx == 0)
- conf = ap ? auth->conf_ap : auth->conf_sta;
- else if (idx == 1)
- conf = ap ? auth->conf2_ap : auth->conf2_sta;
- else
- conf = NULL;
+ if (idx == 0) {
+ if (netrole == DPP_NETROLE_STA)
+ conf = auth->conf_sta;
+ else if (netrole == DPP_NETROLE_AP)
+ conf = auth->conf_ap;
+ } else if (idx == 1) {
+ if (netrole == DPP_NETROLE_STA)
+ conf = auth->conf2_sta;
+ else if (netrole == DPP_NETROLE_AP)
+ conf = auth->conf2_ap;
+ }
if (!conf) {
if (idx == 0)
wpa_printf(MSG_DEBUG,
"DPP: No configuration available for Enrollee(%s) - reject configuration request",
- ap ? "ap" : "sta");
+ dpp_netrole_str(netrole));
return NULL;
}
@@ -5028,7 +5059,7 @@ dpp_build_conf_obj(struct dpp_authentication *auth, int ap, int idx)
static struct wpabuf *
dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
- u16 e_nonce_len, int ap)
+ u16 e_nonce_len, enum dpp_netrole netrole)
{
struct wpabuf *conf, *conf2 = NULL;
size_t clear_len, attr_len;
@@ -5038,11 +5069,11 @@ dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
size_t len[1];
enum dpp_status_error status;
- conf = dpp_build_conf_obj(auth, ap, 0);
+ conf = dpp_build_conf_obj(auth, netrole, 0);
if (conf) {
wpa_hexdump_ascii(MSG_DEBUG, "DPP: configurationObject JSON",
wpabuf_head(conf), wpabuf_len(conf));
- conf2 = dpp_build_conf_obj(auth, ap, 1);
+ conf2 = dpp_build_conf_obj(auth, netrole, 1);
}
status = conf ? DPP_STATUS_OK : DPP_STATUS_CONFIGURE_FAILURE;
auth->conf_resp_status = status;
@@ -5053,7 +5084,8 @@ dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
clear_len += 4 + wpabuf_len(conf);
if (conf2)
clear_len += 4 + wpabuf_len(conf2);
- if (auth->peer_version >= 2 && auth->send_conn_status && !ap)
+ if (auth->peer_version >= 2 && auth->send_conn_status &&
+ netrole == DPP_NETROLE_STA)
clear_len += 4;
clear = wpabuf_alloc(clear_len);
attr_len = 4 + 1 + 4 + clear_len + AES_BLOCK_SIZE;
@@ -5111,7 +5143,8 @@ skip_e_nonce:
"DPP: Second Config Object available, but peer does not support more than one");
}
- if (auth->peer_version >= 2 && auth->send_conn_status && !ap) {
+ if (auth->peer_version >= 2 && auth->send_conn_status &&
+ netrole == DPP_NETROLE_STA) {
wpa_printf(MSG_DEBUG, "DPP: sendConnStatus");
wpabuf_put_le16(clear, DPP_ATTR_SEND_CONN_STATUS);
wpabuf_put_le16(clear, 0);
@@ -5185,7 +5218,7 @@ dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
size_t unwrapped_len = 0;
struct wpabuf *resp = NULL;
struct json_token *root = NULL, *token;
- int ap;
+ enum dpp_netrole netrole;
#ifdef CONFIG_TESTING_OPTIONS
if (dpp_test == DPP_TEST_STOP_AT_CONF_REQ) {
@@ -5283,9 +5316,11 @@ dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
}
wpa_printf(MSG_DEBUG, "DPP: netRole = '%s'", token->string);
if (os_strcmp(token->string, "sta") == 0) {
- ap = 0;
+ netrole = DPP_NETROLE_STA;
} else if (os_strcmp(token->string, "ap") == 0) {
- ap = 1;
+ netrole = DPP_NETROLE_AP;
+ } else if (os_strcmp(token->string, "configurator") == 0) {
+ netrole = DPP_NETROLE_CONFIGURATOR;
} else {
wpa_printf(MSG_DEBUG, "DPP: Unsupported netRole '%s'",
token->string);
@@ -5313,7 +5348,7 @@ dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
}
}
- resp = dpp_build_conf_resp(auth, e_nonce, e_nonce_len, ap);
+ resp = dpp_build_conf_resp(auth, e_nonce, e_nonce_len, netrole);
fail:
json_free(root);
@@ -5819,8 +5854,7 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info,
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail;
}
- prot_hdr = base64_url_decode((const unsigned char *) pos,
- end - pos, &prot_hdr_len);
+ prot_hdr = base64_url_decode(pos, end - pos, &prot_hdr_len);
if (!prot_hdr) {
wpa_printf(MSG_DEBUG,
"DPP: Failed to base64url decode signedConnector JWS Protected Header");
@@ -5852,8 +5886,7 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info,
goto fail;
}
signed_end = end - 1;
- info->payload = base64_url_decode((const unsigned char *) pos,
- end - pos, &info->payload_len);
+ info->payload = base64_url_decode(pos, end - pos, &info->payload_len);
if (!info->payload) {
wpa_printf(MSG_DEBUG,
"DPP: Failed to base64url decode signedConnector JWS Payload");
@@ -5864,8 +5897,7 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info,
"DPP: signedConnector - JWS Payload",
info->payload, info->payload_len);
pos = end + 1;
- signature = base64_url_decode((const unsigned char *) pos,
- os_strlen(pos), &signature_len);
+ signature = base64_url_decode(pos, os_strlen(pos), &signature_len);
if (!signature) {
wpa_printf(MSG_DEBUG,
"DPP: Failed to base64url decode signedConnector signature");
@@ -6120,6 +6152,7 @@ static int dpp_parse_conf_obj(struct dpp_authentication *auth,
int ret = -1;
struct json_token *root, *token, *discovery, *cred;
struct dpp_config_obj *conf;
+ struct wpabuf *ssid64 = NULL;
root = json_parse((const char *) conf_obj, conf_obj_len);
if (!root)
@@ -6147,28 +6180,52 @@ static int dpp_parse_conf_obj(struct dpp_authentication *auth,
goto fail;
}
- token = json_get_member(discovery, "ssid");
- if (!token || token->type != JSON_STRING) {
- dpp_auth_fail(auth, "No discovery::ssid string value found");
- goto fail;
- }
- wpa_hexdump_ascii(MSG_DEBUG, "DPP: discovery::ssid",
- token->string, os_strlen(token->string));
- if (os_strlen(token->string) > SSID_MAX_LEN) {
- dpp_auth_fail(auth, "Too long discovery::ssid string value");
- goto fail;
+ ssid64 = json_get_member_base64url(discovery, "ssid64");
+ if (ssid64) {
+ wpa_hexdump_ascii(MSG_DEBUG, "DPP: discovery::ssid64",
+ wpabuf_head(ssid64), wpabuf_len(ssid64));
+ if (wpabuf_len(ssid64) > SSID_MAX_LEN) {
+ dpp_auth_fail(auth, "Too long discovery::ssid64 value");
+ goto fail;
+ }
+ } else {
+ token = json_get_member(discovery, "ssid");
+ if (!token || token->type != JSON_STRING) {
+ dpp_auth_fail(auth,
+ "No discovery::ssid string value found");
+ goto fail;
+ }
+ wpa_hexdump_ascii(MSG_DEBUG, "DPP: discovery::ssid",
+ token->string, os_strlen(token->string));
+ if (os_strlen(token->string) > SSID_MAX_LEN) {
+ dpp_auth_fail(auth,
+ "Too long discovery::ssid string value");
+ goto fail;
+ }
}
if (auth->num_conf_obj == DPP_MAX_CONF_OBJ) {
wpa_printf(MSG_DEBUG,
"DPP: No room for this many Config Objects - ignore this one");
- json_free(root);
- return 0;
+ ret = 0;
+ goto fail;
}
conf = &auth->conf_obj[auth->num_conf_obj++];
- conf->ssid_len = os_strlen(token->string);
- os_memcpy(conf->ssid, token->string, conf->ssid_len);
+ if (ssid64) {
+ conf->ssid_len = wpabuf_len(ssid64);
+ os_memcpy(conf->ssid, wpabuf_head(ssid64), conf->ssid_len);
+ } else {
+ conf->ssid_len = os_strlen(token->string);
+ os_memcpy(conf->ssid, token->string, conf->ssid_len);
+ }
+
+ token = json_get_member(discovery, "ssid_charset");
+ if (token && token->type == JSON_NUMBER) {
+ conf->ssid_charset = token->number;
+ wpa_printf(MSG_DEBUG, "DPP: ssid_charset=%d",
+ conf->ssid_charset);
+ }
cred = json_get_member(root, "cred");
if (!cred || cred->type != JSON_OBJECT) {
@@ -6199,6 +6256,7 @@ static int dpp_parse_conf_obj(struct dpp_authentication *auth,
wpa_printf(MSG_DEBUG, "DPP: JSON parsing completed successfully");
ret = 0;
fail:
+ wpabuf_free(ssid64);
json_free(root);
return ret;
}
@@ -6487,6 +6545,7 @@ enum dpp_status_error dpp_conn_status_result_rx(struct dpp_authentication *auth,
size_t unwrapped_len = 0;
enum dpp_status_error ret = 256;
struct json_token *root = NULL, *token;
+ struct wpabuf *ssid64;
*ssid_len = 0;
*channel_list = NULL;
@@ -6561,12 +6620,12 @@ enum dpp_status_error dpp_conn_status_result_rx(struct dpp_authentication *auth,
goto fail;
}
- token = json_get_member(root, "ssid");
- if (token && token->type == JSON_STRING &&
- os_strlen(token->string) <= SSID_MAX_LEN) {
- *ssid_len = os_strlen(token->string);
- os_memcpy(ssid, token->string, *ssid_len);
+ ssid64 = json_get_member_base64url(root, "ssid64");
+ if (ssid64 && wpabuf_len(ssid64) <= SSID_MAX_LEN) {
+ *ssid_len = wpabuf_len(ssid64);
+ os_memcpy(ssid, wpabuf_head(ssid64), *ssid_len);
}
+ wpabuf_free(ssid64);
token = json_get_member(root, "channelList");
if (token && token->type == JSON_STRING &&
@@ -6593,7 +6652,7 @@ struct wpabuf * dpp_build_conn_status_result(struct dpp_authentication *auth,
const u8 *ssid, size_t ssid_len,
const char *channel_list)
{
- struct wpabuf *msg, *clear, *json;
+ struct wpabuf *msg = NULL, *clear = NULL, *json;
size_t nonce_len, clear_len, attr_len;
const u8 *addr[2];
size_t len[2];
@@ -6602,19 +6661,18 @@ struct wpabuf * dpp_build_conn_status_result(struct dpp_authentication *auth,
json = wpabuf_alloc(1000);
if (!json)
return NULL;
- wpabuf_printf(json, "{\"result\":%d", result);
+ json_start_object(json, NULL);
+ json_add_int(json, "result", result);
if (ssid) {
- char ssid_str[6 * SSID_MAX_LEN + 1];
-
- wpabuf_put_str(json, ",\"ssid\":\"");
- json_escape_string(ssid_str, sizeof(ssid_str),
- (const char *) ssid, ssid_len);
- wpabuf_put_str(json, ssid_str);
- wpabuf_put_str(json, "\"");
+ json_value_sep(json);
+ if (json_add_base64url(json, "ssid64", ssid, ssid_len) < 0)
+ goto fail;
+ }
+ if (channel_list) {
+ json_value_sep(json);
+ json_add_string(json, "channelList", channel_list);
}
- if (channel_list)
- wpabuf_printf(json, ",\"channelList\":\"%s\"", channel_list);
- wpabuf_put_str(json, "}");
+ json_end_object(json);
wpa_hexdump_ascii(MSG_DEBUG, "DPP: connStatus JSON",
wpabuf_head(json), wpabuf_len(json));
@@ -6755,8 +6813,7 @@ dpp_keygen_configurator(const char *curve, const u8 *privkey,
goto fail;
}
- conf->kid = (char *) base64_url_encode(kid_hash, sizeof(kid_hash),
- NULL, 0);
+ conf->kid = base64_url_encode(kid_hash, sizeof(kid_hash), NULL);
if (!conf->kid)
goto fail;
out:
@@ -6802,8 +6859,11 @@ int dpp_configurator_own_config(struct dpp_authentication *auth,
dpp_copy_csign(&auth->conf_obj[0], auth->conf->csign);
conf_obj = dpp_build_conf_obj(auth, ap, 0);
- if (!conf_obj)
+ if (!conf_obj) {
+ wpabuf_free(auth->conf_obj[0].c_sign_key);
+ auth->conf_obj[0].c_sign_key = NULL;
goto fail;
+ }
ret = dpp_parse_conf_obj(auth, wpabuf_head(conf_obj),
wpabuf_len(conf_obj));
fail:
@@ -7018,8 +7078,7 @@ dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
wpa_printf(MSG_DEBUG, "DPP: Own connector is missing the second dot (.)");
goto fail;
}
- own_conn = base64_url_decode((const unsigned char *) pos,
- end - pos, &own_conn_len);
+ own_conn = base64_url_decode(pos, end - pos, &own_conn_len);
if (!own_conn) {
wpa_printf(MSG_DEBUG,
"DPP: Failed to base64url decode own signedConnector JWS Payload");
@@ -8753,8 +8812,7 @@ char * dpp_corrupt_connector_signature(const char *connector)
wpa_printf(MSG_DEBUG, "DPP: Original base64url encoded signature: %s",
pos);
- signature = base64_url_decode((const unsigned char *) pos,
- os_strlen(pos), &signature_len);
+ signature = base64_url_decode(pos, os_strlen(pos), &signature_len);
if (!signature || signature_len == 0)
goto fail;
wpa_hexdump(MSG_DEBUG, "DPP: Original Connector signature",
@@ -8762,8 +8820,7 @@ char * dpp_corrupt_connector_signature(const char *connector)
signature[signature_len - 1] ^= 0x01;
wpa_hexdump(MSG_DEBUG, "DPP: Corrupted Connector signature",
signature, signature_len);
- signed3 = (char *) base64_url_encode(signature, signature_len,
- &signed3_len, 0);
+ signed3 = base64_url_encode(signature, signature_len, &signed3_len);
if (!signed3)
goto fail;
os_memcpy(pos, signed3, signed3_len);
@@ -8911,10 +8968,30 @@ struct dpp_bootstrap_info * dpp_add_qr_code(struct dpp_global *dpp,
if (!dpp)
return NULL;
- bi = dpp_parse_qr_code(uri);
+ bi = dpp_parse_uri(uri);
+ if (!bi)
+ return NULL;
+
+ bi->type = DPP_BOOTSTRAP_QR_CODE;
+ bi->id = dpp_next_id(dpp);
+ dl_list_add(&dpp->bootstrap, &bi->list);
+ return bi;
+}
+
+
+struct dpp_bootstrap_info * dpp_add_nfc_uri(struct dpp_global *dpp,
+ const char *uri)
+{
+ struct dpp_bootstrap_info *bi;
+
+ if (!dpp)
+ return NULL;
+
+ bi = dpp_parse_uri(uri);
if (!bi)
return NULL;
+ bi->type = DPP_BOOTSTRAP_NFC_URI;
bi->id = dpp_next_id(dpp);
dl_list_add(&dpp->bootstrap, &bi->list);
return bi;
@@ -8942,6 +9019,8 @@ int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd)
bi->type = DPP_BOOTSTRAP_QR_CODE;
else if (os_strstr(cmd, "type=pkex"))
bi->type = DPP_BOOTSTRAP_PKEX;
+ else if (os_strstr(cmd, "type=nfc-uri"))
+ bi->type = DPP_BOOTSTRAP_NFC_URI;
else
goto fail;
diff --git a/src/common/dpp.h b/src/common/dpp.h
index 0be26d7..e2e90c8 100644
--- a/src/common/dpp.h
+++ b/src/common/dpp.h
@@ -106,6 +106,7 @@ struct dpp_curve_params {
enum dpp_bootstrap_type {
DPP_BOOTSTRAP_QR_CODE,
DPP_BOOTSTRAP_PKEX,
+ DPP_BOOTSTRAP_NFC_URI,
};
struct dpp_bootstrap_info {
@@ -164,11 +165,13 @@ enum dpp_akm {
enum dpp_netrole {
DPP_NETROLE_STA,
DPP_NETROLE_AP,
+ DPP_NETROLE_CONFIGURATOR,
};
struct dpp_configuration {
u8 ssid[32];
size_t ssid_len;
+ int ssid_charset;
enum dpp_akm akm;
enum dpp_netrole netrole;
@@ -247,6 +250,7 @@ struct dpp_authentication {
char *connector; /* received signedConnector */
u8 ssid[SSID_MAX_LEN];
u8 ssid_len;
+ int ssid_charset;
char passphrase[64];
u8 psk[PMK_LEN];
int psk_set;
@@ -412,7 +416,6 @@ int dpp_parse_uri_chan_list(struct dpp_bootstrap_info *bi,
const char *chan_list);
int dpp_parse_uri_mac(struct dpp_bootstrap_info *bi, const char *mac);
int dpp_parse_uri_info(struct dpp_bootstrap_info *bi, const char *info);
-struct dpp_bootstrap_info * dpp_parse_qr_code(const char *uri);
char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
const u8 *privkey, size_t privkey_len);
struct hostapd_hw_modes;
@@ -435,7 +438,8 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth,
const char *json);
struct wpabuf * dpp_build_conf_req_helper(struct dpp_authentication *auth,
- const char *name, int netrole_ap,
+ const char *name,
+ enum dpp_netrole netrole,
const char *mud_url, int *opclasses);
int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
const u8 *attr_start, size_t attr_len);
@@ -532,6 +536,8 @@ void dpp_pfs_free(struct dpp_pfs *pfs);
struct dpp_bootstrap_info * dpp_add_qr_code(struct dpp_global *dpp,
const char *uri);
+struct dpp_bootstrap_info * dpp_add_nfc_uri(struct dpp_global *dpp,
+ const char *uri);
int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd);
struct dpp_bootstrap_info *
dpp_bootstrap_get_id(struct dpp_global *dpp, unsigned int id);
diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c
index 1ad8d7c..19593a5 100644
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -40,23 +40,32 @@ struct hostapd_channel_data * hw_get_channel_chan(struct hostapd_hw_modes *mode,
}
-struct hostapd_channel_data * hw_get_channel_freq(struct hostapd_hw_modes *mode,
- int freq, int *chan)
+struct hostapd_channel_data *
+hw_get_channel_freq(enum hostapd_hw_mode mode, int freq, int *chan,
+ struct hostapd_hw_modes *hw_features, int num_hw_features)
{
- int i;
+ int i, j;
if (chan)
*chan = 0;
- if (!mode)
+ if (!hw_features)
return NULL;
- for (i = 0; i < mode->num_channels; i++) {
- struct hostapd_channel_data *ch = &mode->channels[i];
- if (ch->freq == freq) {
- if (chan)
- *chan = ch->chan;
- return ch;
+ for (j = 0; j < num_hw_features; j++) {
+ struct hostapd_hw_modes *curr_mode = &hw_features[j];
+
+ if (curr_mode->mode != mode)
+ continue;
+ for (i = 0; i < curr_mode->num_channels; i++) {
+ struct hostapd_channel_data *ch =
+ &curr_mode->channels[i];
+
+ if (ch->freq == freq) {
+ if (chan)
+ *chan = ch->chan;
+ return ch;
+ }
}
}
@@ -74,29 +83,33 @@ int hw_get_freq(struct hostapd_hw_modes *mode, int chan)
}
-int hw_get_chan(struct hostapd_hw_modes *mode, int freq)
+int hw_get_chan(enum hostapd_hw_mode mode, int freq,
+ struct hostapd_hw_modes *hw_features, int num_hw_features)
{
int chan;
- hw_get_channel_freq(mode, freq, &chan);
+ hw_get_channel_freq(mode, freq, &chan, hw_features, num_hw_features);
return chan;
}
-int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
- int sec_chan)
+int allowed_ht40_channel_pair(enum hostapd_hw_mode mode,
+ struct hostapd_channel_data *p_chan,
+ struct hostapd_channel_data *s_chan)
{
int ok, first;
int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140,
149, 157, 165, 184, 192 };
size_t k;
- struct hostapd_channel_data *p_chan, *s_chan;
- const int ht40_plus = pri_chan < sec_chan;
+ int ht40_plus, pri_chan, sec_chan;
- p_chan = hw_get_channel_chan(mode, pri_chan, NULL);
- if (!p_chan)
+ if (!p_chan || !s_chan)
return 0;
+ pri_chan = p_chan->chan;
+ sec_chan = s_chan->chan;
+
+ ht40_plus = pri_chan < sec_chan;
if (pri_chan == sec_chan || !sec_chan) {
if (chan_pri_allowed(p_chan))
@@ -107,13 +120,9 @@ int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
return 0;
}
- s_chan = hw_get_channel_chan(mode, sec_chan, NULL);
- if (!s_chan)
- return 0;
-
wpa_printf(MSG_DEBUG,
- "HT40: control channel: %d secondary channel: %d",
- pri_chan, sec_chan);
+ "HT40: control channel: %d (%d MHz), secondary channel: %d (%d MHz)",
+ pri_chan, p_chan->freq, sec_chan, s_chan->freq);
/* Verify that HT40 secondary channel is an allowed 20 MHz
* channel */
@@ -131,7 +140,7 @@ int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
* 2.4 GHz rules allow all cases where the secondary channel fits into
* the list of allowed channels (already checked above).
*/
- if (mode->mode != HOSTAPD_MODE_IEEE80211A)
+ if (mode != HOSTAPD_MODE_IEEE80211A)
return 1;
first = pri_chan < sec_chan ? pri_chan : sec_chan;
@@ -176,22 +185,19 @@ void get_pri_sec_chan(struct wpa_scan_res *bss, int *pri_chan, int *sec_chan)
}
-int check_40mhz_5g(struct hostapd_hw_modes *mode,
- struct wpa_scan_results *scan_res, int pri_chan,
- int sec_chan)
+int check_40mhz_5g(struct wpa_scan_results *scan_res,
+ struct hostapd_channel_data *pri_chan,
+ struct hostapd_channel_data *sec_chan)
{
- int pri_freq, sec_freq, pri_bss, sec_bss;
+ int pri_bss, sec_bss;
int bss_pri_chan, bss_sec_chan;
size_t i;
int match;
- if (!mode || !scan_res || !pri_chan || !sec_chan ||
- pri_chan == sec_chan)
+ if (!scan_res || !pri_chan || !sec_chan ||
+ pri_chan->freq == sec_chan->freq)
return 0;
- pri_freq = hw_get_freq(mode, pri_chan);
- sec_freq = hw_get_freq(mode, sec_chan);
-
/*
* Switch PRI/SEC channels if Beacons were detected on selected SEC
* channel, but not on selected PRI channel.
@@ -199,9 +205,9 @@ int check_40mhz_5g(struct hostapd_hw_modes *mode,
pri_bss = sec_bss = 0;
for (i = 0; i < scan_res->num; i++) {
struct wpa_scan_res *bss = scan_res->res[i];
- if (bss->freq == pri_freq)
+ if (bss->freq == pri_chan->freq)
pri_bss++;
- else if (bss->freq == sec_freq)
+ else if (bss->freq == sec_chan->freq)
sec_bss++;
}
if (sec_bss && !pri_bss) {
@@ -219,8 +225,8 @@ int check_40mhz_5g(struct hostapd_hw_modes *mode,
for (i = 0; i < scan_res->num; i++) {
struct wpa_scan_res *bss = scan_res->res[i];
get_pri_sec_chan(bss, &bss_pri_chan, &bss_sec_chan);
- if (pri_chan == bss_pri_chan &&
- sec_chan == bss_sec_chan) {
+ if (pri_chan->chan == bss_pri_chan &&
+ sec_chan->chan == bss_sec_chan) {
match = 1;
break;
}
@@ -229,8 +235,8 @@ int check_40mhz_5g(struct hostapd_hw_modes *mode,
for (i = 0; i < scan_res->num; i++) {
struct wpa_scan_res *bss = scan_res->res[i];
get_pri_sec_chan(bss, &bss_pri_chan, &bss_sec_chan);
- if (pri_chan == bss_sec_chan &&
- sec_chan == bss_pri_chan) {
+ if (pri_chan->chan == bss_sec_chan &&
+ sec_chan->chan == bss_pri_chan) {
wpa_printf(MSG_INFO, "Switch own primary and "
"secondary channel due to BSS "
"overlap with " MACSTR,
@@ -273,12 +279,87 @@ static int check_20mhz_bss(struct wpa_scan_res *bss, int pri_freq, int start,
}
+/*
+ * Returns:
+ * 0: no impact
+ * 1: overlapping BSS
+ * 2: overlapping BSS with 40 MHz intolerant advertisement
+ */
+int check_bss_coex_40mhz(struct wpa_scan_res *bss, int pri_freq, int sec_freq)
+{
+ int affected_start, affected_end;
+ struct ieee802_11_elems elems;
+ int pri_chan, sec_chan;
+ int pri = bss->freq;
+ int sec = pri;
+
+ if (pri_freq == sec_freq)
+ return 1;
+
+ affected_start = (pri_freq + sec_freq) / 2 - 25;
+ affected_end = (pri_freq + sec_freq) / 2 + 25;
+
+ /* Check for overlapping 20 MHz BSS */
+ if (check_20mhz_bss(bss, pri_freq, affected_start, affected_end)) {
+ wpa_printf(MSG_DEBUG, "Overlapping 20 MHz BSS is found");
+ return 1;
+ }
+
+ get_pri_sec_chan(bss, &pri_chan, &sec_chan);
+
+ if (sec_chan) {
+ if (sec_chan < pri_chan)
+ sec = pri - 20;
+ else
+ sec = pri + 20;
+ }
+
+ if ((pri < affected_start || pri > affected_end) &&
+ (sec < affected_start || sec > affected_end))
+ return 0; /* not within affected channel range */
+
+ wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR
+ " freq=%d pri=%d sec=%d",
+ MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan);
+
+ if (sec_chan) {
+ if (pri_freq != pri || sec_freq != sec) {
+ wpa_printf(MSG_DEBUG,
+ "40 MHz pri/sec mismatch with BSS "
+ MACSTR
+ " <%d,%d> (chan=%d%c) vs. <%d,%d>",
+ MAC2STR(bss->bssid),
+ pri, sec, pri_chan,
+ sec > pri ? '+' : '-',
+ pri_freq, sec_freq);
+ return 1;
+ }
+ }
+
+ ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0);
+ if (elems.ht_capabilities) {
+ struct ieee80211_ht_capabilities *ht_cap =
+ (struct ieee80211_ht_capabilities *)
+ elems.ht_capabilities;
+
+ if (le_to_host16(ht_cap->ht_capabilities_info) &
+ HT_CAP_INFO_40MHZ_INTOLERANT) {
+ wpa_printf(MSG_DEBUG,
+ "40 MHz Intolerant is set on channel %d in BSS "
+ MACSTR, pri, MAC2STR(bss->bssid));
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
+
int check_40mhz_2g4(struct hostapd_hw_modes *mode,
struct wpa_scan_results *scan_res, int pri_chan,
int sec_chan)
{
int pri_freq, sec_freq;
- int affected_start, affected_end;
size_t i;
if (!mode || !scan_res || !pri_chan || !sec_chan ||
@@ -288,70 +369,12 @@ int check_40mhz_2g4(struct hostapd_hw_modes *mode,
pri_freq = hw_get_freq(mode, pri_chan);
sec_freq = hw_get_freq(mode, sec_chan);
- affected_start = (pri_freq + sec_freq) / 2 - 25;
- affected_end = (pri_freq + sec_freq) / 2 + 25;
wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
- affected_start, affected_end);
+ (pri_freq + sec_freq) / 2 - 25,
+ (pri_freq + sec_freq) / 2 + 25);
for (i = 0; i < scan_res->num; i++) {
- struct wpa_scan_res *bss = scan_res->res[i];
- int pri = bss->freq;
- int sec = pri;
- struct ieee802_11_elems elems;
-
- /* Check for overlapping 20 MHz BSS */
- if (check_20mhz_bss(bss, pri_freq, affected_start,
- affected_end)) {
- wpa_printf(MSG_DEBUG,
- "Overlapping 20 MHz BSS is found");
+ if (check_bss_coex_40mhz(scan_res->res[i], pri_freq, sec_freq))
return 0;
- }
-
- get_pri_sec_chan(bss, &pri_chan, &sec_chan);
-
- if (sec_chan) {
- if (sec_chan < pri_chan)
- sec = pri - 20;
- else
- sec = pri + 20;
- }
-
- if ((pri < affected_start || pri > affected_end) &&
- (sec < affected_start || sec > affected_end))
- continue; /* not within affected channel range */
-
- wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR
- " freq=%d pri=%d sec=%d",
- MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan);
-
- if (sec_chan) {
- if (pri_freq != pri || sec_freq != sec) {
- wpa_printf(MSG_DEBUG,
- "40 MHz pri/sec mismatch with BSS "
- MACSTR
- " <%d,%d> (chan=%d%c) vs. <%d,%d>",
- MAC2STR(bss->bssid),
- pri, sec, pri_chan,
- sec > pri ? '+' : '-',
- pri_freq, sec_freq);
- return 0;
- }
- }
-
- ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems,
- 0);
- if (elems.ht_capabilities) {
- struct ieee80211_ht_capabilities *ht_cap =
- (struct ieee80211_ht_capabilities *)
- elems.ht_capabilities;
-
- if (le_to_host16(ht_cap->ht_capabilities_info) &
- HT_CAP_INFO_40MHZ_INTOLERANT) {
- wpa_printf(MSG_DEBUG,
- "40 MHz Intolerant is set on channel %d in BSS "
- MACSTR, pri, MAC2STR(bss->bssid));
- return 0;
- }
- }
}
return 1;
@@ -445,6 +468,8 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
data->bandwidth = (1 << (u8) bw) * 20;
data->center_freq1 = freq1;
data->center_freq2 = freq2;
+ data->ht_enabled = 0;
+ data->vht_enabled = 0;
}
return 0;
diff --git a/src/common/hw_features_common.h b/src/common/hw_features_common.h
index c86e195..e57a8d6 100644
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -14,18 +14,22 @@
struct hostapd_channel_data * hw_get_channel_chan(struct hostapd_hw_modes *mode,
int chan, int *freq);
-struct hostapd_channel_data * hw_get_channel_freq(struct hostapd_hw_modes *mode,
- int freq, int *chan);
+struct hostapd_channel_data *
+hw_get_channel_freq(enum hostapd_hw_mode mode, int freq, int *chan,
+ struct hostapd_hw_modes *hw_features, int num_hw_features);
int hw_get_freq(struct hostapd_hw_modes *mode, int chan);
-int hw_get_chan(struct hostapd_hw_modes *mode, int freq);
+int hw_get_chan(enum hostapd_hw_mode mode, int freq,
+ struct hostapd_hw_modes *hw_features, int num_hw_features);
-int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
- int sec_chan);
+int allowed_ht40_channel_pair(enum hostapd_hw_mode mode,
+ struct hostapd_channel_data *p_chan,
+ struct hostapd_channel_data *s_chan);
void get_pri_sec_chan(struct wpa_scan_res *bss, int *pri_chan, int *sec_chan);
-int check_40mhz_5g(struct hostapd_hw_modes *mode,
- struct wpa_scan_results *scan_res, int pri_chan,
- int sec_chan);
+int check_40mhz_5g(struct wpa_scan_results *scan_res,
+ struct hostapd_channel_data *pri_chan,
+ struct hostapd_channel_data *sec_chan);
+int check_bss_coex_40mhz(struct wpa_scan_res *bss, int pri_freq, int sec_freq);
int check_40mhz_2g4(struct hostapd_hw_modes *mode,
struct wpa_scan_results *scan_res, int pri_chan,
int sec_chan);
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 21ca194..36005d7 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -282,6 +282,10 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
elems->oci = pos;
elems->oci_len = elen;
break;
+ case WLAN_EID_EXT_SHORT_SSID_LIST:
+ elems->short_ssid_list = pos;
+ elems->short_ssid_list_len = elen;
+ break;
default:
if (show_errors) {
wpa_printf(MSG_MSGDUMP,
@@ -720,13 +724,14 @@ enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
* for HT40 and VHT. DFS channels are not covered.
* @freq: Frequency (MHz) to convert
* @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
- * @vht: VHT channel width (CHANWIDTH_*)
+ * @chanwidth: VHT/EDMG channel width (CHANWIDTH_*)
* @op_class: Buffer for returning operating class
* @channel: Buffer for returning channel number
* Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
*/
enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
- int sec_channel, int vht,
+ int sec_channel,
+ int chanwidth,
u8 *op_class, u8 *channel)
{
u8 vht_opclass;
@@ -740,7 +745,7 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
if ((freq - 2407) % 5)
return NUM_HOSTAPD_MODES;
- if (vht)
+ if (chanwidth)
return NUM_HOSTAPD_MODES;
/* 2.407 GHz, channels 1..13 */
@@ -757,7 +762,7 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
}
if (freq == 2484) {
- if (sec_channel || vht)
+ if (sec_channel || chanwidth)
return NUM_HOSTAPD_MODES;
*op_class = 82; /* channel 14 */
@@ -774,7 +779,7 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
return HOSTAPD_MODE_IEEE80211A;
}
- switch (vht) {
+ switch (chanwidth) {
case CHANWIDTH_80MHZ:
vht_opclass = 128;
break;
@@ -875,17 +880,6 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
return HOSTAPD_MODE_IEEE80211A;
}
- /* 56.16 GHz, channel 1..6 */
- if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6) {
- if (sec_channel || vht)
- return NUM_HOSTAPD_MODES;
-
- *channel = (freq - 56160) / 2160;
- *op_class = 180;
-
- return HOSTAPD_MODE_IEEE80211AD;
- }
-
if (freq > 5940 && freq <= 7105) {
int bw;
u8 idx = (freq - 5940) / 5;
@@ -899,6 +893,48 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
return HOSTAPD_MODE_IEEE80211A;
}
+ /* 56.16 GHz, channel 1..6 */
+ if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6) {
+ if (sec_channel)
+ return NUM_HOSTAPD_MODES;
+
+ switch (chanwidth) {
+ case CHANWIDTH_USE_HT:
+ case CHANWIDTH_2160MHZ:
+ *channel = (freq - 56160) / 2160;
+ *op_class = 180;
+ break;
+ case CHANWIDTH_4320MHZ:
+ /* EDMG channels 9 - 13 */
+ if (freq > 56160 + 2160 * 5)
+ return NUM_HOSTAPD_MODES;
+
+ *channel = (freq - 56160) / 2160 + 8;
+ *op_class = 181;
+ break;
+ case CHANWIDTH_6480MHZ:
+ /* EDMG channels 17 - 20 */
+ if (freq > 56160 + 2160 * 4)
+ return NUM_HOSTAPD_MODES;
+
+ *channel = (freq - 56160) / 2160 + 16;
+ *op_class = 182;
+ break;
+ case CHANWIDTH_8640MHZ:
+ /* EDMG channels 25 - 27 */
+ if (freq > 56160 + 2160 * 3)
+ return NUM_HOSTAPD_MODES;
+
+ *channel = (freq - 56160) / 2160 + 24;
+ *op_class = 183;
+ break;
+ default:
+ return NUM_HOSTAPD_MODES;
+ }
+
+ return HOSTAPD_MODE_IEEE80211AD;
+ }
+
return NUM_HOSTAPD_MODES;
}
@@ -906,27 +942,39 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
int sec_channel, u8 *op_class, u8 *channel)
{
- int vht = CHAN_WIDTH_UNKNOWN;
+ int cw = CHAN_WIDTH_UNKNOWN;
switch (chanwidth) {
case CHAN_WIDTH_UNKNOWN:
case CHAN_WIDTH_20_NOHT:
case CHAN_WIDTH_20:
case CHAN_WIDTH_40:
- vht = CHANWIDTH_USE_HT;
+ cw = CHANWIDTH_USE_HT;
break;
case CHAN_WIDTH_80:
- vht = CHANWIDTH_80MHZ;
+ cw = CHANWIDTH_80MHZ;
break;
case CHAN_WIDTH_80P80:
- vht = CHANWIDTH_80P80MHZ;
+ cw = CHANWIDTH_80P80MHZ;
break;
case CHAN_WIDTH_160:
- vht = CHANWIDTH_160MHZ;
+ cw = CHANWIDTH_160MHZ;
+ break;
+ case CHAN_WIDTH_2160:
+ cw = CHANWIDTH_2160MHZ;
+ break;
+ case CHAN_WIDTH_4320:
+ cw = CHANWIDTH_4320MHZ;
+ break;
+ case CHAN_WIDTH_6480:
+ cw = CHANWIDTH_6480MHZ;
+ break;
+ case CHAN_WIDTH_8640:
+ cw = CHANWIDTH_8640MHZ;
break;
}
- if (ieee80211_freq_to_channel_ext(freq, sec_channel, vht, op_class,
+ if (ieee80211_freq_to_channel_ext(freq, sec_channel, cw, op_class,
channel) == NUM_HOSTAPD_MODES) {
wpa_printf(MSG_WARNING,
"Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
@@ -1008,10 +1056,22 @@ static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
if (chan < 149 || chan > 165)
return -1;
return 5000 + 5 * chan;
- case 34: /* 60 GHz band, channels 1..6 */
- if (chan < 1 || chan > 6)
+ case 34: /* 60 GHz band, channels 1..8 */
+ if (chan < 1 || chan > 8)
return -1;
return 56160 + 2160 * chan;
+ case 37: /* 60 GHz band, EDMG CB2, channels 9..15 */
+ if (chan < 9 || chan > 15)
+ return -1;
+ return 56160 + 2160 * (chan - 8);
+ case 38: /* 60 GHz band, EDMG CB3, channels 17..22 */
+ if (chan < 17 || chan > 22)
+ return -1;
+ return 56160 + 2160 * (chan - 16);
+ case 39: /* 60 GHz band, EDMG CB4, channels 25..29 */
+ if (chan < 25 || chan > 29)
+ return -1;
+ return 56160 + 2160 * (chan - 24);
}
return -1;
}
@@ -1050,6 +1110,18 @@ static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
if (chan < 1 || chan > 6)
return -1;
return 56160 + 2160 * chan;
+ case 21: /* 60 GHz band, EDMG CB2, channels 9..11 */
+ if (chan < 9 || chan > 11)
+ return -1;
+ return 56160 + 2160 * (chan - 8);
+ case 22: /* 60 GHz band, EDMG CB3, channels 17..18 */
+ if (chan < 17 || chan > 18)
+ return -1;
+ return 56160 + 2160 * (chan - 16);
+ case 23: /* 60 GHz band, EDMG CB4, channels 25 */
+ if (chan != 25)
+ return -1;
+ return 56160 + 2160 * (chan - 24);
}
return -1;
}
@@ -1094,6 +1166,18 @@ static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
if (chan < 1 || chan > 6)
return -1;
return 56160 + 2160 * chan;
+ case 62: /* 60 GHz band, EDMG CB2, channels 9..11 */
+ if (chan < 9 || chan > 11)
+ return -1;
+ return 56160 + 2160 * (chan - 8);
+ case 63: /* 60 GHz band, EDMG CB3, channels 17..18 */
+ if (chan < 17 || chan > 18)
+ return -1;
+ return 56160 + 2160 * (chan - 16);
+ case 64: /* 60 GHz band, EDMG CB4, channel 25 */
+ if (chan != 25)
+ return -1;
+ return 56160 + 2160 * (chan - 24);
}
return -1;
}
@@ -1186,10 +1270,22 @@ static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
if (chan < 1 || chan > 233)
return -1;
return 5940 + chan * 5;
- case 180: /* 60 GHz band, channels 1..6 */
- if (chan < 1 || chan > 6)
+ case 180: /* 60 GHz band, channels 1..8 */
+ if (chan < 1 || chan > 8)
return -1;
return 56160 + 2160 * chan;
+ case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
+ if (chan < 9 || chan > 15)
+ return -1;
+ return 56160 + 2160 * (chan - 8);
+ case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
+ if (chan < 17 || chan > 22)
+ return -1;
+ return 56160 + 2160 * (chan - 16);
+ case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
+ if (chan < 25 || chan > 29)
+ return -1;
+ return 56160 + 2160 * (chan - 24);
}
return -1;
}
@@ -1617,7 +1713,16 @@ const struct oper_class_map global_op_class[] = {
{ HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
- { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
+
+ /*
+ * IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
+ * Class 180 has the legacy channels 1-6. Classes 181-183 include
+ * channels which implement channel bonding features.
+ */
+ { HOSTAPD_MODE_IEEE80211AD, 180, 1, 6, 1, BW2160, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211AD, 181, 9, 13, 1, BW4320, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211AD, 182, 17, 20, 1, BW6480, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211AD, 183, 25, 27, 1, BW8640, P2P_SUPP },
{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
};
@@ -1968,6 +2073,26 @@ int is_6ghz_op_class(u8 op_class)
}
+int is_6ghz_psc_frequency(int freq)
+{
+ int i;
+
+ if (!is_6ghz_freq(freq))
+ return 0;
+ if ((((freq - 5940) / 5) & 0x3) != 0x1)
+ return 0;
+
+ i = (freq - 5940 + 55) % 80;
+ if (i == 0)
+ i = (freq - 5940 + 55) / 80;
+
+ if (i >= 1 && i <= 15)
+ return 1;
+
+ return 0;
+}
+
+
int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
size_t nei_rep_len)
{
@@ -2148,3 +2273,121 @@ int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,
return 1;
}
+
+
+int op_class_to_bandwidth(u8 op_class)
+{
+ switch (op_class) {
+ case 81:
+ case 82:
+ return 20;
+ case 83: /* channels 1..9; 40 MHz */
+ case 84: /* channels 5..13; 40 MHz */
+ return 40;
+ case 115: /* channels 36,40,44,48; indoor only */
+ return 20;
+ case 116: /* channels 36,44; 40 MHz; indoor only */
+ case 117: /* channels 40,48; 40 MHz; indoor only */
+ return 40;
+ case 118: /* channels 52,56,60,64; dfs */
+ return 20;
+ case 119: /* channels 52,60; 40 MHz; dfs */
+ case 120: /* channels 56,64; 40 MHz; dfs */
+ return 40;
+ case 121: /* channels 100-140 */
+ return 20;
+ case 122: /* channels 100-142; 40 MHz */
+ case 123: /* channels 104-136; 40 MHz */
+ return 40;
+ case 124: /* channels 149,153,157,161 */
+ case 125: /* channels 149,153,157,161,165,169 */
+ return 20;
+ case 126: /* channels 149,157; 40 MHz */
+ case 127: /* channels 153,161; 40 MHz */
+ return 40;
+ case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
+ return 80;
+ case 129: /* center freqs 50, 114; 160 MHz */
+ return 160;
+ case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80+80 MHz */
+ return 80;
+ case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
+ return 20;
+ case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
+ return 40;
+ case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
+ return 80;
+ case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
+ case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
+ return 160;
+ case 180: /* 60 GHz band, channels 1..8 */
+ return 2160;
+ case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
+ return 4320;
+ case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
+ return 6480;
+ case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
+ return 8640;
+ }
+
+ return 20;
+}
+
+
+int op_class_to_ch_width(u8 op_class)
+{
+ switch (op_class) {
+ case 81:
+ case 82:
+ return CHANWIDTH_USE_HT;
+ case 83: /* channels 1..9; 40 MHz */
+ case 84: /* channels 5..13; 40 MHz */
+ return CHANWIDTH_USE_HT;
+ case 115: /* channels 36,40,44,48; indoor only */
+ return CHANWIDTH_USE_HT;
+ case 116: /* channels 36,44; 40 MHz; indoor only */
+ case 117: /* channels 40,48; 40 MHz; indoor only */
+ return CHANWIDTH_USE_HT;
+ case 118: /* channels 52,56,60,64; dfs */
+ return CHANWIDTH_USE_HT;
+ case 119: /* channels 52,60; 40 MHz; dfs */
+ case 120: /* channels 56,64; 40 MHz; dfs */
+ return CHANWIDTH_USE_HT;
+ case 121: /* channels 100-140 */
+ return CHANWIDTH_USE_HT;
+ case 122: /* channels 100-142; 40 MHz */
+ case 123: /* channels 104-136; 40 MHz */
+ return CHANWIDTH_USE_HT;
+ case 124: /* channels 149,153,157,161 */
+ case 125: /* channels 149,153,157,161,165,169 */
+ return CHANWIDTH_USE_HT;
+ case 126: /* channels 149,157; 40 MHz */
+ case 127: /* channels 153,161; 40 MHz */
+ return CHANWIDTH_USE_HT;
+ case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
+ return CHANWIDTH_80MHZ;
+ case 129: /* center freqs 50, 114; 160 MHz */
+ return CHANWIDTH_160MHZ;
+ case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80+80 MHz */
+ return CHANWIDTH_80P80MHZ;
+ case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
+ return CHANWIDTH_USE_HT;
+ case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
+ return CHANWIDTH_USE_HT;
+ case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
+ return CHANWIDTH_80MHZ;
+ case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
+ return CHANWIDTH_160MHZ;
+ case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
+ return CHANWIDTH_80P80MHZ;
+ case 180: /* 60 GHz band, channels 1..8 */
+ return CHANWIDTH_2160MHZ;
+ case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
+ return CHANWIDTH_4320MHZ;
+ case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
+ return CHANWIDTH_6480MHZ;
+ case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
+ return CHANWIDTH_8640MHZ;
+ }
+ return CHANWIDTH_USE_HT;
+}
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index 052f333..d133169 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -96,6 +96,7 @@ struct ieee802_11_elems {
const u8 *multi_ap;
const u8 *he_capabilities;
const u8 *he_operation;
+ const u8 *short_ssid_list;
u8 ssid_len;
u8 supp_rates_len;
@@ -147,6 +148,7 @@ struct ieee802_11_elems {
u8 multi_ap_len;
u8 he_capabilities_len;
u8 he_operation_len;
+ u8 short_ssid_list_len;
struct mb_ies_info mb_ies;
};
@@ -198,7 +200,8 @@ struct oper_class_map {
u8 min_chan;
u8 max_chan;
u8 inc;
- enum { BW20, BW40PLUS, BW40MINUS, BW80, BW2160, BW160, BW80P80 } bw;
+ enum { BW20, BW40PLUS, BW40MINUS, BW80, BW2160, BW160, BW80P80, BW4320,
+ BW6480, BW8640} bw;
enum { P2P_SUPP, NO_P2P_SUPP } p2p;
};
@@ -225,11 +228,14 @@ int oper_class_bw_to_int(const struct oper_class_map *map);
int center_idx_to_bw_6ghz(u8 idx);
int is_6ghz_freq(int freq);
int is_6ghz_op_class(u8 op_class);
+int is_6ghz_psc_frequency(int freq);
int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
size_t nei_rep_len);
int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
+int op_class_to_bandwidth(u8 op_class);
+int op_class_to_ch_width(u8 op_class);
/* element iteration helpers */
#define for_each_element(_elem, _data, _datalen) \
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index fbed051..d999a36 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -472,6 +472,7 @@
#define WLAN_EID_EXT_HE_MU_EDCA_PARAMS 38
#define WLAN_EID_EXT_SPATIAL_REUSE 39
#define WLAN_EID_EXT_OCV_OCI 54
+#define WLAN_EID_EXT_SHORT_SSID_LIST 58
#define WLAN_EID_EXT_EDMG_CAPABILITIES 61
#define WLAN_EID_EXT_EDMG_OPERATION 62
#define WLAN_EID_EXT_REJECTED_GROUPS 92
@@ -1285,11 +1286,15 @@ struct ieee80211_ampe_ie {
#define VHT_RX_NSS_MAX_STREAMS 8
-/* VHT channel widths */
+/* VHT/EDMG channel widths */
#define CHANWIDTH_USE_HT 0
#define CHANWIDTH_80MHZ 1
#define CHANWIDTH_160MHZ 2
#define CHANWIDTH_80P80MHZ 3
+#define CHANWIDTH_2160MHZ 4
+#define CHANWIDTH_4320MHZ 5
+#define CHANWIDTH_6480MHZ 6
+#define CHANWIDTH_8640MHZ 7
#define HE_NSS_MAX_STREAMS 8
diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
index a0a0fb5..557b525 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -609,6 +609,14 @@ enum qca_radiotap_vendor_ids {
* coex chain mode from application/service.
* The attributes defined in enum qca_vendor_attr_btc_chain_mode are used
* to deliver the parameters.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO: This vendor subcommand is used to
+ * get information of a station from driver to userspace. This command can
+ * be used in both STA and AP modes. For STA mode, it provides information
+ * of the current association when in connected state or the last
+ * association when in disconnected state. For AP mode, only information
+ * of the currently connected stations is available. This command uses
+ * attributes defined in enum qca_wlan_vendor_attr_get_sta_info.
*/
enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
@@ -784,6 +792,7 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT = 183,
QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE = 184,
QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE = 185,
+ QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO = 186,
};
enum qca_wlan_vendor_attr {
@@ -1180,7 +1189,9 @@ enum qca_wlan_vendor_attr_p2p_listen_offload {
*
* @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL: Required (u8).
* Used with event to notify the VHT segment 0 center channel number selected in
- * ACS operation.
+ * ACS operation. The value is the index of the channel center frequency for
+ * 20 MHz, 40 MHz, and 80 MHz channels. The value is the center frequency index
+ * of the primary 80 MHz segment for 160 MHz and 80+80 MHz channels.
* Note: If both the driver and user-space application supports the 6 GHz band,
* QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL is deprecated; use
* QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY instead.
@@ -1190,7 +1201,10 @@ enum qca_wlan_vendor_attr_p2p_listen_offload {
*
* @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL: Required (u8).
* Used with event to notify the VHT segment 1 center channel number selected in
- * ACS operation.
+ * ACS operation. The value is zero for 20 MHz, 40 MHz, and 80 MHz channels.
+ * The value is the index of the channel center frequency for 160 MHz channels
+ * and the center frequency index of the secondary 80 MHz segment for 80+80 MHz
+ * channels.
* Note: If both the driver and user-space application supports the 6 GHz band,
* QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL is deprecated; use
* QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY instead.
@@ -8046,4 +8060,110 @@ enum qca_vendor_attr_btc_chain_mode {
QCA_VENDOR_ATTR_BTC_CHAIN_MODE_LAST - 1,
};
+/**
+ * enum qca_vendor_wlan_sta_flags - Station feature flags
+ * Bits will be set to 1 if the corresponding features are enabled.
+ * @QCA_VENDOR_WLAN_STA_FLAG_AMPDU: AMPDU is enabled for the station
+ * @QCA_VENDOR_WLAN_STA_FLAG_TX_STBC: TX Space-time block coding is enabled
+ for the station
+ * @QCA_VENDOR_WLAN_STA_FLAG_RX_STBC: RX Space-time block coding is enabled
+ for the station
+ */
+enum qca_vendor_wlan_sta_flags {
+ QCA_VENDOR_WLAN_STA_FLAG_AMPDU = BIT(0),
+ QCA_VENDOR_WLAN_STA_FLAG_TX_STBC = BIT(1),
+ QCA_VENDOR_WLAN_STA_FLAG_RX_STBC = BIT(2),
+};
+
+/**
+ * enum qca_vendor_wlan_sta_guard_interval - Station guard interval
+ * @QCA_VENDOR_WLAN_STA_GI_800_NS: Legacy normal guard interval
+ * @QCA_VENDOR_WLAN_STA_GI_400_NS: Legacy short guard interval
+ * @QCA_VENDOR_WLAN_STA_GI_1600_NS: Guard interval used by HE
+ * @QCA_VENDOR_WLAN_STA_GI_3200_NS: Guard interval used by HE
+ */
+enum qca_vendor_wlan_sta_guard_interval {
+ QCA_VENDOR_WLAN_STA_GI_800_NS = 0,
+ QCA_VENDOR_WLAN_STA_GI_400_NS = 1,
+ QCA_VENDOR_WLAN_STA_GI_1600_NS = 2,
+ QCA_VENDOR_WLAN_STA_GI_3200_NS = 3,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_get_sta_info - Defines attributes
+ * used by QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC:
+ * Required attribute in request, 6-byte MAC address,
+ * used in both STA and AP modes.
+ * MAC address of the station for which information is requested (BSSID of the
+ * AP in STA mode).
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_FLAGS:
+ * Optionally used in response, u32 attribute, contains a bitmap of different
+ * fields defined in enum qca_vendor_wlan_sta_flags, used in AP mode only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_GUARD_INTERVAL:
+ * Optionally used in response, u32 attribute, possible values are defined in
+ * enum qca_vendor_wlan_sta_guard_interval, used in AP mode only.
+ * Guard interval used by the station.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT:
+ * Optionally used in response, u32 attribute, used in AP mode only.
+ * Value indicates the number of data frames received from station with retry
+ * bit set to 1 in FC.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT:
+ * Optionally used in response, u32 attribute, used in AP mode only.
+ * Counter for number of data frames with broadcast or multicast address in
+ * the destination address received from the station.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED:
+ * Optionally used in response, u32 attribute, used in both STA and AP modes.
+ * Value indicates the number of data frames successfully transmitted only
+ * after retrying the packets and for which the TX status has been updated
+ * back to host from target.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED:
+ * Optionally used in response, u32 attribute, used in AP mode only.
+ * Value indicates the number of data frames not transmitted successfully even
+ * after retrying the packets for the number of times equal to the total number
+ * of retries allowed for that packet and for which the TX status has been
+ * updated back to host from target.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL:
+ * Optionally used in response, u32 attribute, used in AP mode only.
+ * Counter in the target for the number of data frames successfully transmitted
+ * to the station.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY:
+ * Optionally used in response, u32 attribute, used in AP mode only.
+ * Value indicates the number of data frames successfully transmitted only
+ * after retrying the packets.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED:
+ * Optionally used in response, u32 attribute, used in AP mode only.
+ * Value indicates the number of data frames not transmitted successfully even
+ * after retrying the packets for the number of times equal to the total number
+ * of retries allowed for that packet.
+ */
+enum qca_wlan_vendor_attr_get_sta_info {
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC = 1,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_FLAGS = 2,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_GUARD_INTERVAL = 3,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT = 4,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT = 5,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED = 6,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED = 7,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL = 8,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY = 9,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED = 10,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX =
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST - 1,
+};
+
#endif /* QCA_VENDOR_H */
diff --git a/src/common/sae.c b/src/common/sae.c
index 2ab168b..bf8cc9d 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -579,20 +579,26 @@ static int sswu_curve_param(int group, int *z)
{
switch (group) {
case 19:
+ *z = -10;
+ return 0;
case 20:
+ *z = -12;
+ return 0;
case 21:
- case 28:
- *z = -2;
+ *z = -4;
return 0;
case 25:
case 29:
*z = -5;
return 0;
case 26:
- *z = -11;
+ *z = 31;
+ return 0;
+ case 28:
+ *z = -2;
return 0;
case 30:
- *z = 2;
+ *z = 7;
return 0;
}
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index ea9f7a2..de4b6ec 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -2200,7 +2200,7 @@ int wpa_insert_pmkid(u8 *ies, size_t *ies_len, const u8 *pmkid)
"RSN: Remove %u old PMKID(s) from RSNE",
num_pmkid);
after = rpos + 2 + num_pmkid * PMKID_LEN;
- os_memmove(rpos + 2, after, rend - after);
+ os_memmove(rpos + 2, after, end - after);
start[1] -= num_pmkid * PMKID_LEN;
added -= num_pmkid * PMKID_LEN;
}
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 70ecf5d..f03c698 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -171,6 +171,7 @@ extern "C" {
#define DPP_EVENT_CONN_STATUS_RESULT "DPP-CONN-STATUS-RESULT "
#define DPP_EVENT_CONFOBJ_AKM "DPP-CONFOBJ-AKM "
#define DPP_EVENT_CONFOBJ_SSID "DPP-CONFOBJ-SSID "
+#define DPP_EVENT_CONFOBJ_SSID_CHARSET "DPP-CONFOBJ-SSID-CHARSET "
#define DPP_EVENT_CONFOBJ_PASS "DPP-CONFOBJ-PASS "
#define DPP_EVENT_CONFOBJ_PSK "DPP-CONFOBJ-PSK "
#define DPP_EVENT_CONNECTOR "DPP-CONNECTOR "
@@ -300,6 +301,8 @@ extern "C" {
#define WPS_EVENT_AP_SETUP_UNLOCKED "WPS-AP-SETUP-UNLOCKED "
#define WPS_EVENT_AP_PIN_ENABLED "WPS-AP-PIN-ENABLED "
#define WPS_EVENT_AP_PIN_DISABLED "WPS-AP-PIN-DISABLED "
+#define WPS_EVENT_PIN_ACTIVE "WPS-PIN-ACTIVE "
+#define WPS_EVENT_CANCEL "WPS-CANCEL "
#define AP_STA_CONNECTED "AP-STA-CONNECTED "
#define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED "
#define AP_STA_POSSIBLE_PSK_MISMATCH "AP-STA-POSSIBLE-PSK-MISMATCH "
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 5661e42..a6a4ce4 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -2190,6 +2190,7 @@ static int openssl_cert_tod(X509 *cert)
else if (os_strcmp(buf, "1.3.6.1.4.1.40808.1.3.2") == 0 && !tod)
tod = 2; /* TOD-TOFU */
}
+ sk_POLICYINFO_pop_free(ext, POLICYINFO_free);
return tod;
}
@@ -4047,6 +4048,7 @@ static int openssl_get_keyblock_size(SSL *ssl)
int cipher, digest;
const EVP_CIPHER *c;
const EVP_MD *h;
+ int mac_key_len, enc_key_len, fixed_iv_len;
ssl_cipher = SSL_get_current_cipher(ssl);
if (!ssl_cipher)
@@ -4057,17 +4059,33 @@ static int openssl_get_keyblock_size(SSL *ssl)
cipher, digest);
if (cipher < 0 || digest < 0)
return -1;
+ if (cipher == NID_undef) {
+ wpa_printf(MSG_DEBUG, "OpenSSL: no cipher in use?!");
+ return -1;
+ }
c = EVP_get_cipherbynid(cipher);
- h = EVP_get_digestbynid(digest);
- if (!c || !h)
+ if (!c)
return -1;
+ enc_key_len = EVP_CIPHER_key_length(c);
+ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE ||
+ EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE)
+ fixed_iv_len = 4; /* only part of IV from PRF */
+ else
+ fixed_iv_len = EVP_CIPHER_iv_length(c);
+ if (digest == NID_undef) {
+ wpa_printf(MSG_DEBUG, "OpenSSL: no digest in use (e.g., AEAD)");
+ mac_key_len = 0;
+ } else {
+ h = EVP_get_digestbynid(digest);
+ if (!h)
+ return -1;
+ mac_key_len = EVP_MD_size(h);
+ }
wpa_printf(MSG_DEBUG,
- "OpenSSL: keyblock size: key_len=%d MD_size=%d IV_len=%d",
- EVP_CIPHER_key_length(c), EVP_MD_size(h),
- EVP_CIPHER_iv_length(c));
- return 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) +
- EVP_CIPHER_iv_length(c));
+ "OpenSSL: keyblock size: mac_key_len=%d enc_key_len=%d fixed_iv_len=%d",
+ mac_key_len, enc_key_len, fixed_iv_len);
+ return 2 * (mac_key_len + enc_key_len + fixed_iv_len);
#endif
}
#endif /* OPENSSL_NEED_EAP_FAST_PRF */
@@ -4891,6 +4909,76 @@ static int ocsp_status_cb(SSL *s, void *arg)
#endif /* HAVE_OCSP */
+static size_t max_str_len(const char **lines)
+{
+ const char **p;
+ size_t max_len = 0;
+
+ for (p = lines; *p; p++) {
+ size_t len = os_strlen(*p);
+
+ if (len > max_len)
+ max_len = len;
+ }
+
+ return max_len;
+}
+
+
+static int match_lines_in_file(const char *path, const char **lines)
+{
+ FILE *f;
+ char *buf;
+ size_t bufsize;
+ int found = 0, is_linestart = 1;
+
+ bufsize = max_str_len(lines) + sizeof("\r\n");
+ buf = os_malloc(bufsize);
+ if (!buf)
+ return 0;
+
+ f = fopen(path, "r");
+ if (!f) {
+ os_free(buf);
+ return 0;
+ }
+
+ while (!found && fgets(buf, bufsize, f)) {
+ int is_lineend;
+ size_t len;
+ const char **p;
+
+ len = strcspn(buf, "\r\n");
+ is_lineend = buf[len] != '\0';
+ buf[len] = '\0';
+
+ if (is_linestart && is_lineend) {
+ for (p = lines; !found && *p; p++)
+ found = os_strcmp(buf, *p) == 0;
+ }
+ is_linestart = is_lineend;
+ }
+
+ fclose(f);
+ bin_clear_free(buf, bufsize);
+
+ return found;
+}
+
+
+static int is_tpm2_key(const char *path)
+{
+ /* Check both new and old format of TPM2 PEM guard tag */
+ static const char *tpm2_tags[] = {
+ "-----BEGIN TSS2 PRIVATE KEY-----",
+ "-----BEGIN TSS2 KEY BLOB-----",
+ NULL
+ };
+
+ return match_lines_in_file(path, tpm2_tags);
+}
+
+
int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
const struct tls_connection_params *params)
{
@@ -4943,6 +5031,17 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
if (can_pkcs11 == 2 && !engine_id)
engine_id = "pkcs11";
+ /* If private_key points to a TPM2-wrapped key, automatically enable
+ * tpm2 engine and use it to unwrap the key. */
+ if (params->private_key &&
+ (!engine_id || os_strcmp(engine_id, "tpm2") == 0) &&
+ is_tpm2_key(params->private_key)) {
+ wpa_printf(MSG_DEBUG, "OpenSSL: Found TPM2 wrapped key %s",
+ params->private_key);
+ key_id = key_id ? key_id : params->private_key;
+ engine_id = engine_id ? engine_id : "tpm2";
+ }
+
#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
if (params->flags & TLS_CONN_EAP_FAST) {
@@ -4974,7 +5073,8 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
}
if (engine_id) {
- wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
+ wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine %s",
+ engine_id);
ret = tls_engine_init(conn, engine_id, params->pin,
key_id, cert_id, ca_cert_id);
if (ret)
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index ad68a07..9bdf880 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1524,6 +1524,121 @@ struct wpa_driver_mesh_join_params {
unsigned int flags;
};
+struct wpa_driver_set_key_params {
+ /**
+ * ifname - Interface name (for multi-SSID/VLAN support) */
+ const char *ifname;
+
+ /**
+ * alg - Encryption algorithm
+ *
+ * (%WPA_ALG_NONE, %WPA_ALG_WEP, %WPA_ALG_TKIP, %WPA_ALG_CCMP,
+ * %WPA_ALG_IGTK, %WPA_ALG_PMK, %WPA_ALG_GCMP, %WPA_ALG_GCMP_256,
+ * %WPA_ALG_CCMP_256, %WPA_ALG_BIP_GMAC_128, %WPA_ALG_BIP_GMAC_256,
+ * %WPA_ALG_BIP_CMAC_256);
+ * %WPA_ALG_NONE clears the key. */
+ enum wpa_alg alg;
+
+ /**
+ * addr - Address of the peer STA
+ *
+ * (BSSID of the current AP when setting pairwise key in station mode),
+ * ff:ff:ff:ff:ff:ff for broadcast keys, %NULL for default keys that
+ * are used both for broadcast and unicast; when clearing keys, %NULL
+ * is used to indicate that both the broadcast-only and default key of
+ * the specified key index is to be cleared */
+ const u8 *addr;
+
+ /**
+ * key_idx - Key index
+ *
+ * (0..3), usually 0 for unicast keys; 0..4095 for IGTK */
+ int key_idx;
+
+ /**
+ * set_tx - Configure this key as the default Tx key
+ *
+ * Only used when driver does not support separate unicast/individual
+ * key */
+ int set_tx;
+
+ /**
+ * seq - Sequence number/packet number
+ *
+ * seq_len octets, the next packet number to be used for in replay
+ * protection; configured for Rx keys (in most cases, this is only used
+ * with broadcast keys and set to zero for unicast keys); %NULL if not
+ * set */
+ const u8 *seq;
+
+ /**
+ * seq_len - Length of the seq, depends on the algorithm
+ *
+ * TKIP: 6 octets, CCMP/GCMP: 6 octets, IGTK: 6 octets */
+ size_t seq_len;
+
+ /**
+ * key - Key buffer
+ *
+ * TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key */
+ const u8 *key;
+
+ /**
+ * key_len - Length of the key buffer in octets
+ *
+ * WEP: 5 or 13, TKIP: 32, CCMP/GCMP: 16, IGTK: 16 */
+ size_t key_len;
+
+ /**
+ * vlan_id - VLAN index (0..4095) for VLAN offload cases */
+ int vlan_id;
+
+ /**
+ * key_flag - Additional key flags
+ *
+ * %KEY_FLAG_MODIFY
+ * Set when an already installed key must be updated.
+ * So far the only use-case is changing RX/TX status of
+ * installed keys. Must not be set when deleting a key.
+ * %KEY_FLAG_DEFAULT
+ * Set when the key is also a default key. Must not be set when
+ * deleting a key.
+ * %KEY_FLAG_RX
+ * The key is valid for RX. Must not be set when deleting a key.
+ * %KEY_FLAG_TX
+ * The key is valid for TX. Must not be set when deleting a key.
+ * %KEY_FLAG_GROUP
+ * The key is a broadcast or group key.
+ * %KEY_FLAG_PAIRWISE
+ * The key is a pairwise key.
+ * %KEY_FLAG_PMK
+ * The key is a Pairwise Master Key (PMK).
+ *
+ * Valid and pre-defined combinations are:
+ * %KEY_FLAG_GROUP_RX_TX
+ * WEP key not to be installed as default key.
+ * %KEY_FLAG_GROUP_RX_TX_DEFAULT
+ * Default WEP or WPA-NONE key.
+ * %KEY_FLAG_GROUP_RX
+ * GTK key valid for RX only.
+ * %KEY_FLAG_GROUP_TX_DEFAULT
+ * GTK key valid for TX only, immediately taking over TX.
+ * %KEY_FLAG_PAIRWISE_RX_TX
+ * Pairwise key immediately becoming the active pairwise key.
+ * %KEY_FLAG_PAIRWISE_RX
+ * Pairwise key not yet valid for TX. (Only usable when Extended
+ * Key ID is supported by the driver.)
+ * %KEY_FLAG_PAIRWISE_RX_TX_MODIFY
+ * Enable TX for a pairwise key installed with
+ * KEY_FLAG_PAIRWISE_RX.
+ *
+ * Not a valid standalone key type but pre-defined to be combined
+ * with other key_flags:
+ * %KEY_FLAG_RX_TX
+ * RX/TX key. */
+ enum key_flag key_flag;
+};
+
/**
* struct wpa_driver_capa - Driver capability information
*/
@@ -1704,6 +1819,10 @@ struct wpa_driver_capa {
#define WPA_DRIVER_FLAGS_FTM_RESPONDER 0x0100000000000000ULL
/** Driver support 4-way handshake offload for WPA-Personal */
#define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK 0x0200000000000000ULL
+/** Driver supports a separate control port for EAPOL frames */
+#define WPA_DRIVER_FLAGS_CONTROL_PORT 0x0400000000000000ULL
+/** Driver supports VLAN offload */
+#define WPA_DRIVER_FLAGS_VLAN_OFFLOAD 0x0800000000000000ULL
u64 flags;
#define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
@@ -2192,9 +2311,7 @@ struct drv_acs_params {
/* Configured ACS channel width */
u16 ch_width;
- /* ACS channel list info */
- unsigned int ch_list_len;
- const u8 *ch_list;
+ /* ACS frequency list info */
const int *freq_list;
};
@@ -2307,35 +2424,8 @@ struct wpa_driver_ops {
/**
* set_key - Configure encryption key
- * @ifname: Interface name (for multi-SSID/VLAN support)
* @priv: private driver interface data
- * @alg: encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP,
- * %WPA_ALG_TKIP, %WPA_ALG_CCMP, %WPA_ALG_IGTK, %WPA_ALG_PMK,
- * %WPA_ALG_GCMP, %WPA_ALG_GCMP_256, %WPA_ALG_CCMP_256,
- * %WPA_ALG_BIP_GMAC_128, %WPA_ALG_BIP_GMAC_256,
- * %WPA_ALG_BIP_CMAC_256);
- * %WPA_ALG_NONE clears the key.
- * @addr: Address of the peer STA (BSSID of the current AP when setting
- * pairwise key in station mode), ff:ff:ff:ff:ff:ff for
- * broadcast keys, %NULL for default keys that are used both for
- * broadcast and unicast; when clearing keys, %NULL is used to
- * indicate that both the broadcast-only and default key of the
- * specified key index is to be cleared
- * @key_idx: key index (0..3), usually 0 for unicast keys; 0..4095 for
- * IGTK
- * @set_tx: configure this key as the default Tx key (only used when
- * driver does not support separate unicast/individual key
- * @seq: sequence number/packet number, seq_len octets, the next
- * packet number to be used for in replay protection; configured
- * for Rx keys (in most cases, this is only used with broadcast
- * keys and set to zero for unicast keys); %NULL if not set
- * @seq_len: length of the seq, depends on the algorithm:
- * TKIP: 6 octets, CCMP/GCMP: 6 octets, IGTK: 6 octets
- * @key: key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key,
- * 8-byte Rx Mic Key
- * @key_len: length of the key buffer in octets (WEP: 5 or 13,
- * TKIP: 32, CCMP/GCMP: 16, IGTK: 16)
- *
+ * @params: Key parameters
* Returns: 0 on success, -1 on failure
*
* Configure the given key for the kernel driver. If the driver
@@ -2356,10 +2446,7 @@ struct wpa_driver_ops {
* in driver_*.c set_key() implementation, see driver_ndis.c for an
* example on how this can be done.
*/
- int (*set_key)(const char *ifname, void *priv, enum wpa_alg alg,
- const u8 *addr, int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len);
+ int (*set_key)(void *priv, struct wpa_driver_set_key_params *params);
/**
* init - Initialize driver interface
@@ -2611,11 +2698,13 @@ struct wpa_driver_ops {
* driver decide
* @csa_offs: Array of CSA offsets or %NULL
* @csa_offs_len: Number of elements in csa_offs
+ * @no_encrypt: Do not encrypt frame even if appropriate key exists
+ * (used only for testing purposes)
* Returns: 0 on success, -1 on failure
*/
int (*send_mlme)(void *priv, const u8 *data, size_t data_len,
int noack, unsigned int freq, const u16 *csa_offs,
- size_t csa_offs_len);
+ size_t csa_offs_len, int no_encrypt);
/**
* update_ft_ies - Update FT (IEEE 802.11r) IEs
@@ -2870,6 +2959,33 @@ struct wpa_driver_ops {
const u8 *addr);
/**
+ * tx_control_port - Send a frame over the 802.1X controlled port
+ * @priv: Private driver interface data
+ * @dest: Destination MAC address
+ * @proto: Ethertype in host byte order
+ * @buf: Frame payload starting from IEEE 802.1X header
+ * @len: Frame payload length
+ * @no_encrypt: Do not encrypt frame
+ *
+ * Returns 0 on success, else an error
+ *
+ * This is like a normal Ethernet send except that the driver is aware
+ * (by other means than the Ethertype) that this frame is special,
+ * and more importantly it gains an ordering between the transmission of
+ * the frame and other driver management operations such as key
+ * installations. This can be used to work around known limitations in
+ * IEEE 802.11 protocols such as race conditions between rekeying 4-way
+ * handshake message 4/4 and a PTK being overwritten.
+ *
+ * This function is only used for a given interface if the driver
+ * instance reports WPA_DRIVER_FLAGS_CONTROL_PORT capability. Otherwise,
+ * API users will fall back to sending the frame via a normal socket.
+ */
+ int (*tx_control_port)(void *priv, const u8 *dest,
+ u16 proto, const u8 *buf, size_t len,
+ int no_encrypt);
+
+ /**
* hapd_send_eapol - Send an EAPOL packet (AP only)
* @priv: private driver interface data
* @addr: Destination MAC address
@@ -3115,19 +3231,6 @@ struct wpa_driver_ops {
int (*commit)(void *priv);
/**
- * send_ether - Send an ethernet packet (AP only)
- * @priv: private driver interface data
- * @dst: Destination MAC address
- * @src: Source MAC address
- * @proto: Ethertype
- * @data: EAPOL packet starting with IEEE 802.1X header
- * @data_len: Length of the EAPOL packet in octets
- * Returns: 0 on success, -1 on failure
- */
- int (*send_ether)(void *priv, const u8 *dst, const u8 *src, u16 proto,
- const u8 *data, size_t data_len);
-
- /**
* set_radius_acl_auth - Notification of RADIUS ACL change
* @priv: Private driver interface data
* @mac: MAC address of the station
@@ -3350,20 +3453,6 @@ struct wpa_driver_ops {
int (*signal_monitor)(void *priv, int threshold, int hysteresis);
/**
- * send_frame - Send IEEE 802.11 frame (testing use only)
- * @priv: Private driver interface data
- * @data: IEEE 802.11 frame with IEEE 802.11 header
- * @data_len: Size of the frame
- * @encrypt: Whether to encrypt the frame (if keys are set)
- * Returns: 0 on success, -1 on failure
- *
- * This function is only used for debugging purposes and is not
- * required to be implemented for normal operations.
- */
- int (*send_frame)(void *priv, const u8 *data, size_t data_len,
- int encrypt);
-
- /**
* get_noa - Get current Notice of Absence attribute payload
* @priv: Private driver interface data
* @buf: Buffer for returning NoA
@@ -3515,6 +3604,12 @@ struct wpa_driver_ops {
unsigned int val);
/**
+ * get_wowlan - Get wake-on-wireless status
+ * @priv: Private driver interface data
+ */
+ int (*get_wowlan)(void *priv);
+
+ /**
* set_wowlan - Set wake-on-wireless triggers
* @priv: Private driver interface data
* @triggers: wowlan triggers
@@ -5609,18 +5704,26 @@ union wpa_event_data {
/**
* struct acs_selected_channels - Data for EVENT_ACS_CHANNEL_SELECTED
- * @pri_channel: Selected primary channel
- * @sec_channel: Selected secondary channel
+ * @pri_freq: Selected primary frequency
+ * @sec_freq: Selected secondary frequency
* @vht_seg0_center_ch: VHT mode Segment0 center channel
+ * The value is the index of the channel center frequency for
+ * 20 MHz, 40 MHz, and 80 MHz channels. The value is the center
+ * frequency index of the primary 80 MHz segment for 160 MHz and
+ * 80+80 MHz channels.
* @vht_seg1_center_ch: VHT mode Segment1 center channel
+ * The value is zero for 20 MHz, 40 MHz, and 80 MHz channels. The
+ * value is the index of the channel center frequency for 160 MHz
+ * channels and the center frequency index of the secondary 80 MHz
+ * segment for 80+80 MHz channels.
* @ch_width: Selected Channel width by driver. Driver may choose to
* change hostapd configured ACS channel width due driver internal
* channel restrictions.
* hw_mode: Selected band (used with hw_mode=any)
*/
struct acs_selected_channels {
- u8 pri_channel;
- u8 sec_channel;
+ unsigned int pri_freq;
+ unsigned int sec_freq;
u8 vht_seg0_center_ch;
u8 vht_seg1_center_ch;
u16 ch_width;
diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c
index eac3ae8..2014f9d 100644
--- a/src/drivers/driver_atheros.c
+++ b/src/drivers/driver_atheros.c
@@ -492,14 +492,18 @@ atheros_del_key(void *priv, const u8 *addr, int key_idx)
}
static int
-atheros_set_key(const char *ifname, void *priv, enum wpa_alg alg,
- const u8 *addr, int key_idx, int set_tx, const u8 *seq,
- size_t seq_len, const u8 *key, size_t key_len)
+atheros_set_key(void *priv, struct wpa_driver_set_key_params *params)
{
struct atheros_driver_data *drv = priv;
struct ieee80211req_key wk;
u_int8_t cipher;
int ret;
+ enum wpa_alg alg = params->alg;
+ const u8 *addr = params->addr;
+ int key_idx = params->key_idx;
+ int set_tx = params->set_tx;
+ const u8 *key = params->key;
+ size_t key_len = params->key_len;
if (alg == WPA_ALG_NONE)
return atheros_del_key(drv, addr, key_idx);
@@ -1960,7 +1964,8 @@ static int atheros_set_ap(void *priv, struct wpa_driver_ap_params *params)
static int atheros_send_mgmt(void *priv, const u8 *frm, size_t data_len,
int noack, unsigned int freq,
- const u16 *csa_offs, size_t csa_offs_len)
+ const u16 *csa_offs, size_t csa_offs_len,
+ int no_encrypt)
{
struct atheros_driver_data *drv = priv;
u8 buf[1510];
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index 8667ee5..a9b5d00 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -331,14 +331,20 @@ bsd_ctrl_iface(void *priv, int enable)
}
static int
-bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
- const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
- size_t seq_len, const u8 *key, size_t key_len)
+bsd_set_key(void *priv, struct wpa_driver_set_key_params *params)
{
struct ieee80211req_key wk;
#ifdef IEEE80211_KEY_NOREPLAY
struct bsd_driver_data *drv = priv;
#endif /* IEEE80211_KEY_NOREPLAY */
+ enum wpa_alg alg = params->alg;
+ const u8 *addr = params->addr;
+ int key_idx = params->key_idx;
+ int set_tx = params->set_tx;
+ const u8 *seq = params->seq;
+ size_t seq_len = params->seq_len;
+ const u8 *key = params->key;
+ size_t key_len = params->key_len;
wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "
"seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx,
diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c
index 186eccb..cfc52c7 100644
--- a/src/drivers/driver_hostap.c
+++ b/src/drivers/driver_hostap.c
@@ -263,7 +263,8 @@ static int hostap_init_sockets(struct hostap_driver_data *drv, u8 *own_addr)
static int hostap_send_mlme(void *priv, const u8 *msg, size_t len, int noack,
unsigned int freq,
- const u16 *csa_offs, size_t csa_offs_len)
+ const u16 *csa_offs, size_t csa_offs_len,
+ int no_encrypt)
{
struct hostap_driver_data *drv = priv;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) msg;
@@ -312,7 +313,7 @@ static int hostap_send_eapol(void *priv, const u8 *addr, const u8 *data,
pos += 2;
memcpy(pos, data, data_len);
- res = hostap_send_mlme(drv, (u8 *) hdr, len, 0, 0, NULL, 0);
+ res = hostap_send_mlme(drv, (u8 *) hdr, len, 0, 0, NULL, 0, 0);
if (res < 0) {
wpa_printf(MSG_ERROR, "hostap_send_eapol - packet len: %lu - "
"failed: %d (%s)",
@@ -395,17 +396,20 @@ static int hostapd_ioctl(void *priv, struct prism2_hostapd_param *param,
}
-static int wpa_driver_hostap_set_key(const char *ifname, void *priv,
- enum wpa_alg alg, const u8 *addr,
- int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
+static int wpa_driver_hostap_set_key(void *priv,
+ struct wpa_driver_set_key_params *params)
{
struct hostap_driver_data *drv = priv;
struct prism2_hostapd_param *param;
u8 *buf;
size_t blen;
int ret = 0;
+ enum wpa_alg alg = params->alg;
+ const u8 *addr = params->addr;
+ int key_idx = params->key_idx;
+ int set_tx = params->set_tx;
+ const u8 *key = params->key;
+ size_t key_len = params->key_len;
blen = sizeof(*param) + key_len;
buf = os_zalloc(blen);
@@ -1051,7 +1055,7 @@ static int hostap_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
memcpy(mgmt.bssid, own_addr, ETH_ALEN);
mgmt.u.deauth.reason_code = host_to_le16(reason);
return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN +
- sizeof(mgmt.u.deauth), 0, 0, NULL, 0);
+ sizeof(mgmt.u.deauth), 0, 0, NULL, 0, 0);
}
@@ -1089,7 +1093,7 @@ static int hostap_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
memcpy(mgmt.bssid, own_addr, ETH_ALEN);
mgmt.u.disassoc.reason_code = host_to_le16(reason);
return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN +
- sizeof(mgmt.u.disassoc), 0, 0, NULL, 0);
+ sizeof(mgmt.u.disassoc), 0, 0, NULL, 0, 0);
}
@@ -1169,7 +1173,7 @@ static void wpa_driver_hostap_poll_client(void *priv, const u8 *own_addr,
os_memcpy(hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
os_memcpy(hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
- hostap_send_mlme(priv, (u8 *)&hdr, sizeof(hdr), 0, 0, NULL, 0);
+ hostap_send_mlme(priv, (u8 *) &hdr, sizeof(hdr), 0, 0, NULL, 0, 0);
}
diff --git a/src/drivers/driver_macsec_linux.c b/src/drivers/driver_macsec_linux.c
index e922503..5319ba2 100644
--- a/src/drivers/driver_macsec_linux.c
+++ b/src/drivers/driver_macsec_linux.c
@@ -54,8 +54,6 @@ struct macsec_drv_data {
struct nl_sock *sk;
struct macsec_genl_ctx ctx;
- struct netlink_data *netlink;
- struct nl_handle *nl;
char ifname[IFNAMSIZ + 1];
int ifi;
int parent_ifi;
@@ -321,14 +319,14 @@ static int macsec_drv_macsec_init(void *priv, struct macsec_init_params *params)
if (err < 0) {
wpa_printf(MSG_ERROR, DRV_PREFIX
"Unable to connect NETLINK_ROUTE socket: %s",
- strerror(errno));
+ nl_geterror(err));
goto sock;
}
err = rtnl_link_alloc_cache(drv->sk, AF_UNSPEC, &drv->link_cache);
if (err < 0) {
wpa_printf(MSG_ERROR, DRV_PREFIX "Unable to get link cache: %s",
- strerror(errno));
+ nl_geterror(err));
goto sock;
}
diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c
index 5b4b924..529fc3b 100644
--- a/src/drivers/driver_ndis.c
+++ b/src/drivers/driver_ndis.c
@@ -1034,6 +1034,18 @@ static int wpa_driver_ndis_set_key(const char *ifname, void *priv,
static int
+wpa_driver_ndis_set_key_wrapper(void *priv,
+ struct wpa_driver_set_key_params *params)
+{
+ return wpa_driver_ndis_set_key(params->ifname, priv,
+ params->alg, params->addr,
+ params->key_idx, params->set_tx,
+ params->seq, params->seq_len,
+ params->key, params->key_len);
+}
+
+
+static int
wpa_driver_ndis_associate(void *priv,
struct wpa_driver_associate_params *params)
{
@@ -3195,7 +3207,7 @@ void driver_ndis_init_ops(void)
wpa_driver_ndis_ops.desc = ndis_drv_desc;
wpa_driver_ndis_ops.get_bssid = wpa_driver_ndis_get_bssid;
wpa_driver_ndis_ops.get_ssid = wpa_driver_ndis_get_ssid;
- wpa_driver_ndis_ops.set_key = wpa_driver_ndis_set_key;
+ wpa_driver_ndis_ops.set_key = wpa_driver_ndis_set_key_wrapper;
wpa_driver_ndis_ops.init = wpa_driver_ndis_init;
wpa_driver_ndis_ops.deinit = wpa_driver_ndis_deinit;
wpa_driver_ndis_ops.deauthenticate = wpa_driver_ndis_deauthenticate;
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 4c8dcad..64bea49 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -66,48 +66,6 @@ enum nlmsgerr_attrs {
#define SOL_NETLINK 270
#endif
-#ifndef CONFIG_LIBNL20
-/*
- * libnl 1.1 has a bug, it tries to allocate socket numbers densely
- * but when you free a socket again it will mess up its bitmap and
- * and use the wrong number the next time it needs a socket ID.
- * Therefore, we wrap the handle alloc/destroy and add our own pid
- * accounting.
- */
-static uint32_t port_bitmap[32] = { 0 };
-
-static struct nl_handle *nl80211_handle_alloc(void *cb)
-{
- struct nl_handle *handle;
- uint32_t pid = getpid() & 0x3FFFFF;
- int i;
-
- handle = nl_handle_alloc_cb(cb);
-
- for (i = 0; i < 1024; i++) {
- if (port_bitmap[i / 32] & (1 << (i % 32)))
- continue;
- port_bitmap[i / 32] |= 1 << (i % 32);
- pid += i << 22;
- break;
- }
-
- nl_socket_set_local_port(handle, pid);
-
- return handle;
-}
-
-static void nl80211_handle_destroy(struct nl_handle *handle)
-{
- uint32_t port = nl_socket_get_local_port(handle);
-
- port >>= 22;
- port_bitmap[port / 32] &= ~(1 << (port % 32));
-
- nl_handle_destroy(handle);
-}
-#endif /* CONFIG_LIBNL20 */
-
#ifdef ANDROID
/* system/core/libnl_2 does not include nl_socket_set_nonblocking() */
@@ -117,11 +75,11 @@ static void nl80211_handle_destroy(struct nl_handle *handle)
#endif /* ANDROID */
-static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg)
+static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
{
- struct nl_handle *handle;
+ struct nl_sock *handle;
- handle = nl80211_handle_alloc(cb);
+ handle = nl_socket_alloc_cb(cb);
if (handle == NULL) {
wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
"callbacks (%s)", dbg);
@@ -131,7 +89,7 @@ static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg)
if (genl_connect(handle)) {
wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
"netlink (%s)", dbg);
- nl80211_handle_destroy(handle);
+ nl_socket_free(handle);
return NULL;
}
@@ -139,11 +97,11 @@ static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg)
}
-static void nl_destroy_handles(struct nl_handle **handle)
+static void nl_destroy_handles(struct nl_sock **handle)
{
if (*handle == NULL)
return;
- nl80211_handle_destroy(*handle);
+ nl_socket_free(*handle);
*handle = NULL;
}
@@ -154,11 +112,10 @@ static void nl_destroy_handles(struct nl_handle **handle)
#define ELOOP_SOCKET_INVALID (intptr_t) 0x88888889ULL
#endif
-static void nl80211_register_eloop_read(struct nl_handle **handle,
+static void nl80211_register_eloop_read(struct nl_sock **handle,
eloop_sock_handler handler,
void *eloop_data, int persist)
{
-#ifdef CONFIG_LIBNL20
/*
* libnl uses a pretty small buffer (32 kB that gets converted to 64 kB)
* by default. It is possible to hit that limit in some cases where
@@ -166,13 +123,15 @@ static void nl80211_register_eloop_read(struct nl_handle **handle,
* to hostapd and STA entry deletion. Try to increase the buffer to make
* this less likely to occur.
*/
- if (nl_socket_set_buffer_size(*handle, 262144, 0) < 0) {
+ int err;
+
+ err = nl_socket_set_buffer_size(*handle, 262144, 0);
+ if (err < 0) {
wpa_printf(MSG_DEBUG,
"nl80211: Could not set nl_socket RX buffer size: %s",
- strerror(errno));
+ nl_geterror(err));
/* continue anyway with the default (smaller) buffer */
}
-#endif /* CONFIG_LIBNL20 */
nl_socket_set_nonblocking(*handle);
eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
@@ -183,7 +142,7 @@ static void nl80211_register_eloop_read(struct nl_handle **handle,
}
-static void nl80211_destroy_eloop_handle(struct nl_handle **handle, int persist)
+static void nl80211_destroy_eloop_handle(struct nl_sock **handle, int persist)
{
if (!persist)
*handle = (void *) (((intptr_t) *handle) ^
@@ -206,7 +165,8 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
const char *driver_params);
static int nl80211_send_frame_cmd(struct i802_bss *bss,
unsigned int freq, unsigned int wait,
- const u8 *buf, size_t buf_len, u64 *cookie,
+ const u8 *buf, size_t buf_len,
+ int save_cookie,
int no_cck, int no_ack, int offchanok,
const u16 *csa_offs, size_t csa_offs_len);
static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
@@ -391,7 +351,7 @@ static void nl80211_nlmsg_clear(struct nl_msg *msg)
static int send_and_recv(struct nl80211_global *global,
- struct nl_handle *nl_handle, struct nl_msg *msg,
+ struct nl_sock *nl_handle, struct nl_msg *msg,
int (*valid_handler)(struct nl_msg *, void *),
void *valid_data)
{
@@ -416,8 +376,16 @@ static int send_and_recv(struct nl80211_global *global,
NETLINK_CAP_ACK, &opt, sizeof(opt));
err = nl_send_auto_complete(nl_handle, msg);
- if (err < 0)
+ if (err < 0) {
+ wpa_printf(MSG_INFO,
+ "nl80211: nl_send_auto_complete() failed: %s",
+ nl_geterror(err));
+ /* Need to convert libnl error code to an errno value. For now,
+ * just hardcode this to EBADF; the real error reason is shown
+ * in that error print above. */
+ err = -EBADF;
goto out;
+ }
err = 1;
@@ -431,10 +399,24 @@ static int send_and_recv(struct nl80211_global *global,
while (err > 0) {
int res = nl_recvmsgs(nl_handle, cb);
- if (res < 0) {
+
+ if (res == -NLE_DUMP_INTR) {
+ /* Most likely one of the nl80211 dump routines hit a
+ * case where internal results changed while the dump
+ * was being sent. The most common known case for this
+ * is scan results fetching while associated were every
+ * received Beacon frame from the AP may end up
+ * incrementing bss_generation. This
+ * NL80211_CMD_GET_SCAN case tries again in the caller;
+ * other cases (of which there are no known common ones)
+ * will stop and return an error. */
+ wpa_printf(MSG_DEBUG, "nl80211: %s; convert to -EAGAIN",
+ nl_geterror(res));
+ err = -EAGAIN;
+ } else if (res < 0) {
wpa_printf(MSG_INFO,
- "nl80211: %s->nl_recvmsgs failed: %d",
- __func__, res);
+ "nl80211: %s->nl_recvmsgs failed: %d (%s)",
+ __func__, res, nl_geterror(res));
}
}
out:
@@ -1369,12 +1351,25 @@ int nl80211_get_assoc_ssid(struct wpa_driver_nl80211_data *drv, u8 *ssid)
struct nl_msg *msg;
int ret;
struct nl80211_get_assoc_freq_arg arg;
+ int count = 0;
+try_again:
msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
os_memset(&arg, 0, sizeof(arg));
arg.drv = drv;
ret = send_and_recv_msgs(drv, msg, nl80211_get_assoc_freq_handler,
&arg);
+ if (ret == -EAGAIN) {
+ count++;
+ if (count >= 10) {
+ wpa_printf(MSG_INFO,
+ "nl80211: Failed to receive consistent scan result dump for get_assoc_ssid");
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Failed to receive consistent scan result dump for get_assoc_ssid - try again");
+ goto try_again;
+ }
+ }
if (ret == 0) {
os_memcpy(ssid, arg.assoc_ssid, arg.assoc_ssid_len);
return arg.assoc_ssid_len;
@@ -1390,12 +1385,25 @@ unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
struct nl_msg *msg;
int ret;
struct nl80211_get_assoc_freq_arg arg;
+ int count = 0;
+try_again:
msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
os_memset(&arg, 0, sizeof(arg));
arg.drv = drv;
ret = send_and_recv_msgs(drv, msg, nl80211_get_assoc_freq_handler,
&arg);
+ if (ret == -EAGAIN) {
+ count++;
+ if (count >= 10) {
+ wpa_printf(MSG_INFO,
+ "nl80211: Failed to receive consistent scan result dump for get_assoc_freq");
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Failed to receive consistent scan result dump for get_assoc_freq - try again");
+ goto try_again;
+ }
+ }
if (ret == 0) {
unsigned int freq = drv->nlmode == NL80211_IFTYPE_ADHOC ?
arg.ibss_freq : arg.assoc_freq;
@@ -1733,7 +1741,7 @@ static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
if (ret < 0) {
wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
"membership for scan events: %d (%s)",
- ret, strerror(-ret));
+ ret, nl_geterror(ret));
goto err;
}
@@ -1743,7 +1751,7 @@ static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
if (ret < 0) {
wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
"membership for mlme events: %d (%s)",
- ret, strerror(-ret));
+ ret, nl_geterror(ret));
goto err;
}
@@ -1753,7 +1761,7 @@ static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
if (ret < 0) {
wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
"membership for regulatory events: %d (%s)",
- ret, strerror(-ret));
+ ret, nl_geterror(ret));
/* Continue without regulatory events */
}
@@ -1763,7 +1771,7 @@ static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
if (ret < 0) {
wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
"membership for vendor events: %d (%s)",
- ret, strerror(-ret));
+ ret, nl_geterror(ret));
/* Continue without vendor events */
}
@@ -1789,7 +1797,7 @@ err:
static void nl80211_check_global(struct nl80211_global *global)
{
- struct nl_handle *handle;
+ struct nl_sock *handle;
const char *groups[] = { "scan", "mlme", "regulatory", "vendor", NULL };
int ret;
unsigned int i;
@@ -1808,7 +1816,7 @@ static void nl80211_check_global(struct nl80211_global *global)
if (ret < 0) {
wpa_printf(MSG_INFO,
"nl80211: Could not re-add multicast membership for %s events: %d (%s)",
- groups[i], ret, strerror(-ret));
+ groups[i], ret, nl_geterror(ret));
}
}
}
@@ -2087,7 +2095,7 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
static int nl80211_register_frame(struct i802_bss *bss,
- struct nl_handle *nl_handle,
+ struct nl_sock *nl_handle,
u16 type, const u8 *match, size_t match_len)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -2100,7 +2108,7 @@ static int nl80211_register_frame(struct i802_bss *bss,
wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x (%s) nl_handle=%p match=%s",
type, fc2str(type), nl_handle, buf);
- if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REGISTER_ACTION)) ||
+ if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REGISTER_FRAME)) ||
nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, type) ||
nla_put(msg, NL80211_ATTR_FRAME_MATCH, match_len, match)) {
nlmsg_free(msg);
@@ -2757,7 +2765,7 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
}
if (drv->rtnl_sk)
- nl80211_handle_destroy(drv->rtnl_sk);
+ nl_socket_free(drv->rtnl_sk);
if (bss->added_bridge) {
if (linux_set_iface_flags(drv->global->ioctl_sock, bss->brname,
@@ -3003,11 +3011,8 @@ static int nl80211_set_pmk(struct wpa_driver_nl80211_data *drv,
}
-static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
- enum wpa_alg alg, const u8 *addr,
- int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
+static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
+ struct wpa_driver_set_key_params *params)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
int ifindex;
@@ -3015,6 +3020,16 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
struct nl_msg *key_msg;
int ret;
int tdls = 0;
+ const char *ifname = params->ifname;
+ enum wpa_alg alg = params->alg;
+ const u8 *addr = params->addr;
+ int key_idx = params->key_idx;
+ int set_tx = params->set_tx;
+ const u8 *seq = params->seq;
+ size_t seq_len = params->seq_len;
+ const u8 *key = params->key;
+ size_t key_len = params->key_len;
+ int vlan_id = params->vlan_id;
/* Ignore for P2P Device */
if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
@@ -3104,6 +3119,12 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
nlmsg_free(key_msg);
key_msg = NULL;
+ if (vlan_id && (drv->capa.flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
+ wpa_printf(MSG_DEBUG, "nl80211: VLAN ID %d", vlan_id);
+ if (nla_put_u16(msg, NL80211_ATTR_VLAN_ID, vlan_id))
+ goto fail;
+ }
+
ret = send_and_recv_msgs(drv, msg, NULL, key ? (void *) -1 : NULL);
if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
ret = 0;
@@ -3161,6 +3182,13 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
nlmsg_free(key_msg);
key_msg = NULL;
+ if (vlan_id && (drv->capa.flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
+ wpa_printf(MSG_DEBUG, "nl80211: set_key default - VLAN ID %d",
+ vlan_id);
+ if (nla_put_u16(msg, NL80211_ATTR_VLAN_ID, vlan_id))
+ goto fail;
+ }
+
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
if (ret == -ENOENT)
ret = 0;
@@ -3271,7 +3299,7 @@ static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
const u8 *addr, int cmd, u16 reason_code,
int local_state_change,
- struct nl_handle *nl_connect)
+ struct nl_sock *nl_connect)
{
int ret;
struct nl_msg *msg;
@@ -3300,7 +3328,7 @@ int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
u16 reason_code,
- struct nl_handle *nl_connect)
+ struct nl_sock *nl_connect)
{
int ret;
int drv_associated = drv->associated;
@@ -3332,7 +3360,7 @@ static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss,
return nl80211_leave_ibss(drv, 1);
}
if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
- struct nl_handle *nl_connect = NULL;
+ struct nl_sock *nl_connect = NULL;
if (bss->use_nl_connect)
nl_connect = bss->nl_connect;
@@ -3450,6 +3478,7 @@ static int wpa_driver_nl80211_authenticate(
enum nl80211_iftype nlmode;
int count = 0;
int is_retry;
+ struct wpa_driver_set_key_params p;
nl80211_unmask_11b_rates(bss);
@@ -3478,14 +3507,17 @@ retry:
if (!msg)
goto fail;
+ os_memset(&p, 0, sizeof(p));
+ p.ifname = bss->ifname;
+ p.alg = WPA_ALG_WEP;
for (i = 0; i < 4; i++) {
if (!params->wep_key[i])
continue;
- wpa_driver_nl80211_set_key(bss->ifname, bss, WPA_ALG_WEP,
- NULL, i,
- i == params->wep_tx_keyidx, NULL, 0,
- params->wep_key[i],
- params->wep_key_len[i]);
+ p.key_idx = i;
+ p.set_tx = i == params->wep_tx_keyidx;
+ p.key = params->wep_key[i];
+ p.key_len = params->wep_key_len[i];
+ wpa_driver_nl80211_set_key(bss, &p);
if (params->wep_tx_keyidx != i)
continue;
if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
@@ -3647,80 +3679,27 @@ int wpa_driver_nl80211_authenticate_retry(struct wpa_driver_nl80211_data *drv)
}
-static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
- const void *data, size_t len,
- int encrypt, int noack,
- unsigned int freq, int no_cck,
- int offchanok, unsigned int wait_time,
- const u16 *csa_offs,
- size_t csa_offs_len)
-{
- struct wpa_driver_nl80211_data *drv = bss->drv;
- u64 cookie;
- int res;
-
- if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
- freq = nl80211_get_assoc_freq(drv);
- wpa_printf(MSG_DEBUG,
- "nl80211: send_frame - Use assoc_freq=%u for IBSS",
- freq);
- }
- if (freq == 0) {
- wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
- bss->freq);
- freq = bss->freq;
- }
-
- if (drv->use_monitor) {
- wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
- freq, bss->freq);
- return nl80211_send_monitor(drv, data, len, encrypt, noack);
- }
-
- wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
- res = nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
- &cookie, no_cck, noack, offchanok,
- csa_offs, csa_offs_len);
- if (res == 0 && !noack) {
- const struct ieee80211_mgmt *mgmt;
- u16 fc;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- fc = le_to_host16(mgmt->frame_control);
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
- WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
- wpa_printf(MSG_MSGDUMP,
- "nl80211: Update send_action_cookie from 0x%llx to 0x%llx",
- (long long unsigned int)
- drv->send_action_cookie,
- (long long unsigned int) cookie);
- drv->send_action_cookie = cookie;
- }
- }
-
- return res;
-}
-
-
static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
size_t data_len, int noack,
unsigned int freq, int no_cck,
int offchanok,
unsigned int wait_time,
const u16 *csa_offs,
- size_t csa_offs_len)
+ size_t csa_offs_len, int no_encrypt)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
struct ieee80211_mgmt *mgmt;
- int encrypt = 1;
+ int encrypt = !no_encrypt;
u16 fc;
+ int use_cookie = 1;
+ int res;
mgmt = (struct ieee80211_mgmt *) data;
fc = le_to_host16(mgmt->frame_control);
wpa_printf(MSG_DEBUG, "nl80211: send_mlme - da= " MACSTR
- " noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u fc=0x%x (%s) nlmode=%d",
+ " noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u no_encrypt=%d fc=0x%x (%s) nlmode=%d",
MAC2STR(mgmt->da), noack, freq, no_cck, offchanok, wait_time,
- fc, fc2str(fc), drv->nlmode);
+ no_encrypt, fc, fc2str(fc), drv->nlmode);
if ((is_sta_interface(drv->nlmode) ||
drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
@@ -3736,9 +3715,11 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
drv->last_mgmt_freq);
freq = drv->last_mgmt_freq;
}
- return nl80211_send_frame_cmd(bss, freq, 0,
- data, data_len, NULL, 1, noack,
- 1, csa_offs, csa_offs_len);
+ wait_time = 0;
+ use_cookie = 0;
+ no_cck = 1;
+ offchanok = 1;
+ goto send_frame_cmd;
}
if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
@@ -3747,13 +3728,9 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
bss->freq);
freq = bss->freq;
}
- return nl80211_send_frame_cmd(bss, freq,
- (int) freq == bss->freq ? 0 :
- wait_time,
- data, data_len,
- &drv->send_action_cookie,
- no_cck, noack, offchanok,
- csa_offs, csa_offs_len);
+ if ((int) freq == bss->freq)
+ wait_time = 0;
+ goto send_frame_cmd;
}
if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
@@ -3770,11 +3747,49 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
encrypt = 0;
}
- wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
- return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
- noack, freq, no_cck, offchanok,
- wait_time, csa_offs,
- csa_offs_len);
+ if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
+ freq = nl80211_get_assoc_freq(drv);
+ wpa_printf(MSG_DEBUG,
+ "nl80211: send_mlme - Use assoc_freq=%u for IBSS",
+ freq);
+ }
+ if (freq == 0) {
+ wpa_printf(MSG_DEBUG, "nl80211: send_mlme - Use bss->freq=%u",
+ bss->freq);
+ freq = bss->freq;
+ }
+
+ if (drv->use_monitor) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
+ freq, bss->freq);
+ return nl80211_send_monitor(drv, data, data_len, encrypt,
+ noack);
+ }
+
+ if (noack || WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
+ WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
+ use_cookie = 0;
+send_frame_cmd:
+#ifdef CONFIG_TESTING_OPTIONS
+ if (no_encrypt && !encrypt && !drv->use_monitor) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Request to send an unencrypted frame - use a monitor interface for this");
+ if (nl80211_create_monitor_interface(drv) < 0)
+ return -1;
+ res = nl80211_send_monitor(drv, data, data_len, encrypt,
+ noack);
+ nl80211_remove_monitor_interface(drv);
+ return res;
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+
+ wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame_cmd");
+ res = nl80211_send_frame_cmd(bss, freq, wait_time, data, data_len,
+ use_cookie, no_cck, noack, offchanok,
+ csa_offs, csa_offs_len);
+
+ return res;
}
@@ -5101,6 +5116,40 @@ static void nl80211_teardown_ap(struct i802_bss *bss)
}
+static int nl80211_tx_control_port(void *priv, const u8 *dest,
+ u16 proto, const u8 *buf, size_t len,
+ int no_encrypt)
+{
+ struct i802_bss *bss = priv;
+ struct nl_msg *msg;
+ int ret;
+
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Send over control port dest=" MACSTR
+ " proto=0x%04x len=%u no_encrypt=%d",
+ MAC2STR(dest), proto, (unsigned int) len, no_encrypt);
+
+ msg = nl80211_bss_msg(bss, 0, NL80211_CMD_CONTROL_PORT_FRAME);
+ if (!msg ||
+ nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dest) ||
+ nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
+ (no_encrypt &&
+ nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))) {
+ nlmsg_free(msg);
+ return -ENOBUFS;
+ }
+
+ ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
+ if (ret)
+ wpa_printf(MSG_DEBUG,
+ "nl80211: tx_control_port failed: ret=%d (%s)",
+ ret, strerror(ret));
+
+ return ret;
+}
+
+
static int nl80211_send_eapol_data(struct i802_bss *bss,
const u8 *addr, const u8 *data,
size_t data_len)
@@ -5143,6 +5192,10 @@ static int wpa_driver_nl80211_hapd_send_eapol(
int res;
int qos = flags & WPA_STA_WMM;
+ if (drv->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT)
+ return nl80211_tx_control_port(bss, addr, ETH_P_EAPOL,
+ data, data_len, !encrypt);
+
if (drv->device_ap_sme || !drv->use_monitor)
return nl80211_send_eapol_data(bss, addr, data, data_len);
@@ -5183,12 +5236,11 @@ static int wpa_driver_nl80211_hapd_send_eapol(
pos += 2;
memcpy(pos, data, data_len);
- res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0,
- 0, 0, 0, 0, NULL, 0);
+ res = nl80211_send_monitor(drv, hdr, len, encrypt, 0);
if (res < 0) {
wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
"failed: %d (%s)",
- (unsigned long) len, errno, strerror(errno));
+ (unsigned long) len, res, strerror(res));
}
os_free(hdr);
@@ -5775,7 +5827,7 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
static int wpa_driver_nl80211_try_connect(
struct wpa_driver_nl80211_data *drv,
struct wpa_driver_associate_params *params,
- struct nl_handle *nl_connect)
+ struct nl_sock *nl_connect)
{
struct nl_msg *msg;
enum nl80211_auth_type type;
@@ -5866,7 +5918,7 @@ fail:
static int wpa_driver_nl80211_connect(
struct wpa_driver_nl80211_data *drv,
struct wpa_driver_associate_params *params,
- struct nl_handle *nl_connect)
+ struct nl_sock *nl_connect)
{
int ret;
@@ -5914,7 +5966,7 @@ static int wpa_driver_nl80211_associate(
if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
enum nl80211_iftype nlmode = params->p2p ?
NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
- struct nl_handle *nl_connect = NULL;
+ struct nl_sock *nl_connect = NULL;
if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
return -1;
@@ -6646,6 +6698,8 @@ static int i802_set_sta_vlan(struct i802_bss *bss, const u8 *addr,
MAC2STR(addr), ifname, if_nametoindex(ifname), vlan_id);
if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
+ ((drv->capa.flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD) &&
+ nla_put_u16(msg, NL80211_ATTR_VLAN_ID, vlan_id)) ||
nla_put_u32(msg, NL80211_ATTR_STA_VLAN, if_nametoindex(ifname))) {
nlmsg_free(msg);
return -ENOBUFS;
@@ -6718,7 +6772,7 @@ static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
IEEE80211_HDRLEN +
sizeof(mgmt.u.deauth), 0, 0, 0, 0,
- 0, NULL, 0);
+ 0, NULL, 0, 0);
}
@@ -6745,7 +6799,7 @@ static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
IEEE80211_HDRLEN +
sizeof(mgmt.u.disassoc), 0, 0, 0, 0,
- 0, NULL, 0);
+ 0, NULL, 0, 0);
}
@@ -6993,10 +7047,14 @@ static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
ifname, brname);
if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
- wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
- "into bridge %s: %s",
+ wpa_printf(MSG_WARNING,
+ "nl80211: Failed to add interface %s into bridge %s: %s",
ifname, brname, strerror(errno));
- return -1;
+ /* Try to continue without the interface being in a bridge. This
+ * may be needed for some cases, e.g., with Open vSwitch, where
+ * an external component will need to handle bridge
+ * configuration. */
+ return 0;
}
bss->added_if_into_bridge = 1;
@@ -7074,15 +7132,18 @@ static void *i802_init(struct hostapd_data *hapd,
#ifdef CONFIG_LIBNL3_ROUTE
if (bss->added_if_into_bridge || bss->already_in_bridge) {
+ int err;
+
drv->rtnl_sk = nl_socket_alloc();
if (drv->rtnl_sk == NULL) {
wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
goto failed;
}
- if (nl_connect(drv->rtnl_sk, NETLINK_ROUTE)) {
+ err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
+ if (err) {
wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
- strerror(errno));
+ nl_geterror(err));
goto failed;
}
}
@@ -7456,7 +7517,7 @@ static int cookie_handler(struct nl_msg *msg, void *arg)
static int nl80211_send_frame_cmd(struct i802_bss *bss,
unsigned int freq, unsigned int wait,
const u8 *buf, size_t buf_len,
- u64 *cookie_out, int no_cck, int no_ack,
+ int save_cookie, int no_cck, int no_ack,
int offchanok, const u16 *csa_offs,
size_t csa_offs_len)
{
@@ -7495,22 +7556,22 @@ static int nl80211_send_frame_cmd(struct i802_bss *bss,
"cookie 0x%llx", no_ack ? " (no ACK)" : "",
(long long unsigned int) cookie);
- if (cookie_out)
- *cookie_out = no_ack ? (u64) -1 : cookie;
+ if (save_cookie)
+ drv->send_frame_cookie = no_ack ? (u64) -1 : cookie;
- if (drv->num_send_action_cookies == MAX_SEND_ACTION_COOKIES) {
+ if (drv->num_send_frame_cookies == MAX_SEND_FRAME_COOKIES) {
wpa_printf(MSG_DEBUG,
- "nl80211: Drop oldest pending send action cookie 0x%llx",
+ "nl80211: Drop oldest pending send frame cookie 0x%llx",
(long long unsigned int)
- drv->send_action_cookies[0]);
- os_memmove(&drv->send_action_cookies[0],
- &drv->send_action_cookies[1],
- (MAX_SEND_ACTION_COOKIES - 1) *
+ drv->send_frame_cookies[0]);
+ os_memmove(&drv->send_frame_cookies[0],
+ &drv->send_frame_cookies[1],
+ (MAX_SEND_FRAME_COOKIES - 1) *
sizeof(u64));
- drv->num_send_action_cookies--;
+ drv->num_send_frame_cookies--;
}
- drv->send_action_cookies[drv->num_send_action_cookies] = cookie;
- drv->num_send_action_cookies++;
+ drv->send_frame_cookies[drv->num_send_frame_cookies] = cookie;
+ drv->num_send_frame_cookies++;
}
fail:
@@ -7531,10 +7592,14 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
int ret = -1;
u8 *buf;
struct ieee80211_hdr *hdr;
+ int offchanok = 1;
+
+ if (is_ap_interface(drv->nlmode) && (int) freq == bss->freq)
+ offchanok = 0;
wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
- "freq=%u MHz wait=%d ms no_cck=%d)",
- drv->ifindex, freq, wait_time, no_cck);
+ "freq=%u MHz wait=%d ms no_cck=%d offchanok=%d)",
+ drv->ifindex, freq, wait_time, no_cck, offchanok);
buf = os_zalloc(24 + data_len);
if (buf == NULL)
@@ -7560,13 +7625,12 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
(int) freq == bss->freq || drv->device_ap_sme ||
!drv->use_monitor))
ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
- 0, freq, no_cck, 1,
- wait_time, NULL, 0);
+ 0, freq, no_cck, offchanok,
+ wait_time, NULL, 0, 0);
else
ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
24 + data_len,
- &drv->send_action_cookie,
- no_cck, 0, 1, NULL, 0);
+ 1, no_cck, 0, offchanok, NULL, 0);
os_free(buf);
return ret;
@@ -7602,19 +7666,19 @@ static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
u64 cookie;
/* Cancel the last pending TX cookie */
- nl80211_frame_wait_cancel(bss, drv->send_action_cookie);
+ nl80211_frame_wait_cancel(bss, drv->send_frame_cookie);
/*
* Cancel the other pending TX cookies, if any. This is needed since
* the driver may keep a list of all pending offchannel TX operations
* and free up the radio only once they have expired or cancelled.
*/
- for (i = drv->num_send_action_cookies; i > 0; i--) {
- cookie = drv->send_action_cookies[i - 1];
- if (cookie != drv->send_action_cookie)
+ for (i = drv->num_send_frame_cookies; i > 0; i--) {
+ cookie = drv->send_frame_cookies[i - 1];
+ if (cookie != drv->send_frame_cookie)
nl80211_frame_wait_cancel(bss, cookie);
}
- drv->num_send_action_cookies = 0;
+ drv->num_send_frame_cookies = 0;
}
@@ -7934,15 +7998,6 @@ static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
}
-static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
- int encrypt)
-{
- struct i802_bss *bss = priv;
- return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
- 0, 0, 0, 0, NULL, 0);
-}
-
-
static int nl80211_set_param(void *priv, const char *param)
{
struct i802_bss *bss = priv;
@@ -7977,6 +8032,9 @@ static int nl80211_set_param(void *priv, const char *param)
drv->test_use_roc_tx = 1;
}
+ if (os_strstr(param, "control_port=0"))
+ drv->capa.flags &= ~WPA_DRIVER_FLAGS_CONTROL_PORT;
+
return 0;
}
@@ -8397,7 +8455,7 @@ static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0,
- 0, 0, NULL, 0) < 0)
+ 0, 0, NULL, 0, 0) < 0)
wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
"send poll frame");
}
@@ -8671,15 +8729,12 @@ nl80211_tdls_disable_channel_switch(void *priv, const u8 *addr)
#endif /* CONFIG TDLS */
-static int driver_nl80211_set_key(const char *ifname, void *priv,
- enum wpa_alg alg, const u8 *addr,
- int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
+static int driver_nl80211_set_key(void *priv,
+ struct wpa_driver_set_key_params *params)
{
struct i802_bss *bss = priv;
- return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx,
- set_tx, seq, seq_len, key, key_len);
+
+ return wpa_driver_nl80211_set_key(bss, params);
}
@@ -8738,12 +8793,13 @@ static int driver_nl80211_if_remove(void *priv, enum wpa_driver_if_type type,
static int driver_nl80211_send_mlme(void *priv, const u8 *data,
size_t data_len, int noack,
unsigned int freq,
- const u16 *csa_offs, size_t csa_offs_len)
+ const u16 *csa_offs, size_t csa_offs_len,
+ int no_encrypt)
{
struct i802_bss *bss = priv;
return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
freq, 0, 0, 0, csa_offs,
- csa_offs_len);
+ csa_offs_len, no_encrypt);
}
@@ -9394,6 +9450,46 @@ static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set,
}
+static int get_wowlan_handler(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *tb[NL80211_ATTR_MAX + 1];
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ int *wowlan_enabled = arg;
+
+ nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL);
+
+ *wowlan_enabled = !!tb[NL80211_ATTR_WOWLAN_TRIGGERS];
+
+ return NL_SKIP;
+}
+
+
+static int nl80211_get_wowlan(void *priv)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ int wowlan_enabled;
+ int ret;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Getting wowlan status");
+
+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_WOWLAN);
+
+ ret = send_and_recv_msgs(drv, msg, get_wowlan_handler, &wowlan_enabled);
+ if (ret) {
+ wpa_printf(MSG_DEBUG, "nl80211: Getting wowlan status failed");
+ return 0;
+ }
+
+ wpa_printf(MSG_DEBUG, "nl80211: wowlan is %s",
+ wowlan_enabled ? "enabled" : "disabled");
+
+ return wowlan_enabled;
+}
+
+
static int nl80211_set_wowlan(void *priv,
const struct wowlan_triggers *triggers)
{
@@ -9937,7 +10033,7 @@ static int wpa_driver_br_add_ip_neigh(void *priv, u8 version,
if (res) {
wpa_printf(MSG_DEBUG,
"nl80211: Adding bridge ip neigh failed: %s",
- strerror(errno));
+ nl_geterror(res));
}
errout:
if (nl_lladdr)
@@ -10013,7 +10109,7 @@ static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version,
if (res) {
wpa_printf(MSG_DEBUG,
"nl80211: Deleting bridge ip neigh failed: %s",
- strerror(errno));
+ nl_geterror(res));
}
errout:
if (nl_ipaddr)
@@ -10157,6 +10253,48 @@ static int hw_mode_to_qca_acs(enum hostapd_hw_mode hw_mode)
}
+static int add_acs_ch_list(struct nl_msg *msg, const int *freq_list)
+{
+ int num_channels = 0, num_freqs;
+ u8 *ch_list;
+ enum hostapd_hw_mode hw_mode;
+ int ret = 0;
+ int i;
+
+ if (!freq_list)
+ return 0;
+
+ num_freqs = int_array_len(freq_list);
+ ch_list = os_malloc(sizeof(u8) * num_freqs);
+ if (!ch_list)
+ return -1;
+
+ for (i = 0; i < num_freqs; i++) {
+ const int freq = freq_list[i];
+
+ if (freq == 0)
+ break;
+ /* Send 2.4 GHz and 5 GHz channels with
+ * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST to maintain backwards
+ * compatibility.
+ */
+ if (!(freq >= 2412 && freq <= 2484) &&
+ !(freq >= 5180 && freq <= 5900))
+ continue;
+ hw_mode = ieee80211_freq_to_chan(freq, &ch_list[num_channels]);
+ if (hw_mode != NUM_HOSTAPD_MODES)
+ num_channels++;
+ }
+
+ if (num_channels)
+ ret = nla_put(msg, QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST,
+ num_channels, ch_list);
+
+ os_free(ch_list);
+ return ret;
+}
+
+
static int add_acs_freq_list(struct nl_msg *msg, const int *freq_list)
{
int i, len, ret;
@@ -10204,9 +10342,7 @@ static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED)) ||
nla_put_u16(msg, QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH,
params->ch_width) ||
- (params->ch_list_len &&
- nla_put(msg, QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST, params->ch_list_len,
- params->ch_list)) ||
+ add_acs_ch_list(msg, params->freq_list) ||
add_acs_freq_list(msg, params->freq_list)) {
nlmsg_free(msg);
return -ENOBUFS;
@@ -10214,15 +10350,15 @@ static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
nla_nest_end(msg, data);
wpa_printf(MSG_DEBUG,
- "nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d VHT: %d BW: %d CH_LIST_LEN: %u",
+ "nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d VHT: %d BW: %d",
params->hw_mode, params->ht_enabled, params->ht40_enabled,
- params->vht_enabled, params->ch_width, params->ch_list_len);
+ params->vht_enabled, params->ch_width);
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
if (ret) {
wpa_printf(MSG_DEBUG,
"nl80211: Failed to invoke driver ACS function: %s",
- strerror(errno));
+ strerror(-ret));
}
return ret;
}
@@ -10269,7 +10405,7 @@ static int nl80211_set_band(void *priv, enum set_band band)
if (ret) {
wpa_printf(MSG_DEBUG,
"nl80211: Driver setband function failed: %s",
- strerror(errno));
+ strerror(-ret));
}
return ret;
}
@@ -11051,8 +11187,8 @@ static int nl80211_send_external_auth_status(void *priv,
int ret = -1;
/* External auth command/status is intended for drivers that implement
- * intenral SME but want to offload authentication processing (e.g.,
- * SAE) to hostapd/wpa_supplicant. Do nott send the status to drivers
+ * internal SME but want to offload authentication processing (e.g.,
+ * SAE) to hostapd/wpa_supplicant. Do not send the status to drivers
* which do not support AP SME or use wpa_supplicant/hostapd SME.
*/
if ((is_ap_interface(drv->nlmode) && !bss->drv->device_ap_sme) ||
@@ -11160,6 +11296,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.get_hw_feature_data = nl80211_get_hw_feature_data,
.sta_add = wpa_driver_nl80211_sta_add,
.sta_remove = driver_nl80211_sta_remove,
+ .tx_control_port = nl80211_tx_control_port,
.hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
.sta_set_flags = wpa_driver_nl80211_sta_set_flags,
.sta_set_airtime_weight = driver_nl80211_sta_set_airtime_weight,
@@ -11190,7 +11327,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.signal_monitor = nl80211_signal_monitor,
.signal_poll = nl80211_signal_poll,
.channel_info = nl80211_channel_info,
- .send_frame = nl80211_send_frame,
.set_param = nl80211_set_param,
.get_radio_name = nl80211_get_radio_name,
.add_pmkid = nl80211_add_pmkid,
@@ -11225,6 +11361,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
#endif /* ANDROID */
.vendor_cmd = nl80211_vendor_cmd,
.set_qos_map = nl80211_set_qos_map,
+ .get_wowlan = nl80211_get_wowlan,
.set_wowlan = nl80211_set_wowlan,
.set_mac_addr = nl80211_set_mac_addr,
#ifdef CONFIG_MESH
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index 716504c..e4d81b1 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -17,13 +17,6 @@
#include "utils/list.h"
#include "driver.h"
-#ifdef CONFIG_LIBNL20
-/* libnl 2.0 compatibility code */
-#define nl_handle nl_sock
-#define nl80211_handle_alloc nl_socket_alloc_cb
-#define nl80211_handle_destroy nl_socket_free
-#endif /* CONFIG_LIBNL20 */
-
struct nl80211_global {
void *ctx;
struct dl_list interfaces;
@@ -32,11 +25,11 @@ struct nl80211_global {
int if_add_wdevid_set;
struct netlink_data *netlink;
struct nl_cb *nl_cb;
- struct nl_handle *nl;
+ struct nl_sock *nl;
int nl80211_id;
int ioctl_sock; /* socket for ioctl() use */
- struct nl_handle *nl_event;
+ struct nl_sock *nl_event;
};
struct nl80211_wiphy_data {
@@ -44,7 +37,7 @@ struct nl80211_wiphy_data {
struct dl_list bsss;
struct dl_list drvs;
- struct nl_handle *nl_beacons;
+ struct nl_sock *nl_beacons;
struct nl_cb *nl_cb;
int wiphy_idx;
@@ -75,7 +68,7 @@ struct i802_bss {
int if_dynamic;
void *ctx;
- struct nl_handle *nl_preq, *nl_mgmt, *nl_connect;
+ struct nl_sock *nl_preq, *nl_mgmt, *nl_connect;
struct nl_cb *nl_cb;
struct nl80211_wiphy_data *wiphy_data;
@@ -176,10 +169,10 @@ struct wpa_driver_nl80211_data {
u64 vendor_scan_cookie;
u64 remain_on_chan_cookie;
- u64 send_action_cookie;
-#define MAX_SEND_ACTION_COOKIES 20
- u64 send_action_cookies[MAX_SEND_ACTION_COOKIES];
- unsigned int num_send_action_cookies;
+ u64 send_frame_cookie;
+#define MAX_SEND_FRAME_COOKIES 20
+ u64 send_frame_cookies[MAX_SEND_FRAME_COOKIES];
+ unsigned int num_send_frame_cookies;
unsigned int last_mgmt_freq;
@@ -192,7 +185,7 @@ struct wpa_driver_nl80211_data {
int eapol_sock; /* socket for EAPOL frames */
- struct nl_handle *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
+ struct nl_sock *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
struct drv_nl80211_if_info default_if_indices[16];
struct drv_nl80211_if_info *if_indices;
@@ -256,7 +249,7 @@ int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
const u8 *addr, int cmd, u16 reason_code,
int local_state_change,
- struct nl_handle *nl_connect);
+ struct nl_sock *nl_connect);
int nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv);
void nl80211_remove_monitor_interface(struct wpa_driver_nl80211_data *drv);
@@ -275,7 +268,7 @@ int process_bss_event(struct nl_msg *msg, void *arg);
const char * nl80211_iftype_str(enum nl80211_iftype mode);
#ifdef ANDROID
-int android_nl_socket_set_nonblocking(struct nl_handle *handle);
+int android_nl_socket_set_nonblocking(struct nl_sock *handle);
int android_pno_start(struct i802_bss *bss,
struct wpa_driver_scan_params *params);
int android_pno_stop(struct i802_bss *bss);
diff --git a/src/drivers/driver_nl80211_android.c b/src/drivers/driver_nl80211_android.c
index ba47888..9431a12 100644
--- a/src/drivers/driver_nl80211_android.c
+++ b/src/drivers/driver_nl80211_android.c
@@ -182,9 +182,7 @@ int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
#endif /* ANDROID_P2P */
-int android_nl_socket_set_nonblocking(struct nl_handle *handle)
+int android_nl_socket_set_nonblocking(struct nl_sock *handle)
{
return fcntl(nl_socket_get_fd(handle), F_SETFL, O_NONBLOCK);
}
-
-
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index d8630bb..6b17d28 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -433,6 +433,14 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
if (ext_feature_isset(ext_features, len,
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
capa->flags |= WPA_DRIVER_FLAGS_FTM_RESPONDER;
+
+ if (ext_feature_isset(ext_features, len,
+ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
+ capa->flags |= WPA_DRIVER_FLAGS_CONTROL_PORT;
+
+ if (ext_feature_isset(ext_features, len,
+ NL80211_EXT_FEATURE_VLAN_OFFLOAD))
+ capa->flags |= WPA_DRIVER_FLAGS_VLAN_OFFLOAD;
}
@@ -1365,12 +1373,18 @@ static void phy_info_freq(struct hostapd_hw_modes *mode,
struct nlattr *tb_freq[])
{
u8 channel;
+
+ os_memset(chan, 0, sizeof(*chan));
chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
chan->flag = 0;
chan->allowed_bw = ~0;
chan->dfs_cac_ms = 0;
if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
chan->chan = channel;
+ else
+ wpa_printf(MSG_DEBUG,
+ "nl80211: No channel number found for frequency %u MHz",
+ chan->freq);
if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
chan->flag |= HOSTAPD_CHAN_DISABLED;
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 7c16330..8327644 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -524,6 +524,10 @@ static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
break;
case CHAN_WIDTH_UNKNOWN:
case CHAN_WIDTH_80P80:
+ case CHAN_WIDTH_2160:
+ case CHAN_WIDTH_4320:
+ case CHAN_WIDTH_6480:
+ case CHAN_WIDTH_8640:
/* FIXME: implement this */
return 0;
}
@@ -690,12 +694,12 @@ static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
return;
cookie_val = nla_get_u64(cookie);
- wpa_printf(MSG_DEBUG, "nl80211: Action TX status:"
- " cookie=0x%llx%s (ack=%d)",
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Frame TX status: cookie=0x%llx%s (ack=%d)",
(long long unsigned int) cookie_val,
- cookie_val == drv->send_action_cookie ?
+ cookie_val == drv->send_frame_cookie ?
" (match)" : " (unknown)", ack != NULL);
- if (cookie_val != drv->send_action_cookie)
+ if (cookie_val != drv->send_frame_cookie)
return;
}
@@ -1736,30 +1740,61 @@ static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
}
+static unsigned int chan_2ghz_or_5ghz_to_freq(u8 chan)
+{
+ if (chan >= 1 && chan <= 13)
+ return 2407 + 5 * chan;
+ if (chan == 14)
+ return 2484;
+ if (chan >= 36 && chan <= 169)
+ return 5000 + 5 * chan;
+
+ return 0;
+}
+
+
static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
const u8 *data, size_t len)
{
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
union wpa_event_data event;
+ u8 chan;
wpa_printf(MSG_DEBUG,
"nl80211: ACS channel selection vendor event received");
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX,
(struct nlattr *) data, len, NULL) ||
- !tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL] ||
- !tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL])
+ (!tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY] &&
+ !tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]) ||
+ (!tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY] &&
+ !tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]))
return;
os_memset(&event, 0, sizeof(event));
- event.acs_selected_channels.pri_channel =
- nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
- event.acs_selected_channels.sec_channel =
- nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
+ if (tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]) {
+ event.acs_selected_channels.pri_freq = nla_get_u32(
+ tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]);
+ } else {
+ chan = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
+ event.acs_selected_channels.pri_freq =
+ chan_2ghz_or_5ghz_to_freq(chan);
+ }
+
+ if (tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]) {
+ event.acs_selected_channels.sec_freq = nla_get_u32(
+ tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]);
+ } else {
+ chan = nla_get_u8(
+ tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
+ event.acs_selected_channels.sec_freq =
+ chan_2ghz_or_5ghz_to_freq(chan);
+ }
+
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
event.acs_selected_channels.vht_seg0_center_ch =
nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
- if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
+ if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL])
event.acs_selected_channels.vht_seg1_center_ch =
nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH])
@@ -1780,9 +1815,9 @@ static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
}
wpa_printf(MSG_INFO,
- "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
- event.acs_selected_channels.pri_channel,
- event.acs_selected_channels.sec_channel,
+ "nl80211: ACS Results: PFreq: %d SFreq: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
+ event.acs_selected_channels.pri_freq,
+ event.acs_selected_channels.sec_freq,
event.acs_selected_channels.ch_width,
event.acs_selected_channels.vht_seg0_center_ch,
event.acs_selected_channels.vht_seg1_center_ch,
@@ -2413,6 +2448,18 @@ static void nl80211_sta_opmode_change_event(struct wpa_driver_nl80211_data *drv,
}
+static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv,
+ struct nlattr **tb)
+{
+ if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_FRAME])
+ return;
+
+ drv_event_eapol_rx(drv->ctx, nla_data(tb[NL80211_ATTR_MAC]),
+ nla_data(tb[NL80211_ATTR_FRAME]),
+ nla_len(tb[NL80211_ATTR_FRAME]));
+}
+
+
static void do_process_drv_event(struct i802_bss *bss, int cmd,
struct nlattr **tb)
{
@@ -2628,6 +2675,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
case NL80211_CMD_UPDATE_OWE_INFO:
mlme_event_dh_event(drv, bss, tb);
break;
+ case NL80211_CMD_CONTROL_PORT_FRAME:
+ nl80211_control_port_frame(drv, tb);
+ break;
default:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
"(cmd=%d)", cmd);
diff --git a/src/drivers/driver_nl80211_monitor.c b/src/drivers/driver_nl80211_monitor.c
index f25cd79..7ff55f1 100644
--- a/src/drivers/driver_nl80211_monitor.c
+++ b/src/drivers/driver_nl80211_monitor.c
@@ -71,6 +71,9 @@ static void handle_frame(struct wpa_driver_nl80211_data *drv,
u16 fc;
union wpa_event_data event;
+ if (!drv->use_monitor)
+ return;
+
hdr = (struct ieee80211_hdr *) buf;
fc = le_to_host16(hdr->frame_control);
diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c
index 9afa5b3..413d6f7 100644
--- a/src/drivers/driver_nl80211_scan.c
+++ b/src/drivers/driver_nl80211_scan.c
@@ -928,7 +928,9 @@ nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
struct wpa_scan_results *res;
int ret;
struct nl80211_bss_info_arg arg;
+ int count = 0;
+try_again:
res = os_zalloc(sizeof(*res));
if (res == NULL)
return NULL;
@@ -941,6 +943,18 @@ nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
arg.drv = drv;
arg.res = res;
ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
+ if (ret == -EAGAIN) {
+ count++;
+ if (count >= 10) {
+ wpa_printf(MSG_INFO,
+ "nl80211: Failed to receive consistent scan result dump");
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Failed to receive consistent scan result dump - try again");
+ wpa_scan_results_free(res);
+ goto try_again;
+ }
+ }
if (ret == 0) {
struct nl80211_noise_info info;
diff --git a/src/drivers/driver_none.c b/src/drivers/driver_none.c
index 6ff3eae..ccd2d9d 100644
--- a/src/drivers/driver_none.c
+++ b/src/drivers/driver_none.c
@@ -43,13 +43,6 @@ static void none_driver_hapd_deinit(void *priv)
}
-static int none_driver_send_ether(void *priv, const u8 *dst, const u8 *src,
- u16 proto, const u8 *data, size_t data_len)
-{
- return 0;
-}
-
-
static void * none_driver_init(void *ctx, const char *ifname)
{
struct none_driver_data *drv;
@@ -79,7 +72,6 @@ const struct wpa_driver_ops wpa_driver_none_ops = {
.desc = "no driver (RADIUS server/WPS ER)",
.hapd_init = none_driver_hapd_init,
.hapd_deinit = none_driver_hapd_deinit,
- .send_ether = none_driver_send_ether,
.init = none_driver_init,
.deinit = none_driver_deinit,
};
diff --git a/src/drivers/driver_openbsd.c b/src/drivers/driver_openbsd.c
index c06e75c..e0eede9 100644
--- a/src/drivers/driver_openbsd.c
+++ b/src/drivers/driver_openbsd.c
@@ -69,12 +69,13 @@ wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa)
static int
-wpa_driver_openbsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
- const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
- size_t seq_len, const u8 *key, size_t key_len)
+wpa_driver_openbsd_set_key(void *priv, struct wpa_driver_set_key_params *params)
{
struct openbsd_driver_data *drv = priv;
struct ieee80211_keyavail keyavail;
+ enum wpa_alg alg = params->alg;
+ const u8 *key = params->key;
+ size_t key_len = params->key_len;
if (alg != WPA_ALG_PMK || key_len > IEEE80211_PMK_LEN)
return -1;
diff --git a/src/drivers/driver_privsep.c b/src/drivers/driver_privsep.c
index 55cf618..807657e 100644
--- a/src/drivers/driver_privsep.c
+++ b/src/drivers/driver_privsep.c
@@ -205,14 +205,19 @@ wpa_driver_privsep_get_scan_results2(void *priv)
}
-static int wpa_driver_privsep_set_key(const char *ifname, void *priv,
- enum wpa_alg alg, const u8 *addr,
- int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
+static int wpa_driver_privsep_set_key(void *priv,
+ struct wpa_driver_set_key_params *params)
{
struct wpa_driver_privsep_data *drv = priv;
struct privsep_cmd_set_key cmd;
+ enum wpa_alg alg = params->alg;
+ const u8 *addr = params->addr;
+ int key_idx = params->key_idx;
+ int set_tx = params->set_tx;
+ const u8 *seq = params->seq;
+ size_t seq_len = params->seq_len;
+ const u8 *key = params->key;
+ size_t key_len = params->key_len;
wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d",
__func__, priv, alg, key_idx, set_tx);
diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index 32c2971..776eff7 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -1803,37 +1803,26 @@ static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg,
/**
* wpa_driver_wext_set_key - Configure encryption key
* @priv: Pointer to private wext data from wpa_driver_wext_init()
- * @priv: Private driver interface data
- * @alg: Encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP,
- * %WPA_ALG_TKIP, %WPA_ALG_CCMP); %WPA_ALG_NONE clears the key.
- * @addr: Address of the peer STA or ff:ff:ff:ff:ff:ff for
- * broadcast/default keys
- * @key_idx: key index (0..3), usually 0 for unicast keys
- * @set_tx: Configure this key as the default Tx key (only used when
- * driver does not support separate unicast/individual key
- * @seq: Sequence number/packet number, seq_len octets, the next
- * packet number to be used for in replay protection; configured
- * for Rx keys (in most cases, this is only used with broadcast
- * keys and set to zero for unicast keys)
- * @seq_len: Length of the seq, depends on the algorithm:
- * TKIP: 6 octets, CCMP: 6 octets
- * @key: Key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key,
- * 8-byte Rx Mic Key
- * @key_len: Length of the key buffer in octets (WEP: 5 or 13,
- * TKIP: 32, CCMP: 16)
+ * @params: Key parameters
* Returns: 0 on success, -1 on failure
*
* This function uses SIOCSIWENCODEEXT by default, but tries to use
* SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key.
*/
-int wpa_driver_wext_set_key(const char *ifname, void *priv, enum wpa_alg alg,
- const u8 *addr, int key_idx,
- int set_tx, const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
+static int wpa_driver_wext_set_key(void *priv,
+ struct wpa_driver_set_key_params *params)
{
struct wpa_driver_wext_data *drv = priv;
struct iwreq iwr;
int ret = 0;
+ enum wpa_alg alg = params->alg;
+ const u8 *addr = params->addr;
+ int key_idx = params->key_idx;
+ int set_tx = params->set_tx;
+ const u8 *seq = params->seq;
+ size_t seq_len = params->seq_len;
+ const u8 *key = params->key;
+ size_t key_len = params->key_len;
wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu "
"key_len=%lu",
diff --git a/src/drivers/driver_wext.h b/src/drivers/driver_wext.h
index b4b5960..6214cdf 100644
--- a/src/drivers/driver_wext.h
+++ b/src/drivers/driver_wext.h
@@ -52,10 +52,6 @@ int wpa_driver_wext_get_ssid(void *priv, u8 *ssid);
int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len);
int wpa_driver_wext_set_freq(void *priv, int freq);
int wpa_driver_wext_set_mode(void *priv, int mode);
-int wpa_driver_wext_set_key(const char *ifname, void *priv, enum wpa_alg alg,
- const u8 *addr, int key_idx,
- int set_tx, const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len);
int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params);
struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv);
diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak
index 442c59c..55a98ef 100644
--- a/src/drivers/drivers.mak
+++ b/src/drivers/drivers.mak
@@ -140,10 +140,6 @@ ifdef NEED_NETLINK
DRV_OBJS += ../src/drivers/netlink.o
endif
-ifdef NEED_LINUX_IOCTL
-DRV_OBJS += ../src/drivers/linux_ioctl.o
-endif
-
ifdef NEED_RFKILL
DRV_OBJS += ../src/drivers/rfkill.o
endif
@@ -152,13 +148,18 @@ ifdef NEED_RADIOTAP
DRV_OBJS += ../src/utils/radiotap.o
endif
-ifdef CONFIG_VLAN_NETLINK
ifdef CONFIG_FULL_DYNAMIC_VLAN
+NEED_LINUX_IOCTL=y
+ifdef CONFIG_VLAN_NETLINK
NEED_LIBNL=y
CONFIG_LIBNL3_ROUTE=y
endif
endif
+ifdef NEED_LINUX_IOCTL
+DRV_OBJS += ../src/drivers/linux_ioctl.o
+endif
+
ifdef NEED_LIBNL
ifndef CONFIG_LIBNL32
ifndef CONFIG_LIBNL20
@@ -175,7 +176,6 @@ endif
ifdef CONFIG_LIBNL32
DRV_LIBS += -lnl-3
DRV_LIBS += -lnl-genl-3
- DRV_CFLAGS += -DCONFIG_LIBNL20
ifdef LIBNL_INC
DRV_CFLAGS += -I$(LIBNL_INC)
else
@@ -192,14 +192,8 @@ else
else
ifndef CONFIG_OSX
DRV_LIBS += -lnl
- endif
- endif
-
- ifdef CONFIG_LIBNL20
- ifndef CONFIG_LIBNL_TINY
DRV_LIBS += -lnl-genl
endif
- DRV_CFLAGS += -DCONFIG_LIBNL20
endif
endif
endif
diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk
index 599a0b5..5a32a24 100644
--- a/src/drivers/drivers.mk
+++ b/src/drivers/drivers.mk
@@ -132,10 +132,6 @@ ifdef NEED_NETLINK
DRV_OBJS += src/drivers/netlink.c
endif
-ifdef NEED_LINUX_IOCTL
-DRV_OBJS += src/drivers/linux_ioctl.c
-endif
-
ifdef NEED_RFKILL
DRV_OBJS += src/drivers/rfkill.c
endif
@@ -148,18 +144,23 @@ ifdef CONFIG_DRIVER_CUSTOM
DRV_CFLAGS += -DCONFIG_DRIVER_CUSTOM
endif
-ifdef CONFIG_VLAN_NETLINK
ifdef CONFIG_FULL_DYNAMIC_VLAN
+NEED_LINUX_IOCTL=y
+ifdef CONFIG_VLAN_NETLINK
NEED_LIBNL=y
CONFIG_LIBNL3_ROUTE=y
endif
endif
+ifdef NEED_LINUX_IOCTL
+DRV_OBJS += src/drivers/linux_ioctl.c
+endif
+
ifdef NEED_LIBNL
ifdef CONFIG_LIBNL32
DRV_LIBS += -lnl-3
DRV_LIBS += -lnl-genl-3
- DRV_CFLAGS += -DCONFIG_LIBNL20 -I/usr/include/libnl3
+ DRV_CFLAGS += -I/usr/include/libnl3
ifdef CONFIG_LIBNL3_ROUTE
DRV_LIBS += -lnl-route-3
DRV_CFLAGS += -DCONFIG_LIBNL3_ROUTE
@@ -169,13 +170,7 @@ else
DRV_LIBS += -lnl-tiny
else
DRV_LIBS += -lnl
- endif
-
- ifdef CONFIG_LIBNL20
- ifndef CONFIG_LIBNL_TINY
- DRV_LIBS += -lnl-genl
- endif
- DRV_CFLAGS += -DCONFIG_LIBNL20
+ DRV_LIBS += -lnl-genl
endif
endif
endif
diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
index beee59c..341e0e8 100644
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -249,6 +249,22 @@
*/
/**
+ * DOC: VLAN offload support for setting group keys and binding STAs to VLANs
+ *
+ * By setting @NL80211_EXT_FEATURE_VLAN_OFFLOAD flag drivers can indicate they
+ * support offloading VLAN functionality in a manner where the driver exposes a
+ * single netdev that uses VLAN tagged frames and separate VLAN-specific netdevs
+ * can then be added using RTM_NEWLINK/IFLA_VLAN_ID similarly to the Ethernet
+ * case. Frames received from stations that are not assigned to any VLAN are
+ * delivered on the main netdev and frames to such stations can be sent through
+ * that main netdev.
+ *
+ * %NL80211_CMD_NEW_KEY (for group keys), %NL80211_CMD_NEW_STATION, and
+ * %NL80211_CMD_SET_STATION will optionally specify vlan_id using
+ * %NL80211_ATTR_VLAN_ID.
+ */
+
+/**
* enum nl80211_commands - supported nl80211 commands
*
* @NL80211_CMD_UNSPEC: unspecified command to catch errors
@@ -571,6 +587,14 @@
* set of BSSID,frequency parameters is used (i.e., either the enforcing
* %NL80211_ATTR_MAC,%NL80211_ATTR_WIPHY_FREQ or the less strict
* %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT).
+ * Driver shall not modify the IEs specified through %NL80211_ATTR_IE if
+ * %NL80211_ATTR_MAC is included. However, if %NL80211_ATTR_MAC_HINT is
+ * included, these IEs through %NL80211_ATTR_IE are specified by the user
+ * space based on the best possible BSS selected. Thus, if the driver ends
+ * up selecting a different BSS, it can modify these IEs accordingly (e.g.
+ * userspace asks the driver to perform PMKSA caching with BSS1 and the
+ * driver ends up selecting BSS2 with different PMKSA cache entry; RSNIE
+ * has to get updated with the apt PMKID).
* %NL80211_ATTR_PREV_BSSID can be used to request a reassociation within
* the ESS in case the device is already associated and an association with
* a different BSS is desired.
@@ -2373,6 +2397,9 @@ enum nl80211_commands {
* the allowed channel bandwidth configurations. (u8 attribute)
* Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13.
*
+ * @NL80211_ATTR_VLAN_ID: VLAN ID (1..4094) for the station and VLAN group key
+ * (u16).
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2835,6 +2862,8 @@ enum nl80211_attrs {
NL80211_ATTR_WIPHY_EDMG_CHANNELS,
NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
+ NL80211_ATTR_VLAN_ID,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -5484,6 +5513,10 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
* station mode (SAE password is passed as part of the connect command).
*
+ * @NL80211_EXT_FEATURE_VLAN_OFFLOAD: The driver supports a single netdev
+ * with VLAN tagged frames and separate VLAN-specific netdevs added using
+ * vconfig similarly to the Ethernet case.
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -5529,6 +5562,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_EXT_KEY_ID,
NL80211_EXT_FEATURE_STA_TX_PWR,
NL80211_EXT_FEATURE_SAE_OFFLOAD,
+ NL80211_EXT_FEATURE_VLAN_OFFLOAD,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/src/eap_common/eap_sim_common.c b/src/eap_common/eap_sim_common.c
index 1e0f808..4a93244 100644
--- a/src/eap_common/eap_sim_common.c
+++ b/src/eap_common/eap_sim_common.c
@@ -1219,6 +1219,10 @@ int eap_sim_anonymous_username(const u8 *id, size_t id_len)
os_memcmp(id, anonymous_id_prefix, anonymous_id_len) == 0)
return 1; /* 'anonymous@realm' */
+ if (id_len > anonymous_id_len + 1 &&
+ os_memcmp(id + 1, anonymous_id_prefix, anonymous_id_len) == 0)
+ return 1; /* 'Xanonymous@realm' where X is an EAP method code */
+
if (id_len > 1 && id[0] == '@')
return 1; /* '@realm' */
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 2ea4efd..dd9848e 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -44,7 +44,7 @@ struct eap_sim_data {
u8 *last_eap_identity;
size_t last_eap_identity_len;
enum {
- CONTINUE, RESULT_SUCCESS, SUCCESS, FAILURE
+ CONTINUE, START_DONE, RESULT_SUCCESS, SUCCESS, FAILURE
} state;
int result_ind, use_result_ind;
int use_pseudonym;
@@ -58,6 +58,8 @@ static const char * eap_sim_state_txt(int state)
switch (state) {
case CONTINUE:
return "CONTINUE";
+ case START_DONE:
+ return "START_DONE";
case RESULT_SUCCESS:
return "RESULT_SUCCESS";
case SUCCESS:
@@ -486,6 +488,7 @@ static struct wpabuf * eap_sim_response_start(struct eap_sm *sm,
const u8 *identity = NULL;
size_t identity_len = 0;
struct eap_sim_msg *msg;
+ struct wpabuf *resp;
data->reauth = 0;
if (id_req == ANY_ID && data->reauth_id) {
@@ -535,7 +538,10 @@ static struct wpabuf * eap_sim_response_start(struct eap_sm *sm,
identity, identity_len);
}
- return eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0);
+ resp = eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0);
+ if (resp)
+ eap_sim_state(data, START_DONE);
+ return resp;
}
@@ -721,6 +727,13 @@ static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm,
int res;
wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Challenge");
+ if (data->state != START_DONE) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-SIM: Unexpected Challenge in state %s",
+ eap_sim_state_txt(data->state));
+ return eap_sim_client_error(data, id,
+ EAP_SIM_UNABLE_TO_PROCESS_PACKET);
+ }
data->reauth = 0;
if (!attr->mac || !attr->rand) {
wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message "
diff --git a/src/eap_peer/tncc.c b/src/eap_peer/tncc.c
index a9bafe2..c460980 100644
--- a/src/eap_peer/tncc.c
+++ b/src/eap_peer/tncc.c
@@ -144,7 +144,7 @@ static TNC_Result TNC_TNCC_SendMessage(
TNC_MessageType messageType)
{
struct tnc_if_imc *imc;
- unsigned char *b64;
+ char *b64;
size_t b64len;
wpa_printf(MSG_DEBUG, "TNC: TNC_TNCC_SendMessage(imcID=%lu "
@@ -629,8 +629,7 @@ static unsigned char * tncc_get_base64(char *start, size_t *decoded_len)
return NULL;
*pos2 = '\0';
- decoded = base64_decode((unsigned char *) pos, os_strlen(pos),
- decoded_len);
+ decoded = base64_decode(pos, os_strlen(pos), decoded_len);
*pos2 = '<';
if (decoded == NULL) {
wpa_printf(MSG_DEBUG, "TNC: Failed to decode Base64 data");
diff --git a/src/eap_server/tncs.c b/src/eap_server/tncs.c
index 942a195..4a30486 100644
--- a/src/eap_server/tncs.c
+++ b/src/eap_server/tncs.c
@@ -179,7 +179,7 @@ static TNC_Result TNC_TNCS_SendMessage(
TNC_MessageType messageType)
{
struct tncs_data *tncs;
- unsigned char *b64;
+ char *b64;
size_t b64len;
wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_SendMessage(imvID=%lu "
@@ -678,8 +678,7 @@ static unsigned char * tncs_get_base64(char *start, size_t *decoded_len)
return NULL;
*pos2 = '\0';
- decoded = base64_decode((unsigned char *) pos, os_strlen(pos),
- decoded_len);
+ decoded = base64_decode(pos, os_strlen(pos), decoded_len);
*pos2 = '<';
if (decoded == NULL) {
wpa_printf(MSG_DEBUG, "TNC: Failed to decode Base64 data");
diff --git a/src/l2_packet/l2_packet_linux.c b/src/l2_packet/l2_packet_linux.c
index 291c9dd..138dcaf 100644
--- a/src/l2_packet/l2_packet_linux.c
+++ b/src/l2_packet/l2_packet_linux.c
@@ -171,13 +171,16 @@ static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
u8 hash[SHA1_MAC_LEN];
const u8 *addr[1];
size_t len[1];
+ const struct l2_ethhdr *eth = (const struct l2_ethhdr *) buf;
/*
* Close the workaround socket if the kernel version seems to be
* able to deliver packets through the packet socket before
* authorization has been completed (in dormant state).
*/
- if (l2->num_rx_br <= 1) {
+ if (l2->num_rx_br <= 1 &&
+ (os_memcmp(eth->h_dest, l2->own_addr, ETH_ALEN) == 0 ||
+ is_multicast_ether_addr(eth->h_dest))) {
wpa_printf(MSG_DEBUG,
"l2_packet_receive: Main packet socket for %s seems to have working RX - close workaround bridge socket",
l2->ifname);
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 7c1a8a5..b7a5eae 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -1404,6 +1404,7 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
const int op_classes_5ghz[] = { 124, 125, 115, 0 };
const int op_classes_ht40[] = { 126, 127, 116, 117, 0 };
const int op_classes_vht[] = { 128, 0 };
+ const int op_classes_edmg[] = { 181, 182, 183, 0 };
p2p_dbg(p2p, "Prepare channel best");
@@ -1435,6 +1436,11 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
p2p_dbg(p2p, "Select first pref_chan entry as operating channel preference");
p2p->op_reg_class = p2p->cfg->pref_chan[0].op_class;
p2p->op_channel = p2p->cfg->pref_chan[0].chan;
+ } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_edmg,
+ &p2p->op_reg_class, &p2p->op_channel) ==
+ 0) {
+ p2p_dbg(p2p, "Select possible EDMG channel (op_class %u channel %u) as operating channel preference",
+ p2p->op_reg_class, p2p->op_channel);
} else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht,
&p2p->op_reg_class, &p2p->op_channel) ==
0) {
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 425b037..79de09c 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -99,6 +99,8 @@ struct p2p_go_neg_results {
int vht;
+ int edmg;
+
u8 max_oper_chwidth;
unsigned int vht_center_freq2;
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index c94bf41..1133461 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -390,6 +390,7 @@ void p2p_reselect_channel(struct p2p_data *p2p,
const int op_classes_5ghz[] = { 124, 125, 115, 0 };
const int op_classes_ht40[] = { 126, 127, 116, 117, 0 };
const int op_classes_vht[] = { 128, 129, 130, 0 };
+ const int op_classes_edmg[] = { 181, 182, 183, 0 };
if (p2p->own_freq_preference > 0 &&
p2p_freq_to_channel(p2p->own_freq_preference,
@@ -454,6 +455,14 @@ void p2p_reselect_channel(struct p2p_data *p2p,
}
}
+ /* Try a channel where we might be able to use EDMG */
+ if (p2p_channel_select(intersection, op_classes_edmg,
+ &p2p->op_reg_class, &p2p->op_channel) == 0) {
+ p2p_dbg(p2p, "Pick possible EDMG channel (op_class %u channel %u) from intersection",
+ p2p->op_reg_class, p2p->op_channel);
+ return;
+ }
+
/* Try a channel where we might be able to use VHT */
if (p2p_channel_select(intersection, op_classes_vht,
&p2p->op_reg_class, &p2p->op_channel) == 0) {
diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c
index a3db404..2b7a604 100644
--- a/src/radius/radius_client.c
+++ b/src/radius/radius_client.c
@@ -457,7 +457,7 @@ static int radius_client_retransmit(struct radius_client_data *radius,
}
/* retransmit; remove entry if too many attempts */
- if (entry->accu_attempts > RADIUS_CLIENT_MAX_FAILOVER *
+ if (entry->accu_attempts >= RADIUS_CLIENT_MAX_FAILOVER *
RADIUS_CLIENT_NUM_FAILOVER * num_servers) {
wpa_printf(MSG_INFO,
"RADIUS: Removing un-ACKed message due to too many failed retransmit attempts");
@@ -507,7 +507,7 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
if (now.sec >= entry->next_try) {
s = entry->msg_type == RADIUS_AUTH ? radius->auth_sock :
radius->acct_sock;
- if (entry->attempts > RADIUS_CLIENT_NUM_FAILOVER ||
+ if (entry->attempts >= RADIUS_CLIENT_NUM_FAILOVER ||
(s < 0 && entry->attempts > 0)) {
if (entry->msg_type == RADIUS_ACCT ||
entry->msg_type == RADIUS_ACCT_INTERIM)
@@ -1116,7 +1116,7 @@ radius_change_server(struct radius_client_data *radius,
(!auth && entry->msg_type != RADIUS_ACCT))
continue;
entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT;
- entry->attempts = 1;
+ entry->attempts = 0;
entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
}
diff --git a/src/rsn_supp/preauth.c b/src/rsn_supp/preauth.c
index d0c43f4..a7ca2ed 100644
--- a/src/rsn_supp/preauth.c
+++ b/src/rsn_supp/preauth.c
@@ -49,6 +49,15 @@ void pmksa_candidate_free(struct wpa_sm *sm)
}
+static int rsn_preauth_key_mgmt(int akmp)
+{
+ return !!(akmp & (WPA_KEY_MGMT_IEEE8021X |
+ WPA_KEY_MGMT_IEEE8021X_SHA256 |
+ WPA_KEY_MGMT_IEEE8021X_SUITE_B |
+ WPA_KEY_MGMT_IEEE8021X_SUITE_B_192));
+}
+
+
static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
const u8 *buf, size_t len)
{
@@ -311,10 +320,7 @@ void rsn_preauth_candidate_process(struct wpa_sm *sm)
if (sm->preauth_eapol ||
sm->proto != WPA_PROTO_RSN ||
wpa_sm_get_state(sm) != WPA_COMPLETED ||
- (sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
- sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SHA256 &&
- sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SUITE_B &&
- sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)) {
+ !rsn_preauth_key_mgmt(sm->key_mgmt)) {
wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: not in suitable "
"state for new pre-authentication");
return; /* invalid state for new pre-auth */
@@ -488,6 +494,9 @@ void rsn_preauth_scan_result(struct wpa_sm *sm, const u8 *bssid,
!(ie.capabilities & WPA_CAPABILITY_PREAUTH)))
return;
+ if (!rsn_preauth_key_mgmt(ie.key_mgmt))
+ return;
+
/* Give less priority to candidates found from normal scan results. */
pmksa_candidate_add(sm, bssid, PMKID_CANDIDATE_PRIO_SCAN,
ie.capabilities & WPA_CAPABILITY_PREAUTH);
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 704c95e..bb89739 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -178,7 +178,7 @@ static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
static int wpa_tdls_del_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
{
if (wpa_sm_set_key(sm, WPA_ALG_NONE, peer->addr,
- 0, 0, NULL, 0, NULL, 0) < 0) {
+ 0, 0, NULL, 0, NULL, 0, KEY_FLAG_PAIRWISE) < 0) {
wpa_printf(MSG_WARNING, "TDLS: Failed to delete TPK-TK from "
"the driver");
return -1;
@@ -227,8 +227,9 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR,
MAC2STR(peer->addr));
- if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1,
- rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) {
+ if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1, rsc, sizeof(rsc),
+ peer->tpk.tk, key_len,
+ KEY_FLAG_PAIRWISE_RX_TX) < 0) {
wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the "
"driver");
return -1;
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 504feaf..5f08d0e 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -488,6 +488,8 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
if (wpa_key_mgmt_ft(sm->key_mgmt)) {
int res;
+ wpa_hexdump(MSG_DEBUG, "WPA: WPA IE before FT processing",
+ wpa_ie, wpa_ie_len);
/*
* Add PMKR1Name into RSN IE (PMKID-List) and add MDIE and
* FTIE from (Re)Association Response.
@@ -503,8 +505,14 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
os_free(rsn_ie_buf);
return -1;
}
+ wpa_hexdump(MSG_DEBUG,
+ "WPA: WPA IE after PMKID[PMKR1Name] addition into RSNE",
+ rsn_ie_buf, wpa_ie_len);
if (sm->assoc_resp_ies) {
+ wpa_hexdump(MSG_DEBUG, "WPA: Add assoc_resp_ies",
+ sm->assoc_resp_ies,
+ sm->assoc_resp_ies_len);
os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
sm->assoc_resp_ies_len);
wpa_ie_len += sm->assoc_resp_ies_len;
@@ -781,7 +789,8 @@ static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
- const struct wpa_eapol_key *key)
+ const struct wpa_eapol_key *key,
+ enum key_flag key_flag)
{
int keylen, rsclen;
enum wpa_alg alg;
@@ -826,7 +835,8 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
}
if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
- sm->ptk.tk, keylen) < 0) {
+ sm->ptk.tk, keylen,
+ KEY_FLAG_PAIRWISE | key_flag) < 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Failed to set PTK to the "
"driver (alg=%d keylen=%d bssid=" MACSTR ")",
@@ -919,7 +929,8 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
if (wpa_sm_set_key(sm, gd->alg, NULL,
gd->keyidx, 1, key_rsc, gd->key_rsc_len,
- _gtk, gd->gtk_len) < 0) {
+ _gtk, gd->gtk_len,
+ KEY_FLAG_GROUP_RX_TX_DEFAULT) < 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Failed to set GTK to the driver "
"(Group only)");
@@ -928,7 +939,7 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
}
} else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
- _gtk, gd->gtk_len) < 0) {
+ _gtk, gd->gtk_len, KEY_FLAG_GROUP_RX) < 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Failed to set GTK to "
"the driver (alg=%d keylen=%d keyidx=%d)",
@@ -1082,7 +1093,7 @@ static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
broadcast_ether_addr,
keyidx, 0, igtk->pn, sizeof(igtk->pn),
- igtk->igtk, len) < 0) {
+ igtk->igtk, len, KEY_FLAG_GROUP_RX) < 0) {
if (keyidx == 0x0400 || keyidx == 0x0500) {
/* Assume the AP has broken PMF implementation since it
* seems to have swapped the KeyID bytes. The AP cannot
@@ -1534,7 +1545,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
sm->renew_snonce = 1;
if (key_info & WPA_KEY_INFO_INSTALL) {
- if (wpa_supplicant_install_ptk(sm, key))
+ if (wpa_supplicant_install_ptk(sm, key, KEY_FLAG_RX_TX))
goto failed;
}
@@ -3502,6 +3513,14 @@ int wpa_sm_has_ptk(struct wpa_sm *sm)
}
+int wpa_sm_has_ptk_installed(struct wpa_sm *sm)
+{
+ if (!sm)
+ return 0;
+ return sm->ptk.installed;
+}
+
+
void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
{
os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
@@ -4558,7 +4577,7 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
wpa_hexdump_key(MSG_DEBUG, "FILS: Set TK to driver",
sm->ptk.tk, keylen);
if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, null_rsc, rsclen,
- sm->ptk.tk, keylen) < 0) {
+ sm->ptk.tk, keylen, KEY_FLAG_PAIRWISE_RX_TX) < 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"FILS: Failed to set PTK to the driver (alg=%d keylen=%d bssid="
MACSTR ")",
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index f1fbb1b..85fedee 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -30,7 +30,7 @@ struct wpa_sm_ctx {
int (*set_key)(void *ctx, enum wpa_alg alg,
const u8 *addr, int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len);
+ const u8 *key, size_t key_len, enum key_flag key_flag);
void * (*get_network_ctx)(void *ctx);
int (*get_bssid)(void *ctx, u8 *bssid);
int (*ether_send)(void *ctx, const u8 *dest, u16 proto, const u8 *buf,
@@ -172,6 +172,7 @@ int wpa_sm_pmksa_exists(struct wpa_sm *sm, const u8 *bssid,
const void *network_ctx);
void wpa_sm_drop_sa(struct wpa_sm *sm);
int wpa_sm_has_ptk(struct wpa_sm *sm);
+int wpa_sm_has_ptk_installed(struct wpa_sm *sm);
void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr);
diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
index 2b8b41f..8a8c545 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -422,8 +422,9 @@ static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid)
alg = wpa_cipher_to_alg(sm->pairwise_cipher);
keylen = wpa_cipher_key_len(sm->pairwise_cipher);
- if (wpa_sm_set_key(sm, alg, bssid, 0, 1, null_rsc,
- sizeof(null_rsc), (u8 *) sm->ptk.tk, keylen) < 0) {
+ if (wpa_sm_set_key(sm, alg, bssid, 0, 1, null_rsc, sizeof(null_rsc),
+ (u8 *) sm->ptk.tk, keylen,
+ KEY_FLAG_PAIRWISE_RX_TX) < 0) {
wpa_printf(MSG_WARNING, "FT: Failed to set PTK to the driver");
return -1;
}
@@ -773,7 +774,8 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem,
os_memcpy(gtk + 24, tmp, 8);
}
if (wpa_sm_set_key(sm, alg, broadcast_ether_addr, keyidx, 0,
- gtk_elem + 3, rsc_len, gtk, keylen) < 0) {
+ gtk_elem + 3, rsc_len, gtk, keylen,
+ KEY_FLAG_GROUP_RX) < 0) {
wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the "
"driver.");
return -1;
@@ -840,7 +842,8 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
igtk_len);
if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
broadcast_ether_addr, keyidx, 0,
- igtk_elem + 2, 6, igtk, igtk_len) < 0) {
+ igtk_elem + 2, 6, igtk, igtk_len,
+ KEY_FLAG_GROUP_RX) < 0) {
wpa_printf(MSG_WARNING, "WPA: Failed to set IGTK to the "
"driver.");
forced_memzero(igtk, sizeof(igtk));
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 2a43342..7d7c06e 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -198,11 +198,12 @@ static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, u16 reason_code)
static inline int wpa_sm_set_key(struct wpa_sm *sm, enum wpa_alg alg,
const u8 *addr, int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
+ const u8 *key, size_t key_len,
+ enum key_flag key_flag)
{
WPA_ASSERT(sm->ctx->set_key);
return sm->ctx->set_key(sm->ctx->ctx, alg, addr, key_idx, set_tx,
- seq, seq_len, key, key_len);
+ seq, seq_len, key, key_len, key_flag);
}
static inline void * wpa_sm_get_network_ctx(struct wpa_sm *sm)
diff --git a/src/tls/tlsv1_cred.c b/src/tls/tlsv1_cred.c
index 842e5dd..01b2f83 100644
--- a/src/tls/tlsv1_cred.c
+++ b/src/tls/tlsv1_cred.c
@@ -130,7 +130,7 @@ static int tlsv1_add_cert(struct x509_certificate **chain,
return -1;
}
- der = base64_decode(pos, end - pos, &der_len);
+ der = base64_decode((const char *) pos, end - pos, &der_len);
if (der == NULL) {
wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM "
"certificate");
@@ -293,7 +293,7 @@ static struct crypto_private_key * tlsv1_set_key_pem(const u8 *key, size_t len)
}
}
- der = base64_decode(pos, end - pos, &der_len);
+ der = base64_decode((const char *) pos, end - pos, &der_len);
if (!der)
return NULL;
pkey = crypto_private_key_import(der, der_len, NULL);
@@ -321,7 +321,7 @@ static struct crypto_private_key * tlsv1_set_key_enc_pem(const u8 *key,
if (!end)
return NULL;
- der = base64_decode(pos, end - pos, &der_len);
+ der = base64_decode((const char *) pos, end - pos, &der_len);
if (!der)
return NULL;
pkey = crypto_private_key_import(der, der_len, passwd);
@@ -1225,7 +1225,7 @@ static int tlsv1_set_dhparams_blob(struct tlsv1_credentials *cred,
return -1;
}
- der = base64_decode(pos, end - pos, &der_len);
+ der = base64_decode((const char *) pos, end - pos, &der_len);
if (der == NULL) {
wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM dhparams");
return -1;
diff --git a/src/utils/base64.c b/src/utils/base64.c
index 53a92f4..a17d2d3 100644
--- a/src/utils/base64.c
+++ b/src/utils/base64.c
@@ -12,18 +12,16 @@
#include "os.h"
#include "base64.h"
-static const unsigned char base64_table[65] =
+static const char base64_table[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static const unsigned char base64_url_table[65] =
+static const char base64_url_table[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
-static unsigned char * base64_gen_encode(const unsigned char *src, size_t len,
- size_t *out_len,
- const unsigned char *table,
- int add_pad)
+static char * base64_gen_encode(const unsigned char *src, size_t len,
+ size_t *out_len, const char *table, int add_pad)
{
- unsigned char *out, *pos;
+ char *out, *pos;
const unsigned char *end, *in;
size_t olen;
int line_len;
@@ -83,9 +81,8 @@ static unsigned char * base64_gen_encode(const unsigned char *src, size_t len,
}
-static unsigned char * base64_gen_decode(const unsigned char *src, size_t len,
- size_t *out_len,
- const unsigned char *table)
+static unsigned char * base64_gen_decode(const char *src, size_t len,
+ size_t *out_len, const char *table)
{
unsigned char dtable[256], *out, *pos, block[4], tmp;
size_t i, count, olen;
@@ -94,12 +91,12 @@ static unsigned char * base64_gen_decode(const unsigned char *src, size_t len,
os_memset(dtable, 0x80, 256);
for (i = 0; i < sizeof(base64_table) - 1; i++)
- dtable[table[i]] = (unsigned char) i;
+ dtable[(unsigned char) table[i]] = (unsigned char) i;
dtable['='] = 0;
count = 0;
for (i = 0; i < len; i++) {
- if (dtable[src[i]] != 0x80)
+ if (dtable[(unsigned char) src[i]] != 0x80)
count++;
}
@@ -165,17 +162,15 @@ static unsigned char * base64_gen_decode(const unsigned char *src, size_t len,
* nul terminated to make it easier to use as a C string. The nul terminator is
* not included in out_len.
*/
-unsigned char * base64_encode(const unsigned char *src, size_t len,
- size_t *out_len)
+char * base64_encode(const void *src, size_t len, size_t *out_len)
{
return base64_gen_encode(src, len, out_len, base64_table, 1);
}
-unsigned char * base64_url_encode(const unsigned char *src, size_t len,
- size_t *out_len, int add_pad)
+char * base64_url_encode(const void *src, size_t len, size_t *out_len)
{
- return base64_gen_encode(src, len, out_len, base64_url_table, add_pad);
+ return base64_gen_encode(src, len, out_len, base64_url_table, 0);
}
@@ -189,15 +184,13 @@ unsigned char * base64_url_encode(const unsigned char *src, size_t len,
*
* Caller is responsible for freeing the returned buffer.
*/
-unsigned char * base64_decode(const unsigned char *src, size_t len,
- size_t *out_len)
+unsigned char * base64_decode(const char *src, size_t len, size_t *out_len)
{
return base64_gen_decode(src, len, out_len, base64_table);
}
-unsigned char * base64_url_decode(const unsigned char *src, size_t len,
- size_t *out_len)
+unsigned char * base64_url_decode(const char *src, size_t len, size_t *out_len)
{
return base64_gen_decode(src, len, out_len, base64_url_table);
}
diff --git a/src/utils/base64.h b/src/utils/base64.h
index 5a72c3e..6216f44 100644
--- a/src/utils/base64.h
+++ b/src/utils/base64.h
@@ -9,13 +9,9 @@
#ifndef BASE64_H
#define BASE64_H
-unsigned char * base64_encode(const unsigned char *src, size_t len,
- size_t *out_len);
-unsigned char * base64_decode(const unsigned char *src, size_t len,
- size_t *out_len);
-unsigned char * base64_url_encode(const unsigned char *src, size_t len,
- size_t *out_len, int add_pad);
-unsigned char * base64_url_decode(const unsigned char *src, size_t len,
- size_t *out_len);
+char * base64_encode(const void *src, size_t len, size_t *out_len);
+unsigned char * base64_decode(const char *src, size_t len, size_t *out_len);
+char * base64_url_encode(const void *src, size_t len, size_t *out_len);
+unsigned char * base64_url_decode(const char *src, size_t len, size_t *out_len);
#endif /* BASE64_H */
diff --git a/src/utils/json.c b/src/utils/json.c
index 3e5e214..5a0edf2 100644
--- a/src/utils/json.c
+++ b/src/utils/json.c
@@ -300,8 +300,10 @@ struct json_token * json_parse(const char *data, size_t data_len)
goto fail;
if (!curr_token) {
token = json_alloc_token(&tokens);
- if (!token)
+ if (!token) {
+ os_free(str);
goto fail;
+ }
token->type = JSON_STRING;
token->string = str;
token->state = JSON_COMPLETED;
@@ -514,8 +516,8 @@ struct wpabuf * json_get_member_base64url(struct json_token *json,
token = json_get_member(json, name);
if (!token || token->type != JSON_STRING)
return NULL;
- buf = base64_url_decode((const unsigned char *) token->string,
- os_strlen(token->string), &buflen);
+ buf = base64_url_decode(token->string, os_strlen(token->string),
+ &buflen);
if (!buf)
return NULL;
ret = wpabuf_alloc_ext_data(buf, buflen);
@@ -574,3 +576,79 @@ void json_print_tree(struct json_token *root, char *buf, size_t buflen)
buf[0] = '\0';
json_print_token(root, 1, buf, buflen);
}
+
+
+void json_add_int(struct wpabuf *json, const char *name, int val)
+{
+ wpabuf_printf(json, "\"%s\":%d", name, val);
+}
+
+
+void json_add_string(struct wpabuf *json, const char *name, const char *val)
+{
+ wpabuf_printf(json, "\"%s\":\"%s\"", name, val);
+}
+
+
+int json_add_string_escape(struct wpabuf *json, const char *name,
+ const void *val, size_t len)
+{
+ char *tmp;
+ size_t tmp_len = 6 * len + 1;
+
+ tmp = os_malloc(tmp_len);
+ if (!tmp)
+ return -1;
+ json_escape_string(tmp, tmp_len, val, len);
+ json_add_string(json, name, tmp);
+ bin_clear_free(tmp, tmp_len);
+ return 0;
+}
+
+
+int json_add_base64url(struct wpabuf *json, const char *name, const void *val,
+ size_t len)
+{
+ char *b64;
+
+ b64 = base64_url_encode(val, len, NULL);
+ if (!b64)
+ return -1;
+ json_add_string(json, name, b64);
+ os_free(b64);
+ return 0;
+}
+
+
+void json_start_object(struct wpabuf *json, const char *name)
+{
+ if (name)
+ wpabuf_printf(json, "\"%s\":", name);
+ wpabuf_put_u8(json, '{');
+}
+
+
+void json_end_object(struct wpabuf *json)
+{
+ wpabuf_put_u8(json, '}');
+}
+
+
+void json_start_array(struct wpabuf *json, const char *name)
+{
+ if (name)
+ wpabuf_printf(json, "\"%s\":", name);
+ wpabuf_put_u8(json, '[');
+}
+
+
+void json_end_array(struct wpabuf *json)
+{
+ wpabuf_put_u8(json, ']');
+}
+
+
+void json_value_sep(struct wpabuf *json)
+{
+ wpabuf_put_u8(json, ',');
+}
diff --git a/src/utils/json.h b/src/utils/json.h
index 8faa95d..ca4a2e4 100644
--- a/src/utils/json.h
+++ b/src/utils/json.h
@@ -38,5 +38,16 @@ struct json_token * json_get_member(struct json_token *json, const char *name);
struct wpabuf * json_get_member_base64url(struct json_token *json,
const char *name);
void json_print_tree(struct json_token *root, char *buf, size_t buflen);
+void json_add_int(struct wpabuf *json, const char *name, int val);
+void json_add_string(struct wpabuf *json, const char *name, const char *val);
+int json_add_string_escape(struct wpabuf *json, const char *name,
+ const void *val, size_t len);
+int json_add_base64url(struct wpabuf *json, const char *name, const void *val,
+ size_t len);
+void json_start_object(struct wpabuf *json, const char *name);
+void json_end_object(struct wpabuf *json);
+void json_start_array(struct wpabuf *json, const char *name);
+void json_end_array(struct wpabuf *json);
+void json_value_sep(struct wpabuf *json);
#endif /* JSON_H */
diff --git a/src/utils/trace.c b/src/utils/trace.c
index 4084343..8f12da8 100644
--- a/src/utils/trace.c
+++ b/src/utils/trace.c
@@ -146,6 +146,17 @@ struct bfd_data {
unsigned int line;
};
+/*
+ * binutils removed the bfd parameter and renamed things but
+ * those were macros so we can detect their absence.
+ * Cf. https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=fd3619828e94a24a92cddec42cbc0ab33352eeb4;hp=5dfda3562a69686c43aad4fb0269cc9d5ec010d5
+ */
+#ifndef bfd_get_section_vma
+#define bfd_get_section_vma(bfd, section) bfd_section_vma(section)
+#endif
+#ifndef bfd_get_section_size
+#define bfd_get_section_size bfd_section_size
+#endif
static void find_addr_sect(bfd *abfd, asection *section, void *obj)
{
diff --git a/src/utils/utils_module_tests.c b/src/utils/utils_module_tests.c
index 3af4fcd..f75d406 100644
--- a/src/utils/utils_module_tests.c
+++ b/src/utils/utils_module_tests.c
@@ -296,52 +296,53 @@ static int base64_tests(void)
{
int errors = 0;
unsigned char *res;
+ char *res2;
size_t res_len;
wpa_printf(MSG_INFO, "base64 tests");
- res = base64_encode((const unsigned char *) "", ~0, &res_len);
- if (res) {
+ res2 = base64_encode("", ~0, &res_len);
+ if (res2) {
errors++;
- os_free(res);
+ os_free(res2);
}
- res = base64_encode((const unsigned char *) "=", 1, &res_len);
- if (!res || res_len != 5 || res[0] != 'P' || res[1] != 'Q' ||
- res[2] != '=' || res[3] != '=' || res[4] != '\n')
+ res2 = base64_encode("=", 1, &res_len);
+ if (!res2 || res_len != 5 || res2[0] != 'P' || res2[1] != 'Q' ||
+ res2[2] != '=' || res2[3] != '=' || res2[4] != '\n')
errors++;
- os_free(res);
+ os_free(res2);
- res = base64_encode((const unsigned char *) "=", 1, NULL);
- if (!res || res[0] != 'P' || res[1] != 'Q' ||
- res[2] != '=' || res[3] != '=' || res[4] != '\n')
+ res2 = base64_encode("=", 1, NULL);
+ if (!res2 || res2[0] != 'P' || res2[1] != 'Q' ||
+ res2[2] != '=' || res2[3] != '=' || res2[4] != '\n')
errors++;
- os_free(res);
+ os_free(res2);
- res = base64_decode((const unsigned char *) "", 0, &res_len);
+ res = base64_decode("", 0, &res_len);
if (res) {
errors++;
os_free(res);
}
- res = base64_decode((const unsigned char *) "a", 1, &res_len);
+ res = base64_decode("a", 1, &res_len);
if (res) {
errors++;
os_free(res);
}
- res = base64_decode((const unsigned char *) "====", 4, &res_len);
+ res = base64_decode("====", 4, &res_len);
if (res) {
errors++;
os_free(res);
}
- res = base64_decode((const unsigned char *) "PQ==", 4, &res_len);
+ res = base64_decode("PQ==", 4, &res_len);
if (!res || res_len != 1 || res[0] != '=')
errors++;
os_free(res);
- res = base64_decode((const unsigned char *) "P.Q-=!=*", 8, &res_len);
+ res = base64_decode("P.Q-=!=*", 8, &res_len);
if (!res || res_len != 1 || res[0] != '=')
errors++;
os_free(res);
@@ -929,7 +930,7 @@ static int const_time_tests(void)
{ 0, 0 },
{ 1, 0 },
{ 2, 0 },
- { 1 << (sizeof(unsigned int) * 8 - 1), ~0 },
+ { 1U << (sizeof(unsigned int) * 8 - 1), ~0 },
{ ~0 - 1, ~0 },
{ ~0, ~0 }
};
@@ -940,7 +941,7 @@ static int const_time_tests(void)
{ 0, ~0 },
{ 1, 0 },
{ 2, 0 },
- { 1 << (sizeof(unsigned int) * 8 - 1), 0 },
+ { 1U << (sizeof(unsigned int) * 8 - 1), 0 },
{ ~0 - 1, 0 },
{ ~0, 0 }
};
diff --git a/src/utils/wpa_debug.c b/src/utils/wpa_debug.c
index c336e53..a338a20 100644
--- a/src/utils/wpa_debug.c
+++ b/src/utils/wpa_debug.c
@@ -12,8 +12,6 @@
#ifdef CONFIG_DEBUG_SYSLOG
#include <syslog.h>
-
-int wpa_debug_syslog = 0;
#endif /* CONFIG_DEBUG_SYSLOG */
#ifdef CONFIG_DEBUG_LINUX_TRACING
@@ -32,6 +30,10 @@ static FILE *wpa_debug_tracing_file = NULL;
int wpa_debug_level = MSG_INFO;
int wpa_debug_show_keys = 0;
int wpa_debug_timestamp = 0;
+int wpa_debug_syslog = 0;
+#ifndef CONFIG_NO_STDOUT_DEBUG
+static FILE *out_file = NULL;
+#endif /* CONFIG_NO_STDOUT_DEBUG */
#ifdef CONFIG_ANDROID_LOG
@@ -61,8 +63,6 @@ static int wpa_to_android_level(int level)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-
-static FILE *out_file = NULL;
#endif /* CONFIG_DEBUG_FILE */
@@ -76,12 +76,12 @@ void wpa_debug_print_timestamp(void)
os_get_time(&tv);
#ifdef CONFIG_DEBUG_FILE
- if (out_file) {
+ if (out_file)
fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
(unsigned int) tv.usec);
- } else
#endif /* CONFIG_DEBUG_FILE */
- printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
+ if (!out_file && !wpa_debug_syslog)
+ printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
#endif /* CONFIG_ANDROID_LOG */
}
@@ -210,35 +210,37 @@ void wpa_printf(int level, const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
if (level >= wpa_debug_level) {
#ifdef CONFIG_ANDROID_LOG
+ va_start(ap, fmt);
__android_log_vprint(wpa_to_android_level(level),
ANDROID_LOG_NAME, fmt, ap);
+ va_end(ap);
#else /* CONFIG_ANDROID_LOG */
#ifdef CONFIG_DEBUG_SYSLOG
if (wpa_debug_syslog) {
+ va_start(ap, fmt);
vsyslog(syslog_priority(level), fmt, ap);
- } else {
+ va_end(ap);
+ }
#endif /* CONFIG_DEBUG_SYSLOG */
wpa_debug_print_timestamp();
#ifdef CONFIG_DEBUG_FILE
if (out_file) {
+ va_start(ap, fmt);
vfprintf(out_file, fmt, ap);
fprintf(out_file, "\n");
- } else {
-#endif /* CONFIG_DEBUG_FILE */
- vprintf(fmt, ap);
- printf("\n");
-#ifdef CONFIG_DEBUG_FILE
+ va_end(ap);
}
#endif /* CONFIG_DEBUG_FILE */
-#ifdef CONFIG_DEBUG_SYSLOG
+ if (!wpa_debug_syslog && !out_file) {
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ printf("\n");
+ va_end(ap);
}
-#endif /* CONFIG_DEBUG_SYSLOG */
#endif /* CONFIG_ANDROID_LOG */
}
- va_end(ap);
#ifdef CONFIG_DEBUG_LINUX_TRACING
if (wpa_debug_tracing_file != NULL) {
@@ -254,7 +256,7 @@ void wpa_printf(int level, const char *fmt, ...)
static void _wpa_hexdump(int level, const char *title, const u8 *buf,
- size_t len, int show)
+ size_t len, int show, int only_syslog)
{
size_t i;
@@ -345,7 +347,8 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf,
syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
title, (unsigned long) len, display);
bin_clear_free(strbuf, 1 + 3 * len);
- return;
+ if (only_syslog)
+ return;
}
#endif /* CONFIG_DEBUG_SYSLOG */
wpa_debug_print_timestamp();
@@ -362,33 +365,32 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf,
fprintf(out_file, " [REMOVED]");
}
fprintf(out_file, "\n");
- } else {
-#endif /* CONFIG_DEBUG_FILE */
- printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
- if (buf == NULL) {
- printf(" [NULL]");
- } else if (show) {
- for (i = 0; i < len; i++)
- printf(" %02x", buf[i]);
- } else {
- printf(" [REMOVED]");
- }
- printf("\n");
-#ifdef CONFIG_DEBUG_FILE
}
#endif /* CONFIG_DEBUG_FILE */
+ if (!wpa_debug_syslog && !out_file) {
+ printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
+ if (buf == NULL) {
+ printf(" [NULL]");
+ } else if (show) {
+ for (i = 0; i < len; i++)
+ printf(" %02x", buf[i]);
+ } else {
+ printf(" [REMOVED]");
+ }
+ printf("\n");
+ }
#endif /* CONFIG_ANDROID_LOG */
}
void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
{
- _wpa_hexdump(level, title, buf, len, 1);
+ _wpa_hexdump(level, title, buf, len, 1, 0);
}
void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
{
- _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
+ _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 0);
}
@@ -421,13 +423,11 @@ static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
if (level < wpa_debug_level)
return;
#ifdef CONFIG_ANDROID_LOG
- _wpa_hexdump(level, title, buf, len, show);
+ _wpa_hexdump(level, title, buf, len, show, 0);
#else /* CONFIG_ANDROID_LOG */
#ifdef CONFIG_DEBUG_SYSLOG
- if (wpa_debug_syslog) {
- _wpa_hexdump(level, title, buf, len, show);
- return;
- }
+ if (wpa_debug_syslog)
+ _wpa_hexdump(level, title, buf, len, show, 1);
#endif /* CONFIG_DEBUG_SYSLOG */
wpa_debug_print_timestamp();
#ifdef CONFIG_DEBUG_FILE
@@ -436,13 +436,13 @@ static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
fprintf(out_file,
"%s - hexdump_ascii(len=%lu): [REMOVED]\n",
title, (unsigned long) len);
- return;
+ goto file_done;
}
if (buf == NULL) {
fprintf(out_file,
"%s - hexdump_ascii(len=%lu): [NULL]\n",
title, (unsigned long) len);
- return;
+ goto file_done;
}
fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
title, (unsigned long) len);
@@ -466,42 +466,43 @@ static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
pos += llen;
len -= llen;
}
- } else {
-#endif /* CONFIG_DEBUG_FILE */
- if (!show) {
- printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
- title, (unsigned long) len);
- return;
}
- if (buf == NULL) {
- printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
- title, (unsigned long) len);
- return;
- }
- printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
- while (len) {
- llen = len > line_len ? line_len : len;
- printf(" ");
- for (i = 0; i < llen; i++)
- printf(" %02x", pos[i]);
- for (i = llen; i < line_len; i++)
+file_done:
+#endif /* CONFIG_DEBUG_FILE */
+ if (!wpa_debug_syslog && !out_file) {
+ if (!show) {
+ printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
+ title, (unsigned long) len);
+ return;
+ }
+ if (buf == NULL) {
+ printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
+ title, (unsigned long) len);
+ return;
+ }
+ printf("%s - hexdump_ascii(len=%lu):\n", title,
+ (unsigned long) len);
+ while (len) {
+ llen = len > line_len ? line_len : len;
+ printf(" ");
+ for (i = 0; i < llen; i++)
+ printf(" %02x", pos[i]);
+ for (i = llen; i < line_len; i++)
+ printf(" ");
printf(" ");
- printf(" ");
- for (i = 0; i < llen; i++) {
- if (isprint(pos[i]))
- printf("%c", pos[i]);
- else
- printf("_");
+ for (i = 0; i < llen; i++) {
+ if (isprint(pos[i]))
+ printf("%c", pos[i]);
+ else
+ printf("_");
+ }
+ for (i = llen; i < line_len; i++)
+ printf(" ");
+ printf("\n");
+ pos += llen;
+ len -= llen;
}
- for (i = llen; i < line_len; i++)
- printf(" ");
- printf("\n");
- pos += llen;
- len -= llen;
- }
-#ifdef CONFIG_DEBUG_FILE
}
-#endif /* CONFIG_DEBUG_FILE */
#endif /* CONFIG_ANDROID_LOG */
}
diff --git a/src/utils/wpa_debug.h b/src/utils/wpa_debug.h
index c94c439..c6d5cc6 100644
--- a/src/utils/wpa_debug.h
+++ b/src/utils/wpa_debug.h
@@ -14,9 +14,7 @@
extern int wpa_debug_level;
extern int wpa_debug_show_keys;
extern int wpa_debug_timestamp;
-#ifdef CONFIG_DEBUG_SYSLOG
extern int wpa_debug_syslog;
-#endif /* CONFIG_DEBUG_SYSLOG */
/* Debugging function - conditional printf and hex dump. Driver wrappers can
* use these for debugging purposes. */
diff --git a/src/utils/xml_libxml2.c b/src/utils/xml_libxml2.c
index 7b6d276..d73654e 100644
--- a/src/utils/xml_libxml2.c
+++ b/src/utils/xml_libxml2.c
@@ -409,7 +409,7 @@ char * xml_node_get_base64_text(struct xml_node_ctx *ctx, xml_node_t *node,
if (txt == NULL)
return NULL;
- ret = base64_decode((unsigned char *) txt, strlen(txt), &len);
+ ret = base64_decode(txt, strlen(txt), &len);
if (ret_len)
*ret_len = len;
xml_node_get_text_free(ctx, txt);
diff --git a/src/wps/upnp_xml.c b/src/wps/upnp_xml.c
index a9958ee..ca0925c 100644
--- a/src/wps/upnp_xml.c
+++ b/src/wps/upnp_xml.c
@@ -235,7 +235,7 @@ struct wpabuf * xml_get_base64_item(const char *data, const char *name,
return NULL;
}
- decoded = base64_decode((unsigned char *) msg, os_strlen(msg), &len);
+ decoded = base64_decode(msg, os_strlen(msg), &len);
os_free(msg);
if (decoded == NULL) {
*ret = UPNP_OUT_OF_MEMORY;
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 9963c46..f42045e 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -98,6 +98,7 @@ struct wps_device_data {
u16 config_methods;
struct wpabuf *vendor_ext_m1;
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
+ struct wpabuf *application_ext;
int p2p;
u8 multi_ap_ext;
diff --git a/src/wps/wps_dev_attr.c b/src/wps/wps_dev_attr.c
index b209fea..c2e949c 100644
--- a/src/wps/wps_dev_attr.c
+++ b/src/wps/wps_dev_attr.c
@@ -242,6 +242,21 @@ int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg)
}
+int wps_build_application_ext(struct wps_device_data *dev, struct wpabuf *msg)
+{
+ if (!dev->application_ext)
+ return 0;
+
+ wpa_hexdump_buf(MSG_DEBUG, "WPS: * Application Extension",
+ dev->application_ext);
+ wpabuf_put_be16(msg, ATTR_APPLICATION_EXT);
+ wpabuf_put_be16(msg, wpabuf_len(dev->application_ext));
+ wpabuf_put_buf(msg, dev->application_ext);
+
+ return 0;
+}
+
+
static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
size_t str_len)
{
@@ -424,4 +439,6 @@ void wps_device_data_free(struct wps_device_data *dev)
dev->model_number = NULL;
os_free(dev->serial_number);
dev->serial_number = NULL;
+ wpabuf_free(dev->application_ext);
+ dev->application_ext = NULL;
}
diff --git a/src/wps/wps_dev_attr.h b/src/wps/wps_dev_attr.h
index a4b4173..81fdd5f 100644
--- a/src/wps/wps_dev_attr.h
+++ b/src/wps/wps_dev_attr.h
@@ -33,6 +33,7 @@ void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext);
int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands);
void wps_device_data_free(struct wps_device_data *dev);
int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
+int wps_build_application_ext(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_req_dev_type(struct wps_device_data *dev, struct wpabuf *msg,
unsigned int num_req_dev_types,
const u8 *req_dev_types);
diff --git a/src/wps/wps_er.c b/src/wps/wps_er.c
index 06a8fda..6bded14 100644
--- a/src/wps/wps_er.c
+++ b/src/wps/wps_er.c
@@ -897,7 +897,7 @@ static struct wpabuf * wps_er_soap_hdr(const struct wpabuf *msg,
const struct sockaddr_in *dst,
char **len_ptr, char **body_ptr)
{
- unsigned char *encoded;
+ char *encoded;
size_t encoded_len;
struct wpabuf *buf;
@@ -939,7 +939,7 @@ static struct wpabuf * wps_er_soap_hdr(const struct wpabuf *msg,
wpabuf_put_str(buf, "\">\n");
if (encoded) {
wpabuf_printf(buf, "<%s>%s</%s>\n",
- arg_name, (char *) encoded, arg_name);
+ arg_name, encoded, arg_name);
os_free(encoded);
}
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index 0ac5b28..da81d1a 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -1331,7 +1331,8 @@ static int wps_set_ie(struct wps_registrar *reg)
wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
(reg->dualband && wps_build_rf_bands(&reg->wps->dev, beacon, 0)) ||
wps_build_wfa_ext(beacon, 0, auth_macs, count, 0) ||
- wps_build_vendor_ext(&reg->wps->dev, beacon)) {
+ wps_build_vendor_ext(&reg->wps->dev, beacon) ||
+ wps_build_application_ext(&reg->wps->dev, beacon)) {
wpabuf_free(beacon);
wpabuf_free(probe);
return -1;
@@ -1361,7 +1362,8 @@ static int wps_set_ie(struct wps_registrar *reg)
wps_build_probe_config_methods(reg, probe) ||
(reg->dualband && wps_build_rf_bands(&reg->wps->dev, probe, 0)) ||
wps_build_wfa_ext(probe, 0, auth_macs, count, 0) ||
- wps_build_vendor_ext(&reg->wps->dev, probe)) {
+ wps_build_vendor_ext(&reg->wps->dev, probe) ||
+ wps_build_application_ext(&reg->wps->dev, probe)) {
wpabuf_free(beacon);
wpabuf_free(probe);
return -1;
@@ -1745,7 +1747,8 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
return -1;
}
os_free(wps->new_psk);
- wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
+ wps->new_psk = (u8 *) base64_encode(r, sizeof(r),
+ &wps->new_psk_len);
if (wps->new_psk == NULL)
return -1;
wps->new_psk_len--; /* remove newline */
diff --git a/src/wps/wps_upnp.c b/src/wps/wps_upnp.c
index ca893a4..6e10e4b 100644
--- a/src/wps/wps_upnp.c
+++ b/src/wps/wps_upnp.c
@@ -519,8 +519,9 @@ static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm)
dl_list_for_each_safe(s, tmp, &sm->subscriptions, struct subscription,
list) {
- event_add(s, buf,
- sm->wlanevent_type == UPNP_WPS_WLANEVENT_TYPE_PROBE);
+ wps_upnp_event_add(
+ s, buf,
+ sm->wlanevent_type == UPNP_WPS_WLANEVENT_TYPE_PROBE);
}
wpabuf_free(buf);
@@ -541,7 +542,7 @@ void subscription_destroy(struct subscription *s)
struct upnp_wps_device_interface *iface;
wpa_printf(MSG_DEBUG, "WPS UPnP: Destroy subscription %p", s);
subscr_addr_free_all(s);
- event_delete_all(s);
+ wps_upnp_event_delete_all(s);
dl_list_for_each(iface, &s->sm->interfaces,
struct upnp_wps_device_interface, list)
upnp_er_remove_notification(iface->wps->registrar, s);
@@ -647,7 +648,7 @@ static int subscription_first_event(struct subscription *s)
"initial WLANEvent");
msg = build_fake_wsc_ack();
if (msg) {
- s->sm->wlanevent = (char *)
+ s->sm->wlanevent =
base64_encode(wpabuf_head(msg),
wpabuf_len(msg), NULL);
wpabuf_free(msg);
@@ -672,7 +673,7 @@ static int subscription_first_event(struct subscription *s)
wpabuf_put_property(buf, "WLANEvent", wlan_event);
wpabuf_put_str(buf, tail);
- ret = event_add(s, buf, 0);
+ ret = wps_upnp_event_add(s, buf, 0);
if (ret) {
wpabuf_free(buf);
return ret;
@@ -749,7 +750,7 @@ struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
"WPS UPnP: Subscription %p (SID %s) started with %s",
s, str, callback_urls);
/* Schedule sending this */
- event_send_all_later(sm);
+ wps_upnp_event_send_all_later(sm);
return s;
}
@@ -822,7 +823,7 @@ int upnp_wps_device_send_wlan_event(struct upnp_wps_device_sm *sm,
}
raw_len = pos;
- val = (char *) base64_encode(raw, raw_len, &val_len);
+ val = base64_encode(raw, raw_len, &val_len);
if (val == NULL)
goto fail;
@@ -987,7 +988,7 @@ static void upnp_wps_device_stop(struct upnp_wps_device_sm *sm)
advertisement_state_machine_stop(sm, 1);
- event_send_stop_all(sm);
+ wps_upnp_event_send_stop_all(sm);
os_free(sm->wlanevent);
sm->wlanevent = NULL;
os_free(sm->ip_addr_text);
diff --git a/src/wps/wps_upnp_event.c b/src/wps/wps_upnp_event.c
index 94aae75..d7e6edc 100644
--- a/src/wps/wps_upnp_event.c
+++ b/src/wps/wps_upnp_event.c
@@ -96,8 +96,8 @@ static struct wps_event_ *event_dequeue(struct subscription *s)
}
-/* event_delete_all -- delete entire event queue and current event */
-void event_delete_all(struct subscription *s)
+/* wps_upnp_event_delete_all -- delete entire event queue and current event */
+void wps_upnp_event_delete_all(struct subscription *s)
{
struct wps_event_ *e;
while ((e = event_dequeue(s)) != NULL)
@@ -134,11 +134,11 @@ static void event_retry(struct wps_event_ *e, int do_next_address)
event_delete(e);
s->last_event_failed = 1;
if (!dl_list_empty(&s->event_queue))
- event_send_all_later(s->sm);
+ wps_upnp_event_send_all_later(s->sm);
return;
}
dl_list_add(&s->event_queue, &e->list);
- event_send_all_later(sm);
+ wps_upnp_event_send_all_later(sm);
}
@@ -228,7 +228,7 @@ static void event_http_cb(void *ctx, struct http_client *c,
/* Schedule sending more if there is more to send */
if (!dl_list_empty(&s->event_queue))
- event_send_all_later(s->sm);
+ wps_upnp_event_send_all_later(s->sm);
break;
case HTTP_CLIENT_FAILED:
wpa_printf(MSG_DEBUG, "WPS UPnP: Event send failure");
@@ -328,19 +328,19 @@ static void event_send_all_later_handler(void *eloop_data, void *user_ctx)
if (nerrors) {
/* Try again later */
- event_send_all_later(sm);
+ wps_upnp_event_send_all_later(sm);
}
}
-/* event_send_all_later -- schedule sending events to all subscribers
+/* wps_upnp_event_send_all_later -- schedule sending events to all subscribers
* that need it.
* This avoids two problems:
* -- After getting a subscription, we should not send the first event
* until after our reply is fully queued to be sent back,
* -- Possible stack depth or infinite recursion issues.
*/
-void event_send_all_later(struct upnp_wps_device_sm *sm)
+void wps_upnp_event_send_all_later(struct upnp_wps_device_sm *sm)
{
/*
* The exact time in the future isn't too important. Waiting a bit
@@ -354,8 +354,8 @@ void event_send_all_later(struct upnp_wps_device_sm *sm)
}
-/* event_send_stop_all -- cleanup */
-void event_send_stop_all(struct upnp_wps_device_sm *sm)
+/* wps_upnp_event_send_stop_all -- cleanup */
+void wps_upnp_event_send_stop_all(struct upnp_wps_device_sm *sm)
{
if (sm->event_send_all_queued)
eloop_cancel_timeout(event_send_all_later_handler, NULL, sm);
@@ -364,13 +364,14 @@ void event_send_stop_all(struct upnp_wps_device_sm *sm)
/**
- * event_add - Add a new event to a queue
+ * wps_upnp_event_add - Add a new event to a queue
* @s: Subscription
* @data: Event data (is copied; caller retains ownership)
* @probereq: Whether this is a Probe Request event
* Returns: 0 on success, -1 on error, 1 on max event queue limit reached
*/
-int event_add(struct subscription *s, const struct wpabuf *data, int probereq)
+int wps_upnp_event_add(struct subscription *s, const struct wpabuf *data,
+ int probereq)
{
struct wps_event_ *e;
unsigned int len;
@@ -416,6 +417,6 @@ int event_add(struct subscription *s, const struct wpabuf *data, int probereq)
wpa_printf(MSG_DEBUG, "WPS UPnP: Queue event %p for subscriber %p "
"(queue len %u)", e, s, len + 1);
dl_list_add_tail(&s->event_queue, &e->list);
- event_send_all_later(s->sm);
+ wps_upnp_event_send_all_later(s->sm);
return 0;
}
diff --git a/src/wps/wps_upnp_i.h b/src/wps/wps_upnp_i.h
index 6a7c627..e87a932 100644
--- a/src/wps/wps_upnp_i.h
+++ b/src/wps/wps_upnp_i.h
@@ -177,10 +177,11 @@ int web_listener_start(struct upnp_wps_device_sm *sm);
void web_listener_stop(struct upnp_wps_device_sm *sm);
/* wps_upnp_event.c */
-int event_add(struct subscription *s, const struct wpabuf *data, int probereq);
-void event_delete_all(struct subscription *s);
-void event_send_all_later(struct upnp_wps_device_sm *sm);
-void event_send_stop_all(struct upnp_wps_device_sm *sm);
+int wps_upnp_event_add(struct subscription *s, const struct wpabuf *data,
+ int probereq);
+void wps_upnp_event_delete_all(struct subscription *s);
+void wps_upnp_event_send_all_later(struct upnp_wps_device_sm *sm);
+void wps_upnp_event_send_stop_all(struct upnp_wps_device_sm *sm);
/* wps_upnp_ap.c */
int upnp_er_set_selected_registrar(struct wps_registrar *reg,
diff --git a/src/wps/wps_upnp_web.c b/src/wps/wps_upnp_web.c
index 7548e84..3c5a97c 100644
--- a/src/wps/wps_upnp_web.c
+++ b/src/wps/wps_upnp_web.c
@@ -765,8 +765,8 @@ static void web_connection_send_reply(struct http_request *req,
if (reply) {
size_t len;
- replydata = (char *) base64_encode(wpabuf_head(reply),
- wpabuf_len(reply), &len);
+ replydata = base64_encode(wpabuf_head(reply), wpabuf_len(reply),
+ &len);
} else
replydata = NULL;
diff --git a/tests/fuzzing/eap-mschapv2-peer/Makefile b/tests/fuzzing/eap-mschapv2-peer/Makefile
new file mode 100644
index 0000000..801e0af
--- /dev/null
+++ b/tests/fuzzing/eap-mschapv2-peer/Makefile
@@ -0,0 +1,20 @@
+all: eap-mschapv2-peer
+include ../rules.include
+
+CFLAGS += -DIEEE8021X_EAPOL
+
+OBJS += $(SRC)/eap_peer/eap_mschapv2.o
+OBJS += $(SRC)/eap_peer/mschapv2.o
+OBJS += $(SRC)/eap_common/eap_common.o
+LIBS += $(SRC)/crypto/libcrypto.a
+LIBS += $(SRC)/utils/libutils.a
+
+eap-mschapv2-peer: eap-mschapv2-peer.o $(OBJS) $(LIBS)
+ $(Q)$(LDO) $(LDFLAGS) -o $@ $^ $(LIBS) $(ELIBS)
+ @$(E) " LD " $@
+
+clean:
+ $(MAKE) -C $(SRC) clean
+ rm -f eap-mschapv2-peer *~ *.o *.d ../*~ ../*.o ../*.d
+
+-include $(OBJS:%.o=%.d)
diff --git a/tests/fuzzing/eap-mschapv2-peer/corpus/server.msg b/tests/fuzzing/eap-mschapv2-peer/corpus/server.msg
new file mode 100644
index 0000000..50ff9d1
--- /dev/null
+++ b/tests/fuzzing/eap-mschapv2-peer/corpus/server.msg
Binary files differ
diff --git a/tests/fuzzing/eap-mschapv2-peer/eap-mschapv2-peer.c b/tests/fuzzing/eap-mschapv2-peer/eap-mschapv2-peer.c
new file mode 100644
index 0000000..8dc794c
--- /dev/null
+++ b/tests/fuzzing/eap-mschapv2-peer/eap-mschapv2-peer.c
@@ -0,0 +1,152 @@
+/*
+ * EAP-SIM peer fuzzer
+ * Copyright (c) 2019, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+
+#include "utils/common.h"
+#include "eap_peer/eap_methods.h"
+#include "eap_peer/eap_config.h"
+#include "eap_peer/eap_i.h"
+#include "../fuzzer-common.h"
+
+int eap_peer_sim_register(void);
+
+struct eap_method * registered_eap_method = NULL;
+
+
+struct eap_method * eap_peer_method_alloc(int version, int vendor,
+ enum eap_type method,
+ const char *name)
+{
+ struct eap_method *eap;
+ eap = os_zalloc(sizeof(*eap));
+ if (!eap)
+ return NULL;
+ eap->version = version;
+ eap->vendor = vendor;
+ eap->method = method;
+ eap->name = name;
+ return eap;
+}
+
+
+int eap_peer_method_register(struct eap_method *method)
+{
+ registered_eap_method = method;
+ return 0;
+}
+
+
+static struct eap_peer_config eap_mschapv2_config = {
+ .identity = (u8 *) "user",
+ .identity_len = 4,
+ .password = (u8 *) "password",
+ .password_len = 8,
+};
+
+struct eap_peer_config * eap_get_config(struct eap_sm *sm)
+{
+ return &eap_mschapv2_config;
+}
+
+
+const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len)
+{
+ static const char *id = "user";
+
+ *len = os_strlen(id);
+ return (const u8 *) id;
+}
+
+
+const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len)
+{
+ struct eap_peer_config *config = eap_get_config(sm);
+
+ *len = config->password_len;
+ return config->password;
+}
+
+
+const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash)
+{
+ struct eap_peer_config *config = eap_get_config(sm);
+
+ *len = config->password_len;
+ if (hash)
+ *hash = !!(config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH);
+ return config->password;
+}
+
+
+const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len)
+{
+ *len = 3;
+ return (const u8 *) "new";
+}
+
+
+void eap_sm_request_identity(struct eap_sm *sm)
+{
+}
+
+
+void eap_sm_request_password(struct eap_sm *sm)
+{
+}
+
+
+void eap_sm_request_new_password(struct eap_sm *sm)
+{
+}
+
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ const u8 *pos, *end;
+ struct eap_sm *sm;
+ void *priv;
+ struct eap_method_ret ret;
+
+ wpa_fuzzer_set_debug_level();
+
+ eap_peer_mschapv2_register();
+ sm = os_zalloc(sizeof(*sm));
+ if (!sm)
+ return 0;
+ priv = registered_eap_method->init(sm);
+ os_memset(&ret, 0, sizeof(ret));
+
+ pos = data;
+ end = pos + size;
+
+ while (end - pos > 2) {
+ u16 flen;
+ struct wpabuf *buf, *req;
+
+ flen = WPA_GET_BE16(pos);
+ pos += 2;
+ if (end - pos < flen)
+ break;
+ req = wpabuf_alloc_copy(pos, flen);
+ if (!req)
+ break;
+ wpa_hexdump_buf(MSG_MSGDUMP, "fuzzer - request", req);
+ buf = registered_eap_method->process(sm, priv, &ret, req);
+ wpa_hexdump_buf(MSG_MSGDUMP, "fuzzer - local response", buf);
+ wpabuf_free(req);
+ wpabuf_free(buf);
+ pos += flen;
+ }
+
+ registered_eap_method->deinit(sm, priv);
+ os_free(registered_eap_method);
+ os_free(sm);
+
+ return 0;
+}
diff --git a/tests/hwsim/auth_serv/as.conf b/tests/hwsim/auth_serv/as.conf
index bc3ae69..3c0eda2 100644
--- a/tests/hwsim/auth_serv/as.conf
+++ b/tests/hwsim/auth_serv/as.conf
@@ -12,7 +12,7 @@ ca_cert=auth_serv/ca.pem
server_cert=auth_serv/server.pem
private_key=auth_serv/server.key
ocsp_stapling_response=LOGDIR/ocsp-server-cache.der
-ocsp_stapling_response_multi=LOGDIR/ocsp-multi-server-cache.der
+ocsp_stapling_response_multi=auth_serv/ocsp-multi-server-cache.der
server_id=server.w1.fi
eap_sim_db=unix:/tmp/hlr_auc_gw.sock
dh_file=auth_serv/dh.conf
diff --git a/tests/hwsim/auth_serv/as2.conf b/tests/hwsim/auth_serv/as2.conf
index 1c2697f..963db7a 100644
--- a/tests/hwsim/auth_serv/as2.conf
+++ b/tests/hwsim/auth_serv/as2.conf
@@ -12,7 +12,7 @@ ca_cert=auth_serv/ca.pem
server_cert=auth_serv/server.pem
private_key=auth_serv/server.key
ocsp_stapling_response=LOGDIR/ocsp-server-cache.der
-ocsp_stapling_response_multi=LOGDIR/ocsp-multi-server-cache.der
+ocsp_stapling_response_multi=auth_serv/ocsp-multi-server-cache.der
server_id=server2.w1.fi
eap_sim_db=unix:/tmp/hlr_auc_gw.sock db=LOGDIR/hostapd.db
dh_file=auth_serv/dh.conf
diff --git a/tests/hwsim/hostapd.py b/tests/hwsim/hostapd.py
index 4430d80..67e8a7f 100644
--- a/tests/hwsim/hostapd.py
+++ b/tests/hwsim/hostapd.py
@@ -271,6 +271,18 @@ class Hostapd:
if addr and addr not in ev:
raise Exception("Unexpected STA address in connection event: " + ev)
+ def wait_ptkinitdone(self, addr, timeout=2):
+ while timeout > 0:
+ sta = self.get_sta(addr)
+ if 'hostapdWPAPTKState' not in sta:
+ raise Exception("GET_STA did not return hostapdWPAPTKState")
+ state = sta['hostapdWPAPTKState']
+ if state == "11":
+ return
+ time.sleep(0.1)
+ timeout -= 0.1
+ raise Exception("Timeout while waiting for PTKINITDONE")
+
def get_status(self):
res = self.request("STATUS")
lines = res.splitlines()
@@ -619,14 +631,17 @@ def terminate(apdev):
hapd_global = HostapdGlobal(apdev)
hapd_global.terminate()
-def wpa2_params(ssid=None, passphrase=None):
+def wpa2_params(ssid=None, passphrase=None, wpa_key_mgmt="WPA-PSK",
+ ieee80211w=None):
params = {"wpa": "2",
- "wpa_key_mgmt": "WPA-PSK",
+ "wpa_key_mgmt": wpa_key_mgmt,
"rsn_pairwise": "CCMP"}
if ssid:
params["ssid"] = ssid
if passphrase:
params["wpa_passphrase"] = passphrase
+ if ieee80211w is not None:
+ params["ieee80211w"] = ieee80211w
return params
def wpa_params(ssid=None, passphrase=None):
diff --git a/tests/hwsim/p2p_utils.py b/tests/hwsim/p2p_utils.py
index df9f7f9..bfd8e2e 100644
--- a/tests/hwsim/p2p_utils.py
+++ b/tests/hwsim/p2p_utils.py
@@ -248,10 +248,17 @@ def go_neg_pin(i_dev, r_dev, i_intent=None, r_intent=None, i_method='enter', r_m
logger.debug("Wait for GO Negotiation Request on r_dev")
ev = r_dev.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15)
if ev is None:
+ t.join()
raise Exception("GO Negotiation timed out")
r_dev.dump_monitor()
logger.debug("Re-initiate GO Negotiation from r_dev")
- r_res = r_dev.p2p_go_neg_init(i_dev.p2p_dev_addr(), pin, r_method, go_intent=r_intent, timeout=20)
+ try:
+ r_res = r_dev.p2p_go_neg_init(i_dev.p2p_dev_addr(), pin, r_method,
+ go_intent=r_intent, timeout=20)
+ except Exception as e:
+ logger.info("go_neg_pin - r_dev.p2p_go_neg_init() exception: " + str(e))
+ t.join()
+ raise
logger.debug("r_res: " + str(r_res))
r_dev.dump_monitor()
t.join()
@@ -328,14 +335,21 @@ def go_neg_pbc(i_dev, r_dev, i_intent=None, r_intent=None, i_freq=None, r_freq=N
logger.debug("Wait for GO Negotiation Request on r_dev")
ev = r_dev.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15)
if ev is None:
+ t.join()
raise Exception("GO Negotiation timed out")
r_dev.dump_monitor()
# Allow some time for the GO Neg Resp to go out before initializing new
# GO Negotiation.
time.sleep(0.2)
logger.debug("Re-initiate GO Negotiation from r_dev")
- r_res = r_dev.p2p_go_neg_init(i_dev.p2p_dev_addr(), None, "pbc",
- go_intent=r_intent, timeout=20, freq=r_freq)
+ try:
+ r_res = r_dev.p2p_go_neg_init(i_dev.p2p_dev_addr(), None, "pbc",
+ go_intent=r_intent, timeout=20,
+ freq=r_freq)
+ except Exception as e:
+ logger.info("go_neg_pbc - r_dev.p2p_go_neg_init() exception: " + str(e))
+ t.join()
+ raise
logger.debug("r_res: " + str(r_res))
r_dev.dump_monitor()
t.join()
diff --git a/tests/hwsim/run-tests.py b/tests/hwsim/run-tests.py
index d291b9a..b201cd7 100755
--- a/tests/hwsim/run-tests.py
+++ b/tests/hwsim/run-tests.py
@@ -510,6 +510,7 @@ def main():
if args.stdin_ctrl:
set_term_echo(sys.stdin.fileno(), True)
sys.exit(1)
+ skip_reason = None
try:
if t.__code__.co_argcount > 2:
params = {}
@@ -547,6 +548,7 @@ def main():
break
except HwsimSkip as e:
logger.info("Skip test case: %s" % e)
+ skip_reason = e
result = "SKIP"
except NameError as e:
import traceback
@@ -635,6 +637,8 @@ def main():
logger.info(result)
if args.loglevel == logging.WARNING:
print(result)
+ if skip_reason:
+ print("REASON", skip_reason)
sys.stdout.flush()
if not reset_ok:
diff --git a/tests/hwsim/start.sh b/tests/hwsim/start.sh
index de2b5f0..7a26d28 100755
--- a/tests/hwsim/start.sh
+++ b/tests/hwsim/start.sh
@@ -155,51 +155,6 @@ if [ ! -r $LOGDIR/ocsp-server-cache.der ]; then
cp $DIR/auth_serv/ocsp-server-cache.der $LOGDIR/ocsp-server-cache.der
fi
-cp $DIR/auth_serv/ocsp-multi-server-cache.der $LOGDIR/ocsp-multi-server-cache.der
-
-openssl ocsp -index $DIR/auth_serv/index.txt \
- -rsigner $DIR/auth_serv/ocsp-responder.pem \
- -rkey $DIR/auth_serv/ocsp-responder.key \
- -resp_key_id \
- -CA $DIR/auth_serv/ca.pem \
- -issuer $DIR/auth_serv/ca.pem \
- -verify_other $DIR/auth_serv/ca.pem -trust_other \
- -ndays 7 \
- -reqin $DIR/auth_serv/ocsp-req.der \
- -respout $LOGDIR/ocsp-server-cache-key-id.der > $LOGDIR/ocsp.log 2>&1
-
-for i in unknown revoked; do
- openssl ocsp -index $DIR/auth_serv/index-$i.txt \
- -rsigner $DIR/auth_serv/ocsp-responder.pem \
- -rkey $DIR/auth_serv/ocsp-responder.key \
- -CA $DIR/auth_serv/ca.pem \
- -issuer $DIR/auth_serv/ca.pem \
- -verify_other $DIR/auth_serv/ca.pem -trust_other \
- -ndays 7 \
- -reqin $DIR/auth_serv/ocsp-req.der \
- -respout $LOGDIR/ocsp-server-cache-$i.der >> $LOGDIR/ocsp.log 2>&1
-done
-
-openssl ocsp -reqout $LOGDIR/ocsp-req.der -issuer $DIR/auth_serv/ca.pem \
- -sha256 -serial 0xD8D3E3A6CBE3CD1F -no_nonce >> $LOGDIR/ocsp.log 2>&1
-for i in "" "-unknown" "-revoked"; do
- openssl ocsp -index $DIR/auth_serv/index$i.txt \
- -rsigner $DIR/auth_serv/ca.pem \
- -rkey $DIR/auth_serv/ca-key.pem \
- -CA $DIR/auth_serv/ca.pem \
- -ndays 7 \
- -reqin $LOGDIR/ocsp-req.der \
- -resp_no_certs \
- -respout $LOGDIR/ocsp-resp-ca-signed$i.der >> $LOGDIR/ocsp.log 2>&1
-done
-openssl ocsp -index $DIR/auth_serv/index.txt \
- -rsigner $DIR/auth_serv/server.pem \
- -rkey $DIR/auth_serv/server.key \
- -CA $DIR/auth_serv/ca.pem \
- -ndays 7 \
- -reqin $LOGDIR/ocsp-req.der \
- -respout $LOGDIR/ocsp-resp-server-signed.der >> $LOGDIR/ocsp.log 2>&1
-
touch $LOGDIR/hostapd.db
sudo $HAPD_AS -ddKt $LOGDIR/as.conf $LOGDIR/as2.conf > $LOGDIR/auth_serv &
diff --git a/tests/hwsim/test_ap_acs.py b/tests/hwsim/test_ap_acs.py
index 93170dc..3cade3c 100644
--- a/tests/hwsim/test_ap_acs.py
+++ b/tests/hwsim/test_ap_acs.py
@@ -89,6 +89,21 @@ def test_ap_acs_chanlist(dev, apdev):
dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
+def test_ap_acs_freqlist(dev, apdev):
+ """Automatic channel selection with freqlist set"""
+ force_prev_ap_on_24g(apdev[0])
+ params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
+ params['channel'] = '0'
+ params['freqlist'] = '2412 2437 2462'
+ hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+ wait_acs(hapd)
+
+ freq = int(hapd.get_status_field("freq"))
+ if freq not in [2412, 2437, 2462]:
+ raise Exception("Unexpected frequency: " + freq)
+
+ dev[0].connect("test-acs", psk="12345678", scan_freq=str(freq))
+
def test_ap_acs_invalid_chanlist(dev, apdev):
"""Automatic channel selection with invalid chanlist"""
force_prev_ap_on_24g(apdev[0])
diff --git a/tests/hwsim/test_ap_ciphers.py b/tests/hwsim/test_ap_ciphers.py
index e10927a..ae78e0c 100644
--- a/tests/hwsim/test_ap_ciphers.py
+++ b/tests/hwsim/test_ap_ciphers.py
@@ -374,6 +374,7 @@ def test_ap_cipher_mixed_wpa_wpa2(dev, apdev):
"rsn_pairwise": "CCMP",
"wpa_pairwise": "TKIP"}
hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].connect(ssid, psk=passphrase, proto="WPA2",
pairwise="CCMP", group="TKIP", scan_freq="2412")
status = dev[0].get_status()
@@ -862,7 +863,12 @@ def test_ap_wpa2_delayed_m1_m3_zero_tk(dev, apdev):
if "OK" not in hapd.request("RESEND_M3 " + addr):
raise Exception("RESEND_M3 failed")
- if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s" % (addr, 0, 1, 6*"00", 16*"00")):
+ KEY_FLAG_RX = 0x04
+ KEY_FLAG_TX = 0x08
+ KEY_FLAG_PAIRWISE = 0x20
+ KEY_FLAG_RX_TX = KEY_FLAG_RX | KEY_FLAG_TX
+ KEY_FLAG_PAIRWISE_RX_TX = KEY_FLAG_PAIRWISE | KEY_FLAG_RX_TX
+ if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s %d" % (addr, 0, 1, 6*"00", 16*"00", KEY_FLAG_PAIRWISE_RX_TX)):
raise Exception("SET_KEY failed")
time.sleep(0.1)
hwsim_utils.test_connectivity(dev[0], hapd, timeout=1, broadcast=False,
@@ -978,3 +984,104 @@ def test_ap_wpa2_plaintext_group_m1_pmf(dev, apdev):
if "OK" not in hapd.request("RESEND_GROUP_M1 " + addr):
raise Exception("RESEND_GROUP_M1 failed")
time.sleep(0.1)
+
+def test_ap_wpa2_gtk_initial_rsc_tkip(dev, apdev):
+ """Initial group cipher RSC (TKIP)"""
+ run_ap_wpa2_gtk_initial_rsc(dev, apdev, "TKIP")
+
+def test_ap_wpa2_gtk_initial_rsc_ccmp(dev, apdev):
+ """Initial group cipher RSC (CCMP)"""
+ run_ap_wpa2_gtk_initial_rsc(dev, apdev, "CCMP")
+
+def test_ap_wpa2_gtk_initial_rsc_ccmp_256(dev, apdev):
+ """Initial group cipher RSC (CCMP-256)"""
+ run_ap_wpa2_gtk_initial_rsc(dev, apdev, "CCMP-256")
+
+def test_ap_wpa2_gtk_initial_rsc_gcmp(dev, apdev):
+ """Initial group cipher RSC (GCMP)"""
+ run_ap_wpa2_gtk_initial_rsc(dev, apdev, "GCMP")
+
+def test_ap_wpa2_gtk_initial_rsc_gcmp_256(dev, apdev):
+ """Initial group cipher RSC (GCMP-256)"""
+ run_ap_wpa2_gtk_initial_rsc(dev, apdev, "GCMP-256")
+
+def run_ap_wpa2_gtk_initial_rsc(dev, apdev, cipher):
+ if cipher not in dev[0].get_capability("pairwise") or \
+ cipher not in dev[0].get_capability("group"):
+ raise HwsimSkip("Cipher %s not supported" % cipher)
+
+ params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
+ params["rsn_pairwise"] = cipher
+ params["group_cipher"] = cipher
+ params["gtk_rsc_override"] = "341200000000"
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ Wlantest.setup(hapd)
+ wt = Wlantest()
+ wt.flush()
+ wt.add_passphrase("12345678")
+
+ dev[0].connect("test-wpa2-psk", psk="12345678", proto="WPA2",
+ pairwise=cipher, group=cipher, scan_freq="2412")
+ hapd.wait_sta()
+ # Verify that unicast traffic works, but broadcast traffic does not.
+ hwsim_utils.test_connectivity(dev[0], hapd, broadcast=False)
+ hwsim_utils.test_connectivity(dev[0], hapd, success_expected=False)
+ hwsim_utils.test_connectivity(dev[0], hapd, success_expected=False)
+
+def test_ap_wpa2_igtk_initial_rsc_aes_128_cmac(dev, apdev):
+ """Initial management group cipher RSC (AES-128-CMAC)"""
+ run_ap_wpa2_igtk_initial_rsc(dev, apdev, "AES-128-CMAC")
+
+def test_ap_wpa2_igtk_initial_rsc_bip_gmac_128(dev, apdev):
+ """Initial management group cipher RSC (BIP-GMAC-128)"""
+ run_ap_wpa2_igtk_initial_rsc(dev, apdev, "BIP-GMAC-128")
+
+def test_ap_wpa2_igtk_initial_rsc_bip_gmac_256(dev, apdev):
+ """Initial management group cipher RSC (BIP-GMAC-256)"""
+ run_ap_wpa2_igtk_initial_rsc(dev, apdev, "BIP-GMAC-256")
+
+def test_ap_wpa2_igtk_initial_rsc_bip_cmac_256(dev, apdev):
+ """Initial management group cipher RSC (BIP-CMAC-256)"""
+ run_ap_wpa2_igtk_initial_rsc(dev, apdev, "BIP-CMAC-256")
+
+def run_ap_wpa2_igtk_initial_rsc(dev, apdev, cipher):
+ if cipher not in dev[0].get_capability("group_mgmt"):
+ raise HwsimSkip("Cipher %s not supported" % cipher)
+
+ params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
+ params["ieee80211w"] = "2"
+ params["rsn_pairwise"] = "CCMP"
+ params["group_cipher"] = "CCMP"
+ params["group_mgmt_cipher"] = cipher
+ params["igtk_rsc_override"] = "341200000000"
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ Wlantest.setup(hapd)
+ wt = Wlantest()
+ wt.flush()
+ wt.add_passphrase("12345678")
+
+ dev[0].connect("test-wpa2-psk", psk="12345678", proto="WPA2",
+ ieee80211w="2", pairwise="CCMP", group="CCMP",
+ group_mgmt=cipher,
+ scan_freq="2412")
+ hapd.wait_sta()
+ # Verify that broadcast robust management frames are dropped.
+ dev[0].note("Sending broadcast Deauthentication and Disassociation frames with too small IPN")
+ hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff test=1")
+ hapd.request("DISASSOCIATE ff:ff:ff:ff:ff:ff test=1")
+ hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff test=1")
+ hapd.request("DISASSOCIATE ff:ff:ff:ff:ff:ff test=1")
+ dev[0].note("Done sending broadcast Deauthentication and Disassociation frames with too small IPN")
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
+ if ev is not None:
+ raise Exception("Unexpected disconnection")
+
+ # Verify thar unicast robust management frames go through.
+ hapd.request("DEAUTHENTICATE " + dev[0].own_addr() + " reason=123 test=1")
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
+ if ev is None:
+ raise Exception("Disconnection not reported")
+ if "reason=123" not in ev:
+ raise Exception("Unexpected disconnection reason: " + ev)
diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py
index c6e724a..f502bf7 100644
--- a/tests/hwsim/test_ap_eap.py
+++ b/tests/hwsim/test_ap_eap.py
@@ -4118,11 +4118,40 @@ def int_eap_server_params():
"dh_file": "auth_serv/dh.conf"}
return params
+def run_openssl(arg):
+ logger.info(' '.join(arg))
+ cmd = subprocess.Popen(arg, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ res = cmd.stdout.read().decode() + "\n" + cmd.stderr.read().decode()
+ cmd.stdout.close()
+ cmd.stderr.close()
+ cmd.wait()
+ if cmd.returncode != 0:
+ raise Exception("bad return code from openssl\n\n" + res)
+ logger.info("openssl result:\n" + res)
+
+def ocsp_cache_key_id(outfile):
+ if os.path.exists(outfile):
+ return
+ arg = ["openssl", "ocsp", "-index", "auth_serv/index.txt",
+ '-rsigner', 'auth_serv/ocsp-responder.pem',
+ '-rkey', 'auth_serv/ocsp-responder.key',
+ '-resp_key_id',
+ '-CA', 'auth_serv/ca.pem',
+ '-issuer', 'auth_serv/ca.pem',
+ '-verify_other', 'auth_serv/ca.pem',
+ '-trust_other',
+ '-ndays', '7',
+ '-reqin', 'auth_serv/ocsp-req.der',
+ '-respout', outfile]
+ run_openssl(arg)
+
def test_ap_wpa2_eap_tls_ocsp_key_id(dev, apdev, params):
"""EAP-TLS and OCSP certificate signed OCSP response using key ID"""
check_ocsp_support(dev[0])
check_pkcs12_support(dev[0])
ocsp = os.path.join(params['logdir'], "ocsp-server-cache-key-id.der")
+ ocsp_cache_key_id(ocsp)
if not os.path.exists(ocsp):
raise HwsimSkip("No OCSP response available")
params = int_eap_server_params()
@@ -4134,13 +4163,59 @@ def test_ap_wpa2_eap_tls_ocsp_key_id(dev, apdev, params):
private_key_passwd="whatever", ocsp=2,
scan_freq="2412")
+def ocsp_req(outfile):
+ if os.path.exists(outfile):
+ return
+ arg = ["openssl", "ocsp",
+ "-reqout", outfile,
+ '-issuer', 'auth_serv/ca.pem',
+ '-sha256',
+ '-serial', '0xD8D3E3A6CBE3CD1F',
+ '-no_nonce']
+ run_openssl(arg)
+ if not os.path.exists(outfile):
+ raise HwsimSkip("Failed to generate OCSP request")
+
+def ocsp_resp_ca_signed(reqfile, outfile, status):
+ ocsp_req(reqfile)
+ if os.path.exists(outfile):
+ return
+ arg = ["openssl", "ocsp",
+ "-index", "auth_serv/index%s.txt" % status,
+ "-rsigner", "auth_serv/ca.pem",
+ "-rkey", "auth_serv/ca-key.pem",
+ "-CA", "auth_serv/ca.pem",
+ "-ndays", "7",
+ "-reqin", reqfile,
+ "-resp_no_certs",
+ "-respout", outfile]
+ run_openssl(arg)
+ if not os.path.exists(outfile):
+ raise HwsimSkip("No OCSP response available")
+
+def ocsp_resp_server_signed(reqfile, outfile):
+ ocsp_req(reqfile)
+ if os.path.exists(outfile):
+ return
+ arg = ["openssl", "ocsp",
+ "-index", "auth_serv/index.txt",
+ "-rsigner", "auth_serv/server.pem",
+ "-rkey", "auth_serv/server.key",
+ "-CA", "auth_serv/ca.pem",
+ "-ndays", "7",
+ "-reqin", reqfile,
+ "-respout", outfile]
+ run_openssl(arg)
+ if not os.path.exists(outfile):
+ raise HwsimSkip("No OCSP response available")
+
def test_ap_wpa2_eap_tls_ocsp_ca_signed_good(dev, apdev, params):
"""EAP-TLS and CA signed OCSP response (good)"""
check_ocsp_support(dev[0])
check_pkcs12_support(dev[0])
+ req = os.path.join(params['logdir'], "ocsp-req.der")
ocsp = os.path.join(params['logdir'], "ocsp-resp-ca-signed.der")
- if not os.path.exists(ocsp):
- raise HwsimSkip("No OCSP response available")
+ ocsp_resp_ca_signed(req, ocsp, "")
params = int_eap_server_params()
params["ocsp_stapling_response"] = ocsp
hostapd.add_ap(apdev[0], params)
@@ -4154,9 +4229,9 @@ def test_ap_wpa2_eap_tls_ocsp_ca_signed_revoked(dev, apdev, params):
"""EAP-TLS and CA signed OCSP response (revoked)"""
check_ocsp_support(dev[0])
check_pkcs12_support(dev[0])
+ req = os.path.join(params['logdir'], "ocsp-req.der")
ocsp = os.path.join(params['logdir'], "ocsp-resp-ca-signed-revoked.der")
- if not os.path.exists(ocsp):
- raise HwsimSkip("No OCSP response available")
+ ocsp_resp_ca_signed(req, ocsp, "-revoked")
params = int_eap_server_params()
params["ocsp_stapling_response"] = ocsp
hostapd.add_ap(apdev[0], params)
@@ -4186,9 +4261,9 @@ def test_ap_wpa2_eap_tls_ocsp_ca_signed_unknown(dev, apdev, params):
"""EAP-TLS and CA signed OCSP response (unknown)"""
check_ocsp_support(dev[0])
check_pkcs12_support(dev[0])
+ req = os.path.join(params['logdir'], "ocsp-req.der")
ocsp = os.path.join(params['logdir'], "ocsp-resp-ca-signed-unknown.der")
- if not os.path.exists(ocsp):
- raise HwsimSkip("No OCSP response available")
+ ocsp_resp_ca_signed(req, ocsp, "-unknown")
params = int_eap_server_params()
params["ocsp_stapling_response"] = ocsp
hostapd.add_ap(apdev[0], params)
@@ -4216,9 +4291,9 @@ def test_ap_wpa2_eap_tls_ocsp_server_signed(dev, apdev, params):
"""EAP-TLS and server signed OCSP response"""
check_ocsp_support(dev[0])
check_pkcs12_support(dev[0])
+ req = os.path.join(params['logdir'], "ocsp-req.der")
ocsp = os.path.join(params['logdir'], "ocsp-resp-server-signed.der")
- if not os.path.exists(ocsp):
- raise HwsimSkip("No OCSP response available")
+ ocsp_resp_server_signed(req, ocsp)
params = int_eap_server_params()
params["ocsp_stapling_response"] = ocsp
hostapd.add_ap(apdev[0], params)
@@ -4323,10 +4398,26 @@ def test_ap_wpa2_eap_tls_ocsp_unknown_sign(dev, apdev):
if ev is None:
raise Exception("Timeout on EAP failure report")
+def ocsp_resp_status(outfile, status):
+ if os.path.exists(outfile):
+ return
+ arg = ["openssl", "ocsp", "-index", "auth_serv/index-%s.txt" % status,
+ '-rsigner', 'auth_serv/ocsp-responder.pem',
+ '-rkey', 'auth_serv/ocsp-responder.key',
+ '-CA', 'auth_serv/ca.pem',
+ '-issuer', 'auth_serv/ca.pem',
+ '-verify_other', 'auth_serv/ca.pem',
+ '-trust_other',
+ '-ndays', '7',
+ '-reqin', 'auth_serv/ocsp-req.der',
+ '-respout', outfile]
+ run_openssl(arg)
+
def test_ap_wpa2_eap_ttls_ocsp_revoked(dev, apdev, params):
"""WPA2-Enterprise connection using EAP-TTLS and OCSP status revoked"""
check_ocsp_support(dev[0])
ocsp = os.path.join(params['logdir'], "ocsp-server-cache-revoked.der")
+ ocsp_resp_status(ocsp, "revoked")
if not os.path.exists(ocsp):
raise HwsimSkip("No OCSP response available")
params = int_eap_server_params()
@@ -4355,9 +4446,10 @@ def test_ap_wpa2_eap_ttls_ocsp_revoked(dev, apdev, params):
raise Exception("Timeout on EAP failure report")
def test_ap_wpa2_eap_ttls_ocsp_unknown(dev, apdev, params):
- """WPA2-Enterprise connection using EAP-TTLS and OCSP status revoked"""
+ """WPA2-Enterprise connection using EAP-TTLS and OCSP status unknown"""
check_ocsp_support(dev[0])
ocsp = os.path.join(params['logdir'], "ocsp-server-cache-unknown.der")
+ ocsp_resp_status(ocsp, "unknown")
if not os.path.exists(ocsp):
raise HwsimSkip("No OCSP response available")
params = int_eap_server_params()
@@ -4384,9 +4476,10 @@ def test_ap_wpa2_eap_ttls_ocsp_unknown(dev, apdev, params):
raise Exception("Timeout on EAP failure report")
def test_ap_wpa2_eap_ttls_optional_ocsp_unknown(dev, apdev, params):
- """WPA2-Enterprise connection using EAP-TTLS and OCSP status revoked"""
+ """WPA2-Enterprise connection using EAP-TTLS and OCSP status unknown"""
check_ocsp_support(dev[0])
ocsp = os.path.join(params['logdir'], "ocsp-server-cache-unknown.der")
+ ocsp_resp_status(ocsp, "unknown")
if not os.path.exists(ocsp):
raise HwsimSkip("No OCSP response available")
params = int_eap_server_params()
@@ -4426,16 +4519,7 @@ def root_ocsp(cert):
arg = ["openssl", "ocsp", "-reqout", fn2, "-issuer", ca, "-sha256",
"-cert", cert, "-no_nonce", "-text"]
- logger.info(' '.join(arg))
- cmd = subprocess.Popen(arg, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- res = cmd.stdout.read().decode() + "\n" + cmd.stderr.read().decode()
- cmd.stdout.close()
- cmd.stderr.close()
- cmd.wait()
- if cmd.returncode != 0:
- raise Exception("bad return code from openssl ocsp\n\n" + res)
- logger.info("OCSP request:\n" + res)
+ run_openssl(arg)
fd, fn = tempfile.mkstemp()
os.close(fd)
@@ -4444,15 +4528,7 @@ def root_ocsp(cert):
"-CA", ca, "-issuer", ca, "-verify_other", ca, "-trust_other",
"-ndays", "7", "-reqin", fn2, "-resp_no_certs", "-respout", fn,
"-text"]
- cmd = subprocess.Popen(arg, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- res = cmd.stdout.read().decode() + "\n" + cmd.stderr.read().decode()
- cmd.stdout.close()
- cmd.stderr.close()
- cmd.wait()
- if cmd.returncode != 0:
- raise Exception("bad return code from openssl ocsp\n\n" + res)
- logger.info("OCSP response:\n" + res)
+ run_openssl(arg)
os.unlink(fn2)
return fn
@@ -4466,15 +4542,7 @@ def ica_ocsp(cert, md="-sha256"):
arg = ["openssl", "ocsp", "-reqout", fn2, "-issuer", ca, md,
"-cert", cert, "-no_nonce", "-text"]
- cmd = subprocess.Popen(arg, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- res = cmd.stdout.read().decode() + "\n" + cmd.stderr.read().decode()
- cmd.stdout.close()
- cmd.stderr.close()
- cmd.wait()
- if cmd.returncode != 0:
- raise Exception("bad return code from openssl ocsp\n\n" + res)
- logger.info("OCSP request:\n" + res)
+ run_openssl(arg)
fd, fn = tempfile.mkstemp()
os.close(fd)
@@ -4483,15 +4551,7 @@ def ica_ocsp(cert, md="-sha256"):
"-CA", ca, "-issuer", ca, "-verify_other", ca, "-trust_other",
"-ndays", "7", "-reqin", fn2, "-resp_no_certs", "-respout", fn,
"-text"]
- cmd = subprocess.Popen(arg, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- res = cmd.stdout.read().decode() + "\n" + cmd.stderr.read().decode()
- cmd.stdout.close()
- cmd.stderr.close()
- cmd.wait()
- if cmd.returncode != 0:
- raise Exception("bad return code from openssl ocsp\n\n" + res)
- logger.info("OCSP response:\n" + res)
+ run_openssl(arg)
os.unlink(fn2)
return fn
@@ -4691,14 +4751,13 @@ def test_ap_wpa2_eap_tls_ocsp_multi_revoked(dev, apdev, params):
check_ocsp_multi_support(dev[0])
check_pkcs12_support(dev[0])
+ req = os.path.join(params['logdir'], "ocsp-req.der")
ocsp_revoked = os.path.join(params['logdir'],
"ocsp-resp-ca-signed-revoked.der")
- if not os.path.exists(ocsp_revoked):
- raise HwsimSkip("No OCSP response (revoked) available")
ocsp_unknown = os.path.join(params['logdir'],
"ocsp-resp-ca-signed-unknown.der")
- if not os.path.exists(ocsp_unknown):
- raise HwsimSkip("No OCSP response(unknown) available")
+ ocsp_resp_ca_signed(req, ocsp_revoked, "-revoked")
+ ocsp_resp_ca_signed(req, ocsp_unknown, "-unknown")
with open(ocsp_revoked, "rb") as f:
resp_revoked = f.read()
@@ -7191,3 +7250,20 @@ def test_ap_wpa2_eap_tls_tod_tofu(dev, apdev):
raise Exception("TOD-TOFU policy not reported for server certificate")
if tod1:
raise Exception("TOD-TOFU policy unexpectedly reported for CA certificate")
+
+def test_ap_wpa2_eap_sake_no_control_port(dev, apdev):
+ """WPA2-Enterprise connection using EAP-SAKE without nl80211 control port"""
+ params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
+ params['driver_params'] = "control_port=0"
+ hapd = hostapd.add_ap(apdev[0], params)
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add("wlan5", drv_params="control_port=0")
+ eap_connect(wpas, hapd, "SAKE", "sake user",
+ password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
+ eap_reauth(wpas, "SAKE")
+
+ logger.info("Negative test with incorrect password")
+ wpas.request("REMOVE_NETWORK all")
+ eap_connect(wpas, hapd, "SAKE", "sake user",
+ password_hex="ff23456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
+ expect_failure=True)
diff --git a/tests/hwsim/test_ap_ft.py b/tests/hwsim/test_ap_ft.py
index 66ca8cf..e3cd4be 100644
--- a/tests/hwsim/test_ap_ft.py
+++ b/tests/hwsim/test_ap_ft.py
@@ -175,6 +175,10 @@ def run_roams(dev, apdev, hapd0, hapd1, ssid, passphrase, over_ds=False,
copts["bssid"] = apdev[0]['bssid']
netw = dev.connect(ssid, **copts)
if pmksa_caching:
+ if dev.get_status_field('bssid') == apdev[0]['bssid']:
+ hapd0.wait_sta()
+ else:
+ hapd1.wait_sta()
dev.request("DISCONNECT")
dev.wait_disconnected()
dev.request("RECONNECT")
@@ -1107,6 +1111,60 @@ def test_ap_ft_sae_pmksa_caching(dev, apdev):
run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True,
pmksa_caching=True)
+def test_ap_ft_sae_pmksa_caching_pwe(dev, apdev):
+ """WPA2-FT-SAE AP and PMKSA caching for initial mobility domain association (STA PWE both)"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ params['wpa_key_mgmt'] = "FT-SAE"
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ params['wpa_key_mgmt'] = "FT-SAE"
+ hapd = hostapd.add_ap(apdev[1], params)
+ key_mgmt = hapd.get_config()['key_mgmt']
+ if key_mgmt.split(' ')[0] != "FT-SAE":
+ raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
+
+ try:
+ dev[0].request("SET sae_groups ")
+ dev[0].set("sae_pwe", "2")
+ run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True,
+ pmksa_caching=True)
+ finally:
+ dev[0].set("sae_groups", "")
+ dev[0].set("sae_pwe", "0")
+
+def test_ap_ft_sae_pmksa_caching_h2e(dev, apdev):
+ """WPA2-FT-SAE AP and PMKSA caching for initial mobility domain association (H2E)"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ params['wpa_key_mgmt'] = "FT-SAE"
+ params['sae_pwe'] = "1"
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ params['wpa_key_mgmt'] = "FT-SAE"
+ params['sae_pwe'] = "1"
+ hapd = hostapd.add_ap(apdev[1], params)
+ key_mgmt = hapd.get_config()['key_mgmt']
+ if key_mgmt.split(' ')[0] != "FT-SAE":
+ raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
+
+ try:
+ dev[0].request("SET sae_groups ")
+ dev[0].set("sae_pwe", "1")
+ run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True,
+ pmksa_caching=True)
+ finally:
+ dev[0].set("sae_groups", "")
+ dev[0].set("sae_pwe", "0")
+
def generic_ap_ft_eap(dev, apdev, vlan=False, cui=False, over_ds=False,
discovery=False, roams=1, wpa_ptk_rekey=0,
only_one_way=False):
@@ -1290,6 +1348,84 @@ def test_ap_ft_eap_pull_wildcard(dev, apdev):
run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True)
+def test_ap_ft_eap_pull_wildcard_multi_bss(dev, apdev, params):
+ """WPA2-EAP-FT AP (pull PMK) - wildcard R0KH/R1KH with multiple BSSs"""
+ bssconf = os.path.join(params['logdir'],
+ 'ap_ft_eap_pull_wildcard_multi_bss.bss.conf')
+ ssid = "test-ft"
+ passphrase = "12345678"
+ radius = hostapd.radius_params()
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=True)
+ params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
+ params["ieee8021x"] = "1"
+ params["pmk_r1_push"] = "0"
+ params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
+ params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
+ params["eap_server"] = "0"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd = hostapd.add_ap(apdev[0], params)
+ ifname2 = apdev[0]['ifname'] + "-2"
+ bssid2 = "02:00:00:00:03:01"
+ params['nas_identifier'] = "nas1b.w1.fi"
+ params['r1_key_holder'] = "000102030415"
+ with open(bssconf, 'w') as f:
+ f.write("driver=nl80211\n")
+ f.write("hw_mode=g\n")
+ f.write("channel=1\n")
+ f.write("ieee80211n=1\n")
+ f.write("interface=%s\n" % ifname2)
+ f.write("bssid=%s\n" % bssid2)
+ f.write("ctrl_interface=/var/run/hostapd\n")
+ for name, val in params.items():
+ f.write("%s=%s\n" % (name, val))
+ hapd2 = hostapd.add_bss(apdev[0], ifname2, bssconf)
+
+ params = ft_params2(ssid=ssid, passphrase=passphrase, discovery=True)
+ params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
+ params["ieee8021x"] = "1"
+ params["pmk_r1_push"] = "0"
+ params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
+ params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
+ params["eap_server"] = "0"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ # The first iteration of the roaming test will use wildcard R0KH discovery
+ # and RRB sequence number synchronization while the second iteration shows
+ # the clean RRB exchange where those extra steps are not needed.
+ for i in range(2):
+ hapd.note("Test iteration %d" % i)
+ dev[0].note("Test iteration %d" % i)
+
+ id = dev[0].connect(ssid, key_mgmt="FT-EAP", eap="GPSK",
+ identity="gpsk user",
+ password="abcdefghijklmnop0123456789abcdef",
+ bssid=bssid2,
+ scan_freq="2412")
+ res = dev[0].get_status_field("bssid")
+ if res != bssid2:
+ raise Exception("Unexpected BSSID after initial connection: " + res)
+
+ dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
+ dev[0].set_network(id, "bssid", "00:00:00:00:00:00")
+ dev[0].roam(apdev[1]['bssid'])
+ res = dev[0].get_status_field("bssid")
+ if res != apdev[1]['bssid']:
+ raise Exception("Unexpected BSSID after first roam: " + res)
+
+ dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
+ dev[0].roam(apdev[0]['bssid'])
+ res = dev[0].get_status_field("bssid")
+ if res != apdev[0]['bssid']:
+ raise Exception("Unexpected BSSID after second roam: " + res)
+
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+ dev[0].dump_monitor()
+ hapd.dump_monitor()
+ hapd2.dump_monitor()
+
@remote_compatible
def test_ap_ft_mismatching_rrb_key_push(dev, apdev):
"""WPA2-PSK-FT AP over DS with mismatching RRB key (push)"""
@@ -2406,20 +2542,6 @@ def test_rsn_ie_proto_ft_psk_sta(dev, apdev):
raise Exception("Unexpected connection")
dev[0].request("DISCONNECT")
- logger.info('Unexpected PMKID causing internal hostapd error')
- hapd.disable()
- hapd.set('own_ie_override', '30260100000fac040100000fac040100000fac048c000100ffffffffffffffffffffffffffffffff' + '3603a1b201')
- hapd.enable()
- dev[0].request("BSS_FLUSH 0")
- dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
- dev[0].select_network(id, freq=2412)
- # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
- # complete.
- ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
- if ev is not None:
- raise Exception("Unexpected connection")
- dev[0].request("DISCONNECT")
-
def start_ft(apdev, wpa_ptk_rekey=None):
ssid = "test-ft"
passphrase = "12345678"
diff --git a/tests/hwsim/test_ap_hs20.py b/tests/hwsim/test_ap_hs20.py
index fb12152..ff84bb4 100644
--- a/tests/hwsim/test_ap_hs20.py
+++ b/tests/hwsim/test_ap_hs20.py
@@ -22,6 +22,7 @@ import hwsim_utils
from tshark import run_tshark
from wlantest import Wlantest
from wpasupplicant import WpaSupplicant
+from wlantest import WlantestCapture
from test_ap_eap import check_eap_capa, check_domain_match_full
from test_gas import gas_rx, parse_gas, action_response, anqp_initial_resp, send_gas_resp, ACTION_CATEG_PUBLIC, GAS_INITIAL_RESPONSE
@@ -797,6 +798,7 @@ def eap_test(dev, ap, eap_params, method, user, release=0):
params['hs20_release'] = str(release)
hapd = hostapd.add_ap(ap, params)
+ dev.flush_scan_cache()
dev.hs20_enable()
dev.add_cred_values({'realm': "example.com",
'ca_cert': "auth_serv/ca.pem",
@@ -917,6 +919,7 @@ def test_ap_hs20_eap_tls(dev, apdev):
params['nai_realm'] = ["0,example.com,13[5:6]"]
hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].hs20_enable()
dev[0].add_cred_values({'realm': "example.com",
'username': "certificate-user",
@@ -979,6 +982,7 @@ def test_ap_hs20_nai_realms(dev, apdev):
params['nai_realm'] = ["0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]"]
hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].hs20_enable()
id = dev[0].add_cred_values({'realm': "example.com",
'ca_cert': "auth_serv/ca.pem",
@@ -996,6 +1000,7 @@ def test_ap_hs20_roaming_consortium(dev, apdev):
params['hessid'] = bssid
hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].hs20_enable()
for consortium in ["112233", "1020304050", "010203040506", "fedcba"]:
id = dev[0].add_cred_values({'username': "user",
@@ -1020,6 +1025,7 @@ def test_ap_hs20_roaming_consortiums_match(dev, apdev):
params['hessid'] = bssid
hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].hs20_enable()
tests = [("112233", "112233"),
("ffffff,1020304050,eeeeee", "1020304050")]
@@ -1441,6 +1447,7 @@ def _test_ap_hs20_gas_while_associated_with_pmf(dev, apdev):
params['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"]
hostapd.add_ap(apdev[1], params)
+ dev[0].flush_scan_cache()
dev[0].hs20_enable()
dev[0].request("SET pmf 2")
id = dev[0].add_cred_values({'realm': "example.com",
@@ -4671,18 +4678,10 @@ def _test_proxyarp_open(dev, apdev, params, ebtables=False):
time.sleep(0.5)
cmd = {}
- cmd[0] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
- '-w', cap_br, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
- cmd[1] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[0].ifname,
- '-w', cap_dev0, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
- cmd[2] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[1].ifname,
- '-w', cap_dev1, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
- cmd[3] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[2].ifname,
- '-w', cap_dev2, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
+ cmd[0] = WlantestCapture('ap-br0', cap_br)
+ cmd[1] = WlantestCapture(dev[0].ifname, cap_dev0)
+ cmd[2] = WlantestCapture(dev[1].ifname, cap_dev1)
+ cmd[3] = WlantestCapture(dev[2].ifname, cap_dev2)
dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
dev[1].connect("open", key_mgmt="NONE", scan_freq="2412")
@@ -4875,7 +4874,7 @@ def _test_proxyarp_open(dev, apdev, params, ebtables=False):
dev[1].request("DISCONNECT")
time.sleep(1.5)
for i in range(len(cmd)):
- cmd[i].terminate()
+ cmd[i].close()
time.sleep(0.1)
macs = get_bridge_macs("ap-br0")
logger.info("After disconnect (showmacs): " + str(macs))
@@ -5019,18 +5018,10 @@ def _test_proxyarp_open_ipv6(dev, apdev, params, ebtables=False):
time.sleep(0.5)
cmd = {}
- cmd[0] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
- '-w', cap_br, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
- cmd[1] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[0].ifname,
- '-w', cap_dev0, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
- cmd[2] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[1].ifname,
- '-w', cap_dev1, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
- cmd[3] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[2].ifname,
- '-w', cap_dev2, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
+ cmd[0] = WlantestCapture('ap-br0', cap_br)
+ cmd[1] = WlantestCapture(dev[0].ifname, cap_dev0)
+ cmd[2] = WlantestCapture(dev[1].ifname, cap_dev1)
+ cmd[3] = WlantestCapture(dev[2].ifname, cap_dev2)
dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
dev[1].connect("open", key_mgmt="NONE", scan_freq="2412")
@@ -5134,7 +5125,7 @@ def _test_proxyarp_open_ipv6(dev, apdev, params, ebtables=False):
dev[1].request("DISCONNECT")
time.sleep(0.5)
for i in range(len(cmd)):
- cmd[i].terminate()
+ cmd[i].close()
macs = get_bridge_macs("ap-br0")
logger.info("After disconnect (showmacs): " + str(macs))
matches = get_permanent_neighbors("ap-br0")
@@ -5162,7 +5153,12 @@ def _test_proxyarp_open_ipv6(dev, apdev, params, ebtables=False):
if ebtables:
for req in ns:
- if req[1] != addr0:
+ if req[1] == bssid and req[0] == "33:33:ff:" + bssid[9:] and \
+ req[3] == 'ff02::1:ff00:300' and req[4] == 'fe80::ff:fe00:300':
+ # At least for now, ignore this special case until the kernel
+ # can be prevented from sending it out.
+ logger.info("dev0: Ignore NS from AP to own local addr: " + str(req))
+ elif req[1] != addr0:
raise Exception("Unexpected foreign NS on dev0: " + str(req))
ns = tshark_get_ns(cap_dev1)
@@ -5176,7 +5172,12 @@ def _test_proxyarp_open_ipv6(dev, apdev, params, ebtables=False):
if ebtables:
for req in ns:
- if req[1] != addr1:
+ if req[1] == bssid and req[0] == "33:33:ff:" + bssid[9:] and \
+ req[3] == 'ff02::1:ff00:300' and req[4] == 'fe80::ff:fe00:300':
+ # At least for now, ignore this special case until the kernel
+ # can be prevented from sending it out.
+ logger.info("dev1: Ignore NS from AP to own local addr: " + str(req))
+ elif req[1] != addr1:
raise Exception("Unexpected foreign NS on dev1: " + str(req))
ns = tshark_get_ns(cap_dev2)
@@ -5437,7 +5438,7 @@ def test_ap_hs20_cred_and_no_roaming_consortium(dev, apdev):
'domain': "example.com",
'roaming_consortium': "112234",
'eap': 'TTLS'})
- interworking_select(dev[0], bssid, "home", freq=2412, no_match=True)
+ interworking_select(dev[0], bssid, "home", freq=2412)
def test_ap_hs20_interworking_oom(dev, apdev):
"""Hotspot 2.0 network selection and OOM"""
diff --git a/tests/hwsim/test_ap_ht.py b/tests/hwsim/test_ap_ht.py
index b1e2a10..14c5366 100644
--- a/tests/hwsim/test_ap_ht.py
+++ b/tests/hwsim/test_ap_ht.py
@@ -561,6 +561,7 @@ def test_ap_ht40_5ghz_switch2(dev, apdev):
def test_obss_scan(dev, apdev):
"""Overlapping BSS scan request"""
+ clear_scan_cache(apdev[0])
params = {"ssid": "obss-scan",
"channel": "6",
"ht_capab": "[HT40-]",
@@ -575,6 +576,7 @@ def test_obss_scan(dev, apdev):
def test_obss_scan_ht40_plus(dev, apdev):
"""Overlapping BSS scan request (HT40+)"""
+ clear_scan_cache(apdev[0])
params = {"ssid": "obss-scan",
"channel": "6",
"ht_capab": "[HT40+]",
@@ -585,10 +587,21 @@ def test_obss_scan_ht40_plus(dev, apdev):
"channel": "9",
"ieee80211n": "0"}
hostapd.add_ap(apdev[1], params)
- run_obss_scan(hapd, dev)
+ run_obss_scan(hapd, dev, ht40plus=True)
-def run_obss_scan(hapd, dev):
+def run_obss_scan(hapd, dev, ht40plus=False):
dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
+ res = dev[0].request("SIGNAL_POLL")
+ logger.info("SIGNAL_POLL:\n" + res)
+ sig = res.splitlines()
+ if "FREQUENCY=2437" not in sig:
+ raise Exception("Unexpected frequency")
+ if "WIDTH=40 MHz" not in sig:
+ raise Exception("Not a 40 MHz connection")
+ if ht40plus and "CENTER_FRQ1=2447" not in sig:
+ raise Exception("Not HT40+")
+ if not ht40plus and "CENTER_FRQ1=2427" not in sig:
+ raise Exception("Not HT40-")
hapd.set("ext_mgmt_frame_handling", "1")
logger.info("Waiting for OBSS scan to occur")
ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
diff --git a/tests/hwsim/test_ap_open.py b/tests/hwsim/test_ap_open.py
index dd479d8..0d83438 100644
--- a/tests/hwsim/test_ap_open.py
+++ b/tests/hwsim/test_ap_open.py
@@ -17,6 +17,7 @@ import hwsim_utils
from tshark import run_tshark
from utils import *
from wpasupplicant import WpaSupplicant
+from wlantest import WlantestCapture
from test_ap_ht import set_world_reg
@remote_compatible
@@ -911,10 +912,7 @@ def test_ap_open_layer_2_update(dev, apdev, params):
cap = os.path.join(params['logdir'], prefix + "." + ifname + ".pcap")
hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
- capture = subprocess.Popen(['tcpdump', '-p', '-U', '-i', ifname,
- '-w', cap, '-s', '2000'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ wt = WlantestCapture(ifname, cap)
time.sleep(1)
dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
@@ -923,11 +921,7 @@ def test_ap_open_layer_2_update(dev, apdev, params):
time.sleep(1)
hwsim_utils.test_connectivity(dev[0], hapd)
time.sleep(0.5)
- capture.terminate()
- res = capture.communicate()
- logger.info("tcpdump stdout: " + res[0].decode())
- logger.info("tcpdump stderr: " + res[1].decode())
- time.sleep(0.5)
+ wt.close()
# Check for Layer 2 Update frame and unexpected frames from the station
# that did not fully complete authentication.
diff --git a/tests/hwsim/test_ap_pmf.py b/tests/hwsim/test_ap_pmf.py
index be9b5d2..0a36457 100644
--- a/tests/hwsim/test_ap_pmf.py
+++ b/tests/hwsim/test_ap_pmf.py
@@ -489,6 +489,128 @@ def test_ap_pmf_sta_sa_query_local_failure(dev, apdev):
wpas.request("DISCONNECT")
dev[0].wait_disconnected()
+def test_ap_pmf_sta_sa_query_hostapd(dev, apdev):
+ """WPA2-PSK AP with station using SA Query (hostapd)"""
+ ssid = "assoc-comeback"
+ passphrase = "12345678"
+ addr = dev[0].own_addr()
+
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase,
+ wpa_key_mgmt="WPA-PSK-SHA256",
+ ieee80211w="2")
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ Wlantest.setup(hapd)
+ wt = Wlantest()
+ wt.flush()
+ wt.add_passphrase("12345678")
+
+ dev[0].connect(ssid, psk=passphrase, ieee80211w="2",
+ key_mgmt="WPA-PSK-SHA256", proto="WPA2",
+ scan_freq="2412")
+ hapd.wait_sta()
+ if "OK" not in hapd.request("DEAUTHENTICATE " + addr + " test=0") or \
+ "OK" not in hapd.request("DISASSOCIATE " + addr + " test=0"):
+ raise Exception("Failed to send unprotected disconnection messages")
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
+ if ev is not None:
+ raise Exception("Unexpected disconnection")
+
+ if "OK" not in hapd.request("DEAUTHENTICATE " + addr + " reason=6 test=0") or \
+ "OK" not in hapd.request("DISASSOCIATE " + addr + " reason=7 test=0"):
+ raise Exception("Failed to send unprotected disconnection messages (2)")
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
+ if ev is not None:
+ raise Exception("Unexpected disconnection")
+ if wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr) < 1:
+ raise Exception("STA did not send SA Query")
+ if wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr) < 1:
+ raise Exception("AP did not reply to SA Query")
+
+def test_ap_pmf_sta_sa_query_no_response_hostapd(dev, apdev):
+ """WPA2-PSK AP with station using SA Query and getting no response (hostapd)"""
+ ssid = "assoc-comeback"
+ passphrase = "12345678"
+ addr = dev[0].own_addr()
+
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase,
+ wpa_key_mgmt="WPA-PSK-SHA256",
+ ieee80211w="2")
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ Wlantest.setup(hapd)
+ wt = Wlantest()
+ wt.flush()
+ wt.add_passphrase("12345678")
+
+ dev[0].connect(ssid, psk=passphrase, ieee80211w="2",
+ key_mgmt="WPA-PSK-SHA256", proto="WPA2",
+ scan_freq="2412")
+ hapd.wait_sta()
+ hapd.set("ext_mgmt_frame_handling", "1")
+ if "OK" not in hapd.request("DEAUTHENTICATE " + addr + " reason=6 test=0") or \
+ "OK" not in hapd.request("DISASSOCIATE " + addr + " reason=7 test=0"):
+ raise Exception("Failed to send unprotected disconnection messages")
+ dev[0].wait_disconnected()
+ hapd.set("ext_mgmt_frame_handling", "0")
+ if wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr) < 1:
+ raise Exception("STA did not send SA Query")
+ if wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr) > 0:
+ raise Exception("AP replied to SA Query")
+ dev[0].wait_connected()
+
+def test_ap_pmf_sta_unprot_deauth_burst_hostapd(dev, apdev):
+ """WPA2-PSK AP with station receiving burst of unprotected Deauthentication frames (hostapd)"""
+ ssid = "deauth-attack"
+ passphrase = "12345678"
+ addr = dev[0].own_addr()
+
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase,
+ wpa_key_mgmt="WPA-PSK-SHA256",
+ ieee80211w="2")
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ Wlantest.setup(hapd)
+ wt = Wlantest()
+ wt.flush()
+ wt.add_passphrase("12345678")
+
+ dev[0].connect(ssid, psk=passphrase, ieee80211w="2",
+ key_mgmt="WPA-PSK-SHA256", proto="WPA2",
+ scan_freq="2412")
+ hapd.wait_sta()
+ for i in range(10):
+ if "OK" not in hapd.request("DEAUTHENTICATE " + addr + " reason=6 test=0") or \
+ "OK" not in hapd.request("DISASSOCIATE " + addr + " reason=7 test=0"):
+ raise Exception("Failed to send unprotected disconnection messages")
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
+ if ev is not None:
+ raise Exception("Unexpected disconnection")
+ num_req = wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr)
+ num_resp = wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr)
+ if num_req < 1:
+ raise Exception("STA did not send SA Query")
+ if num_resp < 1:
+ raise Exception("AP did not reply to SA Query")
+ if num_req > 1:
+ raise Exception("STA initiated too many SA Query procedures (%d)" % num_req)
+
+ time.sleep(10)
+ for i in range(5):
+ if "OK" not in hapd.request("DEAUTHENTICATE " + addr + " reason=6 test=0") or \
+ "OK" not in hapd.request("DISASSOCIATE " + addr + " reason=7 test=0"):
+ raise Exception("Failed to send unprotected disconnection messages")
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
+ if ev is not None:
+ raise Exception("Unexpected disconnection")
+ num_req = wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr)
+ num_resp = wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr)
+ if num_req != 2 or num_resp != 2:
+ raise Exception("Unexpected number of SA Query procedures (req=%d resp=%d)" % (num_req, num_resp))
+
def test_ap_pmf_required_eap(dev, apdev):
"""WPA2-EAP AP with PMF required"""
ssid = "test-pmf-required-eap"
diff --git a/tests/hwsim/test_ap_psk.py b/tests/hwsim/test_ap_psk.py
index 0e01f7f..ac0fabc 100644
--- a/tests/hwsim/test_ap_psk.py
+++ b/tests/hwsim/test_ap_psk.py
@@ -23,6 +23,7 @@ from utils import HwsimSkip, fail_test, skip_with_fips, start_monitor, stop_moni
import hwsim_utils
from wpasupplicant import WpaSupplicant
from tshark import run_tshark
+from wlantest import WlantestCapture
def check_mib(dev, vals):
mib = dev.get_mib()
@@ -1330,11 +1331,6 @@ def reply_eapol(info, hapd, addr, msg, key_info, nonce, data, kck):
eapol_key_mic(kck, msg)
send_eapol(hapd, addr, build_eapol(msg))
-def hapd_connected(hapd):
- ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=15)
- if ev is None:
- raise Exception("Timeout on AP-STA-CONNECTED from hostapd")
-
def eapol_test(apdev, dev, wpa2=True, ieee80211w=0):
bssid = apdev['bssid']
if wpa2:
@@ -1391,7 +1387,7 @@ def test_ap_wpa2_psk_ext_eapol(dev, apdev):
send_eapol(hapd, addr, build_eapol(msg))
reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
- hapd_connected(hapd)
+ hapd.wait_sta(timeout=15)
@remote_compatible
def test_ap_wpa2_psk_ext_eapol_retry1(dev, apdev):
@@ -1418,7 +1414,7 @@ def test_ap_wpa2_psk_ext_eapol_retry1(dev, apdev):
raise Exception("ANonce changed")
reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
- hapd_connected(hapd)
+ hapd.wait_sta(timeout=15)
@remote_compatible
def test_ap_wpa2_psk_ext_eapol_retry1b(dev, apdev):
@@ -1440,7 +1436,7 @@ def test_ap_wpa2_psk_ext_eapol_retry1b(dev, apdev):
raise Exception("ANonce changed")
reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
- hapd_connected(hapd)
+ hapd.wait_sta(timeout=15)
@remote_compatible
def test_ap_wpa2_psk_ext_eapol_retry1c(dev, apdev):
@@ -1464,7 +1460,7 @@ def test_ap_wpa2_psk_ext_eapol_retry1c(dev, apdev):
if anonce != msg['rsn_key_nonce']:
raise Exception("ANonce changed")
reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
- hapd_connected(hapd)
+ hapd.wait_sta(timeout=15)
@remote_compatible
def test_ap_wpa2_psk_ext_eapol_retry1d(dev, apdev):
@@ -1488,7 +1484,7 @@ def test_ap_wpa2_psk_ext_eapol_retry1d(dev, apdev):
if anonce != msg['rsn_key_nonce']:
raise Exception("ANonce changed")
reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
- hapd_connected(hapd)
+ hapd.wait_sta(timeout=15)
@remote_compatible
def test_ap_wpa2_psk_ext_eapol_type_diff(dev, apdev):
@@ -1519,7 +1515,7 @@ def test_ap_wpa2_psk_ext_eapol_type_diff(dev, apdev):
send_eapol(hapd, addr, build_eapol(msg))
reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
- hapd_connected(hapd)
+ hapd.wait_sta(timeout=15)
@remote_compatible
def test_ap_wpa_psk_ext_eapol(dev, apdev):
@@ -1547,7 +1543,7 @@ def test_ap_wpa_psk_ext_eapol(dev, apdev):
send_eapol(hapd, addr, build_eapol(msg))
reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
- hapd_connected(hapd)
+ hapd.wait_sta(timeout=15)
@remote_compatible
def test_ap_wpa2_psk_ext_eapol_key_info(dev, apdev):
@@ -1593,7 +1589,7 @@ def test_ap_wpa2_psk_ext_eapol_key_info(dev, apdev):
send_eapol(hapd, addr, build_eapol(msg))
reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
- hapd_connected(hapd)
+ hapd.wait_sta(timeout=15)
def build_eapol_key_1_4(anonce, replay_counter=1, key_data=b'', key_len=16):
msg = {}
@@ -3079,16 +3075,20 @@ def test_ap_wpa2_disable_eapol_retry_group(dev, apdev):
bssid = apdev[0]['bssid']
id = dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
+ hapd.wait_sta()
dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
+ hapd.wait_sta()
dev[0].dump_monitor()
addr = dev[0].own_addr()
dev[1].request("DISCONNECT")
+ dev[1].wait_disconnected()
ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
if ev is None:
raise Exception("GTK rekey timed out")
dev[1].request("RECONNECT")
dev[1].wait_connected()
+ hapd.wait_sta()
dev[0].dump_monitor()
hapd.request("SET ext_eapol_frame_io 1")
@@ -3220,10 +3220,7 @@ def test_ap_wpa2_psk_inject_assoc(dev, apdev, params):
params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
params["wpa_key_mgmt"] = "WPA-PSK"
hapd = hostapd.add_ap(apdev[0], params)
- capture = subprocess.Popen(['tcpdump', '-p', '-U', '-i', ifname,
- '-w', cap, '-s', '2000'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ wt = WlantestCapture(ifname, cap)
time.sleep(1)
bssid = hapd.own_addr().replace(':', '')
@@ -3261,10 +3258,7 @@ def test_ap_wpa2_psk_inject_assoc(dev, apdev, params):
time.sleep(1)
hwsim_utils.test_connectivity(dev[0], hapd)
time.sleep(0.5)
- capture.terminate()
- res = capture.communicate()
- logger.info("tcpdump stdout: " + res[0].decode())
- logger.info("tcpdump stderr: " + res[1].decode())
+ wt.close()
time.sleep(0.5)
# Check for Layer 2 Update frame and unexpected frames from the station
@@ -3288,3 +3282,27 @@ def test_ap_wpa2_psk_inject_assoc(dev, apdev, params):
wait=False)
if len(res) > 0:
raise Exception("Unexpected frame from unauthorized STA seen")
+
+def test_ap_wpa2_psk_no_control_port(dev, apdev):
+ """WPA2-PSK AP without nl80211 control port"""
+ ssid = "test-wpa2-psk"
+ passphrase = 'qwertyuiop'
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+ params['driver_params'] = "control_port=0"
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add("wlan5", drv_params="control_port=0")
+ wpas.connect(ssid, psk=passphrase, scan_freq="2412")
+ hapd.wait_sta()
+ hwsim_utils.test_connectivity(wpas, hapd)
+ if "OK" not in wpas.request("KEY_REQUEST 0 1"):
+ raise Exception("KEY_REQUEST failed")
+ ev = wpas.wait_event(["WPA: Key negotiation completed"])
+ if ev is None:
+ raise Exception("PTK rekey timed out")
+ hapd.wait_ptkinitdone(wpas.own_addr())
+ hwsim_utils.test_connectivity(wpas, hapd)
+ wpas.request("DISCONNECT")
+ wpas.wait_disconnected()
+ wpas.dump_monitor()
diff --git a/tests/hwsim/test_ap_roam.py b/tests/hwsim/test_ap_roam.py
index d7eb104..9047c7a 100644
--- a/tests/hwsim/test_ap_roam.py
+++ b/tests/hwsim/test_ap_roam.py
@@ -1,5 +1,5 @@
# Roaming tests
-# Copyright (c) 2013, Jouni Malinen <j@w1.fi>
+# Copyright (c) 2013-2019, Jouni Malinen <j@w1.fi>
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.
@@ -48,6 +48,27 @@ def test_ap_roam_open_failed(dev, apdev):
dev[0].wait_connected(timeout=5)
hwsim_utils.test_connectivity(dev[0], hapd0)
+def test_ap_roam_open_failed_ssid_mismatch(dev, apdev):
+ """Roam failure due to SSID mismatch"""
+ hapd0 = hostapd.add_ap(apdev[0], {"ssid": "test-open"})
+ bssid0 = hapd0.own_addr()
+ hapd1 = hostapd.add_ap(apdev[1], {"ssid": "test-open2"})
+ bssid1 = hapd1.own_addr()
+ dev[0].flush_scan_cache()
+ dev[0].scan_for_bss(bssid0, freq=2412)
+ dev[0].scan_for_bss(bssid1, freq=2412)
+ dev[0].connect("test-open", key_mgmt="NONE", scan_freq="2412")
+ hapd0.wait_sta()
+ bssid = dev[0].get_status_field("bssid")
+ if bssid != bssid0:
+ raise Exception("Unexpected BSSID reported after initial connection: " + bssid)
+ if "FAIL" not in dev[0].request("ROAM " + bssid1):
+ raise Exception("ROAM succeed unexpectedly")
+ bssid = dev[0].get_status_field("bssid")
+ if bssid != bssid0:
+ raise Exception("Unexpected BSSID reported after failed roam attempt: " + bssid)
+ hwsim_utils.test_connectivity(dev[0], hapd0)
+
@remote_compatible
def test_ap_roam_wpa2_psk(dev, apdev):
"""Roam between two WPA2-PSK APs"""
@@ -65,6 +86,33 @@ def test_ap_roam_wpa2_psk(dev, apdev):
hapd0.wait_sta()
hwsim_utils.test_connectivity(dev[0], hapd0)
+def test_ap_roam_wpa2_psk_pmf_mismatch(dev, apdev):
+ """Roam between two WPA2-PSK APs - PMF mismatch"""
+ params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
+ params['ieee80211w'] = '1'
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ bssid0 = hapd0.own_addr()
+ params['ieee80211w'] = '0'
+ hapd1 = hostapd.add_ap(apdev[1], params)
+ bssid1 = hapd1.own_addr()
+ dev[0].flush_scan_cache()
+ dev[0].scan_for_bss(bssid0, freq=2412)
+ dev[0].scan_for_bss(bssid1, freq=2412)
+ dev[0].connect("test-wpa2-psk", psk="12345678", ieee80211w='2')
+ hapd0.wait_sta()
+ bssid = dev[0].get_status_field("bssid")
+ if bssid != bssid0:
+ raise Exception("Unexpected BSSID reported after initial connection: " + bssid)
+ if "OK" not in dev[0].request("ROAM " + apdev[1]['bssid']):
+ raise Exception("ROAM failed")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5)
+ if ev is not None:
+ raise Exception("Unexpected connection reported")
+ bssid = dev[0].get_status_field("bssid")
+ if bssid != bssid0:
+ raise Exception("Unexpected BSSID reported after failed roam attempt: " + bssid)
+ hwsim_utils.test_connectivity(dev[0], hapd0)
+
def get_blacklist(dev):
return dev.request("BLACKLIST").splitlines()
@@ -242,3 +290,61 @@ def test_ap_roam_wpa2_psk_race(dev, apdev):
for i in range(3):
time.sleep(0.8)
hwsim_utils.test_connectivity(dev[0], hapd0)
+
+def test_ap_roam_signal_level_override(dev, apdev):
+ """Roam between two APs based on driver signal level override"""
+ hapd0 = hostapd.add_ap(apdev[0], {"ssid": "test-open"})
+ bssid0 = apdev[0]['bssid']
+ hapd1 = hostapd.add_ap(apdev[1], {"ssid": "test-open"})
+ bssid1 = apdev[1]['bssid']
+ dev[0].scan_for_bss(bssid0, freq=2412)
+ dev[0].scan_for_bss(bssid1, freq=2412)
+
+ dev[0].connect("test-open", key_mgmt="NONE")
+ bssid = dev[0].get_status_field('bssid')
+ if bssid == bssid0:
+ dst = bssid1
+ src = bssid0
+ else:
+ dst = bssid0
+ src = bssid1
+
+ dev[0].scan(freq=2412)
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], 0.5)
+ if ev is not None:
+ raise Exception("Unexpected roam")
+
+ orig_res = dev[0].request("SIGNAL_POLL")
+ dev[0].set("driver_signal_override", src + " -1 -2 -3 -4 -5")
+ res = dev[0].request("SIGNAL_POLL").splitlines()
+ if "RSSI=-1" not in res or \
+ "AVG_RSSI=-2" not in res or \
+ "AVG_BEACON_RSSI=-3" not in res or \
+ "NOISE=-4" not in res:
+ raise Exception("SIGNAL_POLL override did not work: " + str(res))
+
+ dev[0].set("driver_signal_override", src)
+ new_res = dev[0].request("SIGNAL_POLL")
+ if orig_res != new_res:
+ raise Exception("SIGNAL_POLL restore did not work: " + new_res)
+
+ tests = [("-30 -30 -30 -95 -30", "-30 -30 -30 -95 -30"),
+ ("-30 -30 -30 -95 -30", "-20 -20 -20 -95 -20"),
+ ("-90 -90 -90 -95 -90", "-89 -89 -89 -95 -89"),
+ ("-90 -90 -90 -95 -95", "-89 -89 -89 -95 -89")]
+ for src_override, dst_override in tests:
+ dev[0].set("driver_signal_override", src + " " + src_override)
+ dev[0].set("driver_signal_override", dst + " " + dst_override)
+ dev[0].scan(freq=2412)
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], 0.1)
+ if ev is not None:
+ raise Exception("Unexpected roam")
+ dev[0].dump_monitor()
+
+ dev[0].set("driver_signal_override", src + " -90 -90 -90 -95 -90")
+ dev[0].set("driver_signal_override", dst + " -80 -80 -80 -95 -80")
+ dev[0].scan(freq=2412)
+ dev[0].wait_connected()
+ if dst != dev[0].get_status_field('bssid'):
+ raise Exception("Unexpected AP after roam")
+ dev[0].dump_monitor()
diff --git a/tests/hwsim/test_ap_tdls.py b/tests/hwsim/test_ap_tdls.py
index 5a639d0..caba13d 100644
--- a/tests/hwsim/test_ap_tdls.py
+++ b/tests/hwsim/test_ap_tdls.py
@@ -30,6 +30,8 @@ def connectivity(dev, hapd):
def connect_2sta(dev, ssid, hapd):
dev[0].connect(ssid, psk="12345678", scan_freq="2412")
dev[1].connect(ssid, psk="12345678", scan_freq="2412")
+ hapd.wait_sta()
+ hapd.wait_sta()
connectivity(dev, hapd)
def connect_2sta_wpa2_psk(dev, hapd):
@@ -43,6 +45,8 @@ def connect_2sta_wpa_psk_mixed(dev, hapd):
scan_freq="2412")
dev[1].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA2",
scan_freq="2412")
+ hapd.wait_sta()
+ hapd.wait_sta()
connectivity(dev, hapd)
def connect_2sta_wep(dev, hapd):
@@ -50,11 +54,15 @@ def connect_2sta_wep(dev, hapd):
scan_freq="2412")
dev[1].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"',
scan_freq="2412")
+ hapd.wait_sta()
+ hapd.wait_sta()
connectivity(dev, hapd)
def connect_2sta_open(dev, hapd, scan_freq="2412"):
dev[0].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
dev[1].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
+ hapd.wait_sta()
+ hapd.wait_sta()
connectivity(dev, hapd)
def wlantest_setup(hapd):
diff --git a/tests/hwsim/test_ap_wps.py b/tests/hwsim/test_ap_wps.py
index 33d6ffb..adcff63 100644
--- a/tests/hwsim/test_ap_wps.py
+++ b/tests/hwsim/test_ap_wps.py
@@ -548,6 +548,7 @@ def test_ap_wps_reg_connect(dev, apdev):
"ap_pin": appin})
logger.info("WPS provisioning step")
dev[0].dump_monitor()
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], appin)
status = dev[0].get_status()
@@ -571,6 +572,7 @@ def test_ap_wps_reg_connect_zero_len_ap_pin(dev, apdev):
"ap_pin": appin})
logger.info("WPS provisioning step")
dev[0].dump_monitor()
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], appin, no_wait=True)
ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
@@ -588,6 +590,7 @@ def test_ap_wps_reg_connect_mixed_mode(dev, apdev):
"wpa_passphrase": "12345678", "wpa": "3",
"wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
"wpa_pairwise": "TKIP", "ap_pin": appin})
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], appin)
status = dev[0].get_status()
@@ -624,6 +627,7 @@ def test_ap_wps_reg_override_ap_settings(dev, apdev):
"wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
"ap_pin": appin, "ap_settings": ap_settings})
hapd2 = hostapd.add_ap(apdev[1], {"ssid": "test"})
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].scan_for_bss(apdev[1]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], appin)
@@ -662,6 +666,7 @@ def test_ap_wps_random_ap_pin(dev, apdev):
if appin not in hapd.request("WPS_AP_PIN get"):
raise Exception("Could not fetch current AP PIN")
logger.info("WPS provisioning step")
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], appin)
@@ -717,6 +722,7 @@ def test_ap_wps_reg_config(dev, apdev):
{"ssid": ssid, "eap_server": "1", "wps_state": "2",
"ap_pin": appin})
logger.info("WPS configuration step")
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].dump_monitor()
new_ssid = "wps-new-ssid"
@@ -753,6 +759,7 @@ def test_ap_wps_reg_config_ext_processing(dev, apdev):
params = {"ssid": ssid, "eap_server": "1", "wps_state": "2",
"wps_cred_processing": "1", "ap_pin": appin}
hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
new_ssid = "wps-new-ssid"
new_passphrase = "1234567890"
@@ -780,6 +787,7 @@ def test_ap_wps_reg_config_tkip(dev, apdev):
{"ssid": ssid, "eap_server": "1", "wps_state": "1",
"ap_pin": appin})
logger.info("WPS configuration step")
+ dev[0].flush_scan_cache()
dev[0].request("SET wps_version_number 0x10")
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].dump_monitor()
@@ -815,6 +823,7 @@ def test_ap_wps_setup_locked(dev, apdev):
new_ssid = "wps-new-ssid-test"
new_passphrase = "1234567890"
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
ap_setup_locked = False
for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
@@ -880,6 +889,7 @@ def test_ap_wps_setup_locked_timeout(dev, apdev):
new_ssid = "wps-new-ssid-test"
new_passphrase = "1234567890"
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
ap_setup_locked = False
for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
@@ -918,6 +928,7 @@ def test_ap_wps_setup_locked_2(dev, apdev):
new_ssid = "wps-new-ssid-test"
new_passphrase = "1234567890"
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], appin)
dev[0].request("REMOVE_NETWORK all")
@@ -1071,6 +1082,7 @@ def _test_ap_wps_er_add_enrollee(dev, apdev):
logger.info("WPS configuration step")
new_passphrase = "1234567890"
dev[0].dump_monitor()
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
new_passphrase)
@@ -1203,6 +1215,7 @@ def _test_ap_wps_er_add_enrollee_uuid(dev, apdev):
"config_methods": "label push_button",
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
logger.info("WPS configuration step")
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
@@ -1297,6 +1310,7 @@ def _test_ap_wps_er_multi_add_enrollee(dev, apdev):
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
for i in range(2):
+ dev[i].flush_scan_cache()
dev[i].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[i].wps_reg(apdev[0]['bssid'], ap_pin)
for i in range(2):
@@ -1355,6 +1369,7 @@ def _test_ap_wps_er_add_enrollee_pbc(dev, apdev):
"config_methods": "label push_button",
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
logger.info("Learn AP configuration")
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].dump_monitor()
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
@@ -1425,6 +1440,7 @@ def _test_ap_wps_er_pbc_overlap(dev, apdev):
"os_version": "01020300",
"config_methods": "label push_button",
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].dump_monitor()
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
@@ -1502,6 +1518,7 @@ def _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
logger.info("Learn AP configuration")
dev[0].request("SET wps_version_number 0x10")
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].dump_monitor()
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
@@ -1610,6 +1627,7 @@ def _test_ap_wps_er_cache_ap_settings(dev, apdev):
"config_methods": "label push_button",
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"}
hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
id = int(dev[0].list_networks()[0]['id'])
@@ -1688,6 +1706,7 @@ def _test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
"config_methods": "label push_button",
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"}
hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
id = int(dev[0].list_networks()[0]['id'])
@@ -1750,6 +1769,7 @@ def _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
"config_methods": "label push_button",
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"}
hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
id = int(dev[0].list_networks()[0]['id'])
@@ -1812,6 +1832,7 @@ def _test_ap_wps_er_subscribe_oom(dev, apdev):
"config_methods": "label push_button",
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"}
hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
id = int(dev[0].list_networks()[0]['id'])
@@ -1851,6 +1872,7 @@ def _test_ap_wps_er_set_sel_reg_oom(dev, apdev):
"config_methods": "label push_button",
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"}
hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
@@ -1903,6 +1925,7 @@ def _test_ap_wps_er_learn_oom(dev, apdev):
"config_methods": "label push_button",
"ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"}
hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
@@ -2065,6 +2088,7 @@ def test_ap_wps_wep_config(dev, apdev):
hapd = hostapd.add_ap(apdev[0],
{"ssid": ssid, "eap_server": "1", "wps_state": "2",
"ap_pin": appin})
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
"hello", no_wait=True)
@@ -2166,6 +2190,7 @@ def test_ap_wps_per_station_psk(dev, apdev):
logger.info("First enrollee")
hapd.request("WPS_PBC")
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
dev[0].request("WPS_PBC " + apdev[0]['bssid'])
dev[0].wait_connected(timeout=30)
@@ -3130,7 +3155,7 @@ def test_ap_wps_upnp_subscribe(dev, apdev):
sid = resp.getheader("sid")
logger.debug("Subscription SID " + sid)
- with alloc_fail(hapd, 1, "=event_add"):
+ with alloc_fail(hapd, 1, "=wps_upnp_event_add"):
for i in range(2):
dev[1].dump_monitor()
dev[2].dump_monitor()
@@ -3150,7 +3175,7 @@ def test_ap_wps_upnp_subscribe(dev, apdev):
if resp.status != 200:
raise Exception("Unexpected HTTP response: %d" % resp.status)
- with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
+ with alloc_fail(hapd, 1, "wpabuf_dup;wps_upnp_event_add"):
dev[1].dump_monitor()
dev[2].dump_monitor()
dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
@@ -3198,7 +3223,7 @@ def test_ap_wps_upnp_subscribe(dev, apdev):
if resp.status != 500:
raise Exception("Unexpected HTTP response: %d" % resp.status)
- with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
+ with alloc_fail(hapd, 1, "wps_upnp_event_add;subscription_first_event"):
conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
resp = conn.getresponse()
if resp.status != 500:
@@ -10127,6 +10152,7 @@ def run_ap_wps_conf_pin_cipher(dev, apdev, cipher):
logger.info("WPS provisioning step")
pin = dev[0].wps_read_pin()
hapd.request("WPS_PIN any " + pin)
+ dev[0].flush_scan_cache()
dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
dev[0].wait_connected(timeout=15)
@@ -10215,6 +10241,7 @@ def run_ap_wps_reg_config_and_sae(dev, apdev):
{"ssid": ssid, "eap_server": "1", "wps_state": "2",
"ap_pin": appin, "wps_cred_add_sae": "1"})
logger.info("WPS configuration step")
+ dev[0].flush_scan_cache()
dev[0].set("wps_cred_add_sae", "1")
dev[0].request("SET sae_groups ")
dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
@@ -10231,3 +10258,17 @@ def run_ap_wps_reg_config_and_sae(dev, apdev):
dev[1].connect(new_ssid, psk=new_passphrase, scan_freq="2412", proto="WPA2",
key_mgmt="WPA-PSK", ieee80211w="0")
+
+def test_ap_wps_appl_ext(dev, apdev):
+ """WPS Application Extension attribute"""
+ ssid = "test-wps-conf"
+ params = {"ssid": ssid, "eap_server": "1", "wps_state": "2",
+ "wps_application_ext": 16*"11" + 5*"ee",
+ "wpa_passphrase": "12345678", "wpa": "2",
+ "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
+ hapd = hostapd.add_ap(apdev[0], params)
+ pin = dev[0].wps_read_pin()
+ hapd.request("WPS_PIN any " + pin)
+ dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
+ dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
+ dev[0].wait_connected(timeout=30)
diff --git a/tests/hwsim/test_dfs.py b/tests/hwsim/test_dfs.py
index bd09840..a10d32b 100644
--- a/tests/hwsim/test_dfs.py
+++ b/tests/hwsim/test_dfs.py
@@ -26,9 +26,9 @@ def wait_dfs_event(hapd, event, timeout):
raise Exception("Unexpected DFS event: " + ev + " (expected: %s)" % event)
return ev
-def start_dfs_ap(ap, allow_failure=False, ssid="dfs", ht=True, ht40=False,
+def start_dfs_ap(ap, ssid="dfs", ht=True, ht40=False,
ht40minus=False, vht80=False, vht20=False, chanlist=None,
- channel=None, country="FI"):
+ channel=None, country="FI", rrm_beacon_report=False):
ifname = ap['ifname']
logger.info("Starting AP " + ifname + " on DFS channel")
hapd = hostapd.add_ap(ap, {}, no_enable=True)
@@ -57,6 +57,8 @@ def start_dfs_ap(ap, allow_failure=False, ssid="dfs", ht=True, ht40=False,
hapd.set("chanlist", chanlist)
if channel:
hapd.set("channel", str(channel))
+ if rrm_beacon_report:
+ hapd.set("rrm_beacon_report", "1")
hapd.enable()
ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
@@ -65,11 +67,6 @@ def start_dfs_ap(ap, allow_failure=False, ssid="dfs", ht=True, ht40=False,
state = hapd.get_status_field("state")
if state != "DFS":
- if allow_failure:
- logger.info("Interface state not DFS: " + state)
- if not os.path.exists("dfs"):
- raise HwsimSkip("Assume DFS testing not supported")
- raise Exception("Failed to start DFS AP")
raise Exception("Unexpected interface state: " + state)
return hapd
@@ -85,7 +82,7 @@ def test_dfs(dev, apdev):
"""DFS CAC functionality on clear channel"""
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], allow_failure=True, country="US")
+ hapd = start_dfs_ap(apdev[0], country="US")
ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
if "success=1" not in ev:
@@ -137,7 +134,7 @@ def test_dfs_etsi(dev, apdev, params):
raise HwsimSkip("Skip test case with long duration due to --long not specified")
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], allow_failure=True)
+ hapd = start_dfs_ap(apdev[0])
ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
if "success=1" not in ev:
@@ -201,7 +198,7 @@ def test_dfs_radar1(dev, apdev):
"""DFS CAC functionality with radar detected during initial CAC"""
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], allow_failure=True)
+ hapd = start_dfs_ap(apdev[0])
time.sleep(1)
dfs_simulate_radar(hapd)
@@ -290,7 +287,7 @@ def test_dfs_radar_chanlist(dev, apdev):
"""DFS chanlist when radar is detected"""
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], chanlist="40 44", allow_failure=True)
+ hapd = start_dfs_ap(apdev[0], chanlist="40 44")
time.sleep(1)
dfs_simulate_radar(hapd)
@@ -321,8 +318,7 @@ def test_dfs_radar_chanlist_vht80(dev, apdev):
"""DFS chanlist when radar is detected and VHT80 configured"""
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], chanlist="36", ht40=True, vht80=True,
- allow_failure=True)
+ hapd = start_dfs_ap(apdev[0], chanlist="36", ht40=True, vht80=True)
time.sleep(1)
dfs_simulate_radar(hapd)
@@ -356,8 +352,7 @@ def test_dfs_radar_chanlist_vht20(dev, apdev):
"""DFS chanlist when radar is detected and VHT40 configured"""
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], chanlist="36", vht20=True,
- allow_failure=True)
+ hapd = start_dfs_ap(apdev[0], chanlist="36", vht20=True)
time.sleep(1)
dfs_simulate_radar(hapd)
@@ -388,8 +383,7 @@ def test_dfs_radar_no_ht(dev, apdev):
"""DFS chanlist when radar is detected and no HT configured"""
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], chanlist="36", ht=False,
- allow_failure=True)
+ hapd = start_dfs_ap(apdev[0], chanlist="36", ht=False)
time.sleep(1)
dfs_simulate_radar(hapd)
@@ -420,8 +414,7 @@ def test_dfs_radar_ht40minus(dev, apdev):
"""DFS chanlist when radar is detected and HT40- configured"""
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], chanlist="36", ht40minus=True,
- allow_failure=True)
+ hapd = start_dfs_ap(apdev[0], chanlist="36", ht40minus=True)
time.sleep(1)
dfs_simulate_radar(hapd)
@@ -456,8 +449,7 @@ def test_dfs_ht40_minus(dev, apdev, params):
raise HwsimSkip("Skip test case with long duration due to --long not specified")
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], allow_failure=True, ht40minus=True,
- channel=104)
+ hapd = start_dfs_ap(apdev[0], ht40minus=True, channel=104)
ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
if "success=1" not in ev:
@@ -487,7 +479,7 @@ def test_dfs_cac_restart_on_enable(dev, apdev):
"""DFS CAC interrupted and restarted"""
try:
hapd = None
- hapd = start_dfs_ap(apdev[0], allow_failure=True)
+ hapd = start_dfs_ap(apdev[0])
time.sleep(0.1)
subprocess.check_call(['ip', 'link', 'set', 'dev', hapd.ifname, 'down'])
ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 5)
@@ -505,3 +497,32 @@ def test_dfs_cac_restart_on_enable(dev, apdev):
finally:
clear_regdom(hapd, dev)
+
+def test_dfs_rrm(dev, apdev, params):
+ """DFS with RRM [long]"""
+ if not params['long']:
+ raise HwsimSkip("Skip test case with long duration due to --long not specified")
+ try:
+ hapd = None
+ hapd = start_dfs_ap(apdev[0], country="US", rrm_beacon_report=True)
+
+ ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
+ if "success=1" not in ev or "freq=5260" not in ev:
+ raise Exception("Unexpected DFS freq result")
+ ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
+ if not ev:
+ raise Exception("AP setup timed out")
+
+ dev[0].connect("dfs", key_mgmt="NONE", scan_freq="5260")
+ dev[0].wait_regdom(country_ie=True)
+ hapd.wait_sta()
+ hwsim_utils.test_connectivity(dev[0], hapd)
+ addr = dev[0].own_addr()
+ token = hapd.request("REQ_BEACON " + addr + " " + "51000000000002ffffffffffff")
+ if "FAIL" in token:
+ raise Exception("REQ_BEACON failed")
+ ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
+ if ev is None:
+ raise Exception("Beacon report response not received")
+ finally:
+ clear_regdom(hapd, dev)
diff --git a/tests/hwsim/test_dpp.py b/tests/hwsim/test_dpp.py
index 12156cd..c5104ba 100644
--- a/tests/hwsim/test_dpp.py
+++ b/tests/hwsim/test_dpp.py
@@ -18,8 +18,10 @@ import time
import hostapd
import hwsim_utils
+from hwsim import HWSimRadio
from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
from wpasupplicant import WpaSupplicant
+from wlantest import WlantestCapture
try:
import OpenSSL
@@ -439,7 +441,7 @@ def test_dpp_auth_resp_retries(dev, apdev):
logger.info("dev0 scans QR Code")
id0b = dev[0].dpp_qr_code(uri1b)
- ev = dev[0].wait_event(["DPP-TX"], timeout=5)
+ ev = dev[0].wait_event(["DPP-TX "], timeout=5)
if ev is None or "type=1" not in ev:
raise Exception("DPP Authentication Response not sent")
ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=5)
@@ -448,7 +450,7 @@ def test_dpp_auth_resp_retries(dev, apdev):
if "result=no-ACK" not in ev:
raise Exception("Unexpected TX status for Authentication Response: " + ev)
- ev = dev[0].wait_event(["DPP-TX"], timeout=15)
+ ev = dev[0].wait_event(["DPP-TX "], timeout=15)
if ev is None or "type=1" not in ev:
raise Exception("DPP Authentication Response retransmission not sent")
@@ -655,7 +657,7 @@ def test_dpp_qr_code_auth_neg_chan(dev, apdev):
dev[1].dpp_auth_init(uri=uri0, conf="sta-dpp", neg_freq=2462,
configurator=conf_id)
- ev = dev[1].wait_event(["DPP-TX"], timeout=5)
+ ev = dev[1].wait_event(["DPP-TX "], timeout=5)
if ev is None:
raise Exception("DPP Authentication Request not sent")
if "freq=2412 type=0" not in ev:
@@ -673,7 +675,7 @@ def test_dpp_qr_code_auth_neg_chan(dev, apdev):
if "freq=2412 result=SUCCESS" not in ev:
raise Exception("Unexpected TX status for Authentication Request: " + ev)
- ev = dev[0].wait_event(["DPP-TX"], timeout=5)
+ ev = dev[0].wait_event(["DPP-TX "], timeout=5)
if ev is None:
raise Exception("DPP Authentication Response not sent")
if "freq=2462 type=1" not in ev:
@@ -691,7 +693,7 @@ def test_dpp_qr_code_auth_neg_chan(dev, apdev):
if "freq=2462 result=SUCCESS" not in ev:
raise Exception("Unexpected TX status for Authentication Response: " + ev)
- ev = dev[1].wait_event(["DPP-TX"], timeout=5)
+ ev = dev[1].wait_event(["DPP-TX "], timeout=5)
if ev is None:
raise Exception("DPP Authentication Confirm not sent")
if "freq=2462 type=2" not in ev:
@@ -1624,6 +1626,7 @@ def update_hapd_config(hapd):
logger.info("Update AP configuration to use key_mgmt=DPP")
hapd.disable()
hapd.set("ssid", ssid)
+ hapd.set("utf8_ssid", "1")
hapd.set("wpa", "2")
hapd.set("wpa_key_mgmt", "DPP")
hapd.set("ieee80211w", "2")
@@ -1776,6 +1779,13 @@ def test_dpp_auto_connect_legacy(dev, apdev):
finally:
dev[0].set("dpp_config_processing", "0")
+def test_dpp_auto_connect_legacy_ssid_charset(dev, apdev):
+ """DPP and auto connect (legacy, ssid_charset)"""
+ try:
+ run_dpp_auto_connect_legacy(dev, apdev, ssid_charset=12345)
+ finally:
+ dev[0].set("dpp_config_processing", "0")
+
def test_dpp_auto_connect_legacy_sae_1(dev, apdev):
"""DPP and auto connect (legacy SAE)"""
try:
@@ -1814,6 +1824,7 @@ def test_dpp_auto_connect_legacy_psk_sae_3(dev, apdev):
dev[0].set("dpp_config_processing", "0")
def run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk',
+ ssid_charset=None,
psk_sae=False, sae_only=False):
check_dpp_capab(dev[0])
check_dpp_capab(dev[1])
@@ -1837,8 +1848,16 @@ def run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk',
dev[0].dpp_listen(2412)
dev[1].dpp_auth_init(uri=uri0, conf=conf, ssid="dpp-legacy",
+ ssid_charset=ssid_charset,
passphrase="secret passphrase")
wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0])
+ if ssid_charset:
+ ev = dev[0].wait_event(["DPP-CONFOBJ-SSID-CHARSET"], timeout=1)
+ if ev is None:
+ raise Exception("ssid_charset not reported")
+ charset = ev.split(' ')[1]
+ if charset != str(ssid_charset):
+ raise Exception("Incorrect ssid_charset reported: " + ev)
ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
if ev is None:
raise Exception("DPP network profile not generated")
@@ -3306,7 +3325,7 @@ def test_dpp_proto_network_introduction(dev, apdev):
dpp_netaccesskey=params1_sta_netaccesskey,
wait_connect=False)
- ev = dev[0].wait_event(["DPP-TX"], timeout=10)
+ ev = dev[0].wait_event(["DPP-TX "], timeout=10)
if ev is None or "type=5" not in ev:
raise Exception("Peer Discovery Request TX not reported")
ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=2)
@@ -3679,7 +3698,7 @@ def wait_auth_success(responder, initiator, configurator=None, enrollee=None,
if ev is None:
raise Exception("DPP configuration not completed (Configurator)")
if "DPP-CONF-FAILED" in ev and not allow_configurator_failure:
- raise Exception("DPP configuration did not succeed (Configurator")
+ raise Exception("DPP configuration did not succeed (Configurator)")
if "DPP-CONF-SENT" in ev and require_configurator_failure:
raise Exception("DPP configuration succeeded (Configurator)")
if "DPP-CONF-SENT" in ev and "wait_conn_status=1" in ev:
@@ -4462,9 +4481,7 @@ def run_dpp_controller_relay(dev, apdev, params):
prefix = "dpp_controller_relay"
cap_lo = os.path.join(params['logdir'], prefix + ".lo.pcap")
- cmd = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'lo',
- '-w', cap_lo, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
+ wt = WlantestCapture('lo', cap_lo)
# Controller
conf_id = dev[1].dpp_configurator_add()
@@ -4508,7 +4525,7 @@ def run_dpp_controller_relay(dev, apdev, params):
dev[0].wait_connected()
time.sleep(0.5)
- cmd.terminate()
+ wt.close()
def test_dpp_tcp(dev, apdev, params):
"""DPP over TCP"""
@@ -4532,9 +4549,7 @@ def run_dpp_tcp(dev, apdev, cap_lo, port=None):
check_dpp_capab(dev[0])
check_dpp_capab(dev[1])
- cmd = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'lo',
- '-w', cap_lo, '-s', '2000'],
- stderr=open('/dev/null', 'w'))
+ wt = WlantestCapture('lo', cap_lo)
time.sleep(1)
# Controller
@@ -4565,7 +4580,7 @@ def run_dpp_tcp(dev, apdev, cap_lo, port=None):
allow_enrollee_failure=True,
allow_configurator_failure=True)
time.sleep(0.5)
- cmd.terminate()
+ wt.close()
def test_dpp_tcp_controller_start_failure(dev, apdev, params):
"""DPP Controller startup failure"""
@@ -4708,7 +4723,15 @@ def test_dpp_conn_status_connector_mismatch(dev, apdev):
finally:
dev[0].set("dpp_config_processing", "0")
-def run_dpp_conn_status(dev, apdev, result=0):
+def test_dpp_conn_status_assoc_reject(dev, apdev):
+ """DPP connection status - association rejection"""
+ try:
+ dev[0].request("TEST_ASSOC_IE 30020000")
+ run_dpp_conn_status(dev, apdev, assoc_reject=True)
+ finally:
+ dev[0].set("dpp_config_processing", "0")
+
+def run_dpp_conn_status(dev, apdev, result=0, assoc_reject=False):
check_dpp_capab(dev[0], min_ver=2)
check_dpp_capab(dev[1], min_ver=2)
@@ -4756,6 +4779,8 @@ def run_dpp_conn_status(dev, apdev, result=0):
if 'wait_conn_status' not in res:
raise Exception("Configurator did not request connection status")
+ if assoc_reject and result == 0:
+ result = 2
ev = dev[1].wait_event(["DPP-CONN-STATUS-RESULT"], timeout=20)
if ev is None:
raise Exception("No connection status reported")
@@ -4836,3 +4861,36 @@ def run_dpp_config_save(dev, apdev, config, conf_ssid, exp_ssid):
raise Exception("SSID not saved")
if 'psk="secret passphrase"' not in data:
raise Exception("Passphtase not saved")
+
+def test_dpp_nfc_uri(dev, apdev):
+ """DPP bootstrapping via NFC URI record"""
+ check_dpp_capab(dev[0])
+ check_dpp_capab(dev[1])
+
+ id = dev[0].dpp_bootstrap_gen(type="nfc-uri", chan="81/1", mac=True)
+ uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
+ logger.info("Generated URI: " + uri)
+ info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id)
+ logger.info("Bootstrapping info:\n" + info)
+ if "type=NFC-URI" not in info:
+ raise Exception("Unexpected bootstrapping info contents")
+
+ dev[0].dpp_listen(2412)
+ conf_id = dev[1].dpp_configurator_add()
+ dev[1].dpp_auth_init(nfc_uri=uri, configurator=conf_id, conf="sta-dpp")
+ wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0])
+
+def test_dpp_with_p2p_device(dev, apdev):
+ """DPP exchange when driver uses a separate P2P Device interface"""
+ check_dpp_capab(dev[0])
+ with HWSimRadio(use_p2p_device=True) as (radio, iface):
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add(iface)
+ check_dpp_capab(wpas)
+ id1 = wpas.dpp_bootstrap_gen(chan="81/1", mac=True)
+ uri1 = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % id1)
+ wpas.dpp_listen(2412)
+ time.sleep(7)
+ dev[0].dpp_auth_init(uri=uri1)
+ wait_auth_success(wpas, dev[0], configurator=dev[0], enrollee=wpas,
+ allow_enrollee_failure=True)
diff --git a/tests/hwsim/test_fils.py b/tests/hwsim/test_fils.py
index f8e2bcc..4db7666 100644
--- a/tests/hwsim/test_fils.py
+++ b/tests/hwsim/test_fils.py
@@ -1640,6 +1640,7 @@ def test_fils_sk_auth_mismatch(dev, apdev, params):
dev[0].request("DISCONNECT")
dev[0].wait_disconnected()
+ hapd.dump_monitor()
dev[0].dump_monitor()
dev[0].select_network(id, freq=2412)
ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
@@ -1650,6 +1651,7 @@ def test_fils_sk_auth_mismatch(dev, apdev, params):
if "CTRL-EVENT-EAP-STARTED" not in ev:
raise Exception("No EAP exchange seen")
dev[0].wait_connected()
+ hapd.wait_sta()
hwsim_utils.test_connectivity(dev[0], hapd)
def setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=0, wpa_group_rekey=0,
@@ -1904,6 +1906,7 @@ def run_fils_and_ft_setup(dev, apdev, params, key_mgmt):
eap="PSK", identity="psk.user@example.com",
password_hex="0123456789abcdef0123456789abcdef",
erp="1", scan_freq="2412")
+ hapd.wait_sta()
hwsim_utils.test_connectivity(dev[0], hapd)
dev[0].request("DISCONNECT")
@@ -1950,6 +1953,7 @@ def run_fils_and_ft_setup(dev, apdev, params, key_mgmt):
raise Exception("Authentication failed")
if "EVENT-ASSOC-REJECT" in ev:
raise Exception("Association failed")
+ hapd.wait_sta()
hwsim_utils.test_connectivity(dev[0], hapd)
er.disable()
@@ -2183,6 +2187,66 @@ def run_fils_sk_erp_radius_ext(dev, apdev, params):
raise Exception("Association failed")
hwsim_utils.test_connectivity(dev[0], hapd)
+def test_fils_sk_erp_radius_roam(dev, apdev):
+ """FILS SK/ERP and roaming with different AKM"""
+ as_hapd = hostapd.Hostapd("as")
+ try:
+ as_hapd.disable()
+ as_hapd.set("eap_server_erp", "1")
+ as_hapd.set("erp_domain", "example.com")
+ as_hapd.enable()
+ run_fils_sk_erp_radius_roam(dev, apdev)
+ finally:
+ as_hapd.disable()
+ as_hapd.set("eap_server_erp", "0")
+ as_hapd.set("erp_domain", "")
+ as_hapd.enable()
+
+def run_fils_sk_erp_radius_roam(dev, apdev):
+ check_fils_capa(dev[0])
+ check_erp_capa(dev[0])
+
+ bssid = apdev[0]['bssid']
+ params = hostapd.wpa2_eap_params(ssid="fils")
+ params['wpa_key_mgmt'] = "FILS-SHA256"
+ params['erp_domain'] = 'example.com'
+ params['fils_realm'] = 'example.com'
+ params['disable_pmksa_caching'] = '1'
+ hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+
+ dev[0].scan_for_bss(bssid, freq=2412)
+ dev[0].request("ERP_FLUSH")
+ id = dev[0].connect("fils", key_mgmt="FILS-SHA256 FILS-SHA384",
+ eap="PWD", identity="erp-pwd@example.com",
+ password="secret password",
+ erp="1", scan_freq="2412")
+
+ bssid2 = apdev[1]['bssid']
+ params = hostapd.wpa2_eap_params(ssid="fils")
+ params['wpa_key_mgmt'] = "FILS-SHA384"
+ params['erp_domain'] = 'example.com'
+ params['fils_realm'] = 'example.com'
+ params['disable_pmksa_caching'] = '1'
+ hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
+
+ dev[0].scan_for_bss(bssid2, freq=2412)
+
+ dev[0].dump_monitor()
+ if "OK" not in dev[0].request("ROAM " + bssid2):
+ raise Exception("ROAM failed")
+
+ ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
+ "CTRL-EVENT-CONNECTED"], timeout=10)
+ if ev is None:
+ raise Exception("Connection using PMKSA caching timed out")
+ if "CTRL-EVENT-EAP-STARTED" in ev:
+ raise Exception("Unexpected EAP exchange")
+ if bssid2 not in ev:
+ raise Exception("Failed to connect to the second AP")
+
+ hapd2.wait_sta()
+ hwsim_utils.test_connectivity(dev[0], hapd2)
+
def test_fils_sk_erp_roam_diff_akm(dev, apdev, params):
"""FILS SK using ERP and SHA256/SHA384 change in roam"""
check_fils_capa(dev[0])
diff --git a/tests/hwsim/test_hapd_ctrl.py b/tests/hwsim/test_hapd_ctrl.py
index 245aad7..5b802e4 100644
--- a/tests/hwsim/test_hapd_ctrl.py
+++ b/tests/hwsim/test_hapd_ctrl.py
@@ -79,9 +79,20 @@ def run_hapd_ctrl_sta(dev, apdev):
passphrase = "12345678"
params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
hapd = hostapd.add_ap(apdev[0], params)
+ hglobal = hostapd.HostapdGlobal(apdev[0])
dev[0].request("VENDOR_ELEM_ADD 13 2102ff02")
dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
addr = dev[0].own_addr()
+ ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=2)
+ if ev is None:
+ raise Exception("No hostapd per-interface event reported")
+ ev2 = hglobal.wait_event(["AP-STA-CONNECTED"], timeout=2)
+ if ev2 is None:
+ raise Exception("No hostapd global event reported")
+ if not ev2.startswith("IFNAME=" + apdev[0]['ifname'] + " <"):
+ raise Exception("Unexpected global event prefix: " + ev2)
+ if ev not in ev2:
+ raise Exception("Event mismatch (%s,%s)" % (ev, ev2))
if "FAIL" in hapd.request("STA " + addr):
raise Exception("Unexpected STA failure")
if "FAIL" not in hapd.request("STA " + addr + " eapol"):
diff --git a/tests/hwsim/test_he.py b/tests/hwsim/test_he.py
index f042d71..d86e242 100644
--- a/tests/hwsim/test_he.py
+++ b/tests/hwsim/test_he.py
@@ -79,7 +79,7 @@ def test_he_params(dev, apdev):
def he_supported():
cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
- reg = cmd.stdout.read()
+ reg = cmd.stdout.read().decode()
if "@ 80)" in reg or "@ 160)" in reg:
return True
return False
diff --git a/tests/hwsim/test_ieee8021x.py b/tests/hwsim/test_ieee8021x.py
index b759847..bc1c3c9 100644
--- a/tests/hwsim/test_ieee8021x.py
+++ b/tests/hwsim/test_ieee8021x.py
@@ -244,7 +244,7 @@ def test_ieee8021x_held(dev, apdev):
def send_eapol_key(dev, bssid, signkey, frame_start, frame_end):
zero_sign = "00000000000000000000000000000000"
frame = frame_start + zero_sign + frame_end
- hmac_obj = hmac.new(binascii.unhexlify(signkey))
+ hmac_obj = hmac.new(binascii.unhexlify(signkey), digestmod='MD5')
hmac_obj.update(binascii.unhexlify(frame))
sign = hmac_obj.digest()
frame = frame_start + binascii.hexlify(sign).decode() + frame_end
diff --git a/tests/hwsim/test_macsec.py b/tests/hwsim/test_macsec.py
index 8ef4fec..e521c6b 100644
--- a/tests/hwsim/test_macsec.py
+++ b/tests/hwsim/test_macsec.py
@@ -16,6 +16,7 @@ import hostapd
from wpasupplicant import WpaSupplicant
import hwsim_utils
from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
+from wlantest import WlantestCapture
def cleanup_macsec():
wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False)
@@ -275,14 +276,8 @@ def run_macsec_psk(dev, apdev, params, prefix, integ_only=False, port0=None,
subprocess.check_call(["ip", "link", "set", "dev", "veth%d" % i, "up"])
cmd = {}
- cmd[0] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'veth0',
- '-w', cap_veth0, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
- cmd[1] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'veth1',
- '-w', cap_veth1, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
+ cmd[0] = WlantestCapture('veth0', cap_veth0)
+ cmd[1] = WlantestCapture('veth1', cap_veth1)
wpa = add_wpas_interfaces()
wpas0 = wpa[0]
@@ -307,17 +302,11 @@ def run_macsec_psk(dev, apdev, params, prefix, integ_only=False, port0=None,
if expect_failure:
for i in range(len(cmd)):
- cmd[i].terminate()
+ cmd[i].close()
return
- cmd[2] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', macsec_ifname0,
- '-w', cap_macsec0, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
- cmd[3] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', macsec_ifname1,
- '-w', cap_macsec1, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
+ cmd[2] = WlantestCapture(macsec_ifname0, cap_macsec0)
+ cmd[3] = WlantestCapture(macsec_ifname1, cap_macsec1)
time.sleep(0.5)
mi0 = wpas0.get_status_field("mi")
@@ -353,7 +342,7 @@ def run_macsec_psk(dev, apdev, params, prefix, integ_only=False, port0=None,
time.sleep(1)
for i in range(len(cmd)):
- cmd[i].terminate()
+ cmd[i].close()
def cleanup_macsec_br(count):
wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False)
@@ -591,16 +580,8 @@ def run_macsec_psk_ns(dev, apdev, params):
"up"])
cmd = {}
- cmd[0] = subprocess.Popen(['ip', 'netns', 'exec', 'ns0',
- 'tcpdump', '-p', '-U', '-i', 'veth0',
- '-w', cap_veth0, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
- cmd[1] = subprocess.Popen(['ip', 'netns', 'exec', 'ns1',
- 'tcpdump', '-p', '-U', '-i', 'veth1',
- '-w', cap_veth1, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
+ cmd[0] = WlantestCapture('veth0', cap_veth0, netns='ns0')
+ cmd[1] = WlantestCapture('veth1', cap_veth1, netns='ns1')
write_conf(conffile + '0')
write_conf(conffile + '1', mka_priority=100)
@@ -661,16 +642,8 @@ def run_macsec_psk_ns(dev, apdev, params):
break
time.sleep(1)
- cmd[2] = subprocess.Popen(['ip', 'netns', 'exec', 'ns0',
- 'tcpdump', '-p', '-U', '-i', macsec_ifname0,
- '-w', cap_macsec0, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
- cmd[3] = subprocess.Popen(['ip', 'netns', 'exec', 'ns0',
- 'tcpdump', '-p', '-U', '-i', macsec_ifname1,
- '-w', cap_macsec1, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
+ cmd[2] = WlantestCapture(macsec_ifname0, cap_macsec0, netns='ns0')
+ cmd[3] = WlantestCapture(macsec_ifname1, cap_macsec1, netns='ns0')
time.sleep(0.5)
logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS"))
@@ -708,7 +681,7 @@ def run_macsec_psk_ns(dev, apdev, params):
time.sleep(1)
for i in range(len(cmd)):
- cmd[i].terminate()
+ cmd[i].close()
def test_macsec_psk_fail_cp(dev, apdev):
"""MACsec PSK local failures in CP state machine"""
@@ -769,14 +742,8 @@ def run_macsec_hostapd_psk(dev, apdev, params, prefix, integ_only=False,
subprocess.check_call(["ip", "link", "set", "dev", "veth%d" % i, "up"])
cmd = {}
- cmd[0] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'veth0',
- '-w', cap_veth0, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
- cmd[1] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'veth1',
- '-w', cap_veth1, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
+ cmd[0] = WlantestCapture('veth0', cap_veth0)
+ cmd[1] = WlantestCapture('veth1', cap_veth1)
wpa = add_wpas_interfaces(count=1)
wpas0 = wpa[0]
@@ -816,20 +783,14 @@ def run_macsec_hostapd_psk(dev, apdev, params, prefix, integ_only=False,
if expect_failure:
for i in range(len(cmd)):
- cmd[i].terminate()
+ cmd[i].close()
return
macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname")
macsec_ifname1 = hapd.get_driver_status_field("parent_ifname")
- cmd[2] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', macsec_ifname0,
- '-w', cap_macsec0, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
- cmd[3] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', macsec_ifname1,
- '-w', cap_macsec1, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
+ cmd[2] = WlantestCapture(macsec_ifname0, cap_macsec0)
+ cmd[3] = WlantestCapture(macsec_ifname1, cap_macsec1)
time.sleep(0.5)
logger.info("wpas0 MIB:\n" + wpas0.request("MIB"))
@@ -843,7 +804,7 @@ def run_macsec_hostapd_psk(dev, apdev, params, prefix, integ_only=False,
time.sleep(1)
for i in range(len(cmd)):
- cmd[i].terminate()
+ cmd[i].close()
def test_macsec_hostapd_eap(dev, apdev, params):
"""MACsec EAP with hostapd"""
@@ -865,14 +826,8 @@ def run_macsec_hostapd_eap(dev, apdev, params, prefix, integ_only=False,
subprocess.check_call(["ip", "link", "set", "dev", "veth%d" % i, "up"])
cmd = {}
- cmd[0] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'veth0',
- '-w', cap_veth0, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
- cmd[1] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'veth1',
- '-w', cap_veth1, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
+ cmd[0] = WlantestCapture('veth0', cap_veth0)
+ cmd[1] = WlantestCapture('veth1', cap_veth1)
wpa = add_wpas_interfaces(count=1)
wpas0 = wpa[0]
@@ -911,20 +866,14 @@ def run_macsec_hostapd_eap(dev, apdev, params, prefix, integ_only=False,
if expect_failure:
for i in range(len(cmd)):
- cmd[i].terminate()
+ cmd[i].close()
return
macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname")
macsec_ifname1 = hapd.get_driver_status_field("parent_ifname")
- cmd[2] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', macsec_ifname0,
- '-w', cap_macsec0, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
- cmd[3] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', macsec_ifname1,
- '-w', cap_macsec1, '-s', '2000',
- '--immediate-mode'],
- stderr=open('/dev/null', 'w'))
+ cmd[2] = WlantestCapture(macsec_ifname0, cap_macsec0)
+ cmd[3] = WlantestCapture(macsec_ifname1, cap_macsec1)
time.sleep(0.5)
logger.info("wpas0 MIB:\n" + wpas0.request("MIB"))
@@ -938,4 +887,4 @@ def run_macsec_hostapd_eap(dev, apdev, params, prefix, integ_only=False,
time.sleep(1)
for i in range(len(cmd)):
- cmd[i].terminate()
+ cmd[i].close()
diff --git a/tests/hwsim/test_nfc_wps.py b/tests/hwsim/test_nfc_wps.py
index 7609639..e98eb41 100644
--- a/tests/hwsim/test_nfc_wps.py
+++ b/tests/hwsim/test_nfc_wps.py
@@ -241,6 +241,9 @@ def _test_nfc_wps_handover_init(dev, apdev):
if "FAIL" in res:
raise Exception("Failed to report NFC connection handover to to wpa_supplicant")
dev[0].wait_connected(timeout=15)
+ # WPS provisioning
+ hapd.wait_sta()
+ # data connection
hapd.wait_sta()
check_wpa2_connection(dev[0], apdev[0], hapd, ssid, mixed=True)
diff --git a/tests/hwsim/test_oce.py b/tests/hwsim/test_oce.py
index dd2ed40..39ec5df 100644
--- a/tests/hwsim/test_oce.py
+++ b/tests/hwsim/test_oce.py
@@ -8,6 +8,7 @@ import logging
logger = logging.getLogger()
import hostapd
+from wpasupplicant import WpaSupplicant
from hwsim_utils import set_rx_rssi, reset_rx_rssi
import time
@@ -162,3 +163,23 @@ def test_oce_ap(dev, apdev):
params['oce'] = "4"
hapd = hostapd.add_ap(apdev[0], params)
dev[0].connect(ssid, psk=passphrase, ieee80211w="1", scan_freq="2412")
+
+def test_oce_ap_open(dev, apdev):
+ """OCE AP (open)"""
+ ssid = "test-oce"
+ params = {"ssid": ssid}
+ params['mbo'] = "1"
+ params['oce'] = "4"
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
+
+def test_oce_ap_open_connect_cmd(dev, apdev):
+ """OCE AP (open, connect command)"""
+ ssid = "test-oce"
+ params = {"ssid": ssid}
+ params['mbo'] = "1"
+ params['oce'] = "4"
+ hapd = hostapd.add_ap(apdev[0], params)
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
+ wpas.connect(ssid, key_mgmt="NONE", scan_freq="2412")
diff --git a/tests/hwsim/test_ocv.py b/tests/hwsim/test_ocv.py
index 176e17f..df84e71 100644
--- a/tests/hwsim/test_ocv.py
+++ b/tests/hwsim/test_ocv.py
@@ -15,7 +15,7 @@ import hwsim_utils
from utils import HwsimSkip
from test_ap_ht import set_world_reg
-from test_ap_psk import parse_eapol, build_eapol, pmk_to_ptk, eapol_key_mic, recv_eapol, send_eapol, reply_eapol, hapd_connected, build_eapol_key_3_4, aes_wrap, pad_key_data
+from test_ap_psk import parse_eapol, build_eapol, pmk_to_ptk, eapol_key_mic, recv_eapol, send_eapol, reply_eapol, build_eapol_key_3_4, aes_wrap, pad_key_data
#TODO: Refuse setting up AP with OCV but without MFP support
#TODO: Refuse to connect to AP that advertises OCV but not MFP
@@ -424,7 +424,7 @@ class APConnection:
reply_eapol("4/4", self.hapd, self.addr, self.msg, 0x030a, None, None,
self.kck)
- hapd_connected(self.hapd)
+ self.hapd.wait_sta(timeout=15)
@remote_compatible
def test_wpa2_ocv_ap_mismatch(dev, apdev):
@@ -648,6 +648,7 @@ def test_wpa2_ocv_ap_group_hs(dev, apdev):
conn.hapd.request("SET ext_eapol_frame_io 0")
dev[1].connect(conn.ssid, psk=conn.passphrase, scan_freq="2412", ocv="1",
ieee80211w="1")
+ conn.hapd.wait_sta()
conn.hapd.request("SET ext_eapol_frame_io 1")
# Trigger a group key handshake
diff --git a/tests/hwsim/test_owe.py b/tests/hwsim/test_owe.py
index ee03182..9250558 100644
--- a/tests/hwsim/test_owe.py
+++ b/tests/hwsim/test_owe.py
@@ -224,6 +224,36 @@ def test_owe_transition_mode_open_only_ap(dev, apdev):
if val != "NONE":
raise Exception("Unexpected key_mgmt: " + val)
+def test_owe_only_sta(dev, apdev):
+ """Opportunistic Wireless Encryption transition mode disabled on STA"""
+ if "OWE" not in dev[0].get_capability("key_mgmt"):
+ raise HwsimSkip("OWE not supported")
+ dev[0].flush_scan_cache()
+ params = {"ssid": "owe-test-open"}
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ dev[0].scan_for_bss(bssid, freq="2412")
+ id = dev[0].connect("owe-test-open", key_mgmt="OWE", ieee80211w="2",
+ scan_freq="2412", owe_only="1", wait_connect=False)
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
+ if not ev:
+ raise Exception("Unknown result for the connection attempt")
+ if "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Unexpected connection to open network")
+ dev[0].request("DISCONNECT")
+ dev[0].dump_monitor()
+
+ params = {"ssid": "owe-test-open",
+ "wpa": "2",
+ "ieee80211w": "2",
+ "wpa_key_mgmt": "OWE",
+ "rsn_pairwise": "CCMP"}
+ hapd2 = hostapd.add_ap(apdev[1], params)
+ dev[0].request("RECONNECT")
+ dev[0].wait_connected()
+
def test_owe_transition_mode_open_multiple_scans(dev, apdev):
"""Opportunistic Wireless Encryption transition mode and need for multiple scans"""
if "OWE" not in dev[0].get_capability("key_mgmt"):
@@ -414,7 +444,8 @@ def test_owe_limited_group_set_pmf(dev, apdev, params):
logger.info("Association Response frame status codes: " + str(status))
if len(status) != 3:
raise Exception("Unexpected number of Association Response frames")
- if int(status[0]) != 77 or int(status[1]) != 77 or int(status[2]) != 0:
+ if (int(status[0], base=0) != 77 or int(status[1], base=0) != 77 or
+ int(status[2], base=0) != 0):
raise Exception("Unexpected Association Response frame status code")
def test_owe_group_negotiation(dev, apdev):
diff --git a/tests/hwsim/test_p2p_discovery.py b/tests/hwsim/test_p2p_discovery.py
index 5f9f6c9..f4353e8 100644
--- a/tests/hwsim/test_p2p_discovery.py
+++ b/tests/hwsim/test_p2p_discovery.py
@@ -654,6 +654,22 @@ def test_discovery_long_listen(dev):
dev[1].p2p_stop_find()
wpas.p2p_stop_find()
+def test_discovery_long_listen2(dev):
+ """Long P2P_LISTEN longer than remain-on-channel time"""
+ with HWSimRadio(use_p2p_device=True) as (radio, iface):
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add(iface)
+ addr = wpas.p2p_dev_addr()
+ wpas.request("P2P_LISTEN 15")
+
+ # Wait for remain maximum remain-on-channel time to pass
+ time.sleep(7)
+
+ if not dev[0].discover_peer(addr):
+ raise Exception("Device discovery timed out")
+ dev[0].p2p_stop_find()
+ wpas.p2p_stop_find()
+
def pd_test(dev, addr):
if not dev.discover_peer(addr, freq=2412):
raise Exception("Device discovery timed out")
diff --git a/tests/hwsim/test_pmksa_cache.py b/tests/hwsim/test_pmksa_cache.py
index d309ebb..11daaaa 100644
--- a/tests/hwsim/test_pmksa_cache.py
+++ b/tests/hwsim/test_pmksa_cache.py
@@ -353,6 +353,7 @@ def test_pmksa_cache_expiration(dev, apdev):
pmksa2 = dev[0].get_pmksa(bssid)
if pmksa['pmkid'] == pmksa2['pmkid']:
raise Exception("PMKID did not change")
+ hapd.wait_ptkinitdone(dev[0].own_addr())
hwsim_utils.test_connectivity(dev[0], hapd)
def test_pmksa_cache_expiration_disconnect(dev, apdev):
diff --git a/tests/hwsim/test_radius.py b/tests/hwsim/test_radius.py
index dbefaf5..fde5650 100644
--- a/tests/hwsim/test_radius.py
+++ b/tests/hwsim/test_radius.py
@@ -114,11 +114,16 @@ def test_radius_acct_unreachable2(dev, apdev):
subprocess.call(['ip', 'ro', 'del', '192.168.213.17', 'dev', 'lo'])
connect(dev[0], "radius-acct")
logger.info("Checking for RADIUS retries")
- time.sleep(4)
- mib = hapd.get_mib()
- if "radiusAccClientRetransmissions" not in mib:
- raise Exception("Missing MIB fields")
- if int(mib["radiusAccClientRetransmissions"]) < 1 and int(mib["radiusAccClientPendingRequests"]) < 1:
+ found = False
+ for i in range(4):
+ time.sleep(1)
+ mib = hapd.get_mib()
+ if "radiusAccClientRetransmissions" not in mib:
+ raise Exception("Missing MIB fields")
+ if int(mib["radiusAccClientRetransmissions"]) > 0 or \
+ int(mib["radiusAccClientPendingRequests"]) > 0:
+ found = True
+ if not found:
raise Exception("Missing pending or retransmitted RADIUS Accounting requests")
def test_radius_acct_unreachable3(dev, apdev):
diff --git a/tests/hwsim/test_rrm.py b/tests/hwsim/test_rrm.py
index c9c8d61..dde9893 100644
--- a/tests/hwsim/test_rrm.py
+++ b/tests/hwsim/test_rrm.py
@@ -68,6 +68,22 @@ def test_rrm_neighbor_db(dev, apdev):
"""hostapd ctrl_iface SET_NEIGHBOR"""
params = {"ssid": "test", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+ params = {"ssid": "test2", "rrm_neighbor_report": "1"}
+ hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
+
+ res = hapd.request("SHOW_NEIGHBOR")
+ if len(res.splitlines()) != 1:
+ raise Exception("Unexpected SHOW_NEIGHBOR output(1): " + res)
+ if apdev[0]['bssid'] not in res:
+ raise Exception("Own BSS not visible in SHOW_NEIGHBOR output")
+
+ if "OK" not in hapd2.request("SET_NEIGHBOR " + res.strip()):
+ raise Exception("Failed to copy neighbor entry to another hostapd")
+ res2 = hapd2.request("SHOW_NEIGHBOR")
+ if len(res2.splitlines()) != 2:
+ raise Exception("Unexpected SHOW_NEIGHBOR output: " + res2)
+ if res not in res2:
+ raise Exception("Copied entry not visible")
# Bad BSSID
if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:gg ssid=\"test1\" nr=" + nr):
@@ -105,10 +121,28 @@ def test_rrm_neighbor_db(dev, apdev):
if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic):
raise Exception("Set neighbor failed")
+ res = hapd.request("SHOW_NEIGHBOR")
+ if len(res.splitlines()) != 2:
+ raise Exception("Unexpected SHOW_NEIGHBOR output(2): " + res)
+ if apdev[0]['bssid'] not in res:
+ raise Exception("Own BSS not visible in SHOW_NEIGHBOR output")
+ if "00:11:22:33:44:55" not in res:
+ raise Exception("Added BSS not visible in SHOW_NEIGHBOR output")
+
# Another BSSID with the same SSID
if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:56 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic):
raise Exception("Set neighbor failed")
+ res = hapd.request("SHOW_NEIGHBOR")
+ if len(res.splitlines()) != 3:
+ raise Exception("Unexpected SHOW_NEIGHBOR output(3): " + res)
+ if apdev[0]['bssid'] not in res:
+ raise Exception("Own BSS not visible in SHOW_NEIGHBOR output")
+ if "00:11:22:33:44:55" not in res:
+ raise Exception("Added BSS not visible in SHOW_NEIGHBOR output")
+ if "00:11:22:33:44:56" not in res:
+ raise Exception("Second added BSS not visible in SHOW_NEIGHBOR output")
+
# Fewer parameters
if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr):
raise Exception("Set neighbor failed")
@@ -146,9 +180,19 @@ def test_rrm_neighbor_db(dev, apdev):
if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test3\" nr=" + nr + " lci=" + lci + " civic=" + civic + " stat"):
raise Exception("Set neighbor failed")
+ res = hapd.request("SHOW_NEIGHBOR")
+ if len(res.splitlines()) != 2:
+ raise Exception("Unexpected SHOW_NEIGHBOR output(4): " + res)
+ if "00:11:22:33:44:55" not in res or " stat" not in res:
+ raise Exception("Unexpected SHOW_NEIGHBOR output(4b): " + res)
+
if "OK" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test3\""):
raise Exception("Remove neighbor failed")
+ # Add an entry for following REMOVE_NEIGHBOR tests
+ if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=7465737431 nr=" + nr):
+ raise Exception("Set neighbor failed")
+
# Invalid remove - bad BSSID
if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:5 ssid=\"test1\""):
raise Exception("Remove neighbor succeeded unexpectedly")
@@ -157,9 +201,15 @@ def test_rrm_neighbor_db(dev, apdev):
if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1"):
raise Exception("Remove neighbor succeeded unexpectedly")
- # Invalid remove - missing SSID
- if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55"):
- raise Exception("Remove neighbor succeeded unexpectedly")
+ # Remove without specifying SSID
+ if "OK" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55"):
+ raise Exception("Remove neighbor without SSID failed")
+
+ res = hapd.request("SHOW_NEIGHBOR")
+ if len(res.splitlines()) != 1:
+ raise Exception("Unexpected SHOW_NEIGHBOR output(5): " + res)
+ if apdev[0]['bssid'] not in res:
+ raise Exception("Own BSS not visible in SHOW_NEIGHBOR output")
def test_rrm_neighbor_rep_req(dev, apdev):
"""wpa_supplicant ctrl_iface NEIGHBOR_REP_REQUEST"""
@@ -969,6 +1019,7 @@ def test_rrm_beacon_req_table_request(dev, apdev):
params = {"ssid": "rrm", "rrm_beacon_report": "1"}
hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].flush_scan_cache()
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
addr = dev[0].own_addr()
@@ -2046,6 +2097,7 @@ def test_rrm_reassociation(dev, apdev):
bssid = hapd.own_addr()
addr = dev[0].own_addr()
+ dev[0].flush_scan_cache()
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
check_beacon_req(hapd, addr, 1)
diff --git a/tests/hwsim/test_sae.py b/tests/hwsim/test_sae.py
index e45287d..978c28f 100644
--- a/tests/hwsim/test_sae.py
+++ b/tests/hwsim/test_sae.py
@@ -1396,7 +1396,7 @@ def test_sae_bignum_failure(dev, apdev):
hapd.request("NOTE STA failure testing %d:%s" % (count, func))
dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
scan_freq="2412", wait_connect=False)
- wait_fail_trigger(dev[0], "GET_FAIL")
+ wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1)
dev[0].request("REMOVE_NETWORK all")
dev[0].dump_monitor()
hapd.dump_monitor()
@@ -1426,7 +1426,7 @@ def test_sae_bignum_failure(dev, apdev):
hapd.request("NOTE STA failure testing %d:%s" % (count, func))
dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
scan_freq="2412", wait_connect=False)
- wait_fail_trigger(dev[0], "GET_FAIL")
+ wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1)
dev[0].request("REMOVE_NETWORK all")
dev[0].dump_monitor()
hapd.dump_monitor()
@@ -1868,6 +1868,18 @@ def test_sae_confirm_immediate(dev, apdev):
dev[0].request("SET sae_groups ")
dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412")
+def test_sae_confirm_immediate2(dev, apdev):
+ """SAE and AP sending Confirm message without waiting STA (2)"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params['sae_confirm_immediate'] = '2'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].request("SET sae_groups ")
+ dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412")
+
def test_sae_pwe_group_19(dev, apdev):
"""SAE PWE derivation options with group 19"""
run_sae_pwe_group(dev, apdev, 19)
@@ -1981,6 +1993,17 @@ def test_sae_pwe_h2e_only_ap(dev, apdev):
if ev is None:
raise Exception("No indication of mismatching network seen")
+def test_sae_pwe_h2e_only_ap_sta_forcing_loop(dev, apdev):
+ """SAE PWE derivation with H2E-only AP and STA forcing loop"""
+ start_sae_pwe_ap(apdev[0], 19, 1)
+ dev[0].set("ignore_sae_h2e_only", "1")
+ dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412",
+ wait_connect=False)
+ ev = dev[0].wait_event(["CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10)
+ dev[0].request("DISCONNECT")
+ if ev is None:
+ raise Exception("No indication of temporary disabled network seen")
+
def test_sae_pwe_loop_only_ap(dev, apdev):
"""SAE PWE derivation with loop-only AP"""
start_sae_pwe_ap(apdev[0], 19, 0)
@@ -2009,6 +2032,38 @@ def test_sae_h2e_rejected_groups(dev, apdev):
dev[0].set("sae_pwe", "1")
dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
scan_freq="2412")
+ addr = dev[0].own_addr()
+ hapd.wait_sta(addr)
+ sta = hapd.get_sta(addr)
+ if 'sae_rejected_groups' not in sta:
+ raise Exception("No sae_rejected_groups")
+ val = sta['sae_rejected_groups']
+ if val != "21 20":
+ raise Exception("Unexpected sae_rejected_groups value: " + val)
+ finally:
+ dev[0].set("sae_groups", "")
+ dev[0].set("sae_pwe", "0")
+
+def test_sae_h2e_rejected_groups_unexpected(dev, apdev):
+ """SAE H2E and rejected groups indication (unexpected group)"""
+ params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params['sae_groups'] = "19 20"
+ params['sae_pwe'] = "1"
+ hapd = hostapd.add_ap(apdev[0], params)
+ try:
+ dev[0].set("sae_groups", "21 19")
+ dev[0].set("extra_sae_rejected_groups", "19")
+ dev[0].set("sae_pwe", "1")
+ dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
+ scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10)
+ dev[0].request("DISCONNECT")
+ if ev is None:
+ raise Exception("No indication of temporary disabled network seen")
+ if "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Unexpected connection")
finally:
dev[0].set("sae_groups", "")
dev[0].set("sae_pwe", "0")
@@ -2033,6 +2088,14 @@ def test_sae_h2e_password_id(dev, apdev):
dev[0].set("sae_groups", "")
dev[0].set("sae_pwe", "0")
+def test_sae_pwe_in_psk_ap(dev, apdev):
+ """sae_pwe parameter in PSK-only-AP"""
+ params = hostapd.wpa2_params(ssid="test-psk", passphrase="12345678")
+ params['sae_pwe'] = '1'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].connect("test-psk", psk="12345678", scan_freq="2412")
+
def test_sae_auth_restart(dev, apdev):
"""SAE and authentication restarts with H2E/looping"""
if "SAE" not in dev[0].get_capability("auth_alg"):
@@ -2062,3 +2125,149 @@ def test_sae_auth_restart(dev, apdev):
finally:
dev[0].set("sae_groups", "")
dev[0].set("sae_pwe", "0")
+
+def test_sae_h2e_rsnxe_mismatch(dev, apdev):
+ """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4"""
+ params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params['sae_pwe'] = "1"
+ hapd = hostapd.add_ap(apdev[0], params)
+ try:
+ dev[0].set("sae_groups", "19")
+ dev[0].set("sae_pwe", "1")
+ for rsnxe in ["F40100", "F400", ""]:
+ dev[0].set("rsnxe_override_eapol", rsnxe)
+ dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
+ scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["Associated with"], timeout=10)
+ if ev is None:
+ raise Exception("No indication of association seen")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=5)
+ dev[0].request("REMOVE_NETWORK all")
+ if ev is None:
+ raise Exception("No disconnection seen")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection")
+ dev[0].dump_monitor()
+ finally:
+ dev[0].set("sae_groups", "")
+ dev[0].set("sae_pwe", "0")
+
+def test_sae_h2e_rsnxe_mismatch_retries(dev, apdev):
+ """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 retries"""
+ params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params['sae_pwe'] = "1"
+ hapd = hostapd.add_ap(apdev[0], params)
+ try:
+ dev[0].set("sae_groups", "19")
+ dev[0].set("sae_pwe", "1")
+ rsnxe = "F40100"
+ dev[0].set("rsnxe_override_eapol", rsnxe)
+ dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
+ scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["Associated with"], timeout=10)
+ if ev is None:
+ raise Exception("No indication of association seen")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=5)
+ if ev is None:
+ raise Exception("No disconnection seen")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection")
+
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=10)
+ if ev is None:
+ raise Exception("No disconnection seen (2)")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection (2)")
+
+ dev[0].dump_monitor()
+ finally:
+ dev[0].set("sae_groups", "")
+ dev[0].set("sae_pwe", "0")
+
+def test_sae_h2e_rsnxe_mismatch_assoc(dev, apdev):
+ """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 (assoc)"""
+ params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params['sae_pwe'] = "1"
+ hapd = hostapd.add_ap(apdev[0], params)
+ try:
+ dev[0].set("sae_groups", "19")
+ dev[0].set("sae_pwe", "1")
+ for rsnxe in ["F40100", "F400", ""]:
+ dev[0].set("rsnxe_override_assoc", rsnxe)
+ dev[0].set("rsnxe_override_eapol", "F40120")
+ dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
+ scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["Associated with"], timeout=10)
+ if ev is None:
+ raise Exception("No indication of association seen")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=5)
+ dev[0].request("REMOVE_NETWORK all")
+ if ev is None:
+ raise Exception("No disconnection seen")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection")
+ dev[0].dump_monitor()
+ finally:
+ dev[0].set("sae_groups", "")
+ dev[0].set("sae_pwe", "0")
+
+def test_sae_h2e_rsnxe_mismatch_ap(dev, apdev):
+ """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4"""
+ run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F40100")
+
+def test_sae_h2e_rsnxe_mismatch_ap2(dev, apdev):
+ """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4"""
+ run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F400")
+
+def run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, rsnxe):
+ params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params['sae_pwe'] = "1"
+ params['rsnxe_override_eapol'] = rsnxe
+ hapd = hostapd.add_ap(apdev[0], params)
+ try:
+ dev[0].set("sae_groups", "19")
+ dev[0].set("sae_pwe", "1")
+ dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
+ scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["Associated with"], timeout=10)
+ if ev is None:
+ raise Exception("No indication of association seen")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=5)
+ dev[0].request("REMOVE_NETWORK all")
+ if ev is None:
+ raise Exception("No disconnection seen")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection")
+ finally:
+ dev[0].set("sae_groups", "")
+ dev[0].set("sae_pwe", "0")
+
+def test_sae_forced_anti_clogging_h2e(dev, apdev):
+ """SAE anti clogging (forced, H2E)"""
+ if "SAE" not in dev[0].get_capability("auth_alg") or \
+ "SAE" not in dev[1].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE WPA-PSK'
+ params['sae_pwe'] = "1"
+ params['sae_anti_clogging_threshold'] = '0'
+ hostapd.add_ap(apdev[0], params)
+ dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
+ try:
+ for i in range(2):
+ dev[i].request("SET sae_groups ")
+ dev[i].set("sae_pwe", "1")
+ dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
+ scan_freq="2412")
+ finally:
+ for i in range(2):
+ dev[i].set("sae_pwe", "0")
diff --git a/tests/hwsim/test_scan.py b/tests/hwsim/test_scan.py
index a1e4171..682f427 100644
--- a/tests/hwsim/test_scan.py
+++ b/tests/hwsim/test_scan.py
@@ -467,11 +467,30 @@ def test_scan_for_auth_wep(dev, apdev):
@remote_compatible
def test_scan_hidden(dev, apdev):
"""Control interface behavior on scan parameters"""
- hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan",
+ dev[0].flush_scan_cache()
+ ssid = "test-scan"
+ wrong_ssid = "wrong"
+ hapd = hostapd.add_ap(apdev[0], {"ssid": ssid,
"ignore_broadcast_ssid": "1"})
bssid = apdev[0]['bssid']
check_scan(dev[0], "freq=2412 use_id=1")
+ try:
+ payload = struct.pack('BB', 0, len(wrong_ssid)) + wrong_ssid.encode()
+ ssid_list = struct.pack('BB', 84, len(payload)) + payload
+ cmd = "VENDOR_ELEM_ADD 14 " + binascii.hexlify(ssid_list).decode()
+ if "OK" not in dev[0].request(cmd):
+ raise Exception("VENDOR_ELEM_ADD failed")
+ check_scan(dev[0], "freq=2412 use_id=1")
+
+ payload = struct.pack('<L', binascii.crc32(wrong_ssid.encode()))
+ ssid_list = struct.pack('BBB', 255, 1 + len(payload), 58) + payload
+ cmd = "VENDOR_ELEM_ADD 14 " + binascii.hexlify(ssid_list).decode()
+ if "OK" not in dev[0].request(cmd):
+ raise Exception("VENDOR_ELEM_ADD failed")
+ check_scan(dev[0], "freq=2412 use_id=1")
+ finally:
+ dev[0].request("VENDOR_ELEM_REMOVE 14 *")
if "test-scan" in dev[0].request("SCAN_RESULTS"):
raise Exception("BSS unexpectedly found in initial scan")
@@ -1191,6 +1210,7 @@ def test_scan_bss_limit(dev, apdev):
pass
def _test_scan_bss_limit(dev, apdev):
+ dev[0].flush_scan_cache()
# Trigger 'Increasing the MAX BSS count to 2 because all BSSes are in use.
# We should normally not get here!' message by limiting the maximum BSS
# count to one so that the second AP would not fit in the BSS list and the
@@ -1903,3 +1923,53 @@ def test_scan_only_one(dev, apdev):
entries = len(list(filter(lambda x: x.startswith('BSS '), lines)))
if entries != 1:
raise Exception("expected to find 1 BSS entry, got %d" % entries)
+
+def test_scan_ssid_list(dev, apdev):
+ """Scan using SSID List element"""
+ dev[0].flush_scan_cache()
+ ssid = "test-ssid-list"
+ hapd = hostapd.add_ap(apdev[0], {"ssid": ssid,
+ "ignore_broadcast_ssid": "1"})
+ bssid = apdev[0]['bssid']
+ found = False
+ try:
+ payload = struct.pack('BB', 0, len(ssid)) + ssid.encode()
+ ssid_list = struct.pack('BB', 84, len(payload)) + payload
+ cmd = "VENDOR_ELEM_ADD 14 " + binascii.hexlify(ssid_list).decode()
+ if "OK" not in dev[0].request(cmd):
+ raise Exception("VENDOR_ELEM_ADD failed")
+ for i in range(10):
+ check_scan(dev[0], "freq=2412 use_id=1")
+ if ssid in dev[0].request("SCAN_RESULTS"):
+ found = True
+ break
+ finally:
+ dev[0].request("VENDOR_ELEM_REMOVE 14 *")
+
+ if not found:
+ raise Exception("AP not found in scan results")
+
+def test_scan_short_ssid_list(dev, apdev):
+ """Scan using Short SSID List element"""
+ dev[0].flush_scan_cache()
+ ssid = "test-short-ssid-list"
+ hapd = hostapd.add_ap(apdev[0], {"ssid": ssid,
+ "ignore_broadcast_ssid": "1"})
+ bssid = apdev[0]['bssid']
+ found = False
+ try:
+ payload = struct.pack('<L', binascii.crc32(ssid.encode()))
+ ssid_list = struct.pack('BBB', 255, 1 + len(payload), 58) + payload
+ cmd = "VENDOR_ELEM_ADD 14 " + binascii.hexlify(ssid_list).decode()
+ if "OK" not in dev[0].request(cmd):
+ raise Exception("VENDOR_ELEM_ADD failed")
+ for i in range(10):
+ check_scan(dev[0], "freq=2412 use_id=1")
+ if ssid in dev[0].request("SCAN_RESULTS"):
+ found = True
+ break
+ finally:
+ dev[0].request("VENDOR_ELEM_REMOVE 14 *")
+
+ if not found:
+ raise Exception("AP not found in scan results")
diff --git a/tests/hwsim/test_sigma_dut.py b/tests/hwsim/test_sigma_dut.py
index 38bb50c..19845a0 100644
--- a/tests/hwsim/test_sigma_dut.py
+++ b/tests/hwsim/test_sigma_dut.py
@@ -6,6 +6,8 @@
# See README for more details.
import binascii
+import errno
+import fcntl
import hashlib
import logging
logger = logging.getLogger()
@@ -35,6 +37,24 @@ def to_hex(s):
def from_hex(s):
return binascii.unhexlify(s).decode()
+def sigma_log_output(cmd):
+ try:
+ out = cmd.stdout.read()
+ if out:
+ logger.debug("sigma_dut stdout: " + str(out.decode()))
+ except IOError as e:
+ if e.errno != errno.EAGAIN:
+ raise
+ try:
+ out = cmd.stderr.read()
+ if out:
+ logger.debug("sigma_dut stderr: " + str(out.decode()))
+ except IOError as e:
+ if e.errno != errno.EAGAIN:
+ raise
+
+sigma_prog = None
+
def sigma_dut_cmd(cmd, port=9000, timeout=2):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
socket.IPPROTO_TCP)
@@ -64,6 +84,9 @@ def sigma_dut_cmd(cmd, port=9000, timeout=2):
sock.close()
res = res.rstrip()
logger.debug("sigma_dut: '%s' --> '%s'" % (cmd, res))
+ global sigma_prog
+ if sigma_prog:
+ sigma_log_output(sigma_prog)
return res
def sigma_dut_cmd_check(cmd, port=9000, timeout=2):
@@ -72,40 +95,59 @@ def sigma_dut_cmd_check(cmd, port=9000, timeout=2):
raise Exception("sigma_dut command failed: " + cmd)
return res
-def start_sigma_dut(ifname, debug=False, hostapd_logdir=None, cert_path=None,
- bridge=None):
+def start_sigma_dut(ifname, hostapd_logdir=None, cert_path=None,
+ bridge=None, sae_h2e=False):
check_sigma_dut()
cmd = ['./sigma_dut',
+ '-d',
'-M', ifname,
'-S', ifname,
'-F', '../../hostapd/hostapd',
'-G',
'-w', '/var/run/wpa_supplicant/',
'-j', ifname]
- if debug:
- cmd += ['-d']
if hostapd_logdir:
cmd += ['-H', hostapd_logdir]
if cert_path:
cmd += ['-C', cert_path]
if bridge:
cmd += ['-b', bridge]
+ if sae_h2e:
+ cmd += ['-2']
sigma = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
+ for stream in [sigma.stdout, sigma.stderr]:
+ fd = stream.fileno()
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+
+ global sigma_prog
+ sigma_prog = sigma
+ res = None
for i in range(20):
try:
res = sigma_dut_cmd("HELLO")
break
except:
time.sleep(0.05)
- return sigma
+ if res is None or "errorCode,Unknown command" not in res:
+ raise Exception("Failed to start sigma_dut")
+ return {'cmd': sigma, 'ifname': ifname}
def stop_sigma_dut(sigma):
- sigma.terminate()
- sigma.wait()
- out, err = sigma.communicate()
+ global sigma_prog
+ sigma_prog = None
+ cmd = sigma['cmd']
+ sigma_log_output(cmd)
+ logger.debug("Terminating sigma_dut process")
+ cmd.terminate()
+ cmd.wait()
+ out, err = cmd.communicate()
logger.debug("sigma_dut stdout: " + str(out.decode()))
logger.debug("sigma_dut stderr: " + str(err.decode()))
+ subprocess.call(["ip", "addr", "del", "dev", sigma['ifname'],
+ "127.0.0.11/24"],
+ stderr=open('/dev/null', 'w'))
def sigma_dut_wait_connected(ifname):
for i in range(50):
@@ -120,21 +162,22 @@ def test_sigma_dut_basic(dev, apdev):
"""sigma_dut basic functionality"""
sigma = start_sigma_dut(dev[0].ifname)
- res = sigma_dut_cmd("UNKNOWN")
- if "status,INVALID,errorCode,Unknown command" not in res:
- raise Exception("Unexpected sigma_dut response to unknown command")
-
tests = [("ca_get_version", "status,COMPLETE,version,1.0"),
("device_get_info", "status,COMPLETE,vendor"),
("device_list_interfaces,interfaceType,foo", "status,ERROR"),
("device_list_interfaces,interfaceType,802.11",
"status,COMPLETE,interfaceType,802.11,interfaceID," + dev[0].ifname)]
- for cmd, response in tests:
- res = sigma_dut_cmd(cmd)
- if response not in res:
- raise Exception("Unexpected %s response: %s" % (cmd, res))
-
- stop_sigma_dut(sigma)
+ try:
+ res = sigma_dut_cmd("UNKNOWN")
+ if "status,INVALID,errorCode,Unknown command" not in res:
+ raise Exception("Unexpected sigma_dut response to unknown command")
+
+ for cmd, response in tests:
+ res = sigma_dut_cmd(cmd)
+ if response not in res:
+ raise Exception("Unexpected %s response: %s" % (cmd, res))
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_open(dev, apdev):
"""sigma_dut controlled open network association"""
@@ -147,17 +190,18 @@ def run_sigma_dut_open(dev, apdev):
ifname = dev[0].ifname
sigma = start_sigma_dut(ifname)
- hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
-
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_encryption,interface,%s,ssid,%s,encpType,none" % (ifname, "open"))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s" % (ifname, "open"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ try:
+ hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_encryption,interface,%s,ssid,%s,encpType,none" % (ifname, "open"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s" % (ifname, "open"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_psk_pmf(dev, apdev):
"""sigma_dut controlled PSK+PMF association"""
@@ -170,22 +214,23 @@ def run_sigma_dut_psk_pmf(dev, apdev):
ifname = dev[0].ifname
sigma = start_sigma_dut(ifname)
- ssid = "test-pmf-required"
- params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
- params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
- params["ieee80211w"] = "2"
- hapd = hostapd.add_ap(apdev[0], params)
-
- sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_psk,interface,%s,ssid,%s,passphrase,%s,encpType,aes-ccmp,keymgmttype,wpa2,PMF,Required" % (ifname, "test-pmf-required", "12345678"))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-pmf-required"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ try:
+ ssid = "test-pmf-required"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
+ params["ieee80211w"] = "2"
+ hapd = hostapd.add_ap(apdev[0], params)
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_psk,interface,%s,ssid,%s,passphrase,%s,encpType,aes-ccmp,keymgmttype,wpa2,PMF,Required" % (ifname, "test-pmf-required", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-pmf-required"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_psk_pmf_bip_cmac_128(dev, apdev):
"""sigma_dut controlled PSK+PMF association with BIP-CMAC-128"""
@@ -228,35 +273,36 @@ def run_sigma_dut_psk_pmf_cipher(dev, apdev, sigma_cipher, hostapd_cipher,
ifname = dev[0].ifname
sigma = start_sigma_dut(ifname)
- ssid = "test-pmf-required"
- params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
- params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
- params["ieee80211w"] = "2"
- params["group_mgmt_cipher"] = hostapd_cipher
- hapd = hostapd.add_ap(apdev[0], params)
-
- sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_psk,interface,%s,ssid,%s,passphrase,%s,encpType,aes-ccmp,keymgmttype,wpa2,PMF,Required,GroupMgntCipher,%s" % (ifname, "test-pmf-required", "12345678", sigma_cipher))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-pmf-required"))
- if failure:
- ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND",
- "CTRL-EVENT-CONNECTED"], timeout=10)
- if ev is None:
- raise Exception("Network selection result not indicated")
- if "CTRL-EVENT-CONNECTED" in ev:
- raise Exception("Unexpected connection")
- res = sigma_dut_cmd("sta_is_connected,interface," + ifname)
- if "connected,1" in res:
- raise Exception("Connection reported")
- else:
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ try:
+ ssid = "test-pmf-required"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
+ params["ieee80211w"] = "2"
+ params["group_mgmt_cipher"] = hostapd_cipher
+ hapd = hostapd.add_ap(apdev[0], params)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_psk,interface,%s,ssid,%s,passphrase,%s,encpType,aes-ccmp,keymgmttype,wpa2,PMF,Required,GroupMgntCipher,%s" % (ifname, "test-pmf-required", "12345678", sigma_cipher))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-pmf-required"))
+ if failure:
+ ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND",
+ "CTRL-EVENT-CONNECTED"], timeout=10)
+ if ev is None:
+ raise Exception("Network selection result not indicated")
+ if "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Unexpected connection")
+ res = sigma_dut_cmd("sta_is_connected,interface," + ifname)
+ if "connected,1" in res:
+ raise Exception("Connection reported")
+ else:
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_sae(dev, apdev):
"""sigma_dut controlled SAE association"""
@@ -266,36 +312,67 @@ def test_sigma_dut_sae(dev, apdev):
ifname = dev[0].ifname
sigma = start_sigma_dut(ifname)
- ssid = "test-sae"
- params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
- params['wpa_key_mgmt'] = 'SAE'
- params["ieee80211w"] = "2"
- params['sae_groups'] = '19 20 21'
- hapd = hostapd.add_ap(apdev[0], params)
+ try:
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params["ieee80211w"] = "2"
+ params['sae_groups'] = '19 20 21'
+ hapd = hostapd.add_ap(apdev[0], params)
- sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2" % (ifname, "test-sae", "12345678"))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- if dev[0].get_status_field('sae_group') != '19':
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2" % (ifname, "test-sae", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ if dev[0].get_status_field('sae_group') != '19':
raise Exception("Expected default SAE group not used")
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2,ECGroupID,20" % (ifname, "test-sae", "12345678"))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- if dev[0].get_status_field('sae_group') != '20':
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2,ECGroupID,20" % (ifname, "test-sae", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ if dev[0].get_status_field('sae_group') != '20':
raise Exception("Expected SAE group not used")
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
+
+def test_sigma_dut_sae_groups(dev, apdev):
+ """sigma_dut controlled SAE association with group negotiation"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname)
+
+ try:
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params["ieee80211w"] = "2"
+ params['sae_groups'] = '19'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2,ECGroupID,21 20 19" % (ifname, "test-sae", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ if dev[0].get_status_field('sae_group') != '19':
+ raise Exception("Expected default SAE group not used")
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_sae_pmkid_include(dev, apdev):
"""sigma_dut controlled SAE association with PMKID"""
@@ -305,20 +382,22 @@ def test_sigma_dut_sae_pmkid_include(dev, apdev):
ifname = dev[0].ifname
sigma = start_sigma_dut(ifname)
- ssid = "test-sae"
- params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
- params['wpa_key_mgmt'] = 'SAE'
- params["ieee80211w"] = "2"
- params["sae_confirm_immediate"] = "1"
- hapd = hostapd.add_ap(apdev[0], params)
+ try:
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params["ieee80211w"] = "2"
+ params["sae_confirm_immediate"] = "1"
+ hapd = hostapd.add_ap(apdev[0], params)
- sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2,PMKID_Include,enable" % (ifname, "test-sae", "12345678"))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2,PMKID_Include,enable" % (ifname, "test-sae", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_sae_password(dev, apdev):
"""sigma_dut controlled SAE association and long password"""
@@ -353,25 +432,26 @@ def test_sigma_dut_sae_pw_id(dev, apdev):
raise HwsimSkip("SAE not supported")
ifname = dev[0].ifname
- sigma = start_sigma_dut(ifname, debug=True)
-
- ssid = "test-sae"
- params = hostapd.wpa2_params(ssid=ssid)
- params['wpa_key_mgmt'] = 'SAE'
- params["ieee80211w"] = "2"
- params['sae_password'] = 'secret|id=pw id'
- params['sae_groups'] = '19'
- hapd = hostapd.add_ap(apdev[0], params)
+ sigma = start_sigma_dut(ifname)
- sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,AKMSuiteType,8;9,PasswordID,pw id" % (ifname, "test-sae", "secret"))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ try:
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid)
+ params['wpa_key_mgmt'] = 'SAE'
+ params["ieee80211w"] = "2"
+ params['sae_password'] = 'secret|id=pw id'
+ params['sae_groups'] = '19'
+ hapd = hostapd.add_ap(apdev[0], params)
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,AKMSuiteType,8;9,PasswordID,pw id" % (ifname, "test-sae", "secret"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_sae_pw_id_ft(dev, apdev):
"""sigma_dut controlled SAE association with Password Identifier and FT"""
@@ -386,43 +466,44 @@ def run_sigma_dut_sae_pw_id_ft(dev, apdev, over_ds=False):
raise HwsimSkip("SAE not supported")
ifname = dev[0].ifname
- sigma = start_sigma_dut(ifname, debug=True)
-
- ssid = "test-sae"
- params = hostapd.wpa2_params(ssid=ssid)
- params['wpa_key_mgmt'] = 'SAE FT-SAE'
- params["ieee80211w"] = "2"
- params['sae_password'] = ['pw1|id=id1', 'pw2|id=id2', 'pw3', 'pw4|id=id4']
- params['mobility_domain'] = 'aabb'
- params['ft_over_ds'] = '1' if over_ds else '0'
- bssid = apdev[0]['bssid'].replace(':', '')
- params['nas_identifier'] = bssid + '.nas.example.com'
- params['r1_key_holder'] = bssid
- params['pmk_r1_push'] = '0'
- params['r0kh'] = 'ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff'
- params['r1kh'] = '00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff'
- hapd = hostapd.add_ap(apdev[0], params)
+ sigma = start_sigma_dut(ifname)
- sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
- if over_ds:
- sigma_dut_cmd_check("sta_preset_testparameters,interface,%s,FT_DS,Enable" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,AKMSuiteType,8;9,PasswordID,id2" % (ifname, "test-sae", "pw2"))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
- sigma_dut_wait_connected(ifname)
+ try:
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid)
+ params['wpa_key_mgmt'] = 'SAE FT-SAE'
+ params["ieee80211w"] = "2"
+ params['sae_password'] = ['pw1|id=id1', 'pw2|id=id2', 'pw3', 'pw4|id=id4']
+ params['mobility_domain'] = 'aabb'
+ params['ft_over_ds'] = '1' if over_ds else '0'
+ bssid = apdev[0]['bssid'].replace(':', '')
+ params['nas_identifier'] = bssid + '.nas.example.com'
+ params['r1_key_holder'] = bssid
+ params['pmk_r1_push'] = '0'
+ params['r0kh'] = 'ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff'
+ params['r1kh'] = '00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff'
+ hapd = hostapd.add_ap(apdev[0], params)
- bssid = apdev[1]['bssid'].replace(':', '')
- params['nas_identifier'] = bssid + '.nas.example.com'
- params['r1_key_holder'] = bssid
- hapd2 = hostapd.add_ap(apdev[1], params)
- bssid = hapd2.own_addr()
- sigma_dut_cmd_check("sta_reassoc,interface,%s,Channel,1,bssid,%s" % (ifname, bssid))
- dev[0].wait_connected()
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ if over_ds:
+ sigma_dut_cmd_check("sta_preset_testparameters,interface,%s,FT_DS,Enable" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,AKMSuiteType,8;9,PasswordID,id2" % (ifname, "test-sae", "pw2"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ bssid = apdev[1]['bssid'].replace(':', '')
+ params['nas_identifier'] = bssid + '.nas.example.com'
+ params['r1_key_holder'] = bssid
+ hapd2 = hostapd.add_ap(apdev[1], params)
+ bssid = hapd2.own_addr()
+ sigma_dut_cmd_check("sta_reassoc,interface,%s,Channel,1,bssid,%s" % (ifname, bssid))
+ dev[0].wait_connected()
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_sta_override_rsne(dev, apdev):
"""sigma_dut and RSNE override on STA"""
@@ -435,35 +516,36 @@ def run_sigma_dut_sta_override_rsne(dev, apdev):
ifname = dev[0].ifname
sigma = start_sigma_dut(ifname)
- ssid = "test-psk"
- params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
- hapd = hostapd.add_ap(apdev[0], params)
+ try:
+ ssid = "test-psk"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ hapd = hostapd.add_ap(apdev[0], params)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+
+ tests = ["30120100000fac040100000fac040100000fac02",
+ "30140100000fac040100000fac040100000fac02ffff"]
+ for test in tests:
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,type,PSK,passphrase,%s,EncpType,aes-ccmp,KeyMgmtType,wpa2" % (ifname, "test-psk", "12345678"))
+ sigma_dut_cmd_check("dev_configure_ie,interface,%s,IE_Name,RSNE,Contents,%s" % (ifname, test))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-psk"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ dev[0].dump_monitor()
- tests = ["30120100000fac040100000fac040100000fac02",
- "30140100000fac040100000fac040100000fac02ffff"]
- for test in tests:
sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,type,PSK,passphrase,%s,EncpType,aes-ccmp,KeyMgmtType,wpa2" % (ifname, "test-psk", "12345678"))
- sigma_dut_cmd_check("dev_configure_ie,interface,%s,IE_Name,RSNE,Contents,%s" % (ifname, test))
+ sigma_dut_cmd_check("dev_configure_ie,interface,%s,IE_Name,RSNE,Contents,300101" % ifname)
sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-psk"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- dev[0].dump_monitor()
-
- sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,type,PSK,passphrase,%s,EncpType,aes-ccmp,KeyMgmtType,wpa2" % (ifname, "test-psk", "12345678"))
- sigma_dut_cmd_check("dev_configure_ie,interface,%s,IE_Name,RSNE,Contents,300101" % ifname)
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-psk"))
- ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
- if ev is None:
- raise Exception("Association rejection not reported")
- if "status_code=40" not in ev:
- raise Exception("Unexpected status code: " + ev)
-
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
+ if ev is None:
+ raise Exception("Association rejection not reported")
+ if "status_code=40" not in ev:
+ raise Exception("Unexpected status code: " + ev)
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_ap_psk(dev, apdev):
"""sigma_dut controlled AP"""
@@ -524,7 +606,7 @@ def test_sigma_dut_ap_psk_deauth(dev, apdev, params):
logdir = os.path.join(params['logdir'],
"sigma_dut_ap_psk_deauth.sigma-hostapd")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-psk,MODE,11ng")
@@ -586,41 +668,42 @@ def test_sigma_dut_eap_ttls(dev, apdev, params):
cmd = "sta_set_security,type,eapttls,interface,%s,ssid,%s,keymgmttype,wpa2,encType,AES-CCMP,PairwiseCipher,AES-CCMP-128,trustedRootCA,sigma_dut_eap_ttls.ca.pem,username,DOMAIN\mschapv2 user,password,password" % (ifname, ssid)
- tests = ["",
- ",Domain,server.w1.fi",
- ",DomainSuffix,w1.fi",
- ",DomainSuffix,server.w1.fi",
- ",ServerCert,sigma_dut_eap_ttls.server.pem"]
- for extra in tests:
- sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,WPA3" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check(cmd + extra)
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, ssid))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
- dev[0].dump_monitor()
-
- tests = [",Domain,w1.fi",
- ",DomainSuffix,example.com",
- ",ServerCert,sigma_dut_eap_ttls.incorrect.pem"]
- for extra in tests:
- sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,WPA3" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check(cmd + extra)
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, ssid))
- ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"], timeout=10)
- if ev is None:
- raise Exception("Server certificate error not reported")
- res = sigma_dut_cmd("sta_is_connected,interface," + ifname)
- if "connected,1" in res:
- raise Exception("Unexpected connection reported")
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
- dev[0].dump_monitor()
+ try:
+ tests = ["",
+ ",Domain,server.w1.fi",
+ ",DomainSuffix,w1.fi",
+ ",DomainSuffix,server.w1.fi",
+ ",ServerCert,sigma_dut_eap_ttls.server.pem"]
+ for extra in tests:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,WPA3" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check(cmd + extra)
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, ssid))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ dev[0].dump_monitor()
- stop_sigma_dut(sigma)
+ tests = [",Domain,w1.fi",
+ ",DomainSuffix,example.com",
+ ",ServerCert,sigma_dut_eap_ttls.incorrect.pem"]
+ for extra in tests:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,WPA3" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check(cmd + extra)
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, ssid))
+ ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"], timeout=10)
+ if ev is None:
+ raise Exception("Server certificate error not reported")
+ res = sigma_dut_cmd("sta_is_connected,interface," + ifname)
+ if "connected,1" in res:
+ raise Exception("Unexpected connection reported")
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ dev[0].dump_monitor()
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_suite_b(dev, apdev, params):
"""sigma_dut controlled STA Suite B"""
@@ -661,16 +744,17 @@ def test_sigma_dut_suite_b(dev, apdev, params):
ifname = dev[0].ifname
sigma = start_sigma_dut(ifname, cert_path=logdir)
- sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_security,type,eaptls,interface,%s,ssid,%s,PairwiseCipher,AES-GCMP-256,GroupCipher,AES-GCMP-256,GroupMgntCipher,BIP-GMAC-256,keymgmttype,SuiteB,clientCertificate,suite_b.pem,trustedRootCA,suite_b_ca.pem,CertType,ECC" % (ifname, "test-suite-b"))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-suite-b"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
-
- stop_sigma_dut(sigma)
+ try:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,type,eaptls,interface,%s,ssid,%s,PairwiseCipher,AES-GCMP-256,GroupCipher,AES-GCMP-256,GroupMgntCipher,BIP-GMAC-256,keymgmttype,SuiteB,clientCertificate,suite_b.pem,trustedRootCA,suite_b_ca.pem,CertType,ECC" % (ifname, "test-suite-b"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-suite-b"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_suite_b_rsa(dev, apdev, params):
"""sigma_dut controlled STA Suite B (RSA)"""
@@ -696,20 +780,21 @@ def test_sigma_dut_suite_b_rsa(dev, apdev, params):
cmd = "sta_set_security,type,eaptls,interface,%s,ssid,%s,PairwiseCipher,AES-GCMP-256,GroupCipher,AES-GCMP-256,GroupMgntCipher,BIP-GMAC-256,keymgmttype,SuiteB,clientCertificate,suite_b_rsa.pem,trustedRootCA,suite_b_ca_rsa.pem,CertType,RSA" % (ifname, "test-suite-b")
- tests = ["",
- ",TLSCipher,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
- ",TLSCipher,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"]
- for extra in tests:
- sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check(cmd + extra)
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-suite-b"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
-
- stop_sigma_dut(sigma)
+ try:
+ tests = ["",
+ ",TLSCipher,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ ",TLSCipher,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"]
+ for extra in tests:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check(cmd + extra)
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-suite-b"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_ap_suite_b(dev, apdev, params):
"""sigma_dut controlled AP Suite B"""
@@ -917,7 +1002,7 @@ def test_sigma_dut_ap_sae_pw_id(dev, apdev, params):
if "SAE" not in dev[0].get_capability("auth_alg"):
raise HwsimSkip("SAE not supported")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng")
@@ -953,7 +1038,7 @@ def test_sigma_dut_ap_sae_pw_id_ft(dev, apdev, params):
if "SAE" not in dev[0].get_capability("auth_alg"):
raise HwsimSkip("SAE not supported")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng,DOMAIN,aabb")
@@ -1044,7 +1129,7 @@ def test_sigma_dut_ap_psk_sae_ft(dev, apdev, params):
if "SAE" not in dev[0].get_capability("auth_alg"):
raise HwsimSkip("SAE not supported")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default,NAME,AP,Program,WPA3")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae-psk,MODE,11ng,DOMAIN,aabb")
@@ -2203,7 +2288,7 @@ def test_sigma_dut_dpp_proto_stop_at_initiator_enrollee(dev, apdev):
for frame, result, fail in tests:
dev[0].request("FLUSH")
dev[1].request("FLUSH")
- sigma = start_sigma_dut(dev[0].ifname, debug=True)
+ sigma = start_sigma_dut(dev[0].ifname)
try:
run_sigma_dut_dpp_proto_stop_at_initiator_enrollee(dev, frame,
result, fail)
@@ -2634,19 +2719,20 @@ def run_sigma_dut_preconfigured_profile(dev, apdev):
ifname = dev[0].ifname
sigma = start_sigma_dut(ifname)
- params = hostapd.wpa2_params(ssid="test-psk", passphrase="12345678")
- hapd = hostapd.add_ap(apdev[0], params)
- dev[0].connect("test-psk", psk="12345678", scan_freq="2412",
- only_add_network=True)
-
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s" % (ifname, "test-psk"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ try:
+ params = hostapd.wpa2_params(ssid="test-psk", passphrase="12345678")
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-psk", psk="12345678", scan_freq="2412",
+ only_add_network=True)
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s" % (ifname, "test-psk"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_wps_pbc(dev, apdev):
"""sigma_dut and WPS PBC Enrollee"""
@@ -2666,15 +2752,17 @@ def run_sigma_dut_wps_pbc(dev, apdev):
ifname = dev[0].ifname
sigma = start_sigma_dut(ifname)
- cmd = "start_wps_registration,interface,%s" % ifname
- cmd += ",WpsRole,Enrollee"
- cmd += ",WpsConfigMethod,PBC"
- sigma_dut_cmd_check(cmd, timeout=15)
+ try:
+ cmd = "start_wps_registration,interface,%s" % ifname
+ cmd += ",WpsRole,Enrollee"
+ cmd += ",WpsConfigMethod,PBC"
+ sigma_dut_cmd_check(cmd, timeout=15)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- hapd.disable()
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ hapd.disable()
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
dev[0].flush_scan_cache()
def test_sigma_dut_sta_scan_bss(dev, apdev):
@@ -2694,7 +2782,7 @@ def test_sigma_dut_sta_scan_ssid_bssid(dev, apdev):
"""sigma_dut sta_scan GetParameter,SSID_BSSID"""
hostapd.add_ap(apdev[0], {"ssid": "abcdef"})
hostapd.add_ap(apdev[1], {"ssid": "qwerty"})
- sigma = start_sigma_dut(dev[0].ifname, debug=True)
+ sigma = start_sigma_dut(dev[0].ifname)
try:
cmd = "sta_scan,Interface,%s,GetParameter,SSID_BSSID" % dev[0].ifname
res = sigma_dut_cmd(cmd, timeout=10)
@@ -2769,7 +2857,7 @@ def test_sigma_dut_ap_eap(dev, apdev, params):
"""sigma_dut controlled AP WPA2-Enterprise"""
logdir = os.path.join(params['logdir'], "sigma_dut_ap_eap.sigma-hostapd")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-eap,MODE,11ng")
@@ -2791,7 +2879,7 @@ def test_sigma_dut_ap_eap_sha256(dev, apdev, params):
logdir = os.path.join(params['logdir'],
"sigma_dut_ap_eap_sha256.sigma-hostapd")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-eap,MODE,11ng")
@@ -2812,7 +2900,7 @@ def test_sigma_dut_ap_ft_eap(dev, apdev, params):
"""sigma_dut controlled AP FT-EAP"""
logdir = os.path.join(params['logdir'], "sigma_dut_ap_ft_eap.sigma-hostapd")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-ft-eap,MODE,11ng,DOMAIN,0101,FT_OA,Enable")
@@ -2833,7 +2921,7 @@ def test_sigma_dut_ap_ft_psk(dev, apdev, params):
"""sigma_dut controlled AP FT-PSK"""
logdir = os.path.join(params['logdir'], "sigma_dut_ap_ft_psk.sigma-hostapd")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-ft-psk,MODE,11ng,DOMAIN,0101,FT_OA,Enable")
@@ -2854,7 +2942,7 @@ def test_sigma_dut_ap_ft_over_ds_psk(dev, apdev, params):
conffile = os.path.join(params['logdir'],
"sigma_dut_ap_ft_over_ds_psk.sigma-conf")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-ft-psk,MODE,11ng,DOMAIN,0101,FT_DS,Enable")
@@ -2877,7 +2965,7 @@ def test_sigma_dut_ap_ent_ft_eap(dev, apdev, params):
logdir = os.path.join(params['logdir'],
"sigma_dut_ap_ent_ft_eap.sigma-hostapd")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-ent-ft-eap,MODE,11ng,DOMAIN,0101,FT_OA,Enable")
@@ -2907,44 +2995,45 @@ def test_sigma_dut_venue_url(dev, apdev):
def run_sigma_dut_venue_url(dev, apdev):
ifname = dev[0].ifname
- sigma = start_sigma_dut(ifname, debug=True)
-
- ssid = "venue"
- params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
- params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
- params["ieee80211w"] = "2"
+ sigma = start_sigma_dut(ifname)
- venue_group = 1
- venue_type = 13
- venue_info = struct.pack('BB', venue_group, venue_type)
- lang1 = "eng"
- name1 = "Example venue"
- lang2 = "fin"
- name2 = "Esimerkkipaikka"
- venue1 = struct.pack('B', len(lang1 + name1)) + lang1.encode() + name1.encode()
- venue2 = struct.pack('B', len(lang2 + name2)) + lang2.encode() + name2.encode()
- venue_name = binascii.hexlify(venue_info + venue1 + venue2)
-
- url1 = "http://example.com/venue"
- url2 = "https://example.org/venue-info/"
- params["venue_group"] = str(venue_group)
- params["venue_type"] = str(venue_type)
- params["venue_name"] = [lang1 + ":" + name1, lang2 + ":" + name2]
- params["venue_url"] = ["1:" + url1, "2:" + url2]
+ try:
+ ssid = "venue"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
+ params["ieee80211w"] = "2"
- hapd = hostapd.add_ap(apdev[0], params)
+ venue_group = 1
+ venue_type = 13
+ venue_info = struct.pack('BB', venue_group, venue_type)
+ lang1 = "eng"
+ name1 = "Example venue"
+ lang2 = "fin"
+ name2 = "Esimerkkipaikka"
+ venue1 = struct.pack('B', len(lang1 + name1)) + lang1.encode() + name1.encode()
+ venue2 = struct.pack('B', len(lang2 + name2)) + lang2.encode() + name2.encode()
+ venue_name = binascii.hexlify(venue_info + venue1 + venue2)
+
+ url1 = "http://example.com/venue"
+ url2 = "https://example.org/venue-info/"
+ params["venue_group"] = str(venue_group)
+ params["venue_type"] = str(venue_type)
+ params["venue_name"] = [lang1 + ":" + name1, lang2 + ":" + name2]
+ params["venue_url"] = ["1:" + url1, "2:" + url2]
- sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_set_psk,interface,%s,ssid,%s,passphrase,%s,encpType,aes-ccmp,keymgmttype,wpa2,PMF,Required" % (ifname, "venue", "12345678"))
- sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "venue"))
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- sigma_dut_cmd_check("sta_hs2_venue_info,interface," + ifname + ",Display,Yes")
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ hapd = hostapd.add_ap(apdev[0], params)
- stop_sigma_dut(sigma)
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_psk,interface,%s,ssid,%s,passphrase,%s,encpType,aes-ccmp,keymgmttype,wpa2,PMF,Required" % (ifname, "venue", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "venue"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ sigma_dut_cmd_check("sta_hs2_venue_info,interface," + ifname + ",Display,Yes")
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
def test_sigma_dut_hs20_assoc_24(dev, apdev):
"""sigma_dut controlled Hotspot 2.0 connection (2.4 GHz)"""
@@ -2988,19 +3077,20 @@ def run_sigma_dut_hs20_assoc_2(dev, apdev, band, expect_bssid):
dev[0].flush_scan_cache()
ifname = dev[0].ifname
- sigma = start_sigma_dut(ifname, debug=True)
-
- sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,HS2-R3" % ifname)
- sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
- sigma_dut_cmd_check("sta_add_credential,interface,%s,type,uname_pwd,realm,example.com,username,hs20-test,password,password" % ifname)
- res = sigma_dut_cmd_check("sta_hs2_associate,interface,%s,band,%s" % (ifname, band),
- timeout=15)
- sigma_dut_wait_connected(ifname)
- sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
- sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
- sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ sigma = start_sigma_dut(ifname)
- stop_sigma_dut(sigma)
+ try:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,HS2-R3" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_add_credential,interface,%s,type,uname_pwd,realm,example.com,username,hs20-test,password,password" % ifname)
+ res = sigma_dut_cmd_check("sta_hs2_associate,interface,%s,band,%s" % (ifname, band),
+ timeout=15)
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_get_ip_config,interface," + ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
if "BSSID," + expect_bssid not in res:
raise Exception("Unexpected BSSID: " + res)
@@ -3012,7 +3102,7 @@ def test_sigma_dut_ap_hs20(dev, apdev, params):
conffile = os.path.join(params['logdir'],
"sigma_dut_ap_hs20.sigma-conf")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface, hostapd_logdir=logdir, debug=True)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default,NAME,AP,program,HS2-R3")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,WLAN_TAG,1,CHANNEL,1,SSID,test-hs20,MODE,11ng")
@@ -3067,7 +3157,7 @@ def test_sigma_dut_eap_ttls_uosc(dev, apdev, params):
hapd = hostapd.add_ap(apdev[0], params)
ifname = dev[0].ifname
- sigma = start_sigma_dut(ifname, cert_path=logdir, debug=True)
+ sigma = start_sigma_dut(ifname, cert_path=logdir)
try:
cmd = "sta_set_security,type,eapttls,interface,%s,ssid,%s,keymgmttype,wpa2,encType,AES-CCMP,PairwiseCipher,AES-CCMP-128,username,DOMAIN\mschapv2 user,password,password,ServerCert,sigma_dut_eap_ttls_uosc.incorrect.pem" % (ifname, ssid)
@@ -3135,7 +3225,7 @@ def run_sigma_dut_eap_ttls_uosc_tod(dev, apdev, params, tofu):
hapd = hostapd.add_ap(apdev[0], params)
ifname = dev[0].ifname
- sigma = start_sigma_dut(ifname, cert_path=logdir, debug=True)
+ sigma = start_sigma_dut(ifname, cert_path=logdir)
try:
cmd = ("sta_set_security,type,eapttls,interface,%s,ssid,%s,keymgmttype,wpa2,encType,AES-CCMP,PairwiseCipher,AES-CCMP-128,trustedRootCA," + name + ".ca.pem,username,DOMAIN\mschapv2 user,password,password,ServerCert," + name + ".server.pem") % (ifname, ssid)
@@ -3211,7 +3301,7 @@ def run_sigma_dut_eap_ttls_uosc_initial_tod(dev, apdev, params, tofu):
hapd = hostapd.add_ap(apdev[0], params)
ifname = dev[0].ifname
- sigma = start_sigma_dut(ifname, cert_path=logdir, debug=True)
+ sigma = start_sigma_dut(ifname, cert_path=logdir)
try:
cmd = ("sta_set_security,type,eapttls,interface,%s,ssid,%s,keymgmttype,wpa2,encType,AES-CCMP,PairwiseCipher,AES-CCMP-128,trustedRootCA," + name + ".ca.pem,username,DOMAIN\mschapv2 user,password,password") % (ifname, ssid)
@@ -3252,7 +3342,7 @@ def test_sigma_dut_eap_ttls_uosc_ca_mistrust(dev, apdev, params):
hapd = hostapd.add_ap(apdev[0], params)
ifname = dev[0].ifname
- sigma = start_sigma_dut(ifname, cert_path=logdir, debug=True)
+ sigma = start_sigma_dut(ifname, cert_path=logdir)
try:
cmd = "sta_set_security,type,eapttls,interface,%s,ssid,%s,keymgmttype,wpa2,encType,AES-CCMP,PairwiseCipher,AES-CCMP-128,trustedRootCA,sigma_dut_eap_ttls_uosc_ca_mistrust.ca.pem,username,DOMAIN\mschapv2 user,password,password,domainSuffix,w1.fi" % (ifname, ssid)
@@ -3273,3 +3363,346 @@ def test_sigma_dut_eap_ttls_uosc_ca_mistrust(dev, apdev, params):
dev[0].dump_monitor()
finally:
stop_sigma_dut(sigma)
+
+def start_sae_pwe_ap(apdev, sae_pwe):
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params["ieee80211w"] = "2"
+ params['sae_groups'] = '19'
+ params['sae_pwe'] = str(sae_pwe)
+ return hostapd.add_ap(apdev, params)
+
+def connect_sae_pwe_sta(dev, ifname, extra=None):
+ dev.dump_monitor()
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ cmd = "sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2" % (ifname, "test-sae", "12345678")
+ if extra:
+ cmd += "," + extra
+ sigma_dut_cmd_check(cmd)
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_disconnect,interface," + ifname)
+ dev.wait_disconnected()
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ dev.dump_monitor()
+
+def no_connect_sae_pwe_sta(dev, ifname, extra=None):
+ dev.dump_monitor()
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ cmd = "sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2" % (ifname, "test-sae", "12345678")
+ if extra:
+ cmd += "," + extra
+ sigma_dut_cmd_check(cmd)
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ ev = dev.wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
+ if ev is None or "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Unexpected connection result")
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ dev.dump_monitor()
+
+def test_sigma_dut_sae_h2e(dev, apdev):
+ """sigma_dut controlled SAE H2E association (AP using loop+H2E)"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+
+ start_sae_pwe_ap(apdev[0], 2)
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname, sae_h2e=True)
+ try:
+ connect_sae_pwe_sta(dev[0], ifname)
+ connect_sae_pwe_sta(dev[0], ifname, extra="sae_pwe,h2e")
+ connect_sae_pwe_sta(dev[0], ifname, extra="sae_pwe,loop")
+ res = sigma_dut_cmd("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2,sae_pwe,unknown" % (ifname, "test-sae", "12345678"))
+ if res != "status,ERROR,errorCode,Unsupported sae_pwe value":
+ raise Exception("Unexpected error result: " + res)
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_sae_h2e_ap_loop(dev, apdev):
+ """sigma_dut controlled SAE H2E association (AP using loop-only)"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+
+ start_sae_pwe_ap(apdev[0], 0)
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname, sae_h2e=True)
+ try:
+ connect_sae_pwe_sta(dev[0], ifname)
+ connect_sae_pwe_sta(dev[0], ifname, extra="sae_pwe,loop")
+ no_connect_sae_pwe_sta(dev[0], ifname, extra="sae_pwe,h2e")
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_sae_h2e_ap_h2e(dev, apdev):
+ """sigma_dut controlled SAE H2E association (AP using H2E-only)"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+
+ start_sae_pwe_ap(apdev[0], 1)
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname, sae_h2e=True)
+ try:
+ connect_sae_pwe_sta(dev[0], ifname)
+ no_connect_sae_pwe_sta(dev[0], ifname, extra="sae_pwe,loop")
+ connect_sae_pwe_sta(dev[0], ifname, extra="sae_pwe,h2e")
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_ap_sae_h2e(dev, apdev, params):
+ """sigma_dut controlled AP with SAE H2E"""
+ logdir = os.path.join(params['logdir'],
+ "sigma_dut_ap_sae_h2e.sigma-hostapd")
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, sae_h2e=True, hostapd_logdir=logdir)
+ try:
+ sigma_dut_cmd_check("ap_reset_default")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,WPA2-SAE,PSK,12345678")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+
+ for sae_pwe in [0, 1, 2]:
+ dev[0].request("SET sae_groups ")
+ dev[0].set("sae_pwe", str(sae_pwe))
+ dev[0].connect("test-sae", key_mgmt="SAE", psk="12345678",
+ ieee80211w="2", scan_freq="2412")
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+ dev[0].dump_monitor()
+
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_ap_sae_h2e_only(dev, apdev, params):
+ """sigma_dut controlled AP with SAE H2E-only"""
+ logdir = os.path.join(params['logdir'],
+ "sigma_dut_ap_sae_h2e.sigma-hostapd")
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, sae_h2e=True, hostapd_logdir=logdir)
+ try:
+ sigma_dut_cmd_check("ap_reset_default")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,WPA2-SAE,PSK,12345678,sae_pwe,h2e")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+
+ dev[0].request("SET sae_groups ")
+ dev[0].set("sae_pwe", "1")
+ dev[0].connect("test-sae", key_mgmt="SAE", psk="12345678",
+ ieee80211w="2", scan_freq="2412")
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+ dev[0].dump_monitor()
+
+ dev[0].set("sae_pwe", "0")
+ dev[0].connect("test-sae", key_mgmt="SAE", psk="12345678",
+ ieee80211w="2", scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
+ dev[0].request("DISCONNECT")
+ if ev is None or "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Unexpected connection result")
+
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_ap_sae_loop_only(dev, apdev, params):
+ """sigma_dut controlled AP with SAE looping-only"""
+ logdir = os.path.join(params['logdir'],
+ "sigma_dut_ap_sae_h2e.sigma-hostapd")
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, sae_h2e=True, hostapd_logdir=logdir)
+ try:
+ sigma_dut_cmd_check("ap_reset_default")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,WPA2-SAE,PSK,12345678,sae_pwe,loop")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+
+ dev[0].request("SET sae_groups ")
+ dev[0].set("sae_pwe", "0")
+ dev[0].connect("test-sae", key_mgmt="SAE", psk="12345678",
+ ieee80211w="2", scan_freq="2412")
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+ dev[0].dump_monitor()
+
+ dev[0].set("sae_pwe", "1")
+ dev[0].connect("test-sae", key_mgmt="SAE", psk="12345678",
+ ieee80211w="2", scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
+ dev[0].request("DISCONNECT")
+ if ev is None or "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Unexpected connection result")
+
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_sae_h2e_loop_forcing(dev, apdev):
+ """sigma_dut controlled SAE H2E misbehavior with looping forced"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params["ieee80211w"] = "2"
+ params['sae_pwe'] = '1'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname)
+ try:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2,IgnoreH2E_RSNXE_BSSMemSel,1" % (ifname, "test-sae", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ ev = dev[0].wait_event(["SME: Trying to authenticate with"], timeout=10)
+ if ev is None:
+ raise Exception("No authentication attempt reported")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5)
+ if ev is not None:
+ raise Exception("Unexpected connection reported")
+ finally:
+ stop_sigma_dut(sigma)
+
+def test_sigma_dut_sae_h2e_enabled_group_rejected(dev, apdev):
+ """sigma_dut controlled SAE H2E misbehavior with rejected groups"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params["ieee80211w"] = "2"
+ params['sae_groups'] = "19 20"
+ params['sae_pwe'] = '1'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname, sae_h2e=True)
+ try:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2,ECGroupID_RGE,19 123" % (ifname, "test-sae", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ ev = dev[0].wait_event(["SME: Trying to authenticate with"], timeout=10)
+ if ev is None:
+ raise Exception("No authentication attempt reported")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5)
+ if ev is not None:
+ raise Exception("Unexpected connection reported")
+ finally:
+ stop_sigma_dut(sigma)
+
+def test_sigma_dut_sae_h2e_rsnxe_mismatch(dev, apdev):
+ """sigma_dut controlled SAE H2E misbehavior with RSNXE"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params["ieee80211w"] = "2"
+ params['sae_groups'] = "19"
+ params['sae_pwe'] = '1'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname, sae_h2e=True)
+ try:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,keymgmttype,wpa2,RSNXE_Content,EapolM2:F40100" % (ifname, "test-sae", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"))
+ ev = dev[0].wait_event(["SME: Trying to authenticate with"], timeout=10)
+ if ev is None:
+ raise Exception("No authentication attempt reported")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5)
+ if ev is not None:
+ raise Exception("Unexpected connection reported")
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_ap_sae_h2e_rsnxe_mismatch(dev, apdev, params):
+ """sigma_dut controlled SAE H2E AP misbehavior with RSNXE"""
+ logdir = os.path.join(params['logdir'],
+ "sigma_dut_ap_sae_h2e_rsnxe_mismatch.sigma-hostapd")
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, sae_h2e=True, hostapd_logdir=logdir)
+ try:
+ sigma_dut_cmd_check("ap_reset_default")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,WPA2-SAE,PSK,12345678,sae_pwe,h2e,RSNXE_Content,EapolM3:F40100")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+
+ dev[0].request("SET sae_groups ")
+ dev[0].set("sae_pwe", "1")
+ dev[0].connect("test-sae", key_mgmt="SAE", psk="12345678",
+ ieee80211w="2", scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["Associated with"], timeout=10)
+ if ev is None:
+ raise Exception("No indication of association seen")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=10)
+ dev[0].request("DISCONNECT")
+ if ev is None:
+ raise Exception("No disconnection seen")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection")
+
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_ap_sae_h2e_group_rejection(dev, apdev, params):
+ """sigma_dut controlled AP with SAE H2E-only and group rejection"""
+ logdir = os.path.join(params['logdir'],
+ "sigma_dut_ap_sae_h2e_group_rejection.sigma-hostapd")
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, sae_h2e=True, hostapd_logdir=logdir)
+ try:
+ sigma_dut_cmd_check("ap_reset_default")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,WPA2-SAE,PSK,12345678,sae_pwe,h2e")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+
+ dev[0].request("SET sae_groups 21 20 19")
+ dev[0].set("sae_pwe", "1")
+ dev[0].connect("test-sae", key_mgmt="SAE", psk="12345678",
+ ieee80211w="2", scan_freq="2412")
+ addr = dev[0].own_addr()
+ res = sigma_dut_cmd_check("dev_exec_action,program,WPA3,Dest_MAC,%s,Rejected_DH_Groups,1" % addr)
+ if "DHGroupVerResult,21 20" not in res:
+ raise Exception("Unexpected dev_exec_action response: " + res)
+
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
diff --git a/tests/hwsim/test_sta_dynamic.py b/tests/hwsim/test_sta_dynamic.py
index 72ed243..357bc95 100644
--- a/tests/hwsim/test_sta_dynamic.py
+++ b/tests/hwsim/test_sta_dynamic.py
@@ -165,6 +165,55 @@ def test_sta_dynamic_ext_mac_addr_change(dev, apdev):
'address', prev_addr])
subprocess.call(['ifconfig', wpas.ifname, 'up'])
+def test_sta_dynamic_ext_mac_addr_change_for_connection(dev, apdev):
+ """Dynamically added wpa_supplicant interface with external MAC address change for connection"""
+ params = hostapd.wpa2_params(ssid="sta-dynamic", passphrase="12345678")
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = apdev[0]['ifname']
+
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add("wlan5")
+ wpas.scan_for_bss(bssid, freq=2412)
+ subprocess.call(['ifconfig', wpas.ifname, 'down'])
+ if wpas.get_status_field("wpa_state") != "INTERFACE_DISABLED":
+ raise Exception("Unexpected wpa_state")
+ prev_addr = wpas.own_addr()
+ new_addr = '02:11:22:33:44:55'
+ try:
+ subprocess.call(['ip', 'link', 'set', 'dev', wpas.ifname,
+ 'address', new_addr])
+ subprocess.call(['ifconfig', wpas.ifname, 'up'])
+ wpas.connect("sta-dynamic", psk="12345678", scan_freq="2412",
+ wait_connect=False)
+ ev = wpas.wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-SCAN-RESULTS"], timeout=10)
+ if "CTRL-EVENT-SCAN-RESULTS" in ev:
+ raise Exception("Unexpected scan after MAC address change")
+ hapd.wait_sta()
+ hwsim_utils.test_connectivity(wpas, hapd)
+ sta = hapd.get_sta(new_addr)
+ if sta['addr'] != new_addr:
+ raise Exception("STA association with new address not found")
+ wpas.request("DISCONNECT")
+ wpas.wait_disconnected()
+ wpas.dump_monitor()
+ subprocess.call(['ifconfig', wpas.ifname, 'down'])
+ time.sleep(0.1)
+ res = wpas.get_bss(bssid)
+ if res is None:
+ raise Exception("BSS entry not maintained after interface disabling")
+ ev = wpas.wait_event(["CTRL-EVENT-BSS-REMOVED"], timeout=5.5)
+ if ev is None:
+ raise Exception("BSS entry not removed after interface has been disabled for a while")
+ res2 = wpas.get_bss(bssid)
+ if res2 is not None:
+ raise Exception("Unexpected BSS entry found on a disabled interface")
+ finally:
+ subprocess.call(['ifconfig', wpas.ifname, 'down'])
+ subprocess.call(['ip', 'link', 'set', 'dev', wpas.ifname,
+ 'address', prev_addr])
+ subprocess.call(['ifconfig', wpas.ifname, 'up'])
+
def test_sta_dynamic_random_mac_addr(dev, apdev):
"""Dynamically added wpa_supplicant interface and random MAC address"""
params = hostapd.wpa2_params(ssid="sta-dynamic", passphrase="12345678")
diff --git a/tests/hwsim/test_wmediumd.py b/tests/hwsim/test_wmediumd.py
index a9d4c8e..ad38f03 100644
--- a/tests/hwsim/test_wmediumd.py
+++ b/tests/hwsim/test_wmediumd.py
@@ -465,10 +465,7 @@ def _test_wmediumd_path_rann(dev, apdev):
dev[i].dump_monitor()
def test_wmediumd_scan_only_one(dev, apdev, params):
- """
- Test that scanning with a single active AP only returns that one
- (with wmediumd enabled)
- """
+ """Test that scanning with a single active AP only returns that one (wmediund)"""
fd, fn = tempfile.mkstemp()
try:
f = os.fdopen(fd, 'w')
diff --git a/tests/hwsim/test_wnm.py b/tests/hwsim/test_wnm.py
index aa1bd2d..c9a1609 100644
--- a/tests/hwsim/test_wnm.py
+++ b/tests/hwsim/test_wnm.py
@@ -81,7 +81,12 @@ def start_wnm_ap(apdev, bss_transition=True, time_adv=False, ssid=None,
params["vht_oper_centr_freq_seg0_idx"] = "0"
if mbo:
params["mbo"] = "1"
- hapd = hostapd.add_ap(apdev, params)
+ try:
+ hapd = hostapd.add_ap(apdev, params)
+ except Exception as e:
+ if "Failed to set hostapd parameter ocv" in str(e):
+ raise HwsimSkip("OCV not supported")
+ raise
if rsn:
Wlantest.setup(hapd)
wt = Wlantest()
@@ -301,13 +306,8 @@ def test_wnm_sleep_mode_rsn_pmf(dev, apdev):
@remote_compatible
def test_wnm_sleep_mode_rsn_ocv(dev, apdev):
"""WNM Sleep Mode - RSN with OCV"""
- try:
- hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True,
- time_adv=True, ocv=True)
- except Exception as e:
- if "Failed to set hostapd parameter ocv" in str(e):
- raise HwsimSkip("OCV not supported")
- raise
+ hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True,
+ time_adv=True, ocv=True)
dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", ocv="1",
key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
@@ -325,12 +325,7 @@ def test_wnm_sleep_mode_rsn_ocv(dev, apdev):
def test_wnm_sleep_mode_rsn_badocv(dev, apdev):
"""WNM Sleep Mode - RSN with OCV and bad OCI elements"""
ssid = "test-wnm-rsn"
- try:
- hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, ocv=True)
- except Exception as e:
- if "Failed to set hostapd parameter ocv" in str(e):
- raise HwsimSkip("OCV not supported")
- raise
+ hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, ocv=True)
bssid = apdev[0]['bssid']
dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256", ocv="1",
proto="WPA2", ieee80211w="2", scan_freq="2412")
@@ -406,13 +401,8 @@ def test_wnm_sleep_mode_rsn_badocv(dev, apdev):
def test_wnm_sleep_mode_rsn_ocv_failure(dev, apdev):
"""WNM Sleep Mode - RSN with OCV - local failure"""
- try:
- hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True,
- time_adv=True, ocv=True)
- except Exception as e:
- if "Failed to set hostapd parameter ocv" in str(e):
- raise HwsimSkip("OCV not supported")
- raise
+ hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True,
+ time_adv=True, ocv=True)
dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", ocv="1",
key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
diff --git a/tests/hwsim/test_wpas_mesh.py b/tests/hwsim/test_wpas_mesh.py
index 5f9c83e..0e80a5a 100644
--- a/tests/hwsim/test_wpas_mesh.py
+++ b/tests/hwsim/test_wpas_mesh.py
@@ -285,6 +285,7 @@ def _test_mesh_open_rssi_threshold(dev, apdev, value, expected):
": " + str(mesh_rssi_threshold))
def add_mesh_secure_net(dev, psk=True, pmf=False, pairwise=None, group=None,
+ group_mgmt=None,
sae_password=False, sae_password_id=None, ocv=False):
id = dev.add_network()
dev.set_network(id, "mode", "5")
@@ -303,6 +304,8 @@ def add_mesh_secure_net(dev, psk=True, pmf=False, pairwise=None, group=None,
dev.set_network(id, "pairwise", pairwise)
if group:
dev.set_network(id, "group", group)
+ if group_mgmt:
+ dev.set_network(id, "group_mgmt", group_mgmt)
if ocv:
try:
dev.set_network(id, "ocv", "1")
@@ -485,16 +488,18 @@ def run_mesh_secure_ocv_mix_ht(dev, apdev):
check_mesh_joined_connected(dev, connectivity=True)
-def run_mesh_secure(dev, cipher):
+def run_mesh_secure(dev, cipher, pmf=False, group_mgmt=None):
if cipher not in dev[0].get_capability("pairwise"):
raise HwsimSkip("Cipher %s not supported" % cipher)
check_mesh_support(dev[0], secure=True)
dev[0].request("SET sae_groups ")
- id = add_mesh_secure_net(dev[0], pairwise=cipher, group=cipher)
+ id = add_mesh_secure_net(dev[0], pairwise=cipher, group=cipher, pmf=pmf,
+ group_mgmt=group_mgmt)
dev[0].mesh_group_add(id)
dev[1].request("SET sae_groups ")
- id = add_mesh_secure_net(dev[1], pairwise=cipher, group=cipher)
+ id = add_mesh_secure_net(dev[1], pairwise=cipher, group=cipher, pmf=pmf,
+ group_mgmt=group_mgmt)
dev[1].mesh_group_add(id)
check_mesh_joined_connected(dev, connectivity=True)
@@ -515,6 +520,22 @@ def test_mesh_secure_ccmp_256(dev, apdev):
"""Secure mesh with CCMP-256"""
run_mesh_secure(dev, "CCMP-256")
+def test_mesh_secure_ccmp_cmac(dev, apdev):
+ """Secure mesh with CCMP-128 and BIP-CMAC-128"""
+ run_mesh_secure(dev, "CCMP", pmf=True, group_mgmt="AES-128-CMAC")
+
+def test_mesh_secure_gcmp_gmac(dev, apdev):
+ """Secure mesh with GCMP-128 and BIP-GMAC-128"""
+ run_mesh_secure(dev, "GCMP", pmf=True, group_mgmt="BIP-GMAC-128")
+
+def test_mesh_secure_ccmp_256_cmac_256(dev, apdev):
+ """Secure mesh with CCMP-256 and BIP-CMAC-256"""
+ run_mesh_secure(dev, "CCMP-256", pmf=True, group_mgmt="BIP-CMAC-256")
+
+def test_mesh_secure_gcmp_256_gmac_256(dev, apdev):
+ """Secure mesh with GCMP-256 and BIP-GMAC-256"""
+ run_mesh_secure(dev, "GCMP-256", pmf=True, group_mgmt="BIP-GMAC-256")
+
def test_mesh_secure_invalid_pairwise_cipher(dev, apdev):
"""Secure mesh and invalid group cipher"""
check_mesh_support(dev[0], secure=True)
@@ -1435,13 +1456,21 @@ def test_wpas_mesh_gate_forwarding(dev, apdev, p):
capfile = os.path.join(p['logdir'], "hwsim0.pcapng")
filt = "wlan.sa==%s && wlan_mgt.fixed.mesh_addr5==%s" % (addr2,
external_sta)
- for i in range(15):
+ time.sleep(4)
+ for i in range(5):
da = run_tshark(capfile, filt, ["wlan.da"])
if addr0 in da and addr1 in da:
logger.debug("Frames seen in tshark iteration %d" % i)
break
- time.sleep(0.3)
+ time.sleep(0.5)
+ if addr0 not in da and addr1 not in da:
+ filt = "wlan.sa==%s" % addr2
+ mesh = run_tshark(capfile, filt, ["wlan.mesh.control_field"])
+ if "1" not in mesh:
+ # Wireshark regression in mesh control field parsing:
+ # https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=15521
+ raise HwsimSkip("tshark bug 15521")
if addr0 not in da:
raise Exception("Frame to gate %s not observed" % addr0)
if addr1 not in da:
diff --git a/tests/hwsim/tshark.py b/tests/hwsim/tshark.py
index 019df78..d6a57f0 100644
--- a/tests/hwsim/tshark.py
+++ b/tests/hwsim/tshark.py
@@ -88,7 +88,9 @@ def _run_tshark(filename, filter, display=None, wait=True):
def run_tshark(filename, filter, display=None, wait=True):
if display is None: display = []
try:
- return _run_tshark(filename, filter, display, wait)
+ return _run_tshark(filename, filter.replace('wlan_mgt', 'wlan'),
+ [x.replace('wlan_mgt', 'wlan') for x in display],
+ wait)
except UnknownFieldsException as e:
all_wlan_mgt = True
for f in e.fields:
@@ -97,9 +99,7 @@ def run_tshark(filename, filter, display=None, wait=True):
break
if not all_wlan_mgt:
raise
- return _run_tshark(filename, filter.replace('wlan_mgt', 'wlan'),
- [x.replace('wlan_mgt', 'wlan') for x in display],
- wait)
+ return _run_tshark(filename, filter, display, wait)
def run_tshark_json(filename, filter):
arg = ["tshark", "-r", filename,
diff --git a/tests/hwsim/utils.py b/tests/hwsim/utils.py
index 26620a6..b3a8831 100644
--- a/tests/hwsim/utils.py
+++ b/tests/hwsim/utils.py
@@ -58,13 +58,14 @@ class fail_test(object):
if self._dev.request("GET_FAIL") != "0:%s" % self._funcs:
raise Exception("Test failure did not trigger")
-def wait_fail_trigger(dev, cmd, note="Failure not triggered", max_iter=40):
+def wait_fail_trigger(dev, cmd, note="Failure not triggered", max_iter=40,
+ timeout=0.05):
for i in range(0, max_iter):
if dev.request(cmd).startswith("0:"):
break
if i == max_iter - 1:
raise Exception(note)
- time.sleep(0.05)
+ time.sleep(timeout)
def require_under_vm():
with open('/proc/1/cmdline', 'r') as f:
diff --git a/tests/hwsim/vm/parallel-vm.py b/tests/hwsim/vm/parallel-vm.py
index 24e4a61..d509a04 100755
--- a/tests/hwsim/vm/parallel-vm.py
+++ b/tests/hwsim/vm/parallel-vm.py
@@ -10,7 +10,9 @@ from __future__ import print_function
import curses
import fcntl
import logging
+import multiprocessing
import os
+import selectors
import subprocess
import sys
import time
@@ -87,7 +89,7 @@ def get_failed(vm):
failed += vm[i]['failed']
return failed
-def vm_read_stdout(vm, i, test_queue):
+def vm_read_stdout(vm, test_queue):
global total_started, total_passed, total_failed, total_skipped
global rerun_failures
global first_run_failures
@@ -102,7 +104,7 @@ def vm_read_stdout(vm, i, test_queue):
if e.errno == errno.EAGAIN:
return False
raise
- logger.debug("VM[%d] stdout.read[%s]" % (i, out))
+ logger.debug("VM[%d] stdout.read[%s]" % (vm['idx'], out.rstrip()))
pending = vm['pending'] + out
lines = []
while True:
@@ -111,8 +113,10 @@ def vm_read_stdout(vm, i, test_queue):
break
line = pending[0:pos].rstrip()
pending = pending[(pos + 1):]
- logger.debug("VM[%d] stdout full line[%s]" % (i, line))
+ logger.debug("VM[%d] stdout full line[%s]" % (vm['idx'], line))
if line.startswith("READY"):
+ vm['starting'] = False
+ vm['started'] = True
ready = True
elif line.startswith("PASS"):
ready = True
@@ -122,14 +126,15 @@ def vm_read_stdout(vm, i, test_queue):
total_failed += 1
vals = line.split(' ')
if len(vals) < 2:
- logger.info("VM[%d] incomplete FAIL line: %s" % (i, line))
+ logger.info("VM[%d] incomplete FAIL line: %s" % (vm['idx'],
+ line))
name = line
else:
name = vals[1]
- logger.debug("VM[%d] test case failed: %s" % (i, name))
+ logger.debug("VM[%d] test case failed: %s" % (vm['idx'], name))
vm['failed'].append(name)
if name != vm['current_name']:
- logger.info("VM[%d] test result mismatch: %s (expected %s)" % (i, name, vm['current_name']))
+ logger.info("VM[%d] test result mismatch: %s (expected %s)" % (vm['idx'], name, vm['current_name']))
else:
count = vm['current_count']
if count == 0:
@@ -140,10 +145,12 @@ def vm_read_stdout(vm, i, test_queue):
elif line.startswith("NOT-FOUND"):
ready = True
total_failed += 1
- logger.info("VM[%d] test case not found" % i)
+ logger.info("VM[%d] test case not found" % vm['idx'])
elif line.startswith("SKIP"):
ready = True
total_skipped += 1
+ elif line.startswith("REASON"):
+ vm['skip_reason'].append(line[7:])
elif line.startswith("START"):
total_started += 1
if len(vm['failed']) == 0:
@@ -155,6 +162,124 @@ def vm_read_stdout(vm, i, test_queue):
vm['pending'] = pending
return ready
+def start_vm(vm, sel):
+ logger.info("VM[%d] starting up" % (vm['idx'] + 1))
+ vm['starting'] = True
+ vm['proc'] = subprocess.Popen(vm['cmd'],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ vm['cmd'] = None
+ for stream in [vm['proc'].stdout, vm['proc'].stderr]:
+ fd = stream.fileno()
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+ sel.register(stream, selectors.EVENT_READ, vm)
+
+def num_vm_starting():
+ count = 0
+ for i in range(num_servers):
+ if vm[i]['starting']:
+ count += 1
+ return count
+
+def vm_read_stderr(vm):
+ try:
+ err = vm['proc'].stderr.read()
+ if err != None:
+ err = err.decode()
+ if len(err) > 0:
+ vm['err'] += err
+ logger.info("VM[%d] stderr.read[%s]" % (vm['idx'], err))
+ except IOError as e:
+ if e.errno != errno.EAGAIN:
+ raise
+
+def vm_next_step(_vm, scr, test_queue):
+ scr.move(_vm['idx'] + 1, 10)
+ scr.clrtoeol()
+ if not test_queue:
+ _vm['proc'].stdin.write(b'\n')
+ _vm['proc'].stdin.flush()
+ scr.addstr("shutting down")
+ logger.info("VM[%d] shutting down" % _vm['idx'])
+ return
+ (name, count) = test_queue.pop(0)
+ _vm['current_name'] = name
+ _vm['current_count'] = count
+ _vm['proc'].stdin.write(name.encode() + b'\n')
+ _vm['proc'].stdin.flush()
+ scr.addstr(name)
+ logger.debug("VM[%d] start test %s" % (_vm['idx'], name))
+
+def check_vm_start(scr, sel, test_queue):
+ running = False
+ for i in range(num_servers):
+ if vm[i]['proc']:
+ running = True
+ continue
+
+ # Either not yet started or already stopped VM
+ max_start = multiprocessing.cpu_count()
+ if max_start > 4:
+ max_start /= 2
+ num_starting = num_vm_starting()
+ if vm[i]['cmd'] and len(test_queue) > num_starting and \
+ num_starting < max_start:
+ scr.move(i + 1, 10)
+ scr.clrtoeol()
+ scr.addstr(i + 1, 10, "starting VM")
+ start_vm(vm[i], sel)
+ retu