summaryrefslogtreecommitdiff
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorAndrej Shadura <andrewsh@debian.org>2019-04-27 10:46:08 +0200
committerAndrej Shadura <andrewsh@debian.org>2019-04-27 10:46:08 +0200
commit070dbdae8a92f0081104f7e7f5ef3b3067ed9cd4 (patch)
tree77b3437498154c7e7341e6dcf9cbd7e1c1b3d36d /wpa_supplicant
parentbf44a8f269f77f3309920b07f126d2c9b1ee5682 (diff)
New upstream version 2.8
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/Android.mk42
-rw-r--r--wpa_supplicant/ChangeLog69
-rw-r--r--wpa_supplicant/Makefile59
-rw-r--r--wpa_supplicant/android.config11
-rw-r--r--wpa_supplicant/ap.c5
-rw-r--r--wpa_supplicant/config.c5
-rw-r--r--wpa_supplicant/config.h10
-rw-r--r--wpa_supplicant/config_file.c7
-rw-r--r--wpa_supplicant/config_winreg.c6
-rw-r--r--wpa_supplicant/ctrl_iface.c77
-rw-r--r--wpa_supplicant/dbus/Makefile4
-rw-r--r--wpa_supplicant/dbus/dbus-wpa_supplicant.conf8
-rw-r--r--wpa_supplicant/dbus/dbus_common.c8
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_p2p.c55
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_wps.c2
-rw-r--r--wpa_supplicant/dbus/dbus_old.c745
-rw-r--r--wpa_supplicant/dbus/dbus_old.h142
-rw-r--r--wpa_supplicant/dbus/dbus_old_handlers.c1393
-rw-r--r--wpa_supplicant/dbus/dbus_old_handlers.h101
-rw-r--r--wpa_supplicant/dbus/dbus_old_handlers_wps.c156
-rw-r--r--wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in5
-rw-r--r--wpa_supplicant/defconfig67
-rw-r--r--wpa_supplicant/doc/docbook/wpa_supplicant.sgml2
-rw-r--r--wpa_supplicant/dpp_supplicant.c829
-rw-r--r--wpa_supplicant/dpp_supplicant.h10
-rw-r--r--wpa_supplicant/events.c82
-rwxr-xr-xwpa_supplicant/examples/wpas-test.py91
-rw-r--r--wpa_supplicant/ibss_rsn.c6
-rw-r--r--wpa_supplicant/main.c12
-rw-r--r--wpa_supplicant/mbo.c21
-rw-r--r--wpa_supplicant/mesh.c14
-rw-r--r--wpa_supplicant/mesh_mpm.c2
-rw-r--r--wpa_supplicant/mesh_rsn.c10
-rw-r--r--wpa_supplicant/notify.c30
-rw-r--r--wpa_supplicant/p2p_supplicant.c49
-rw-r--r--wpa_supplicant/rrm.c36
-rw-r--r--wpa_supplicant/scan.c5
-rw-r--r--wpa_supplicant/sme.c96
-rw-r--r--wpa_supplicant/systemd/wpa_supplicant.service.in4
-rw-r--r--wpa_supplicant/wpa_cli.c2
-rw-r--r--wpa_supplicant/wpa_supplicant.c199
-rw-r--r--wpa_supplicant/wpa_supplicant.conf42
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h15
-rw-r--r--wpa_supplicant/wps_supplicant.c18
-rw-r--r--wpa_supplicant/wps_supplicant.h2
45 files changed, 944 insertions, 3610 deletions
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index d63e4c4..5296931 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -259,6 +259,9 @@ NEED_SHA512=y
NEED_JSON=y
NEED_GAS_SERVER=y
NEED_BASE64=y
+ifdef CONFIG_DPP2
+L_CFLAGS += -DCONFIG_DPP2
+endif
endif
ifdef CONFIG_OWE
@@ -1422,44 +1425,25 @@ endif
OBJS += ctrl_iface.c ctrl_iface_$(CONFIG_CTRL_IFACE).c
endif
-ifdef CONFIG_CTRL_IFACE_DBUS
-DBUS=y
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE
-DBUS_OBJS += dbus/dbus_old.c dbus/dbus_old_handlers.c
-ifdef CONFIG_WPS
-DBUS_OBJS += dbus/dbus_old_handlers_wps.c
-endif
-DBUS_OBJS += dbus/dbus_dict_helpers.c
-DBUS_CFLAGS += $(DBUS_INCLUDE)
-endif
-
ifdef CONFIG_CTRL_IFACE_DBUS_NEW
-DBUS=y
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
-DBUS_OBJS ?= dbus/dbus_dict_helpers.c
-DBUS_OBJS += dbus/dbus_new_helpers.c
-DBUS_OBJS += dbus/dbus_new.c dbus/dbus_new_handlers.c
+L_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
+OBJS += dbus/dbus_dict_helpers.c
+OBJS += dbus/dbus_new_helpers.c
+OBJS += dbus/dbus_new.c dbus/dbus_new_handlers.c
+OBJS += dbus/dbus_common.c
ifdef CONFIG_WPS
-DBUS_OBJS += dbus/dbus_new_handlers_wps.c
+OBJS += dbus/dbus_new_handlers_wps.c
endif
ifdef CONFIG_P2P
-DBUS_OBJS += dbus/dbus_new_handlers_p2p.c
+OBJS += dbus/dbus_new_handlers_p2p.c
endif
ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
-DBUS_OBJS += dbus/dbus_new_introspect.c
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
-endif
-DBUS_CFLAGS += $(DBUS_INCLUDE)
+OBJS += dbus/dbus_new_introspect.c
+L_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
endif
-
-ifdef DBUS
-DBUS_CFLAGS += -DCONFIG_DBUS
-DBUS_OBJS += dbus/dbus_common.c
+L_CFLAGS += $(DBUS_INCLUDE)
endif
-OBJS += $(DBUS_OBJS)
-L_CFLAGS += $(DBUS_CFLAGS)
-
ifdef CONFIG_CTRL_IFACE_BINDER
WPA_SUPPLICANT_USE_BINDER=y
L_CFLAGS += -DCONFIG_BINDER -DCONFIG_CTRL_IFACE_BINDER
diff --git a/wpa_supplicant/ChangeLog b/wpa_supplicant/ChangeLog
index bf4daaa..89119e7 100644
--- a/wpa_supplicant/ChangeLog
+++ b/wpa_supplicant/ChangeLog
@@ -1,5 +1,74 @@
ChangeLog for wpa_supplicant
+2019-04-21 - v2.8
+ * SAE changes
+ - added support for SAE Password Identifier
+ - changed default configuration to enable only groups 19, 20, 21
+ (i.e., disable groups 25 and 26) and disable all unsuitable groups
+ completely based on REVmd changes
+ - do not regenerate PWE unnecessarily when the AP uses the
+ anti-clogging token mechanisms
+ - fixed some association cases where both SAE and FT-SAE were enabled
+ on both the station and the selected AP
+ - started to prefer FT-SAE over SAE AKM if both are enabled
+ - started to prefer FT-SAE over FT-PSK if both are enabled
+ - fixed FT-SAE when SAE PMKSA caching is used
+ - reject use of unsuitable groups based on new implementation guidance
+ in REVmd (allow only FFC groups with prime >= 3072 bits and ECC
+ groups with prime >= 256)
+ - minimize timing and memory use differences in PWE derivation
+ [https://w1.fi/security/2019-1/] (CVE-2019-9494)
+ * EAP-pwd changes
+ - minimize timing and memory use differences in PWE derivation
+ [https://w1.fi/security/2019-2/] (CVE-2019-9495)
+ - verify server scalar/element
+ [https://w1.fi/security/2019-4/] (CVE-2019-9499)
+ - fix message reassembly issue with unexpected fragment
+ [https://w1.fi/security/2019-5/]
+ - enforce rand,mask generation rules more strictly
+ - fix a memory leak in PWE derivation
+ - disallow ECC groups with a prime under 256 bits (groups 25, 26, and
+ 27)
+ * fixed CONFIG_IEEE80211R=y (FT) build without CONFIG_FILS=y
+ * Hotspot 2.0 changes
+ - do not indicate release number that is higher than the one
+ AP supports
+ - added support for release number 3
+ - enable PMF automatically for network profiles created from
+ credentials
+ * fixed OWE network profile saving
+ * fixed DPP network profile saving
+ * added support for RSN operating channel validation
+ (CONFIG_OCV=y and network profile parameter ocv=1)
+ * added Multi-AP backhaul STA support
+ * fixed build with LibreSSL
+ * number of MKA/MACsec fixes and extensions
+ * extended domain_match and domain_suffix_match to allow list of values
+ * fixed dNSName matching in domain_match and domain_suffix_match when
+ using wolfSSL
+ * started to prefer FT-EAP-SHA384 over WPA-EAP-SUITE-B-192 AKM if both
+ are enabled
+ * extended nl80211 Connect and external authentication to support
+ SAE, FT-SAE, FT-EAP-SHA384
+ * fixed KEK2 derivation for FILS+FT
+ * extended client_cert file to allow loading of a chain of PEM
+ encoded certificates
+ * extended beacon reporting functionality
+ * extended D-Bus interface with number of new properties
+ * fixed a regression in FT-over-DS with mac80211-based drivers
+ * OpenSSL: allow systemwide policies to be overridden
+ * extended driver flags indication for separate 802.1X and PSK
+ 4-way handshake offload capability
+ * added support for random P2P Device/Interface Address use
+ * extended PEAP to derive EMSK to enable use with ERP/FILS
+ * extended WPS to allow SAE configuration to be added automatically
+ for PSK (wps_cred_add_sae=1)
+ * removed support for the old D-Bus interface (CONFIG_CTRL_IFACE_DBUS)
+ * extended domain_match and domain_suffix_match to allow list of values
+ * added a RSN workaround for misbehaving PMF APs that advertise
+ IGTK/BIP KeyID using incorrect byte order
+ * fixed PTK rekeying with FILS and FT
+
2018-12-02 - v2.7
* fixed WPA packet number reuse with replayed messages and key
reinstallation
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index e55e062..e81238e 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -55,7 +55,6 @@ ALL += systemd/wpa_supplicant.service
ALL += systemd/wpa_supplicant@.service
ALL += systemd/wpa_supplicant-nl80211@.service
ALL += systemd/wpa_supplicant-wired@.service
-ALL += dbus/fi.epitest.hostap.WPASupplicant.service
ALL += dbus/fi.w1.wpa_supplicant1.service
ifdef CONFIG_BUILD_WPA_CLIENT_SO
ALL += libwpa_client.so
@@ -292,6 +291,9 @@ NEED_SHA512=y
NEED_JSON=y
NEED_GAS_SERVER=y
NEED_BASE64=y
+ifdef CONFIG_DPP2
+CFLAGS += -DCONFIG_DPP2
+endif
endif
ifdef CONFIG_OWE
@@ -1576,35 +1578,17 @@ endif
OBJS += ctrl_iface.o ctrl_iface_$(CONFIG_CTRL_IFACE).o
endif
-ifdef CONFIG_CTRL_IFACE_DBUS
-DBUS=y
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE
-DBUS_OBJS += dbus/dbus_old.o dbus/dbus_old_handlers.o
-ifdef CONFIG_WPS
-DBUS_OBJS += dbus/dbus_old_handlers_wps.o
-endif
-DBUS_OBJS += dbus/dbus_dict_helpers.o
-ifndef DBUS_LIBS
-DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
-endif
-ifndef DBUS_INCLUDE
-DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
-endif
-DBUS_CFLAGS += $(DBUS_INCLUDE)
-DBUS_INTERFACE=fi.epitest.hostap.WPASupplicant
-endif
-
ifdef CONFIG_CTRL_IFACE_DBUS_NEW
-DBUS=y
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
-DBUS_OBJS ?= dbus/dbus_dict_helpers.o
-DBUS_OBJS += dbus/dbus_new_helpers.o
-DBUS_OBJS += dbus/dbus_new.o dbus/dbus_new_handlers.o
+CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
+OBJS += dbus/dbus_dict_helpers.o
+OBJS += dbus/dbus_new_helpers.o
+OBJS += dbus/dbus_new.o dbus/dbus_new_handlers.o
+OBJS += dbus/dbus_common.o
ifdef CONFIG_WPS
-DBUS_OBJS += dbus/dbus_new_handlers_wps.o
+OBJS += dbus/dbus_new_handlers_wps.o
endif
ifdef CONFIG_P2P
-DBUS_OBJS += dbus/dbus_new_handlers_p2p.o
+OBJS += dbus/dbus_new_handlers_p2p.o
endif
ifndef DBUS_LIBS
DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
@@ -1613,21 +1597,12 @@ ifndef DBUS_INCLUDE
DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
endif
ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
-DBUS_OBJS += dbus/dbus_new_introspect.o
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
-endif
-DBUS_CFLAGS += $(DBUS_INCLUDE)
-DBUS_INTERFACE=fi.w1.wpa_supplicant1
+OBJS += dbus/dbus_new_introspect.o
+CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
endif
-
-ifdef DBUS
-DBUS_CFLAGS += -DCONFIG_DBUS
-DBUS_OBJS += dbus/dbus_common.o
-endif
-
-OBJS += $(DBUS_OBJS)
-CFLAGS += $(DBUS_CFLAGS)
+CFLAGS += $(DBUS_INCLUDE)
LIBS += $(DBUS_LIBS)
+endif
ifdef CONFIG_READLINE
OBJS_c += ../src/utils/edit_readline.o
@@ -1990,13 +1965,11 @@ else
endif
%.service: %.service.in
- $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' \
- -e 's|\@DBUS_INTERFACE\@|$(DBUS_INTERFACE)|g' $< >$@
+ $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
@$(E) " sed" $<
%@.service: %.service.arg.in
- $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' \
- -e 's|\@DBUS_INTERFACE\@|$(DBUS_INTERFACE)|g' $< >$@
+ $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
@$(E) " sed" $<
wpa_supplicant.exe: wpa_supplicant
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index ab80263..6536c11 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -91,9 +91,6 @@ CONFIG_EAP_PEAP=y
CONFIG_EAP_TTLS=y
# EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
#CONFIG_EAP_FAST=y
# EAP-GTC
@@ -330,10 +327,6 @@ CONFIG_IEEE80211W=y
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -490,8 +483,8 @@ CONFIG_P2P=y
# Enable TDLS support
CONFIG_TDLS=y
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
CONFIG_WIFI_DISPLAY=y
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 453c99d..4e19169 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -334,10 +334,13 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
list[8] = -1;
}
conf->supported_rates = list;
+ }
+
#ifdef CONFIG_IEEE80211AX
+ if (ssid->mode == WPAS_MODE_P2P_GO ||
+ ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
conf->ieee80211ax = ssid->he;
#endif /* CONFIG_IEEE80211AX */
- }
bss->isolate = !wpa_s->conf->p2p_intra_bss;
bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index b4e9952..2058175 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2257,6 +2257,7 @@ static const struct parse_data ssid_fields[] = {
{ STR_KEYe(private_key_passwd) },
{ STRe(dh_file) },
{ STRe(subject_match) },
+ { STRe(check_cert_subject) },
{ STRe(altsubject_match) },
{ STRe(domain_suffix_match) },
{ STRe(domain_match) },
@@ -2267,6 +2268,7 @@ static const struct parse_data ssid_fields[] = {
{ STR_KEYe(private_key2_passwd) },
{ STRe(dh_file2) },
{ STRe(subject_match2) },
+ { STRe(check_cert_subject2) },
{ STRe(altsubject_match2) },
{ STRe(domain_suffix_match2) },
{ STRe(domain_match2) },
@@ -2525,6 +2527,7 @@ static void eap_peer_config_free(struct eap_peer_config *eap)
str_clear_free(eap->private_key_passwd);
os_free(eap->dh_file);
os_free(eap->subject_match);
+ os_free(eap->check_cert_subject);
os_free(eap->altsubject_match);
os_free(eap->domain_suffix_match);
os_free(eap->domain_match);
@@ -2535,6 +2538,7 @@ static void eap_peer_config_free(struct eap_peer_config *eap)
str_clear_free(eap->private_key2_passwd);
os_free(eap->dh_file2);
os_free(eap->subject_match2);
+ os_free(eap->check_cert_subject2);
os_free(eap->altsubject_match2);
os_free(eap->domain_suffix_match2);
os_free(eap->domain_match2);
@@ -4753,6 +4757,7 @@ static const struct global_parse_data global_fields[] = {
{ FUNC(os_version), CFG_CHANGED_OS_VERSION },
{ STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
{ INT_RANGE(wps_cred_processing, 0, 2), 0 },
+ { INT_RANGE(wps_cred_add_sae, 0, 1), 0 },
{ FUNC(wps_vendor_ext_m1), CFG_CHANGED_VENDOR_EXTENSION },
#endif /* CONFIG_WPS */
#ifdef CONFIG_P2P
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 15d8c48..abbd8c9 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -745,6 +745,16 @@ struct wpa_config {
*/
int wps_cred_processing;
+ /**
+ * wps_cred_add_sae - Whether to enable SAE automatically for WPS
+ *
+ * 0 = only add the explicitly listed WPA2-PSK configuration
+ * 1 = add both the WPA2-PSK and SAE configuration and enable PMF so
+ * that the station gets configured in WPA3-Personal transition mode
+ * (supports both WPA2-Personal (PSK) and WPA3-Personal (SAE) APs).
+ */
+ int wps_cred_add_sae;
+
#define MAX_SEC_DEVICE_TYPES 5
/**
* sec_device_types - Secondary Device Types (P2P)
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 9b14699..26f6ee1 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -493,7 +493,7 @@ static void write_str(FILE *f, const char *field, struct wpa_ssid *ssid)
if (value == NULL)
return;
fprintf(f, "\t%s=%s\n", field, value);
- os_free(value);
+ str_clear_free(value);
}
@@ -782,6 +782,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
STR(private_key_passwd);
STR(dh_file);
STR(subject_match);
+ STR(check_cert_subject);
STR(altsubject_match);
STR(domain_suffix_match);
STR(domain_match);
@@ -792,6 +793,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
STR(private_key2_passwd);
STR(dh_file2);
STR(subject_match2);
+ STR(check_cert_subject2);
STR(altsubject_match2);
STR(domain_suffix_match2);
STR(domain_match2);
@@ -1187,6 +1189,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
if (config->wps_cred_processing)
fprintf(f, "wps_cred_processing=%d\n",
config->wps_cred_processing);
+ if (config->wps_cred_add_sae)
+ fprintf(f, "wps_cred_add_sae=%d\n",
+ config->wps_cred_add_sae);
if (config->wps_vendor_ext_m1) {
int i, len = wpabuf_len(config->wps_vendor_ext_m1);
const u8 *p = wpabuf_head_u8(config->wps_vendor_ext_m1);
diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c
index 0ce1830..6328e91 100644
--- a/wpa_supplicant/config_winreg.c
+++ b/wpa_supplicant/config_winreg.c
@@ -255,6 +255,8 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
errors++;
wpa_config_read_reg_dword(hk, TEXT("wps_cred_processing"),
&config->wps_cred_processing);
+ wpa_config_read_reg_dword(hk, TEXT("wps_cred_add_sae"),
+ &config->wps_cred_add_sae);
#endif /* CONFIG_WPS */
#ifdef CONFIG_P2P
config->p2p_ssid_postfix = wpa_config_read_reg_string(
@@ -604,6 +606,8 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
}
wpa_config_write_reg_dword(hk, TEXT("wps_cred_processing"),
config->wps_cred_processing, 0);
+ wpa_config_write_reg_dword(hk, TEXT("wps_cred_add_sae"),
+ config->wps_cred_add_sae, 0);
#endif /* CONFIG_WPS */
#ifdef CONFIG_P2P
wpa_config_write_reg_string(hk, "p2p_ssid_postfix",
@@ -892,6 +896,7 @@ static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
STR(private_key_passwd);
STR(dh_file);
STR(subject_match);
+ STR(check_cert_subject);
STR(altsubject_match);
STR(ca_cert2);
STR(ca_path2);
@@ -900,6 +905,7 @@ static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
STR(private_key2_passwd);
STR(dh_file2);
STR(subject_match2);
+ STR(check_cert_subject2);
STR(altsubject_match2);
STR(phase1);
STR(phase2);
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 7882dcf..198ac56 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -1168,8 +1168,11 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_AP
u8 *_p2p_dev_addr = NULL;
#endif /* CONFIG_AP */
+ char *pos;
+ int multi_ap = 0;
- if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
+ if (!cmd || os_strcmp(cmd, "any") == 0 ||
+ os_strncmp(cmd, "any ", 4) == 0) {
_bssid = NULL;
#ifdef CONFIG_P2P
} else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
@@ -1181,18 +1184,29 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
}
_p2p_dev_addr = p2p_dev_addr;
#endif /* CONFIG_P2P */
+ } else if (os_strncmp(cmd, "multi_ap=", 9) == 0) {
+ _bssid = NULL;
+ multi_ap = atoi(cmd + 9);
} else if (hwaddr_aton(cmd, bssid)) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
cmd);
return -1;
}
+ if (cmd) {
+ pos = os_strstr(cmd, " multi_ap=");
+ if (pos) {
+ pos += 10;
+ multi_ap = atoi(pos);
+ }
+ }
+
#ifdef CONFIG_AP
if (wpa_s->ap_iface)
return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
#endif /* CONFIG_AP */
- return wpas_wps_start_pbc(wpa_s, _bssid, 0);
+ return wpas_wps_start_pbc(wpa_s, _bssid, 0, multi_ap);
}
@@ -2118,6 +2132,18 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
pos += ret;
}
+ if (wpa_s->connection_set &&
+ (wpa_s->connection_ht || wpa_s->connection_vht ||
+ wpa_s->connection_he)) {
+ ret = os_snprintf(pos, end - pos,
+ "wifi_generation=%u\n",
+ wpa_s->connection_he ? 6 :
+ (wpa_s->connection_vht ? 5 : 4));
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+
#ifdef CONFIG_AP
if (wpa_s->ap_iface) {
pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
@@ -3994,6 +4020,14 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
}
#endif /* CONFIG_IEEE80211R */
#endif /* CONFIG_FILS */
+#ifdef CONFIG_IEEE80211R
+ if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK) {
+ ret = os_snprintf(pos, end - pos, " FT-PSK");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_SAE
if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) {
ret = os_snprintf(pos, end - pos, " SAE");
@@ -4409,6 +4443,19 @@ static int wpa_supplicant_ctrl_iface_get_capability(
return res;
}
+#ifdef CONFIG_DPP
+ if (os_strcmp(field, "dpp") == 0) {
+#ifdef CONFIG_DPP2
+ res = os_snprintf(buf, buflen, "DPP=2");
+#else /* CONFIG_DPP2 */
+ res = os_snprintf(buf, buflen, "DPP=1");
+#endif /* CONFIG_DPP2 */
+ if (os_snprintf_error(buflen, res))
+ return -1;
+ return res;
+ }
+#endif /* CONFIG_DPP */
+
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
field);
@@ -5049,10 +5096,11 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
bss = NULL;
dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
{
- if (i-- == 0) {
+ if (i == 0) {
bss = tmp;
break;
}
+ i--;
}
}
@@ -6383,6 +6431,8 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211ANY;
wpa_s->p2p_go_do_acs = 1;
}
+ } else {
+ wpa_s->p2p_go_do_acs = 0;
}
#endif /* CONFIG_ACS */
@@ -7665,7 +7715,7 @@ static int wpas_ctrl_iface_get_pref_freq_list(
wpa_printf(MSG_DEBUG,
"CTRL_IFACE: GET_PREF_FREQ_LIST iface_type=%d (%s)",
- iface_type, buf);
+ iface_type, cmd);
ret = wpa_drv_get_pref_freq_list(wpa_s, iface_type, &num, freq_list);
if (ret)
@@ -10626,7 +10676,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strncmp(buf, "DPP_BOOTSTRAP_GEN ", 18) == 0) {
int res;
- res = wpas_dpp_bootstrap_gen(wpa_s, buf + 18);
+ res = dpp_bootstrap_gen(wpa_s->dpp, buf + 18);
if (res < 0) {
reply_len = -1;
} else {
@@ -10635,12 +10685,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
reply_len = -1;
}
} else if (os_strncmp(buf, "DPP_BOOTSTRAP_REMOVE ", 21) == 0) {
- if (wpas_dpp_bootstrap_remove(wpa_s, buf + 21) < 0)
+ if (dpp_bootstrap_remove(wpa_s->dpp, buf + 21) < 0)
reply_len = -1;
} else if (os_strncmp(buf, "DPP_BOOTSTRAP_GET_URI ", 22) == 0) {
const char *uri;
- uri = wpas_dpp_bootstrap_get_uri(wpa_s, atoi(buf + 22));
+ uri = dpp_bootstrap_get_uri(wpa_s->dpp, atoi(buf + 22));
if (!uri) {
reply_len = -1;
} else {
@@ -10649,8 +10699,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
reply_len = -1;
}
} else if (os_strncmp(buf, "DPP_BOOTSTRAP_INFO ", 19) == 0) {
- reply_len = wpas_dpp_bootstrap_info(wpa_s, atoi(buf + 19),
- reply, reply_size);
+ reply_len = dpp_bootstrap_info(wpa_s->dpp, atoi(buf + 19),
+ reply, reply_size);
} else if (os_strncmp(buf, "DPP_AUTH_INIT ", 14) == 0) {
if (wpas_dpp_auth_init(wpa_s, buf + 13) < 0)
reply_len = -1;
@@ -10663,7 +10713,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strncmp(buf, "DPP_CONFIGURATOR_ADD", 20) == 0) {
int res;
- res = wpas_dpp_configurator_add(wpa_s, buf + 20);
+ res = dpp_configurator_add(wpa_s->dpp, buf + 20);
if (res < 0) {
reply_len = -1;
} else {
@@ -10672,14 +10722,15 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
reply_len = -1;
}
} else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
- if (wpas_dpp_configurator_remove(wpa_s, buf + 24) < 0)
+ if (dpp_configurator_remove(wpa_s->dpp, buf + 24) < 0)
reply_len = -1;
} else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) {
if (wpas_dpp_configurator_sign(wpa_s, buf + 21) < 0)
reply_len = -1;
} else if (os_strncmp(buf, "DPP_CONFIGURATOR_GET_KEY ", 25) == 0) {
- reply_len = wpas_dpp_configurator_get_key(wpa_s, atoi(buf + 25),
- reply, reply_size);
+ reply_len = dpp_configurator_get_key_id(wpa_s->dpp,
+ atoi(buf + 25),
+ reply, reply_size);
} else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
int res;
diff --git a/wpa_supplicant/dbus/Makefile b/wpa_supplicant/dbus/Makefile
index f355ebe..4d87004 100644
--- a/wpa_supplicant/dbus/Makefile
+++ b/wpa_supplicant/dbus/Makefile
@@ -36,7 +36,6 @@ CFLAGS += -DCONFIG_WPS
endif
CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
-CFLAGS += -DCONFIG_CTRL_IFACE_DBUS
ifndef DBUS_LIBS
DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
@@ -54,8 +53,6 @@ CFLAGS += $(DBUS_INCLUDE)
LIB_OBJS= \
dbus_common.o \
- dbus_old.o \
- dbus_old_handlers.o \
dbus_new.o \
dbus_new_handlers.o \
dbus_new_helpers.o \
@@ -63,7 +60,6 @@ LIB_OBJS= \
dbus_dict_helpers.o
ifdef CONFIG_WPS
-LIB_OBJS += dbus_old_handlers_wps.o
LIB_OBJS += dbus_new_handlers_wps.o
endif
diff --git a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
index 382dcb3..e81b495 100644
--- a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
+++ b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
@@ -3,11 +3,6 @@
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
- <allow own="fi.epitest.hostap.WPASupplicant"/>
-
- <allow send_destination="fi.epitest.hostap.WPASupplicant"/>
- <allow send_interface="fi.epitest.hostap.WPASupplicant"/>
-
<allow own="fi.w1.wpa_supplicant1"/>
<allow send_destination="fi.w1.wpa_supplicant1"/>
@@ -15,9 +10,6 @@
<allow receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
</policy>
<policy context="default">
- <deny own="fi.epitest.hostap.WPASupplicant"/>
- <deny send_destination="fi.epitest.hostap.WPASupplicant"/>
-
<deny own="fi.w1.wpa_supplicant1"/>
<deny send_destination="fi.w1.wpa_supplicant1"/>
<deny receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
diff --git a/wpa_supplicant/dbus/dbus_common.c b/wpa_supplicant/dbus/dbus_common.c
index 7ef6cad..efa6c7b 100644
--- a/wpa_supplicant/dbus/dbus_common.c
+++ b/wpa_supplicant/dbus/dbus_common.c
@@ -16,7 +16,6 @@
#include "dbus_common.h"
#include "dbus_common_i.h"
#include "dbus_new.h"
-#include "dbus_old.h"
#include "../wpa_supplicant_i.h"
@@ -351,9 +350,6 @@ struct wpas_dbus_priv * wpas_dbus_init(struct wpa_global *global)
#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
wpas_dbus_ctrl_iface_init(priv) < 0 ||
#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-#ifdef CONFIG_CTRL_IFACE_DBUS
- wpa_supplicant_dbus_ctrl_iface_init(priv) < 0 ||
-#endif /* CONFIG_CTRL_IFACE_DBUS */
wpas_dbus_init_common_finish(priv) < 0) {
wpas_dbus_deinit(priv);
return NULL;
@@ -372,9 +368,5 @@ void wpas_dbus_deinit(struct wpas_dbus_priv *priv)
wpas_dbus_ctrl_iface_deinit(priv);
#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-#ifdef CONFIG_CTRL_IFACE_DBUS
- /* TODO: is any deinit needed? */
-#endif /* CONFIG_CTRL_IFACE_DBUS */
-
wpas_dbus_deinit_common(priv);
}
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 9f44f69..8cdd885 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -2693,7 +2693,7 @@ DBusMessage * wpas_dbus_handler_p2p_delete_service(
if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto error;
- if (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+ while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto error;
@@ -2705,26 +2705,27 @@ DBusMessage * wpas_dbus_handler_p2p_delete_service(
bonjour = 1;
else
goto error_clear;
- wpa_dbus_dict_entry_clear(&entry);
- }
- }
- if (upnp == 1) {
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
- if (os_strcmp(entry.key, "version") == 0 &&
- entry.type == DBUS_TYPE_INT32)
- version = entry.uint32_value;
- else if (os_strcmp(entry.key, "service") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(service);
- service = os_strdup(entry.str_value);
- } else
+ } else if (os_strcmp(entry.key, "version") == 0 &&
+ entry.type == DBUS_TYPE_INT32) {
+ version = entry.uint32_value;
+ } else if (os_strcmp(entry.key, "service") == 0 &&
+ entry.type == DBUS_TYPE_STRING) {
+ os_free(service);
+ service = os_strdup(entry.str_value);
+ } else if (os_strcmp(entry.key, "query") == 0) {
+ if (entry.type != DBUS_TYPE_ARRAY ||
+ entry.array_type != DBUS_TYPE_BYTE)
goto error_clear;
-
- wpa_dbus_dict_entry_clear(&entry);
+ wpabuf_free(query);
+ query = wpabuf_alloc_copy(entry.bytearray_value,
+ entry.array_len);
+ } else {
+ goto error_clear;
}
+ wpa_dbus_dict_entry_clear(&entry);
+ }
+ if (upnp == 1) {
if (version <= 0 || service == NULL)
goto error;
@@ -2732,24 +2733,6 @@ DBusMessage * wpas_dbus_handler_p2p_delete_service(
if (ret != 0)
goto error;
} else if (bonjour == 1) {
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
-
- if (os_strcmp(entry.key, "query") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != DBUS_TYPE_BYTE)
- goto error_clear;
- wpabuf_free(query);
- query = wpabuf_alloc_copy(
- entry.bytearray_value,
- entry.array_len);
- } else
- goto error_clear;
-
- wpa_dbus_dict_entry_clear(&entry);
- }
-
if (query == NULL)
goto error;
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
index 19c1a61..1594daf 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
@@ -293,7 +293,7 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
message, "invalid PIN");
}
} else {
- ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
+ ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0, 0);
}
if (ret < 0) {
diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c
deleted file mode 100644
index 88227af..0000000
--- a/wpa_supplicant/dbus/dbus_old.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include <dbus/dbus.h>
-
-#include "common.h"
-#include "eloop.h"
-#include "wps/wps.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../bss.h"
-#include "dbus_old.h"
-#include "dbus_old_handlers.h"
-#include "dbus_common_i.h"
-
-
-/**
- * wpas_dbus_decompose_object_path - Decompose an interface object path into parts
- * @path: The dbus object path
- * @network: (out) the configured network this object path refers to, if any
- * @bssid: (out) the scanned bssid this object path refers to, if any
- * Returns: The object path of the network interface this path refers to
- *
- * For a given object path, decomposes the object path into object id, network,
- * and BSSID parts, if those parts exist.
- */
-char * wpas_dbus_decompose_object_path(const char *path, char **network,
- char **bssid)
-{
- const unsigned int dev_path_prefix_len =
- strlen(WPAS_DBUS_PATH_INTERFACES "/");
- char *obj_path_only;
- char *next_sep;
-
- /* Be a bit paranoid about path */
- if (!path || strncmp(path, WPAS_DBUS_PATH_INTERFACES "/",
- dev_path_prefix_len))
- return NULL;
-
- /* Ensure there's something at the end of the path */
- if ((path + dev_path_prefix_len)[0] == '\0')
- return NULL;
-
- obj_path_only = os_strdup(path);
- if (obj_path_only == NULL)
- return NULL;
-
- next_sep = strchr(obj_path_only + dev_path_prefix_len, '/');
- if (next_sep != NULL) {
- const char *net_part = strstr(next_sep,
- WPAS_DBUS_NETWORKS_PART "/");
- const char *bssid_part = strstr(next_sep,
- WPAS_DBUS_BSSIDS_PART "/");
-
- if (network && net_part) {
- /* Deal with a request for a configured network */
- const char *net_name = net_part +
- strlen(WPAS_DBUS_NETWORKS_PART "/");
- *network = NULL;
- if (strlen(net_name))
- *network = os_strdup(net_name);
- } else if (bssid && bssid_part) {
- /* Deal with a request for a scanned BSSID */
- const char *bssid_name = bssid_part +
- strlen(WPAS_DBUS_BSSIDS_PART "/");
- if (strlen(bssid_name))
- *bssid = os_strdup(bssid_name);
- else
- *bssid = NULL;
- }
-
- /* Cut off interface object path before "/" */
- *next_sep = '\0';
- }
-
- return obj_path_only;
-}
-
-
-/**
- * wpas_dbus_new_invalid_iface_error - Return a new invalid interface error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: A dbus error message
- *
- * Convenience function to create and return an invalid interface error
- */
-DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message)
-{
- return dbus_message_new_error(
- message, WPAS_ERROR_INVALID_IFACE,
- "wpa_supplicant knows nothing about this interface.");
-}
-
-
-/**
- * wpas_dbus_new_invalid_network_error - Return a new invalid network error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an invalid network error
- */
-DBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message)
-{
- return dbus_message_new_error(message, WPAS_ERROR_INVALID_NETWORK,
- "The requested network does not exist.");
-}
-
-
-/**
- * wpas_dbus_new_invalid_bssid_error - Return a new invalid bssid error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an invalid bssid error
- */
-static DBusMessage * wpas_dbus_new_invalid_bssid_error(DBusMessage *message)
-{
- return dbus_message_new_error(message, WPAS_ERROR_INVALID_BSSID,
- "The BSSID requested was invalid.");
-}
-
-
-/**
- * wpas_dispatch_network_method - dispatch messages for configured networks
- * @message: the incoming dbus message
- * @wpa_s: a network interface's data
- * @network_id: id of the configured network we're interested in
- * Returns: a reply dbus message, or a dbus error message
- *
- * This function dispatches all incoming dbus messages for configured networks.
- */
-static DBusMessage * wpas_dispatch_network_method(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- int network_id)
-{
- DBusMessage *reply = NULL;
- const char *method = dbus_message_get_member(message);
- struct wpa_ssid *ssid;
-
- ssid = wpa_config_get_network(wpa_s->conf, network_id);
- if (ssid == NULL)
- return wpas_dbus_new_invalid_network_error(message);
-
- if (!strcmp(method, "set"))
- reply = wpas_dbus_iface_set_network(message, wpa_s, ssid);
- else if (!strcmp(method, "enable"))
- reply = wpas_dbus_iface_enable_network(message, wpa_s, ssid);
- else if (!strcmp(method, "disable"))
- reply = wpas_dbus_iface_disable_network(message, wpa_s, ssid);
-
- return reply;
-}
-
-
-/**
- * wpas_dispatch_bssid_method - dispatch messages for scanned networks
- * @message: the incoming dbus message
- * @wpa_s: a network interface's data
- * @bssid: bssid of the scanned network we're interested in
- * Returns: a reply dbus message, or a dbus error message
- *
- * This function dispatches all incoming dbus messages for scanned networks.
- */
-static DBusMessage * wpas_dispatch_bssid_method(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- const char *bssid_txt)
-{
- u8 bssid[ETH_ALEN];
- struct wpa_bss *bss;
-
- if (hexstr2bin(bssid_txt, bssid, ETH_ALEN) < 0)
- return wpas_dbus_new_invalid_bssid_error(message);
-
- bss = wpa_bss_get_bssid(wpa_s, bssid);
- if (bss == NULL)
- return wpas_dbus_new_invalid_bssid_error(message);
-
- /* Dispatch the method call against the scanned bssid */
- if (os_strcmp(dbus_message_get_member(message), "properties") == 0)
- return wpas_dbus_bssid_properties(message, wpa_s, bss);
-
- return NULL;
-}
-
-
-/**
- * wpas_iface_message_handler - Dispatch messages for interfaces or networks
- * @connection: Connection to the system message bus
- * @message: An incoming dbus message
- * @user_data: A pointer to a dbus control interface data structure
- * Returns: Whether or not the message was handled
- *
- * This function dispatches all incoming dbus messages for network interfaces,
- * or objects owned by them, such as scanned BSSIDs and configured networks.
- */
-static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- const char *method = dbus_message_get_member(message);
- const char *path = dbus_message_get_path(message);
- const char *msg_interface = dbus_message_get_interface(message);
- char *iface_obj_path = NULL;
- char *network = NULL;
- char *bssid = NULL;
- DBusMessage *reply = NULL;
-
- /* Caller must specify a message interface */
- if (!msg_interface)
- goto out;
-
- wpa_printf(MSG_MSGDUMP, "dbus[old/iface]: %s.%s (%s) [%s]",
- msg_interface, method, path,
- dbus_message_get_signature(message));
-
- iface_obj_path = wpas_dbus_decompose_object_path(path, &network,
- &bssid);
- if (iface_obj_path == NULL) {
- reply = wpas_dbus_new_invalid_iface_error(message);
- goto out;
- }
-
- /* Make sure the message's object path actually refers to the
- * wpa_supplicant structure it's supposed to (which is wpa_s)
- */
- if (wpa_supplicant_get_iface_by_dbus_path(wpa_s->global,
- iface_obj_path) != wpa_s) {
- reply = wpas_dbus_new_invalid_iface_error(message);
- goto out;
- }
-
- if (network && !strcmp(msg_interface, WPAS_DBUS_IFACE_NETWORK)) {
- /* A method for one of this interface's configured networks */
- int nid = strtoul(network, NULL, 10);
-
- if (errno != EINVAL)
- reply = wpas_dispatch_network_method(message, wpa_s,
- nid);
- else
- reply = wpas_dbus_new_invalid_network_error(message);
- } else if (bssid && !strcmp(msg_interface, WPAS_DBUS_IFACE_BSSID)) {
- /* A method for one of this interface's scanned BSSIDs */
- reply = wpas_dispatch_bssid_method(message, wpa_s, bssid);
- } else if (!strcmp(msg_interface, WPAS_DBUS_IFACE_INTERFACE)) {
- /* A method for an interface only. */
- if (!strcmp(method, "scan"))
- reply = wpas_dbus_iface_scan(message, wpa_s);
- else if (!strcmp(method, "scanResults"))
- reply = wpas_dbus_iface_scan_results(message, wpa_s);
- else if (!strcmp(method, "addNetwork"))
- reply = wpas_dbus_iface_add_network(message, wpa_s);
- else if (!strcmp(method, "removeNetwork"))
- reply = wpas_dbus_iface_remove_network(message, wpa_s);
- else if (!strcmp(method, "selectNetwork"))
- reply = wpas_dbus_iface_select_network(message, wpa_s);
- else if (!strcmp(method, "capabilities"))
- reply = wpas_dbus_iface_capabilities(message, wpa_s);
- else if (!strcmp(method, "disconnect"))
- reply = wpas_dbus_iface_disconnect(message, wpa_s);
- else if (!strcmp(method, "setAPScan"))
- reply = wpas_dbus_iface_set_ap_scan(message, wpa_s);
- else if (!strcmp(method, "setSmartcardModules"))
- reply = wpas_dbus_iface_set_smartcard_modules(message,
- wpa_s);
- else if (!strcmp(method, "state"))
- reply = wpas_dbus_iface_get_state(message, wpa_s);
- else if (!strcmp(method, "scanning"))
- reply = wpas_dbus_iface_get_scanning(message, wpa_s);
-#ifndef CONFIG_NO_CONFIG_BLOBS
- else if (!strcmp(method, "setBlobs"))
- reply = wpas_dbus_iface_set_blobs(message, wpa_s);
- else if (!strcmp(method, "removeBlobs"))
- reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-#ifdef CONFIG_WPS
- else if (os_strcmp(method, "wpsPbc") == 0)
- reply = wpas_dbus_iface_wps_pbc(message, wpa_s);
- else if (os_strcmp(method, "wpsPin") == 0)
- reply = wpas_dbus_iface_wps_pin(message, wpa_s);
- else if (os_strcmp(method, "wpsReg") == 0)
- reply = wpas_dbus_iface_wps_reg(message, wpa_s);
-#endif /* CONFIG_WPS */
- else if (os_strcmp(method, "flush") == 0)
- reply = wpas_dbus_iface_flush(message, wpa_s);
- }
-
- /* If the message was handled, send back the reply */
-out:
- if (reply) {
- if (!dbus_message_get_no_reply(message))
- dbus_connection_send(connection, reply, NULL);
- dbus_message_unref(reply);
- }
-
- os_free(iface_obj_path);
- os_free(network);
- os_free(bssid);
- return reply ? DBUS_HANDLER_RESULT_HANDLED :
- DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-
-/**
- * wpas_message_handler - dispatch incoming dbus messages
- * @connection: connection to the system message bus
- * @message: an incoming dbus message
- * @user_data: a pointer to a dbus control interface data structure
- * Returns: whether or not the message was handled
- *
- * This function dispatches all incoming dbus messages to the correct
- * handlers, depending on what the message's target object path is,
- * and what the method call is.
- */
-static DBusHandlerResult wpas_message_handler(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct wpas_dbus_priv *ctrl_iface = user_data;
- const char *method;
- const char *path;
- const char *msg_interface;
- DBusMessage *reply = NULL;
-
- method = dbus_message_get_member(message);
- path = dbus_message_get_path(message);
- msg_interface = dbus_message_get_interface(message);
- if (!method || !path || !ctrl_iface || !msg_interface)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- wpa_printf(MSG_MSGDUMP, "dbus[old]: %s.%s (%s) [%s]",
- msg_interface, method, path,
- dbus_message_get_signature(message));
-
- /* Validate the method interface */
- if (strcmp(msg_interface, WPAS_DBUS_INTERFACE) != 0)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- if (!strcmp(path, WPAS_DBUS_PATH)) {
- /* dispatch methods against our global dbus interface here */
- if (!strcmp(method, "addInterface")) {
- reply = wpas_dbus_global_add_interface(
- message, ctrl_iface->global);
- } else if (!strcmp(method, "removeInterface")) {
- reply = wpas_dbus_global_remove_interface(
- message, ctrl_iface->global);
- } else if (!strcmp(method, "getInterface")) {
- reply = wpas_dbus_global_get_interface(
- message, ctrl_iface->global);
- } else if (!strcmp(method, "setDebugParams")) {
- reply = wpas_dbus_global_set_debugparams(
- message, ctrl_iface->global);
- }
- }
-
- /* If the message was handled, send back the reply */
- if (reply) {
- if (!dbus_message_get_no_reply(message))
- dbus_connection_send(connection, reply, NULL);
- dbus_message_unref(reply);
- }
-
- return reply ? DBUS_HANDLER_RESULT_HANDLED :
- DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-
-/**
- * wpa_supplicant_dbus_notify_scan_results - Send a scan results signal
- * @wpa_s: %wpa_supplicant network interface data
- * Returns: 0 on success, -1 on failure
- *
- * Notify listeners that this interface has updated scan results.
- */
-void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
-{
- struct wpas_dbus_priv *iface = wpa_s->global->dbus;
- DBusMessage *_signal;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_path)
- return;
-
- _signal = dbus_message_new_signal(wpa_s->dbus_path,
- WPAS_DBUS_IFACE_INTERFACE,
- "ScanResultsAvailable");
- if (_signal == NULL) {
- wpa_printf(MSG_ERROR,
- "dbus: Not enough memory to send scan results signal");
- return;
- }
- dbus_connection_send(iface->con, _signal, NULL);
- dbus_message_unref(_signal);
-}
-
-
-/**
- * wpa_supplicant_dbus_notify_state_change - Send a state change signal
- * @wpa_s: %wpa_supplicant network interface data
- * @new_state: new state wpa_supplicant is entering
- * @old_state: old state wpa_supplicant is leaving
- * Returns: 0 on success, -1 on failure
- *
- * Notify listeners that wpa_supplicant has changed state
- */
-void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
- enum wpa_states new_state,
- enum wpa_states old_state)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *_signal = NULL;
- const char *new_state_str, *old_state_str;
-
- if (wpa_s->dbus_path == NULL)
- return; /* Skip signal since D-Bus setup is not yet ready */
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s->global == NULL)
- return;
- iface = wpa_s->global->dbus;
- if (iface == NULL)
- return;
-
- /* Only send signal if state really changed */
- if (new_state == old_state)
- return;
-
- _signal = dbus_message_new_signal(wpa_s->dbus_path,
- WPAS_DBUS_IFACE_INTERFACE,
- "StateChange");
- if (_signal == NULL) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: could not create dbus signal; likely out of memory",
- __func__);
- return;
- }
-
- new_state_str = wpa_supplicant_state_txt(new_state);
- old_state_str = wpa_supplicant_state_txt(old_state);
-
- if (!dbus_message_append_args(_signal,
- DBUS_TYPE_STRING, &new_state_str,
- DBUS_TYPE_STRING, &old_state_str,
- DBUS_TYPE_INVALID)) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: Not enough memory to construct state change signal",
- __func__);
- goto out;
- }
-
- dbus_connection_send(iface->con, _signal, NULL);
-
-out:
- dbus_message_unref(_signal);
-}
-
-
-/**
- * wpa_supplicant_dbus_notify_scanning - send scanning status
- * @wpa_s: %wpa_supplicant network interface data
- * Returns: 0 on success, -1 on failure
- *
- * Notify listeners of interface scanning state changes
- */
-void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
-{
- struct wpas_dbus_priv *iface = wpa_s->global->dbus;
- DBusMessage *_signal;
- dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_path)
- return;
-
- _signal = dbus_message_new_signal(wpa_s->dbus_path,
- WPAS_DBUS_IFACE_INTERFACE,
- "Scanning");
- if (_signal == NULL) {
- wpa_printf(MSG_ERROR,
- "dbus: Not enough memory to send scan results signal");
- return;
- }
-
- if (dbus_message_append_args(_signal,
- DBUS_TYPE_BOOLEAN, &scanning,
- DBUS_TYPE_INVALID)) {
- dbus_connection_send(iface->con, _signal, NULL);
- } else {
- wpa_printf(MSG_ERROR,
- "dbus: Not enough memory to construct signal");
- }
- dbus_message_unref(_signal);
-}
-
-
-#ifdef CONFIG_WPS
-void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
- const struct wps_credential *cred)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *_signal = NULL;
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s->global == NULL)
- return;
- iface = wpa_s->global->dbus;
- if (iface == NULL || !wpa_s->dbus_path)
- return;
-
- _signal = dbus_message_new_signal(wpa_s->dbus_path,
- WPAS_DBUS_IFACE_INTERFACE,
- "WpsCred");
- if (_signal == NULL) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: Could not create dbus signal; likely out of memory",
- __func__);
- return;
- }
-
- if (!dbus_message_append_args(_signal,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
- &cred->cred_attr, cred->cred_attr_len,
- DBUS_TYPE_INVALID)) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: Not enough memory to construct signal",
- __func__);
- goto out;
- }
-
- dbus_connection_send(iface->con, _signal, NULL);
-
-out:
- dbus_message_unref(_signal);
-}
-#else /* CONFIG_WPS */
-void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
- const struct wps_credential *cred)
-{
-}
-#endif /* CONFIG_WPS */
-
-void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
- int depth, const char *subject,
- const char *cert_hash,
- const struct wpabuf *cert)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *_signal = NULL;
- const char *hash;
- const char *cert_hex;
- int cert_hex_len;
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s->global == NULL)
- return;
- iface = wpa_s->global->dbus;
- if (iface == NULL || !wpa_s->dbus_path)
- return;
-
- _signal = dbus_message_new_signal(wpa_s->dbus_path,
- WPAS_DBUS_IFACE_INTERFACE,
- "Certification");
- if (_signal == NULL) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: Could not create dbus signal; likely out of memory",
- __func__);
- return;
- }
-
- hash = cert_hash ? cert_hash : "";
- cert_hex = cert ? wpabuf_head(cert) : "";
- cert_hex_len = cert ? wpabuf_len(cert) : 0;
-
- if (!dbus_message_append_args(_signal,
- DBUS_TYPE_INT32, &depth,
- DBUS_TYPE_STRING, &subject,
- DBUS_TYPE_STRING, &hash,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
- &cert_hex, cert_hex_len,
- DBUS_TYPE_INVALID)) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: Not enough memory to construct signal",
- __func__);
- goto out;
- }
-
- dbus_connection_send(iface->con, _signal, NULL);
-
-out:
- dbus_message_unref(_signal);
-
-}
-
-
-/**
- * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * Returns: 0 on success, -1 on failure
- *
- * Initialize the dbus control interface and start receiving commands from
- * external programs over the bus.
- */
-int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface)
-{
- DBusError error;
- int ret = -1;
- DBusObjectPathVTable wpas_vtable = {
- NULL, &wpas_message_handler, NULL, NULL, NULL, NULL
- };
-
- /* Register the message handler for the global dbus interface */
- if (!dbus_connection_register_object_path(iface->con,
- WPAS_DBUS_PATH, &wpas_vtable,
- iface)) {
- wpa_printf(MSG_ERROR, "dbus: Could not set up message handler");
- return -1;
- }
-
- /* Register our service with the message bus */
- dbus_error_init(&error);
- switch (dbus_bus_request_name(iface->con, WPAS_DBUS_SERVICE,
- 0, &error)) {
- case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
- ret = 0;
- break;
- case DBUS_REQUEST_NAME_REPLY_EXISTS:
- case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
- case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
- wpa_printf(MSG_ERROR,
- "dbus: Could not request service name: already registered");
- break;
- default:
- wpa_printf(MSG_ERROR,
- "dbus: Could not request service name: %s %s",
- error.name, error.message);
- break;
- }
- dbus_error_free(&error);
-
- if (ret != 0)
- return -1;
-
- wpa_printf(MSG_DEBUG, "Providing DBus service '" WPAS_DBUS_SERVICE
- "'.");
-
- return 0;
-}
-
-
-/**
- * wpas_dbus_register_new_iface - Register a new interface with dbus
- * @wpa_s: %wpa_supplicant interface description structure to register
- * Returns: 0 on success, -1 on error
- *
- * Registers a new interface with dbus and assigns it a dbus object path.
- */
-int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
-{
- struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
- DBusConnection * con;
- u32 next;
- DBusObjectPathVTable vtable = {
- NULL, &wpas_iface_message_handler, NULL, NULL, NULL, NULL
- };
-
- /* Do nothing if the control interface is not turned on */
- if (ctrl_iface == NULL)
- return 0;
-
- con = ctrl_iface->con;
- next = ctrl_iface->next_objid++;
-
- /* Create and set the interface's object path */
- wpa_s->dbus_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
- if (wpa_s->dbus_path == NULL)
- return -1;
- os_snprintf(wpa_s->dbus_path, WPAS_DBUS_OBJECT_PATH_MAX,
- WPAS_DBUS_PATH_INTERFACES "/%u",
- next);
-
- /* Register the message handler for the interface functions */
- if (!dbus_connection_register_fallback(con, wpa_s->dbus_path, &vtable,
- wpa_s)) {
- wpa_printf(MSG_ERROR,
- "dbus: Could not set up message handler for interface %s",
- wpa_s->ifname);
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * wpas_dbus_unregister_iface - Unregister an interface from dbus
- * @wpa_s: wpa_supplicant interface structure
- * Returns: 0 on success, -1 on failure
- *
- * Unregisters the interface with dbus
- */
-int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s)
-{
- struct wpas_dbus_priv *ctrl_iface;
- DBusConnection *con;
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL)
- return 0;
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL || wpa_s->dbus_path == NULL)
- return 0;
-
- con = ctrl_iface->con;
- if (!dbus_connection_unregister_object_path(con, wpa_s->dbus_path))
- return -1;
-
- os_free(wpa_s->dbus_path);
- wpa_s->dbus_path = NULL;
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_get_iface_by_dbus_path - Get a new network interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * @path: Pointer to a dbus object path representing an interface
- * Returns: Pointer to the interface or %NULL if not found
- */
-struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path(
- struct wpa_global *global, const char *path)
-{
- struct wpa_supplicant *wpa_s;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (wpa_s->dbus_path && strcmp(wpa_s->dbus_path, path) == 0)
- return wpa_s;
- }
- return NULL;
-}
diff --git a/wpa_supplicant/dbus/dbus_old.h b/wpa_supplicant/dbus/dbus_old.h
deleted file mode 100644
index 451a9f8..0000000
--- a/wpa_supplicant/dbus/dbus_old.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef CTRL_IFACE_DBUS_H
-#define CTRL_IFACE_DBUS_H
-
-struct wps_credential;
-
-#ifdef CONFIG_CTRL_IFACE_DBUS
-
-#define WPAS_DBUS_OBJECT_PATH_MAX 150
-
-#define WPAS_DBUS_SERVICE "fi.epitest.hostap.WPASupplicant"
-#define WPAS_DBUS_PATH "/fi/epitest/hostap/WPASupplicant"
-#define WPAS_DBUS_INTERFACE "fi.epitest.hostap.WPASupplicant"
-
-#define WPAS_DBUS_PATH_INTERFACES WPAS_DBUS_PATH "/Interfaces"
-#define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface"
-
-#define WPAS_DBUS_NETWORKS_PART "Networks"
-#define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network"
-
-#define WPAS_DBUS_BSSIDS_PART "BSSIDs"
-#define WPAS_DBUS_IFACE_BSSID WPAS_DBUS_INTERFACE ".BSSID"
-
-
-/* Errors */
-#define WPAS_ERROR_INVALID_NETWORK \
- WPAS_DBUS_IFACE_INTERFACE ".InvalidNetwork"
-#define WPAS_ERROR_INVALID_BSSID \
- WPAS_DBUS_IFACE_INTERFACE ".InvalidBSSID"
-
-#define WPAS_ERROR_INVALID_OPTS \
- WPAS_DBUS_INTERFACE ".InvalidOptions"
-#define WPAS_ERROR_INVALID_IFACE \
- WPAS_DBUS_INTERFACE ".InvalidInterface"
-
-#define WPAS_ERROR_ADD_ERROR \
- WPAS_DBUS_INTERFACE ".AddError"
-#define WPAS_ERROR_EXISTS_ERROR \
- WPAS_DBUS_INTERFACE ".ExistsError"
-#define WPAS_ERROR_REMOVE_ERROR \
- WPAS_DBUS_INTERFACE ".RemoveError"
-
-#define WPAS_ERROR_SCAN_ERROR \
- WPAS_DBUS_IFACE_INTERFACE ".ScanError"
-#define WPAS_ERROR_ADD_NETWORK_ERROR \
- WPAS_DBUS_IFACE_INTERFACE ".AddNetworkError"
-#define WPAS_ERROR_INTERNAL_ERROR \
- WPAS_DBUS_IFACE_INTERFACE ".InternalError"
-#define WPAS_ERROR_REMOVE_NETWORK_ERROR \
- WPAS_DBUS_IFACE_INTERFACE ".RemoveNetworkError"
-
-#define WPAS_ERROR_WPS_PBC_ERROR \
- WPAS_DBUS_IFACE_INTERFACE ".WpsPbcError"
-#define WPAS_ERROR_WPS_PIN_ERROR \
- WPAS_DBUS_IFACE_INTERFACE ".WpsPinError"
-#define WPAS_ERROR_WPS_REG_ERROR \
- WPAS_DBUS_IFACE_INTERFACE ".WpsRegError"
-
-#define WPAS_DBUS_BSSID_FORMAT "%02x%02x%02x%02x%02x%02x"
-
-struct wpa_global;
-struct wpa_supplicant;
-
-int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface);
-void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
- enum wpa_states new_state,
- enum wpa_states old_state);
-void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
- const struct wps_credential *cred);
-void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
- int depth, const char *subject,
- const char *cert_hash,
- const struct wpabuf *cert);
-
-char * wpas_dbus_decompose_object_path(const char *path, char **network,
- char **bssid);
-
-int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s);
-int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s);
-
-
-/* Methods internal to the dbus control interface */
-struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path(
- struct wpa_global *global, const char *path);
-
-#else /* CONFIG_CTRL_IFACE_DBUS */
-
-static inline void
-wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void
-wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void
-wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
- enum wpa_states new_state,
- enum wpa_states old_state)
-{
-}
-
-static inline void
-wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
- const struct wps_credential *cred)
-{
-}
-
-static inline void
-wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
- int depth, const char *subject,
- const char *cert_hash,
- const struct wpabuf *cert)
-{
-}
-
-static inline int
-wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline int
-wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-#endif /* CONFIG_CTRL_IFACE_DBUS */
-
-#endif /* CTRL_IFACE_DBUS_H */
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c
deleted file mode 100644
index e540832..0000000
--- a/wpa_supplicant/dbus/dbus_old_handlers.c
+++ /dev/null
@@ -1,1393 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include <dbus/dbus.h>
-
-#include "common.h"
-#include "eap_peer/eap_methods.h"
-#include "common/ieee802_11_defs.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "rsn_supp/wpa.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../driver_i.h"
-#include "../notify.h"
-#include "../wpas_glue.h"
-#include "../bss.h"
-#include "../scan.h"
-#include "dbus_old.h"
-#include "dbus_old_handlers.h"
-#include "dbus_dict_helpers.h"
-
-/**
- * wpas_dbus_new_invalid_opts_error - Return a new invalid options error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an invalid options error
- */
-DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message,
- const char *arg)
-{
- DBusMessage *reply;
-
- reply = dbus_message_new_error(
- message, WPAS_ERROR_INVALID_OPTS,
- "Did not receive correct message arguments.");
- if (arg != NULL)
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
- DBUS_TYPE_INVALID);
-
- return reply;
-}
-
-
-/**
- * wpas_dbus_new_success_reply - Return a new success reply message
- * @message: Pointer to incoming dbus message this reply refers to
- * Returns: a dbus message containing a single UINT32 that indicates
- * success (ie, a value of 1)
- *
- * Convenience function to create and return a success reply message
- */
-DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message)
-{
- DBusMessage *reply;
- unsigned int success = 1;
-
- reply = dbus_message_new_method_return(message);
- dbus_message_append_args(reply, DBUS_TYPE_UINT32, &success,
- DBUS_TYPE_INVALID);
- return reply;
-}
-
-
-/**
- * wpas_dbus_global_add_interface - Request registration of a network interface
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: The object path of the new interface object,
- * or a dbus error message with more information
- *
- * Handler function for "addInterface" method call. Handles requests
- * by dbus clients to register a network interface that wpa_supplicant
- * will manage.
- */
-DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
- struct wpa_global *global)
-{
- char *ifname = NULL;
- char *driver = NULL;
- char *driver_param = NULL;
- char *confname = NULL;
- char *bridge_ifname = NULL;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
-
- dbus_message_iter_init(message, &iter);
-
- /* First argument: interface name (DBUS_TYPE_STRING)
- * Required; must be non-zero length
- */
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- goto error;
- dbus_message_iter_get_basic(&iter, &ifname);
- if (!os_strlen(ifname))
- goto error;
-
- /* Second argument: dict of options */
- if (dbus_message_iter_next(&iter)) {
- DBusMessageIter iter_dict;
- struct wpa_dbus_dict_entry entry;
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
- if (!strcmp(entry.key, "driver") &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(driver);
- driver = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (driver == NULL)
- goto error;
- } else if (!strcmp(entry.key, "driver-params") &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(driver_param);
- driver_param = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (driver_param == NULL)
- goto error;
- } else if (!strcmp(entry.key, "config-file") &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(confname);
- confname = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (confname == NULL)
- goto error;
- } else if (!strcmp(entry.key, "bridge-ifname") &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(bridge_ifname);
- bridge_ifname = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (bridge_ifname == NULL)
- goto error;
- } else {
- wpa_dbus_dict_entry_clear(&entry);
- goto error;
- }
- }
- }
-
- /*
- * Try to get the wpa_supplicant record for this iface, return
- * an error if we already control it.
- */
- if (wpa_supplicant_get_iface(global, ifname) != NULL) {
- reply = dbus_message_new_error(
- message, WPAS_ERROR_EXISTS_ERROR,
- "wpa_supplicant already controls this interface.");
- } else {
- struct wpa_supplicant *wpa_s;
- struct wpa_interface iface;
-
- os_memset(&iface, 0, sizeof(iface));
- iface.ifname = ifname;
- iface.driver = driver;
- iface.driver_param = driver_param;
- iface.confname = confname;
- iface.bridge_ifname = bridge_ifname;
- /* Otherwise, have wpa_supplicant attach to it. */
- wpa_s = wpa_supplicant_add_iface(global, &iface, NULL);
- if (wpa_s && wpa_s->dbus_path) {
- const char *path = wpa_s->dbus_path;
-
- reply = dbus_message_new_method_return(message);
- dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
- &path, DBUS_TYPE_INVALID);
- } else {
- reply = dbus_message_new_error(
- message, WPAS_ERROR_ADD_ERROR,
- "wpa_supplicant couldn't grab this interface.");
- }
- }
-
-out:
- os_free(driver);
- os_free(driver_param);
- os_free(confname);
- os_free(bridge_ifname);
- return reply;
-
-error:
- reply = wpas_dbus_new_invalid_opts_error(message, NULL);
- goto out;
-}
-
-
-/**
- * wpas_dbus_global_remove_interface - Request deregistration of an interface
- * @message: Pointer to incoming dbus message
- * @global: wpa_supplicant global data structure
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- * failure (0), or returns a dbus error message with more information
- *
- * Handler function for "removeInterface" method call. Handles requests
- * by dbus clients to deregister a network interface that wpa_supplicant
- * currently manages.
- */
-DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
- struct wpa_global *global)
-{
- struct wpa_supplicant *wpa_s;
- char *path;
- DBusMessage *reply = NULL;
-
- if (!dbus_message_get_args(message, NULL,
- DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID)) {
- reply = wpas_dbus_new_invalid_opts_error(message, NULL);
- goto out;
- }
-
- wpa_s = wpa_supplicant_get_iface_by_dbus_path(global, path);
- if (wpa_s == NULL) {
- reply = wpas_dbus_new_invalid_iface_error(message);
- goto out;
- }
-
- if (!wpa_supplicant_remove_iface(global, wpa_s, 0)) {
- reply = wpas_dbus_new_success_reply(message);
- } else {
- reply = dbus_message_new_error(
- message, WPAS_ERROR_REMOVE_ERROR,
- "wpa_supplicant couldn't remove this interface.");
- }
-
-out:
- return reply;
-}
-
-
-/**
- * wpas_dbus_global_get_interface - Get the object path for an interface name
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: The object path of the interface object,
- * or a dbus error message with more information
- *
- * Handler function for "getInterface" method call. Handles requests
- * by dbus clients for the object path of an specific network interface.
- */
-DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,
- struct wpa_global *global)
-{
- DBusMessage *reply = NULL;
- const char *ifname;
- const char *path;
- struct wpa_supplicant *wpa_s;
-
- if (!dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &ifname,
- DBUS_TYPE_INVALID)) {
- reply = wpas_dbus_new_invalid_opts_error(message, NULL);
- goto out;
- }
-
- wpa_s = wpa_supplicant_get_iface(global, ifname);
- if (wpa_s == NULL || !wpa_s->dbus_path) {
- reply = wpas_dbus_new_invalid_iface_error(message);
- goto out;
- }
-
- path = wpa_s->dbus_path;
- reply = dbus_message_new_method_return(message);
- dbus_message_append_args(reply,
- DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
-
-out:
- return reply;
-}
-
-
-/**
- * wpas_dbus_global_set_debugparams- Set the debug params
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- * failure (0), or returns a dbus error message with more information
- *
- * Handler function for "setDebugParams" method call. Handles requests
- * by dbus clients for the object path of an specific network interface.
- */
-DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message,
- struct wpa_global *global)
-{
- DBusMessage *reply = NULL;
- int debug_level;
- dbus_bool_t debug_timestamp;
- dbus_bool_t debug_show_keys;
-
- if (!dbus_message_get_args(message, NULL,
- DBUS_TYPE_INT32, &debug_level,
- DBUS_TYPE_BOOLEAN, &debug_timestamp,
- DBUS_TYPE_BOOLEAN, &debug_show_keys,
- DBUS_TYPE_INVALID)) {
- return wpas_dbus_new_invalid_opts_error(message, NULL);
- }
-
- if (wpa_supplicant_set_debug_params(global, debug_level,
- debug_timestamp ? 1 : 0,
- debug_show_keys ? 1 : 0)) {
- return wpas_dbus_new_invalid_opts_error(message, NULL);
- }
-
- reply = wpas_dbus_new_success_reply(message);
-
- return reply;
-}
-
-
-/**
- * wpas_dbus_iface_scan - Request a wireless scan on an interface
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "scan" method call of a network device. Requests
- * that wpa_supplicant perform a wireless scan as soon as possible
- * on a particular wireless interface.
- */
-DBusMessage * wpas_dbus_iface_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_scan_results - Get the results of a recent scan request
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing a dbus array of objects paths, or returns
- * a dbus error message if not scan results could be found
- *
- * Handler function for "scanResults" method call of a network device. Returns
- * a dbus message containing the object paths of wireless networks found.
- */
-DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter sub_iter;
- struct wpa_bss *bss;
-
- if (!wpa_s->dbus_path)
- return dbus_message_new_error(message,
- WPAS_ERROR_INTERNAL_ERROR,
- "no D-Bus interface available");
-
- /* Create and initialize the return message */
- reply = dbus_message_new_method_return(message);
- dbus_message_iter_init_append(reply, &iter);
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_OBJECT_PATH_AS_STRING,
- &sub_iter))
- goto error;
-
- /* Loop through scan results and append each result's object path */
- dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
- char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
- char *path = path_buf;
-
- /* Construct the object path for this network. Note that ':'
- * is not a valid character in dbus object paths.
- */
- os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_BSSIDS_PART "/"
- WPAS_DBUS_BSSID_FORMAT,
- wpa_s->dbus_path, MAC2STR(bss->bssid));
- if (!dbus_message_iter_append_basic(&sub_iter,
- DBUS_TYPE_OBJECT_PATH,
- &path))
- goto error;
- }
-
- if (!dbus_message_iter_close_container(&iter, &sub_iter))
- goto error;
-
- return reply;
-
-error:
- dbus_message_unref(reply);
- return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR,
- "an internal error occurred returning scan results");
-}
-
-
-/**
- * wpas_dbus_bssid_properties - Return the properties of a scanned network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * @res: wpa_supplicant scan result for which to get properties
- * Returns: a dbus message containing the properties for the requested network
- *
- * Handler function for "properties" method call of a scanned network.
- * Returns a dbus message containing the the properties.
- */
-DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss)
-{
- DBusMessage *reply;
- DBusMessageIter iter, iter_dict;
- const u8 *wpa_ie, *rsn_ie, *wps_ie;
-
- /* Dump the properties into a dbus message */
- reply = dbus_message_new_method_return(message);
-
- wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- wps_ie = wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
-
- dbus_message_iter_init_append(reply, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &iter_dict) ||
- !wpa_dbus_dict_append_byte_array(&iter_dict, "bssid",
- (const char *) bss->bssid,
- ETH_ALEN) ||
- !wpa_dbus_dict_append_byte_array(&iter_dict, "ssid",
- (const char *) bss->ssid,
- bss->ssid_len) ||
- (wpa_ie &&
- !wpa_dbus_dict_append_byte_array(&iter_dict, "wpaie",
- (const char *) wpa_ie,
- wpa_ie[1] + 2)) ||
- (rsn_ie &&
- !wpa_dbus_dict_append_byte_array(&iter_dict, "rsnie",
- (const char *) rsn_ie,
- rsn_ie[1] + 2)) ||
- (wps_ie &&
- !wpa_dbus_dict_append_byte_array(&iter_dict, "wpsie",
- (const char *) wps_ie,
- wps_ie[1] + 2)) ||
- (bss->freq &&
- !wpa_dbus_dict_append_int32(&iter_dict, "frequency", bss->freq)) ||
- !wpa_dbus_dict_append_uint16(&iter_dict, "capabilities",
- bss->caps) ||
- (!(bss->flags & WPA_BSS_QUAL_INVALID) &&
- !wpa_dbus_dict_append_int32(&iter_dict, "quality", bss->qual)) ||
- (!(bss->flags & WPA_BSS_NOISE_INVALID) &&
- !wpa_dbus_dict_append_int32(&iter_dict, "noise", bss->noise)) ||
- (!(bss->flags & WPA_BSS_LEVEL_INVALID) &&
- !wpa_dbus_dict_append_int32(&iter_dict, "level", bss->level)) ||
- !wpa_dbus_dict_append_int32(&iter_dict, "maxrate",
- wpa_bss_get_max_rate(bss) * 500000) ||
- !wpa_dbus_dict_close_write(&iter, &iter_dict)) {
- if (reply)
- dbus_message_unref(reply);
- reply = dbus_message_new_error(
- message, WPAS_ERROR_INTERNAL_ERROR,
- "an internal error occurred returning BSSID properties.");
- }
-
- return reply;
-}
-
-
-/**
- * wpas_dbus_iface_capabilities - Return interface capabilities
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a dict of strings
- *
- * Handler function for "capabilities" method call of an interface.
- */
-DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- struct wpa_driver_capa capa;
- int res;
- DBusMessageIter iter, iter_dict;
- char **eap_methods;
- size_t num_items;
- dbus_bool_t strict = FALSE;
- DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
-
- if (!dbus_message_get_args(message, NULL,
- DBUS_TYPE_BOOLEAN, &strict,
- DBUS_TYPE_INVALID))
- strict = FALSE;
-
- reply = dbus_message_new_method_return(message);
-
- dbus_message_iter_init_append(reply, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
- goto error;
-
- /* EAP methods */
- eap_methods = eap_get_names_as_string_array(&num_items);
- if (eap_methods) {
- dbus_bool_t success;
- size_t i = 0;
-
- success = wpa_dbus_dict_append_string_array(
- &iter_dict, "eap", (const char **) eap_methods,
- num_items);
-
- /* free returned method array */
- while (eap_methods[i])
- os_free(eap_methods[i++]);
- os_free(eap_methods);
-
- if (!success)
- goto error;
- }
-
- res = wpa_drv_get_capa(wpa_s, &capa);
-
- /***** pairwise cipher */
- if (res < 0) {
- if (!strict) {
- const char *args[] = {"CCMP", "TKIP", "NONE"};
-
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "pairwise", args,
- ARRAY_SIZE(args)))
- goto error;
- }
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "pairwise",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "CCMP")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "TKIP")) ||
- ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "NONE")) ||
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto error;
- }
-
- /***** group cipher */
- if (res < 0) {
- if (!strict) {
- const char *args[] = {
- "CCMP", "TKIP", "WEP104", "WEP40"
- };
-
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "group", args,
- ARRAY_SIZE(args)))
- goto error;
- }
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "group",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto error;
-
- if (((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "CCMP")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "TKIP")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "WEP104")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "WEP40")) ||
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto error;
- }
-
- /***** key management */
- if (res < 0) {
- if (!strict) {
- const char *args[] = {
- "WPA-PSK", "WPA-EAP", "IEEE8021X", "WPA-NONE",
- "NONE"
- };
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "key_mgmt", args,
- ARRAY_SIZE(args)))
- goto error;
- }
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "key_mgmt",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- !wpa_dbus_dict_string_array_add_element(&iter_array,
- "NONE") ||
- !wpa_dbus_dict_string_array_add_element(&iter_array,
- "IEEE8021X") ||
- ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "WPA-EAP")) ||
- ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "WPA-PSK")) ||
- ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "WPA-NONE")) ||
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto error;
- }
-
- /***** WPA protocol */
- if (res < 0) {
- if (!strict) {
- const char *args[] = { "RSN", "WPA" };
-
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "proto", args,
- ARRAY_SIZE(args)))
- goto error;
- }
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "proto",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "RSN")) ||
- ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "WPA")) ||
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto error;
- }
-
- /***** auth alg */
- if (res < 0) {
- if (!strict) {
- const char *args[] = { "OPEN", "SHARED", "LEAP" };
-
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "auth_alg", args,
- ARRAY_SIZE(args)))
- goto error;
- }
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "auth_alg",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- ((capa.auth & WPA_DRIVER_AUTH_OPEN) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "OPEN")) ||
- ((capa.auth & WPA_DRIVER_AUTH_SHARED) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "SHARED")) ||
- ((capa.auth & WPA_DRIVER_AUTH_LEAP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "LEAP")) ||
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto error;
- }
-
- if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
- goto error;
-
- return reply;
-
-error:
- if (reply)
- dbus_message_unref(reply);
- return dbus_message_new_error(
- message, WPAS_ERROR_INTERNAL_ERROR,
- "an internal error occurred returning interface capabilities.");
-}
-
-
-/**
- * wpas_dbus_iface_add_network - Add a new configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing the object path of the new network
- *
- * Handler function for "addNetwork" method call of a network interface.
- */
-DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- struct wpa_ssid *ssid = NULL;
- char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
-
- if (wpa_s->dbus_path)
- ssid = wpa_supplicant_add_network(wpa_s);
- if (ssid == NULL) {
- reply = dbus_message_new_error(
- message, WPAS_ERROR_ADD_NETWORK_ERROR,
- "wpa_supplicant could not add a network on this interface.");
- goto out;
- }
-
- /* Construct the object path for this network. */
- os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NETWORKS_PART "/%d",
- wpa_s->dbus_path, ssid->id);
-
- reply = dbus_message_new_method_return(message);
- dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
- &path, DBUS_TYPE_INVALID);
-
-out:
- return reply;
-}
-
-
-/**
- * wpas_dbus_iface_remove_network - Remove a configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "removeNetwork" method call of a network interface.
- */
-DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- const char *op;
- char *iface = NULL, *net_id = NULL;
- int id;
- int result;
-
- if (!dbus_message_get_args(message, NULL,
- DBUS_TYPE_OBJECT_PATH, &op,
- DBUS_TYPE_INVALID)) {
- reply = wpas_dbus_new_invalid_opts_error(message, NULL);
- goto out;
- }
-
- /* Extract the network ID */
- iface = wpas_dbus_decompose_object_path(op, &net_id, NULL);
- if (iface == NULL || net_id == NULL) {
- reply = wpas_dbus_new_invalid_network_error(message);
- goto out;
- }
-
- /* Ensure the network is actually a child of this interface */
- if (!wpa_s->dbus_path || os_strcmp(iface, wpa_s->dbus_path) != 0) {
- reply = wpas_dbus_new_invalid_network_error(message);
- goto out;
- }
-
- id = strtoul(net_id, NULL, 10);
- result = wpa_supplicant_remove_network(wpa_s, id);
- if (result == -1) {
- reply = wpas_dbus_new_invalid_network_error(message);
- goto out;
- }
- if (result == -2) {
- reply = dbus_message_new_error(
- message, WPAS_ERROR_REMOVE_NETWORK_ERROR,
- "error removing the specified on this interface.");
- goto out;
- }
-
- reply = wpas_dbus_new_success_reply(message);
-
-out:
- os_free(iface);
- os_free(net_id);
- return reply;
-}
-
-
-static const char * const dont_quote[] = {
- "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
- "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
- "bssid", "scan_freq", "freq_list", NULL
-};
-
-
-static dbus_bool_t should_quote_opt(const char *key)
-{
- int i = 0;
-
- while (dont_quote[i] != NULL) {
- if (os_strcmp(key, dont_quote[i]) == 0)
- return FALSE;
- i++;
- }
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_iface_set_network - Set options for a configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "set" method call of a configured network.
- */
-DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- DBusMessage *reply = NULL;
- struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
- DBusMessageIter iter, iter_dict;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) {
- reply = wpas_dbus_new_invalid_opts_error(message, NULL);
- goto out;
- }
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- char *value = NULL;
- size_t size = 50;
- int ret;
-
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
- reply = wpas_dbus_new_invalid_opts_error(message,
- NULL);
- goto out;
- }
-
- /* Type conversions, since wpa_supplicant wants strings */
- if (entry.type == DBUS_TYPE_ARRAY &&
- entry.array_type == DBUS_TYPE_BYTE) {
- if (entry.array_len <= 0)
- goto error;
-
- size = entry.array_len * 2 + 1;
- value = os_zalloc(size);
- if (value == NULL)
- goto error;
- ret = wpa_snprintf_hex(value, size,
- (u8 *) entry.bytearray_value,
- entry.array_len);
- if (ret <= 0)
- goto error;
- } else if (entry.type == DBUS_TYPE_STRING) {
- if (should_quote_opt(entry.key)) {
- size = os_strlen(entry.str_value);
- /* Zero-length option check */
- if (size == 0)
- goto error;
- size += 3; /* For quotes and terminator */
- value = os_zalloc(size);
- if (value == NULL)
- goto error;
- ret = os_snprintf(value, size, "\"%s\"",
- entry.str_value);
- if (os_snprintf_error(size, ret))
- goto error;
- } else {
- value = os_strdup(entry.str_value);
- if (value == NULL)
- goto error;
- }
- } else if (entry.type == DBUS_TYPE_UINT32) {
- value = os_zalloc(size);
- if (value == NULL)
- goto error;
- ret = os_snprintf(value, size, "%u",
- entry.uint32_value);
- if (os_snprintf_error(size, ret))
- goto error;
- } else if (entry.type == DBUS_TYPE_INT32) {
- value = os_zalloc(size);
- if (value == NULL)
- goto error;
- ret = os_snprintf(value, size, "%d",
- entry.int32_value);
- if (os_snprintf_error(size, ret))
- goto error;
- } else
- goto error;
-
- if (wpa_config_set(ssid, entry.key, value, 0) < 0)
- goto error;
-
- if ((os_strcmp(entry.key, "psk") == 0 &&
- value[0] == '"' && ssid->ssid_len) ||
- (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
- wpa_config_update_psk(ssid);
- else if (os_strcmp(entry.key, "priority") == 0)
- wpa_config_update_prio_list(wpa_s->conf);
-
- os_free(value);
- wpa_dbus_dict_entry_clear(&entry);
- continue;
-
- error:
- os_free(value);
- reply = wpas_dbus_new_invalid_opts_error(message, entry.key);
- wpa_dbus_dict_entry_clear(&entry);
- break;
- }
-
- if (!reply)
- reply = wpas_dbus_new_success_reply(message);
-
-out:
- return reply;
-}
-
-
-/**
- * wpas_dbus_iface_enable_network - Mark a configured network as enabled
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "enable" method call of a configured network.
- */
-DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- wpa_supplicant_enable_network(wpa_s, ssid);
- return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_disable_network - Mark a configured network as disabled
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "disable" method call of a configured network.
- */
-DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- wpa_supplicant_disable_network(wpa_s, ssid);
- return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_select_network - Attempt association with a configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "selectNetwork" method call of network interface.
- */
-DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- const char *op;
- struct wpa_ssid *ssid;
- char *iface_obj_path = NULL;
- char *network = NULL;
-
- if (os_strlen(dbus_message_get_signature(message)) == 0) {
- /* Any network */
- ssid = NULL;
- } else {
- int nid;
-
- if (!dbus_message_get_args(message, NULL,
- DBUS_TYPE_OBJECT_PATH, &op,
- DBUS_TYPE_INVALID)) {
- reply = wpas_dbus_new_invalid_opts_error(message,
- NULL);
- goto out;
- }
-
- /* Extract the network number */
- iface_obj_path = wpas_dbus_decompose_object_path(op,
- &network,
- NULL);
- if (iface_obj_path == NULL) {
- reply = wpas_dbus_new_invalid_iface_error(message);
- goto out;
- }
- /* Ensure the object path really points to this interface */
- if (network == NULL || !wpa_s->dbus_path ||
- os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) {
- reply = wpas_dbus_new_invalid_network_error(message);
- goto out;
- }
-
- nid = strtoul(network, NULL, 10);
- if (errno == EINVAL) {
- reply = wpas_dbus_new_invalid_network_error(message);
- goto out;
- }
-
- ssid = wpa_config_get_network(wpa_s->conf, nid);
- if (ssid == NULL) {
- reply = wpas_dbus_new_invalid_network_error(message);
- goto out;
- }
- }
-
- /* Finally, associate with the network */
- wpa_supplicant_select_network(wpa_s, ssid);
-
- reply = wpas_dbus_new_success_reply(message);
-
-out:
- os_free(iface_obj_path);
- os_free(network);
- return reply;
-}
-
-
-/**
- * wpas_dbus_iface_disconnect - Terminate the current connection
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "disconnect" method call of network interface.
- */
-DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- wpas_request_disconnection(wpa_s);
-
- return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_set_ap_scan - Control roaming mode
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "setAPScan" method call.
- */
-DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- dbus_uint32_t ap_scan = 1;
-
- if (!dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &ap_scan,
- DBUS_TYPE_INVALID)) {
- reply = wpas_dbus_new_invalid_opts_error(message, NULL);
- goto out;
- }
-
- if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
- reply = wpas_dbus_new_invalid_opts_error(message, NULL);
- goto out;
- }
-
- reply = wpas_dbus_new_success_reply(message);
-
-out:
- return reply;
-}
-
-
-/**
- * wpas_dbus_iface_set_smartcard_modules - Set smartcard related module paths
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "setSmartcardModules" method call.
- */
-DBusMessage * wpas_dbus_iface_set_smartcard_modules(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter, iter_dict;
- char *opensc_engine_path = NULL;
- char *pkcs11_engine_path = NULL;
- char *pkcs11_module_path = NULL;
- struct wpa_dbus_dict_entry entry;
-
- if (!dbus_message_iter_init(message, &iter))
- goto error;
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
- if (!strcmp(entry.key, "opensc_engine_path") &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(opensc_engine_path);
- opensc_engine_path = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (opensc_engine_path == NULL)
- goto error;
- } else if (!strcmp(entry.key, "pkcs11_engine_path") &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(pkcs11_engine_path);
- pkcs11_engine_path = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (pkcs11_engine_path == NULL)
- goto error;
- } else if (!strcmp(entry.key, "pkcs11_module_path") &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(pkcs11_module_path);
- pkcs11_module_path = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (pkcs11_module_path == NULL)
- goto error;
- } else {
- wpa_dbus_dict_entry_clear(&entry);
- goto error;
- }
- }
-
- os_free(wpa_s->conf->opensc_engine_path);
- wpa_s->conf->opensc_engine_path = opensc_engine_path;
- os_free(wpa_s->conf->pkcs11_engine_path);
- wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path;
- os_free(wpa_s->conf->pkcs11_module_path);
- wpa_s->conf->pkcs11_module_path = pkcs11_module_path;
-
- wpa_sm_set_eapol(wpa_s->wpa, NULL);
- eapol_sm_deinit(wpa_s->eapol);
- wpa_s->eapol = NULL;
- wpa_supplicant_init_eapol(wpa_s);
- wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
-
- return wpas_dbus_new_success_reply(message);
-
-error:
- os_free(opensc_engine_path);
- os_free(pkcs11_engine_path);
- os_free(pkcs11_module_path);
- return wpas_dbus_new_invalid_opts_error(message, NULL);
-}
-
-
-/**
- * wpas_dbus_iface_get_state - Get interface state
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a STRING representing the current
- * interface state
- *
- * Handler function for "state" method call.
- */
-DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- const char *str_state;
-
- reply = dbus_message_new_method_return(message);
- if (reply != NULL) {
- str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_state,
- DBUS_TYPE_INVALID);
- }
-
- return reply;
-}
-
-
-/**
- * wpas_dbus_iface_get_scanning - Get interface scanning state
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing whether the interface is scanning
- *
- * Handler function for "scanning" method call.
- */
-DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
-
- reply = dbus_message_new_method_return(message);
- if (reply != NULL) {
- dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &scanning,
- DBUS_TYPE_INVALID);
- } else {
- wpa_printf(MSG_ERROR,
- "dbus: Not enough memory to return scanning state");
- }
-
- return reply;
-}
-
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
-
-/**
- * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates)
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Asks wpa_supplicant to internally store a one or more binary blobs.
- */
-DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
- DBusMessageIter iter, iter_dict;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- return wpas_dbus_new_invalid_opts_error(message, NULL);
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- struct wpa_config_blob *blob;
-
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
- reply = wpas_dbus_new_invalid_opts_error(message,
- NULL);
- break;
- }
-
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != DBUS_TYPE_BYTE) {
- reply = wpas_dbus_new_invalid_opts_error(
- message, "Byte array expected.");
- break;
- }
-
- if ((entry.array_len <= 0) || (entry.array_len > 65536) ||
- !strlen(entry.key)) {
- reply = wpas_dbus_new_invalid_opts_error(
- message, "Invalid array size.");
- break;
- }
-
- blob = os_zalloc(sizeof(*blob));
- if (blob == NULL) {
- reply = dbus_message_new_error(
- message, WPAS_ERROR_ADD_ERROR,
- "Not enough memory to add blob.");
- break;
- }
- blob->data = os_zalloc(entry.array_len);
- if (blob->data == NULL) {
- reply = dbus_message_new_error(
- message, WPAS_ERROR_ADD_ERROR,
- "Not enough memory to add blob data.");
- os_free(blob);
- break;
- }
-
- blob->name = os_strdup(entry.key);
- blob->len = entry.array_len;
- os_memcpy(blob->data, (u8 *) entry.bytearray_value,
- entry.array_len);
- if (blob->name == NULL) {
- wpa_config_free_blob(blob);
- reply = dbus_message_new_error(
- message, WPAS_ERROR_ADD_ERROR,
- "Error adding blob.");
- break;
- }
-
- /* Success */
- if (!wpa_config_remove_blob(wpa_s->conf, blob->name))
- wpas_notify_blob_removed(wpa_s, blob->name);
- wpa_config_set_blob(wpa_s->conf, blob);
- wpas_notify_blob_added(wpa_s, blob->name);
-
- wpa_dbus_dict_entry_clear(&entry);
- }
- wpa_dbus_dict_entry_clear(&entry);
-
- return reply ? reply : wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_remove_blob - Remove named binary blobs
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Asks wpa_supplicant to remove one or more previously stored binary blobs.
- */
-DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter, array;
- char *err_msg = NULL;
-
- dbus_message_iter_init(message, &iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING)
- return wpas_dbus_new_invalid_opts_error(message, NULL);
-
- dbus_message_iter_recurse(&iter, &array);
- while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
- const char *name;
-
- dbus_message_iter_get_basic(&array, &name);
- if (!os_strlen(name))
- err_msg = "Invalid blob name.";
- else if (wpa_config_remove_blob(wpa_s->conf, name) != 0)
- err_msg = "Error removing blob.";
- else
- wpas_notify_blob_removed(wpa_s, name);
- dbus_message_iter_next(&array);
- }
-
- if (err_msg)
- return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR,
- err_msg);
-
- return wpas_dbus_new_success_reply(message);
-}
-
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-
-
-/**
- * wpas_dbus_iface_flush - Clear BSS of old or all inactive entries
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- * failure (0), or returns a dbus error message with more information
- *
- * Handler function for "flush" method call. Handles requests for an
- * interface with an optional "age" parameter that specifies the minimum
- * age of a BSS to be flushed.
- */
-DBusMessage * wpas_dbus_iface_flush(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- int flush_age = 0;
-
- if (os_strlen(dbus_message_get_signature(message)) != 0 &&
- !dbus_message_get_args(message, NULL,
- DBUS_TYPE_INT32, &flush_age,
- DBUS_TYPE_INVALID)) {
- return wpas_dbus_new_invalid_opts_error(message, NULL);
- }
-
- if (flush_age == 0)
- wpa_bss_flush(wpa_s);
- else
- wpa_bss_flush_by_age(wpa_s, flush_age);
-
- return wpas_dbus_new_success_reply(message);
-}
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.h b/wpa_supplicant/dbus/dbus_old_handlers.h
deleted file mode 100644
index e60ad06..0000000
--- a/wpa_supplicant/dbus/dbus_old_handlers.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef CTRL_IFACE_DBUS_HANDLERS_H
-#define CTRL_IFACE_DBUS_HANDLERS_H
-
-struct wpa_bss;
-
-DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message);
-DBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message);
-
-DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
- struct wpa_global *global);
-
-DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
- struct wpa_global *global);
-
-DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,
- struct wpa_global *global);
-
-DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message,
- struct wpa_global *global);
-
-DBusMessage * wpas_dbus_iface_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss);
-
-DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-
-DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-
-DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-
-DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_set_smartcard_modules(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_flush(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message);
-DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message,
- const char *arg);
-
-#endif /* CTRL_IFACE_DBUS_HANDLERS_H */
-
diff --git a/wpa_supplicant/dbus/dbus_old_handlers_wps.c b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
deleted file mode 100644
index 987e12d..0000000
--- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface (WPS)
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include <dbus/dbus.h>
-
-#include "common.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../wps_supplicant.h"
-#include "dbus_old.h"
-#include "dbus_old_handlers.h"
-
-/**
- * wpas_dbus_iface_wps_pbc - Request credentials using WPS PBC method
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "wpsPbc" method call
- */
-DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- char *arg_bssid = NULL;
- u8 bssid[ETH_ALEN];
- int ret = 0;
-
- if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
- DBUS_TYPE_INVALID))
- return wpas_dbus_new_invalid_opts_error(message, NULL);
-
- if (os_strcmp(arg_bssid, "any") == 0)
- ret = wpas_wps_start_pbc(wpa_s, NULL, 0);
- else if (!hwaddr_aton(arg_bssid, bssid))
- ret = wpas_wps_start_pbc(wpa_s, bssid, 0);
- else {
- return wpas_dbus_new_invalid_opts_error(message,
- "Invalid BSSID");
- }
-
- if (ret < 0) {
- return dbus_message_new_error(
- message, WPAS_ERROR_WPS_PBC_ERROR,
- "Could not start PBC negotiation");
- }
-
- return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_wps_pin - Establish the PIN number of the enrollee
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "wpsPin" method call
- */
-DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- char *arg_bssid;
- char *pin = NULL;
- u8 bssid[ETH_ALEN], *_bssid = NULL;
- int ret;
- char npin[9];
-
- if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
- DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
- return wpas_dbus_new_invalid_opts_error(message, NULL);
-
- if (os_strcmp(arg_bssid, "any") == 0)
- _bssid = NULL;
- else if (!hwaddr_aton(arg_bssid, bssid))
- _bssid = bssid;
- else {
- return wpas_dbus_new_invalid_opts_error(message,
- "Invalid BSSID");
- }
-
- if (os_strlen(pin) > 0)
- ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
- DEV_PW_DEFAULT);
- else
- ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0,
- DEV_PW_DEFAULT);
-
- if (ret < 0) {
- return dbus_message_new_error(message,
- WPAS_ERROR_WPS_PIN_ERROR,
- "Could not init PIN");
- }
-
- reply = dbus_message_new_method_return(message);
- if (reply == NULL)
- return NULL;
-
- if (ret > 0) {
- ret = os_snprintf(npin, sizeof(npin), "%08d", ret);
- if (os_snprintf_error(sizeof(npin), ret))
- return wpas_dbus_new_invalid_opts_error(message,
- "invalid PIN");
-
- pin = npin;
- }
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin,
- DBUS_TYPE_INVALID);
- return reply;
-}
-
-
-/**
- * wpas_dbus_iface_wps_reg - Request credentials using the PIN of the AP
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- * failure (0)
- *
- * Handler function for "wpsReg" method call
- */
-DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- char *arg_bssid;
- char *pin = NULL;
- u8 bssid[ETH_ALEN];
- int ret = 0;
-
- if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
- DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
- return wpas_dbus_new_invalid_opts_error(message, NULL);
-
- if (!hwaddr_aton(arg_bssid, bssid))
- ret = wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
- else {
- return wpas_dbus_new_invalid_opts_error(message,
- "Invalid BSSID");
- }
-
- if (ret < 0) {
- return dbus_message_new_error(message,
- WPAS_ERROR_WPS_REG_ERROR,
- "Could not request credentials");
- }
-
- return wpas_dbus_new_success_reply(message);
-}
diff --git a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in
deleted file mode 100644
index a75918f..0000000
--- a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in
+++ /dev/null
@@ -1,5 +0,0 @@
-[D-BUS Service]
-Name=fi.epitest.hostap.WPASupplicant
-Exec=@BINDIR@/wpa_supplicant -u
-User=root
-SystemdService=wpa_supplicant.service
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index b51675b..88cd790 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -109,10 +109,7 @@ CONFIG_EAP_PEAP=y
CONFIG_EAP_TTLS=y
# EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
-#CONFIG_EAP_FAST=y
+CONFIG_EAP_FAST=y
# EAP-GTC
CONFIG_EAP_GTC=y
@@ -127,10 +124,10 @@ CONFIG_EAP_OTP=y
#CONFIG_EAP_PSK=y
# EAP-pwd (secure authentication using only a password)
-#CONFIG_EAP_PWD=y
+CONFIG_EAP_PWD=y
# EAP-PAX
-#CONFIG_EAP_PAX=y
+CONFIG_EAP_PAX=y
# LEAP
CONFIG_EAP_LEAP=y
@@ -146,18 +143,18 @@ CONFIG_EAP_LEAP=y
#CONFIG_USIM_SIMULATOR=y
# EAP-SAKE
-#CONFIG_EAP_SAKE=y
+CONFIG_EAP_SAKE=y
# EAP-GPSK
-#CONFIG_EAP_GPSK=y
+CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
-#CONFIG_EAP_GPSK_SHA256=y
+CONFIG_EAP_GPSK_SHA256=y
# EAP-TNC and related Trusted Network Connect support (experimental)
-#CONFIG_EAP_TNC=y
+CONFIG_EAP_TNC=y
# Wi-Fi Protected Setup (WPS)
-#CONFIG_WPS=y
+CONFIG_WPS=y
# Enable WPS external registrar functionality
#CONFIG_WPS_ER=y
# Disable credentials for an open network by default when acting as a WPS
@@ -167,7 +164,7 @@ CONFIG_EAP_LEAP=y
#CONFIG_WPS_NFC=y
# EAP-IKEv2
-#CONFIG_EAP_IKEV2=y
+CONFIG_EAP_IKEV2=y
# EAP-EKE
#CONFIG_EAP_EKE=y
@@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+CONFIG_SAE=y
+
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
@@ -299,7 +299,7 @@ CONFIG_BACKEND=file
# IEEE 802.11w (management frame protection), also known as PMF
# Driver support is also needed for IEEE 802.11w.
-#CONFIG_IEEE80211W=y
+CONFIG_IEEE80211W=y
# Support Operating Channel Validation
#CONFIG_OCV=y
@@ -352,16 +352,12 @@ CONFIG_BACKEND=file
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
-#CONFIG_CTRL_IFACE_DBUS_NEW=y
+CONFIG_CTRL_IFACE_DBUS_NEW=y
# Add introspection support for new DBus control interface
-#CONFIG_CTRL_IFACE_DBUS_INTRO=y
+CONFIG_CTRL_IFACE_DBUS_INTRO=y
# Add support for loading EAP methods dynamically as shared libraries.
# When this option is enabled, each EAP method can be either included
@@ -385,13 +381,13 @@ CONFIG_BACKEND=file
#CONFIG_DYNAMIC_EAP_METHODS=y
# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
-#CONFIG_IEEE80211R=y
+CONFIG_IEEE80211R=y
# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
-#CONFIG_DEBUG_FILE=y
+CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
-#CONFIG_DEBUG_SYSLOG=y
+CONFIG_DEBUG_SYSLOG=y
# Set syslog facility for debug messages
#CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
@@ -467,11 +463,11 @@ CONFIG_BACKEND=file
#CONFIG_GETRANDOM=y
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
-#CONFIG_IEEE80211N=y
+CONFIG_IEEE80211N=y
# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
# (depends on CONFIG_IEEE80211N)
-#CONFIG_IEEE80211AC=y
+CONFIG_IEEE80211AC=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
@@ -481,10 +477,10 @@ CONFIG_BACKEND=file
# This can be used to enable functionality to improve interworking with
# external networks (GAS/ANQP to learn more about the networks and network
# selection based on available credentials).
-#CONFIG_INTERWORKING=y
+CONFIG_INTERWORKING=y
# Hotspot 2.0
-#CONFIG_HS20=y
+CONFIG_HS20=y
# Enable interface matching in wpa_supplicant
#CONFIG_MATCH_IFACE=y
@@ -497,20 +493,20 @@ CONFIG_BACKEND=file
# should be noted that this is mainly aimed at simple cases like
# WPA2-Personal while more complex configurations like WPA2-Enterprise with an
# external RADIUS server can be supported with hostapd.
-#CONFIG_AP=y
+CONFIG_AP=y
# P2P (Wi-Fi Direct)
# This can be used to enable P2P support in wpa_supplicant. See README-P2P for
# more information on P2P operations.
-#CONFIG_P2P=y
+CONFIG_P2P=y
# Enable TDLS support
#CONFIG_TDLS=y
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
-#CONFIG_WIFI_DISPLAY=y
+CONFIG_WIFI_DISPLAY=y
# Autoscan
# This can be used to enable automatic scan support in wpa_supplicant.
@@ -576,7 +572,7 @@ CONFIG_BACKEND=file
# Support RSN on IBSS networks
# This is needed to be able to use mode=1 network profile with proto=RSN and
# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
-#CONFIG_IBSS_RSN=y
+CONFIG_IBSS_RSN=y
# External PMKSA cache control
# This can be used to enable control interface commands that allow the current
@@ -591,7 +587,7 @@ CONFIG_BACKEND=file
# operations for roaming within an ESS (same SSID). See the bgscan parameter in
# the wpa_supplicant.conf file for more details.
# Periodic background scans based on signal strength
-#CONFIG_BGSCAN_SIMPLE=y
+CONFIG_BGSCAN_SIMPLE=y
# Learn channels used by the network and try to avoid bgscans on other
# channels (experimental)
#CONFIG_BGSCAN_LEARN=y
@@ -599,3 +595,8 @@ CONFIG_BACKEND=file
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
+
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+CONFIG_DPP=y
diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
index ebf102e..aaff150 100644
--- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
@@ -471,7 +471,7 @@
<para>Enable DBus control interface. If enabled, interface
definitions may be omitted. (This is only available
if <command>wpa_supplicant</command> was built with
- the <literal>CONFIG_DBUS</literal> option.)</para>
+ the <literal>CONFIG_CTRL_IFACE_DBUS_NEW</literal> option.)</para>
</listitem>
</varlistentry>
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index 7bc4661..e003a85 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -1,7 +1,7 @@
/*
* wpa_supplicant - DPP
* Copyright (c) 2017, Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation
+ * Copyright (c) 2018-2019, The Linux Foundation
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -52,34 +52,6 @@ static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static const u8 TRANSACTION_ID = 1;
-static struct dpp_configurator *
-dpp_configurator_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
-{
- struct dpp_configurator *conf;
-
- dl_list_for_each(conf, &wpa_s->dpp_configurator,
- struct dpp_configurator, list) {
- if (conf->id == id)
- return conf;
- }
- return NULL;
-}
-
-
-static unsigned int wpas_dpp_next_id(struct wpa_supplicant *wpa_s)
-{
- struct dpp_bootstrap_info *bi;
- unsigned int max_id = 0;
-
- dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
- list) {
- if (bi->id > max_id)
- max_id = bi->id;
- }
- return max_id + 1;
-}
-
-
/**
* wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
* @wpa_s: Pointer to wpa_supplicant data
@@ -91,13 +63,10 @@ int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd)
struct dpp_bootstrap_info *bi;
struct dpp_authentication *auth = wpa_s->dpp_auth;
- bi = dpp_parse_qr_code(cmd);
+ bi = dpp_add_qr_code(wpa_s->dpp, cmd);
if (!bi)
return -1;
- bi->id = wpas_dpp_next_id(wpa_s);
- dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
-
if (auth && auth->response_pending &&
dpp_notify_new_qr_code(auth, bi) == 1) {
wpa_printf(MSG_DEBUG,
@@ -118,195 +87,6 @@ int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd)
}
-static char * get_param(const char *cmd, const char *param)
-{
- const char *pos, *end;
- char *val;
- size_t len;
-
- pos = os_strstr(cmd, param);
- if (!pos)
- return NULL;
-
- pos += os_strlen(param);
- end = os_strchr(pos, ' ');
- if (end)
- len = end - pos;
- else
- len = os_strlen(pos);
- val = os_malloc(len + 1);
- if (!val)
- return NULL;
- os_memcpy(val, pos, len);
- val[len] = '\0';
- return val;
-}
-
-
-int wpas_dpp_bootstrap_gen(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- char *chan = NULL, *mac = NULL, *info = NULL, *pk = NULL, *curve = NULL;
- char *key = NULL;
- u8 *privkey = NULL;
- size_t privkey_len = 0;
- size_t len;
- int ret = -1;
- struct dpp_bootstrap_info *bi;
-
- bi = os_zalloc(sizeof(*bi));
- if (!bi)
- goto fail;
-
- if (os_strstr(cmd, "type=qrcode"))
- bi->type = DPP_BOOTSTRAP_QR_CODE;
- else if (os_strstr(cmd, "type=pkex"))
- bi->type = DPP_BOOTSTRAP_PKEX;
- else
- goto fail;
-
- chan = get_param(cmd, " chan=");
- mac = get_param(cmd, " mac=");
- info = get_param(cmd, " info=");
- curve = get_param(cmd, " curve=");
- key = get_param(cmd, " key=");
-
- if (key) {
- privkey_len = os_strlen(key) / 2;
- privkey = os_malloc(privkey_len);
- if (!privkey ||
- hexstr2bin(key, privkey, privkey_len) < 0)
- goto fail;
- }
-
- pk = dpp_keygen(bi, curve, privkey, privkey_len);
- if (!pk)
- goto fail;
-
- len = 4; /* "DPP:" */
- if (chan) {
- if (dpp_parse_uri_chan_list(bi, chan) < 0)
- goto fail;
- len += 3 + os_strlen(chan); /* C:...; */
- }
- if (mac) {
- if (dpp_parse_uri_mac(bi, mac) < 0)
- goto fail;
- len += 3 + os_strlen(mac); /* M:...; */
- }
- if (info) {
- if (dpp_parse_uri_info(bi, info) < 0)
- goto fail;
- len += 3 + os_strlen(info); /* I:...; */
- }
- len += 4 + os_strlen(pk);
- bi->uri = os_malloc(len + 1);
- if (!bi->uri)
- goto fail;
- os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;",
- chan ? "C:" : "", chan ? chan : "", chan ? ";" : "",
- mac ? "M:" : "", mac ? mac : "", mac ? ";" : "",
- info ? "I:" : "", info ? info : "", info ? ";" : "",
- pk);
- bi->id = wpas_dpp_next_id(wpa_s);
- dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
- ret = bi->id;
- bi = NULL;
-fail:
- os_free(curve);
- os_free(pk);
- os_free(chan);
- os_free(mac);
- os_free(info);
- str_clear_free(key);
- bin_clear_free(privkey, privkey_len);
- dpp_bootstrap_info_free(bi);
- return ret;
-}
-
-
-static struct dpp_bootstrap_info *
-dpp_bootstrap_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
-{
- struct dpp_bootstrap_info *bi;
-
- dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
- list) {
- if (bi->id == id)
- return bi;
- }
- return NULL;
-}
-
-
-static int dpp_bootstrap_del(struct wpa_supplicant *wpa_s, unsigned int id)
-{
- struct dpp_bootstrap_info *bi, *tmp;
- int found = 0;
-
- dl_list_for_each_safe(bi, tmp, &wpa_s->dpp_bootstrap,
- struct dpp_bootstrap_info, list) {
- if (id && bi->id != id)
- continue;
- found = 1;
- dl_list_del(&bi->list);
- dpp_bootstrap_info_free(bi);
- }
-
- if (id == 0)
- return 0; /* flush succeeds regardless of entries found */
- return found ? 0 : -1;
-}
-
-
-int wpas_dpp_bootstrap_remove(struct wpa_supplicant *wpa_s, const char *id)
-{
- unsigned int id_val;
-
- if (os_strcmp(id, "*") == 0) {
- id_val = 0;
- } else {
- id_val = atoi(id);
- if (id_val == 0)
- return -1;
- }
-
- return dpp_bootstrap_del(wpa_s, id_val);
-}
-
-
-const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- struct dpp_bootstrap_info *bi;
-
- bi = dpp_bootstrap_get_id(wpa_s, id);
- if (!bi)
- return NULL;
- return bi->uri;
-}
-
-
-int wpas_dpp_bootstrap_info(struct wpa_supplicant *wpa_s, int id,
- char *reply, int reply_size)
-{
- struct dpp_bootstrap_info *bi;
-
- bi = dpp_bootstrap_get_id(wpa_s, id);
- if (!bi)
- return -1;
- return os_snprintf(reply, reply_size, "type=%s\n"
- "mac_addr=" MACSTR "\n"
- "info=%s\n"
- "num_freq=%u\n"
- "curve=%s\n",
- dpp_bootstrap_type_txt(bi->type),
- MAC2STR(bi->mac_addr),
- bi->info ? bi->info : "",
- bi->num_freq,
- bi->curve->name);
-}
-
-
static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -364,6 +144,18 @@ static void wpas_dpp_auth_resp_retry(struct wpa_supplicant *wpa_s)
}
+static void wpas_dpp_try_to_connect(struct wpa_supplicant *wpa_s)
+{
+ wpa_printf(MSG_DEBUG, "DPP: Trying to connect to the new network");
+ wpa_s->disconnected = 0;
+ wpa_s->reassociate = 1;
+ wpa_s->scan_runs = 0;
+ wpa_s->normal_scans = 0;
+ wpa_supplicant_cancel_sched_scan(wpa_s);
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+}
+
+
static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
unsigned int freq, const u8 *dst,
const u8 *src, const u8 *bssid,
@@ -387,6 +179,17 @@ static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
return;
}
+#ifdef CONFIG_DPP2
+ if (auth->connect_on_tx_status) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: Try to connect after completed configuration result");
+ wpas_dpp_try_to_connect(wpa_s);
+ dpp_auth_deinit(wpa_s->dpp_auth);
+ wpa_s->dpp_auth = NULL;
+ return;
+ }
+#endif /* CONFIG_DPP2 */
+
if (wpa_s->dpp_auth->remove_on_tx_status) {
wpa_printf(MSG_DEBUG,
"DPP: Terminate authentication exchange due to an earlier error");
@@ -527,176 +330,6 @@ static void wpas_dpp_set_testing_options(struct wpa_supplicant *wpa_s,
}
-static int wpas_dpp_set_configurator(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth,
- const char *cmd)
-{
- const char *pos, *end;
- struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL;
- struct dpp_configurator *conf = NULL;
- u8 ssid[32] = { "test" };
- size_t ssid_len = 4;
- char pass[64] = { };
- size_t pass_len = 0;
- u8 psk[PMK_LEN];
- int psk_set = 0;
- char *group_id = NULL;
-
- if (!cmd)
- return 0;
-
- wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd);
- pos = os_strstr(cmd, " ssid=");
- if (pos) {
- pos += 6;
- end = os_strchr(pos, ' ');
- ssid_len = end ? (size_t) (end - pos) : os_strlen(pos);
- ssid_len /= 2;
- if (ssid_len > sizeof(ssid) ||
- hexstr2bin(pos, ssid, ssid_len) < 0)
- goto fail;
- }
-
- pos = os_strstr(cmd, " pass=");
- if (pos) {
- pos += 6;
- end = os_strchr(pos, ' ');
- pass_len = end ? (size_t) (end - pos) : os_strlen(pos);
- pass_len /= 2;
- if (pass_len > sizeof(pass) - 1 || pass_len < 8 ||
- hexstr2bin(pos, (u8 *) pass, pass_len) < 0)
- goto fail;
- }
-
- pos = os_strstr(cmd, " psk=");
- if (pos) {
- pos += 5;
- if (hexstr2bin(pos, psk, PMK_LEN) < 0)
- goto fail;
- psk_set = 1;
- }
-
- pos = os_strstr(cmd, " group_id=");
- if (pos) {
- size_t group_id_len;
-
- pos += 10;
- end = os_strchr(pos, ' ');
- group_id_len = end ? (size_t) (end - pos) : os_strlen(pos);
- group_id = os_malloc(group_id_len + 1);
- if (!group_id)
- goto fail;
- os_memcpy(group_id, pos, group_id_len);
- group_id[group_id_len] = '\0';
- }
-
- if (os_strstr(cmd, " conf=sta-")) {
- conf_sta = os_zalloc(sizeof(struct dpp_configuration));
- if (!conf_sta)
- goto fail;
- os_memcpy(conf_sta->ssid, ssid, ssid_len);
- conf_sta->ssid_len = ssid_len;
- if (os_strstr(cmd, " conf=sta-psk") ||
- os_strstr(cmd, " conf=sta-sae") ||
- os_strstr(cmd, " conf=sta-psk-sae")) {
- if (os_strstr(cmd, " conf=sta-psk-sae"))
- conf_sta->akm = DPP_AKM_PSK_SAE;
- else if (os_strstr(cmd, " conf=sta-sae"))
- conf_sta->akm = DPP_AKM_SAE;
- else
- conf_sta->akm = DPP_AKM_PSK;
- if (psk_set) {
- os_memcpy(conf_sta->psk, psk, PMK_LEN);
- } else if (pass_len > 0) {
- conf_sta->passphrase = os_strdup(pass);
- if (!conf_sta->passphrase)
- goto fail;
- } else {
- goto fail;
- }
- } else if (os_strstr(cmd, " conf=sta-dpp")) {
- conf_sta->akm = DPP_AKM_DPP;
- } else {
- goto fail;
- }
- if (os_strstr(cmd, " group_id=")) {
- conf_sta->group_id = group_id;
- group_id = NULL;
- }
- }
-
- if (os_strstr(cmd, " conf=ap-")) {
- conf_ap = os_zalloc(sizeof(struct dpp_configuration));
- if (!conf_ap)
- goto fail;
- os_memcpy(conf_ap->ssid, ssid, ssid_len);
- conf_ap->ssid_len = ssid_len;
- if (os_strstr(cmd, " conf=ap-psk") ||
- os_strstr(cmd, " conf=ap-sae") ||
- os_strstr(cmd, " conf=ap-psk-sae")) {
- if (os_strstr(cmd, " conf=ap-psk-sae"))
- conf_ap->akm = DPP_AKM_PSK_SAE;
- else if (os_strstr(cmd, " conf=ap-sae"))
- conf_ap->akm = DPP_AKM_SAE;
- else
- conf_ap->akm = DPP_AKM_PSK;
- if (psk_set) {
- os_memcpy(conf_ap->psk, psk, PMK_LEN);
- } else {
- conf_ap->passphrase = os_strdup(pass);
- if (!conf_ap->passphrase)
- goto fail;
- }
- } else if (os_strstr(cmd, " conf=ap-dpp")) {
- conf_ap->akm = DPP_AKM_DPP;
- } else {
- goto fail;
- }
- if (os_strstr(cmd, " group_id=")) {
- conf_ap->group_id = group_id;
- group_id = NULL;
- }
- }
-
- pos = os_strstr(cmd, " expiry=");
- if (pos) {
- long int val;
-
- pos += 8;
- val = strtol(pos, NULL, 0);
- if (val <= 0)
- goto fail;
- if (conf_sta)
- conf_sta->netaccesskey_expiry = val;
- if (conf_ap)
- conf_ap->netaccesskey_expiry = val;
- }
-
- pos = os_strstr(cmd, " configurator=");
- if (pos) {
- pos += 14;
- conf = dpp_configurator_get_id(wpa_s, atoi(pos));
- if (!conf) {
- wpa_printf(MSG_INFO,
- "DPP: Could not find the specified configurator");
- goto fail;
- }
- }
- auth->conf_sta = conf_sta;
- auth->conf_ap = conf_ap;
- auth->conf = conf;
- os_free(group_id);
- return 0;
-
-fail:
- wpa_msg(wpa_s, MSG_INFO, "DPP: Failed to set configurator parameters");
- dpp_configuration_free(conf_sta);
- dpp_configuration_free(conf_ap);
- os_free(group_id);
- return -1;
-}
-
-
static void wpas_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -809,7 +442,7 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
if (!pos)
return -1;
pos += 6;
- peer_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
+ peer_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
if (!peer_bi) {
wpa_printf(MSG_INFO,
"DPP: Could not find bootstrapping info for the identified peer");
@@ -819,7 +452,7 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
pos = os_strstr(cmd, " own=");
if (pos) {
pos += 5;
- own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
+ own_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
if (!own_bi) {
wpa_printf(MSG_INFO,
"DPP: Could not find bootstrapping info for the identified local entry");
@@ -872,7 +505,7 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
if (!wpa_s->dpp_auth)
goto fail;
wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
- if (wpas_dpp_set_configurator(wpa_s, wpa_s->dpp_auth, cmd) < 0) {
+ if (dpp_set_configurator(wpa_s->dpp, wpa_s, wpa_s->dpp_auth, cmd) < 0) {
dpp_auth_deinit(wpa_s->dpp_auth);
wpa_s->dpp_auth = NULL;
goto fail;
@@ -942,6 +575,7 @@ static void dpp_start_listen_cb(struct wpa_radio_work *work, int deinit)
wpa_printf(MSG_DEBUG,
"DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
lwork->freq);
+ wpa_s->dpp_listen_freq = 0;
wpas_dpp_listen_work_done(wpa_s);
wpa_s->dpp_pending_listen_freq = 0;
return;
@@ -1055,7 +689,10 @@ static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
{
const u8 *r_bootstrap, *i_bootstrap;
u16 r_bootstrap_len, i_bootstrap_len;
- struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL;
+ struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
+
+ if (!wpa_s->dpp)
+ return;
wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
MAC2STR(src));
@@ -1082,28 +719,8 @@ static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
/* Try to find own and peer bootstrapping key matches based on the
* received hash values */
- dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
- list) {
- if (!own_bi && bi->own &&
- os_memcmp(bi->pubkey_hash, r_bootstrap,
- SHA256_MAC_LEN) == 0) {
- wpa_printf(MSG_DEBUG,
- "DPP: Found matching own bootstrapping information");
- own_bi = bi;
- }
-
- if (!peer_bi && !bi->own &&
- os_memcmp(bi->pubkey_hash, i_bootstrap,
- SHA256_MAC_LEN) == 0) {
- wpa_printf(MSG_DEBUG,
- "DPP: Found matching peer bootstrapping information");
- peer_bi = bi;
- }
-
- if (own_bi && peer_bi)
- break;
- }
-
+ dpp_bootstrap_find_pair(wpa_s->dpp, i_bootstrap, r_bootstrap,
+ &own_bi, &peer_bi);
if (!own_bi) {
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
"No matching own bootstrapping key found - ignore message");
@@ -1126,8 +743,8 @@ static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
return;
}
wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
- if (wpas_dpp_set_configurator(wpa_s, wpa_s->dpp_auth,
- wpa_s->dpp_configurator_params) < 0) {
+ if (dpp_set_configurator(wpa_s->dpp, wpa_s, wpa_s->dpp_auth,
+ wpa_s->dpp_configurator_params) < 0) {
dpp_auth_deinit(wpa_s->dpp_auth);
wpa_s->dpp_auth = NULL;
return;
@@ -1164,6 +781,27 @@ static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s,
{
struct wpa_ssid *ssid;
+#ifdef CONFIG_DPP2
+ if (auth->akm == DPP_AKM_SAE) {
+#ifdef CONFIG_SAE
+ struct wpa_driver_capa capa;
+ int res;
+
+ res = wpa_drv_get_capa(wpa_s, &capa);
+ if (res == 0 &&
+ !(capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) &&
+ !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: SAE not supported by the driver");
+ return NULL;
+ }
+#else /* CONFIG_SAE */
+ wpa_printf(MSG_DEBUG, "DPP: SAE not supported in the build");
+ return NULL;
+#endif /* CONFIG_SAE */
+ }
+#endif /* CONFIG_DPP2 */
+
ssid = wpa_config_add_network(wpa_s->conf);
if (!ssid)
return NULL;
@@ -1206,12 +844,14 @@ static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s,
ssid->dpp_netaccesskey_expiry = auth->net_access_key_expiry;
}
- if (!auth->connector) {
- ssid->key_mgmt = 0;
- if (auth->akm == DPP_AKM_PSK || auth->akm == DPP_AKM_PSK_SAE)
+ if (!auth->connector || dpp_akm_psk(auth->akm) ||
+ dpp_akm_sae(auth->akm)) {
+ if (!auth->connector)
+ ssid->key_mgmt = 0;
+ if (dpp_akm_psk(auth->akm))
ssid->key_mgmt |= WPA_KEY_MGMT_PSK |
WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_FT_PSK;
- if (auth->akm == DPP_AKM_SAE || auth->akm == DPP_AKM_PSK_SAE)
+ if (dpp_akm_sae(auth->akm))
ssid->key_mgmt |= WPA_KEY_MGMT_SAE |
WPA_KEY_MGMT_FT_SAE;
ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
@@ -1235,35 +875,47 @@ fail:
}
-static void wpas_dpp_process_config(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth)
+static int wpas_dpp_process_config(struct wpa_supplicant *wpa_s,
+ struct dpp_authentication *auth)
{
struct wpa_ssid *ssid;
if (wpa_s->conf->dpp_config_processing < 1)
- return;
+ return 0;
ssid = wpas_dpp_add_network(wpa_s, auth);
if (!ssid)
- return;
+ return -1;
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_NETWORK_ID "%d", ssid->id);
+ if (wpa_s->conf->dpp_config_processing == 2)
+ ssid->disabled = 0;
+
+#ifndef CONFIG_NO_CONFIG_WRITE
+ if (wpa_s->conf->update_config &&
+ wpa_config_write(wpa_s->confname, wpa_s->conf))
+ wpa_printf(MSG_DEBUG, "DPP: Failed to update configuration");
+#endif /* CONFIG_NO_CONFIG_WRITE */
+
if (wpa_s->conf->dpp_config_processing < 2)
- return;
+ return 0;
- wpa_printf(MSG_DEBUG, "DPP: Trying to connect to the new network");
- ssid->disabled = 0;
- wpa_s->disconnected = 0;
- wpa_s->reassociate = 1;
- wpa_s->scan_runs = 0;
- wpa_s->normal_scans = 0;
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
+#ifdef CONFIG_DPP2
+ if (auth->peer_version >= 2) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: Postpone connection attempt to wait for completion of DPP Configuration Result");
+ auth->connect_on_tx_status = 1;
+ return 0;
+ }
+#endif /* CONFIG_DPP2 */
+
+ wpas_dpp_try_to_connect(wpa_s);
+ return 0;
}
-static void wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth)
+static int wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
+ struct dpp_authentication *auth)
{
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
if (auth->ssid_len)
@@ -1315,7 +967,7 @@ static void wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
}
}
- wpas_dpp_process_config(wpa_s, auth);
+ return wpas_dpp_process_config(wpa_s, auth);
}
@@ -1327,6 +979,8 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
struct wpa_supplicant *wpa_s = ctx;
const u8 *pos;
struct dpp_authentication *auth = wpa_s->dpp_auth;
+ int res;
+ enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
wpa_s->dpp_gas_dialog_token = -1;
@@ -1364,13 +1018,46 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
goto fail;
}
- wpas_dpp_handle_config_obj(wpa_s, auth);
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- return;
+ res = wpas_dpp_handle_config_obj(wpa_s, auth);
+ if (res < 0)
+ goto fail;
+ status = DPP_STATUS_OK;
+#ifdef CONFIG_TESTING_OPTIONS
+ if (dpp_test == DPP_TEST_REJECT_CONFIG) {
+ wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
+ status = DPP_STATUS_CONFIG_REJECTED;
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
fail:
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
+ if (status != DPP_STATUS_OK)
+ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
+#ifdef CONFIG_DPP2
+ if (auth->peer_version >= 2 &&
+ auth->conf_resp_status == DPP_STATUS_OK) {
+ struct wpabuf *msg;
+
+ wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
+ msg = dpp_build_conf_result(auth, status);
+ if (!msg)
+ goto fail2;
+
+ wpa_msg(wpa_s, MSG_INFO,
+ DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
+ MAC2STR(addr), auth->curr_freq,
+ DPP_PA_CONFIGURATION_RESULT);
+ offchannel_send_action(wpa_s, auth->curr_freq,
+ addr, wpa_s->own_addr, broadcast,
+ wpabuf_head(msg),
+ wpabuf_len(msg),
+ 500, wpas_dpp_tx_status, 0);
+ wpabuf_free(msg);
+
+ /* This exchange will be terminated in the TX status handler */
+ return;
+ }
+fail2:
+#endif /* CONFIG_DPP2 */
dpp_auth_deinit(wpa_s->dpp_auth);
wpa_s->dpp_auth = NULL;
}
@@ -1379,7 +1066,7 @@ fail:
static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s)
{
struct dpp_authentication *auth = wpa_s->dpp_auth;
- struct wpabuf *buf, *conf_req;
+ struct wpabuf *buf;
char json[100];
int res;
@@ -1400,34 +1087,13 @@ static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s)
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s);
- conf_req = dpp_build_conf_req(auth, json);
- if (!conf_req) {
+ buf = dpp_build_conf_req(auth, json);
+ if (!buf) {
wpa_printf(MSG_DEBUG,
"DPP: No configuration request data available");
return;
}
- buf = gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req));
- if (!buf) {
- wpabuf_free(conf_req);
- return;
- }
-
- /* Advertisement Protocol IE */
- wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO);
- wpabuf_put_u8(buf, 8); /* Length */
- wpabuf_put_u8(buf, 0x7f);
- wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
- wpabuf_put_u8(buf, 5);
- wpabuf_put_be24(buf, OUI_WFA);
- wpabuf_put_u8(buf, DPP_OUI_TYPE);
- wpabuf_put_u8(buf, 0x01);
-
- /* GAS Query */
- wpabuf_put_le16(buf, wpabuf_len(conf_req));
- wpabuf_put_buf(buf, conf_req);
- wpabuf_free(conf_req);
-
wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
MAC2STR(auth->peer_mac_addr), auth->curr_freq);
@@ -1553,6 +1219,62 @@ static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
}
+#ifdef CONFIG_DPP2
+
+static void wpas_dpp_config_result_wait_timeout(void *eloop_ctx,
+ void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+ if (!auth || !auth->waiting_conf_result)
+ return;
+
+ wpa_printf(MSG_DEBUG,
+ "DPP: Timeout while waiting for Configuration Result");
+ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
+ dpp_auth_deinit(auth);
+ wpa_s->dpp_auth = NULL;
+}
+
+
+static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src,
+ const u8 *hdr, const u8 *buf, size_t len)
+{
+ struct dpp_authentication *auth = wpa_s->dpp_auth;
+ enum dpp_status_error status;
+
+ wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
+ MAC2STR(src));
+
+ if (!auth || !auth->waiting_conf_result) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: No DPP Configuration waiting for result - drop");
+ return;
+ }
+
+ if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
+ wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
+ MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
+ return;
+ }
+
+ status = dpp_conf_result_rx(auth, hdr, buf, len);
+
+ offchannel_send_action_done(wpa_s);
+ wpas_dpp_listen_stop(wpa_s);
+ if (status == DPP_STATUS_OK)
+ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_SENT);
+ else
+ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
+ dpp_auth_deinit(auth);
+ wpa_s->dpp_auth = NULL;
+ eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
+}
+
+#endif /* CONFIG_DPP2 */
+
+
static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
const u8 *src,
const u8 *buf, size_t len)
@@ -1913,27 +1635,12 @@ static struct dpp_bootstrap_info *
wpas_dpp_pkex_finish(struct wpa_supplicant *wpa_s, const u8 *peer,
unsigned int freq)
{
- struct dpp_pkex *pkex = wpa_s->dpp_pkex;
struct dpp_bootstrap_info *bi;
- bi = os_zalloc(sizeof(*bi));
+ bi = dpp_pkex_finish(wpa_s->dpp, wpa_s->dpp_pkex, peer, freq);
if (!bi)
return NULL;
- bi->id = wpas_dpp_next_id(wpa_s);
- bi->type = DPP_BOOTSTRAP_PKEX;
- os_memcpy(bi->mac_addr, peer, ETH_ALEN);
- bi->num_freq = 1;
- bi->freq[0] = freq;
- bi->curve = pkex->own_bi->curve;
- bi->pubkey = pkex->peer_bootstrap_key;
- pkex->peer_bootstrap_key = NULL;
- dpp_pkex_free(pkex);
wpa_s->dpp_pkex = NULL;
- if (dpp_bootstrap_key_hash(bi) < 0) {
- dpp_bootstrap_info_free(bi);
- return NULL;
- }
- dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
return bi;
}
@@ -2096,6 +1803,11 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s, src, hdr, buf, len,
freq);
break;
+#ifdef CONFIG_DPP2
+ case DPP_PA_CONFIGURATION_RESULT:
+ wpas_dpp_rx_conf_result(wpa_s, src, hdr, buf, len);
+ break;
+#endif /* CONFIG_DPP2 */
default:
wpa_printf(MSG_DEBUG,
"DPP: Ignored unsupported frame subtype %d", type);
@@ -2165,6 +1877,21 @@ wpas_dpp_gas_status_handler(void *ctx, struct wpabuf *resp, int ok)
ok);
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
+#ifdef CONFIG_DPP2
+ if (ok && auth->peer_version >= 2 &&
+ auth->conf_resp_status == DPP_STATUS_OK) {
+ wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
+ auth->waiting_conf_result = 1;
+ auth->conf_resp = NULL;
+ wpabuf_free(resp);
+ eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout,
+ wpa_s, NULL);
+ eloop_register_timeout(2, 0,
+ wpas_dpp_config_result_wait_timeout,
+ wpa_s, NULL);
+ return;
+ }
+#endif /* CONFIG_DPP2 */
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s);
if (ok)
@@ -2177,93 +1904,6 @@ wpas_dpp_gas_status_handler(void *ctx, struct wpabuf *resp, int ok)
}
-static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant *wpa_s)
-{
- struct dpp_configurator *conf;
- unsigned int max_id = 0;
-
- dl_list_for_each(conf, &wpa_s->dpp_configurator,
- struct dpp_configurator, list) {
- if (conf->id > max_id)
- max_id = conf->id;
- }
- return max_id + 1;
-}
-
-
-int wpas_dpp_configurator_add(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- char *curve = NULL;
- char *key = NULL;
- u8 *privkey = NULL;
- size_t privkey_len = 0;
- int ret = -1;
- struct dpp_configurator *conf = NULL;
-
- curve = get_param(cmd, " curve=");
- key = get_param(cmd, " key=");
-
- if (key) {
- privkey_len = os_strlen(key) / 2;
- privkey = os_malloc(privkey_len);
- if (!privkey ||
- hexstr2bin(key, privkey, privkey_len) < 0)
- goto fail;
- }
-
- conf = dpp_keygen_configurator(curve, privkey, privkey_len);
- if (!conf)
- goto fail;
-
- conf->id = wpas_dpp_next_configurator_id(wpa_s);
- dl_list_add(&wpa_s->dpp_configurator, &conf->list);
- ret = conf->id;
- conf = NULL;
-fail:
- os_free(curve);
- str_clear_free(key);
- bin_clear_free(privkey, privkey_len);
- dpp_configurator_free(conf);
- return ret;
-}
-
-
-static int dpp_configurator_del(struct wpa_supplicant *wpa_s, unsigned int id)
-{
- struct dpp_configurator *conf, *tmp;
- int found = 0;
-
- dl_list_for_each_safe(conf, tmp, &wpa_s->dpp_configurator,
- struct dpp_configurator, list) {
- if (id && conf->id != id)
- continue;
- found = 1;
- dl_list_del(&conf->list);
- dpp_configurator_free(conf);
- }
-
- if (id == 0)
- return 0; /* flush succeeds regardless of entries found */
- return found ? 0 : -1;
-}
-
-
-int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id)
-{
- unsigned int id_val;
-
- if (os_strcmp(id, "*") == 0) {
- id_val = 0;
- } else {
- id_val = atoi(id);
- if (id_val == 0)
- return -1;
- }
-
- return dpp_configurator_del(wpa_s, id_val);
-}
-
-
int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd)
{
struct dpp_authentication *auth;
@@ -2276,11 +1916,9 @@ int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd)
curve = get_param(cmd, " curve=");
wpas_dpp_set_testing_options(wpa_s, auth);
- if (wpas_dpp_set_configurator(wpa_s, auth, cmd) == 0 &&
- dpp_configurator_own_config(auth, curve, 0) == 0) {
- wpas_dpp_handle_config_obj(wpa_s, auth);
- ret = 0;
- }
+ if (dpp_set_configurator(wpa_s->dpp, wpa_s, auth, cmd) == 0 &&
+ dpp_configurator_own_config(auth, curve, 0) == 0)
+ ret = wpas_dpp_handle_config_obj(wpa_s, auth);
dpp_auth_deinit(auth);
os_free(curve);
@@ -2289,19 +1927,6 @@ int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd)
}
-int wpas_dpp_configurator_get_key(struct wpa_supplicant *wpa_s, unsigned int id,
- char *buf, size_t buflen)
-{
- struct dpp_configurator *conf;
-
- conf = dpp_configurator_get_id(wpa_s, id);
- if (!conf)
- return -1;
-
- return dpp_configurator_get_key(conf, buf, buflen);
-}
-
-
static void
wpas_dpp_tx_introduction_status(struct wpa_supplicant *wpa_s,
unsigned int freq, const u8 *dst,
@@ -2329,9 +1954,15 @@ int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
struct os_time now;
struct wpabuf *msg;
unsigned int wait_time;
+ const u8 *rsn;
+ struct wpa_ie_data ied;
if (!(ssid->key_mgmt & WPA_KEY_MGMT_DPP) || !bss)
return 0; /* Not using DPP AKM - continue */
+ rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
+ !(ied.key_mgmt & WPA_KEY_MGMT_DPP))
+ return 0; /* AP does not support DPP AKM - continue */
if (wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, ssid))
return 0; /* PMKSA exists for DPP AKM - continue */
@@ -2444,7 +2075,7 @@ int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd)
if (!pos)
return -1;
pos += 5;
- own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
+ own_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
if (!own_bi) {
wpa_printf(MSG_DEBUG,
"DPP: Identified bootstrap info not found");
@@ -2577,10 +2208,8 @@ int wpas_dpp_init(struct wpa_supplicant *wpa_s)
sizeof(adv_proto_id), wpas_dpp_gas_req_handler,
wpas_dpp_gas_status_handler, wpa_s) < 0)
return -1;
- dl_list_init(&wpa_s->dpp_bootstrap);
- dl_list_init(&wpa_s->dpp_configurator);
- wpa_s->dpp_init_done = 1;
- return 0;
+ wpa_s->dpp = dpp_global_init();
+ return wpa_s->dpp ? 0 : -1;
}
@@ -2595,16 +2224,20 @@ void wpas_dpp_deinit(struct wpa_supplicant *wpa_s)
wpa_s->dpp_groups_override = NULL;
wpa_s->dpp_ignore_netaccesskey_mismatch = 0;
#endif /* CONFIG_TESTING_OPTIONS */
- if (!wpa_s->dpp_init_done)
+ if (!wpa_s->dpp)
return;
+ dpp_global_clear(wpa_s->dpp);
eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
+#ifdef CONFIG_DPP2
+ eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
+ dpp_pfs_free(wpa_s->dpp_pfs);
+ wpa_s->dpp_pfs = NULL;
+#endif /* CONFIG_DPP2 */
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s);
- dpp_bootstrap_del(wpa_s, 0);
- dpp_configurator_del(wpa_s, 0);
wpas_dpp_stop(wpa_s);
wpas_dpp_pkex_remove(wpa_s, "*");
os_memset(wpa_s->dpp_intro_bssid, 0, ETH_ALEN);
diff --git a/wpa_supplicant/dpp_supplicant.h b/wpa_supplicant/dpp_supplicant.h
index 5a4f06e..ecb7a7d 100644
--- a/wpa_supplicant/dpp_supplicant.h
+++ b/wpa_supplicant/dpp_supplicant.h
@@ -10,12 +10,6 @@
#define DPP_SUPPLICANT_H
int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_bootstrap_gen(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_bootstrap_remove(struct wpa_supplicant *wpa_s, const char *id);
-const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant *wpa_s,
- unsigned int id);
-int wpas_dpp_bootstrap_info(struct wpa_supplicant *wpa_s, int id,
- char *reply, int reply_size);
int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd);
int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd);
void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s);
@@ -23,11 +17,7 @@ void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
unsigned int freq);
void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
const u8 *buf, size_t len, unsigned int freq);
-int wpas_dpp_configurator_add(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id);
int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_configurator_get_key(struct wpa_supplicant *wpa_s, unsigned int id,
- char *buf, size_t buflen);
int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd);
int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id);
void wpas_dpp_stop(struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 638a9ab..f6ec111 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - Driver event processing
- * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -29,6 +29,7 @@
#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "common/gas_server.h"
+#include "common/dpp.h"
#include "crypto/random.h"
#include "blacklist.h"
#include "wpas_glue.h"
@@ -559,6 +560,10 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
" skip RSN IE - parse failed");
break;
}
+ if (!ie.has_pairwise)
+ ie.pairwise_cipher = wpa_default_rsn_cipher(bss->freq);
+ if (!ie.has_group)
+ ie.group_cipher = wpa_default_rsn_cipher(bss->freq);
if (wep_ok &&
(ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
@@ -1899,7 +1904,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
if (sme_proc_obss_scan(wpa_s) > 0)
goto scan_work_done;
- if (own_request &&
+ if (own_request && data &&
wpas_beacon_rep_scan_process(wpa_s, scan_res, &data->scan_info) > 0)
goto scan_work_done;
@@ -2305,6 +2310,13 @@ static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
}
if (!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS)) {
+ if ((map_sub_elem[2] & MULTI_AP_FRONTHAUL_BSS) &&
+ wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
+ wpa_printf(MSG_INFO,
+ "WPS active, accepting fronthaul-only BSS");
+ /* Don't set 4addr mode in this case, so just return */
+ return;
+ }
wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS");
goto fail;
}
@@ -2409,6 +2421,26 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
wpa_dbg(wpa_s, MSG_DEBUG, "freq=%u MHz",
data->assoc_info.freq);
+ wpa_s->connection_set = 0;
+ if (data->assoc_info.req_ies && data->assoc_info.resp_ies) {
+ struct ieee802_11_elems req_elems, resp_elems;
+
+ if (ieee802_11_parse_elems(data->assoc_info.req_ies,
+ data->assoc_info.req_ies_len,
+ &req_elems, 0) != ParseFailed &&
+ ieee802_11_parse_elems(data->assoc_info.resp_ies,
+ data->assoc_info.resp_ies_len,
+ &resp_elems, 0) != ParseFailed) {
+ wpa_s->connection_set = 1;
+ wpa_s->connection_ht = req_elems.ht_capabilities &&
+ resp_elems.ht_capabilities;
+ wpa_s->connection_vht = req_elems.vht_capabilities &&
+ resp_elems.vht_capabilities;
+ wpa_s->connection_he = req_elems.he_capabilities &&
+ resp_elems.he_capabilities;
+ }
+ }
+
p = data->assoc_info.req_ies;
l = data->assoc_info.req_ies_len;
@@ -2467,6 +2499,28 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
}
#endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP2
+ wpa_sm_set_dpp_z(wpa_s->wpa, NULL);
+ if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && wpa_s->dpp_pfs) {
+ struct ieee802_11_elems elems;
+
+ if (ieee802_11_parse_elems(data->assoc_info.resp_ies,
+ data->assoc_info.resp_ies_len,
+ &elems, 0) == ParseFailed ||
+ !elems.owe_dh)
+ goto no_pfs;
+ if (dpp_pfs_process(wpa_s->dpp_pfs, elems.owe_dh,
+ elems.owe_dh_len) < 0) {
+ wpa_supplicant_deauthenticate(wpa_s,
+ WLAN_REASON_UNSPECIFIED);
+ return -1;
+ }
+
+ wpa_sm_set_dpp_z(wpa_s->wpa, wpa_s->dpp_pfs->secret);
+ }
+no_pfs:
+#endif /* CONFIG_DPP2 */
+
#ifdef CONFIG_IEEE80211R
#ifdef CONFIG_SME
if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
@@ -2805,8 +2859,17 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
}
wpa_supplicant_cancel_scan(wpa_s);
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
- wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
+ if (ft_completed) {
+ /*
+ * FT protocol completed - make sure EAPOL state machine ends
+ * up in authenticated.
+ */
+ wpa_supplicant_cancel_auth_timeout(wpa_s);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
+ eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
+ } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
+ wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
/*
* We are done; the driver will take care of RSN 4-way
* handshake.
@@ -2823,15 +2886,6 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
* waiting for WPA supplicant.
*/
eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
- } else if (ft_completed) {
- /*
- * FT protocol completed - make sure EAPOL state machine ends
- * up in authenticated.
- */
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
- eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
- eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
}
wpa_s->last_eapol_matches_bssid = 0;
@@ -4809,7 +4863,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break;
case EVENT_WPS_BUTTON_PUSHED:
#ifdef CONFIG_WPS
- wpas_wps_start_pbc(wpa_s, NULL, 0);
+ wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
#endif /* CONFIG_WPS */
break;
case EVENT_AVOID_FREQUENCIES:
diff --git a/wpa_supplicant/examples/wpas-test.py b/wpa_supplicant/examples/wpas-test.py
deleted file mode 100755
index bdd16a8..0000000
--- a/wpa_supplicant/examples/wpas-test.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/python
-
-import dbus
-import sys, os
-import time
-
-WPAS_DBUS_SERVICE = "fi.epitest.hostap.WPASupplicant"
-WPAS_DBUS_INTERFACE = "fi.epitest.hostap.WPASupplicant"
-WPAS_DBUS_OPATH = "/fi/epitest/hostap/WPASupplicant"
-
-WPAS_DBUS_INTERFACES_INTERFACE = "fi.epitest.hostap.WPASupplicant.Interface"
-WPAS_DBUS_INTERFACES_OPATH = "/fi/epitest/hostap/WPASupplicant/Interfaces"
-WPAS_DBUS_BSSID_INTERFACE = "fi.epitest.hostap.WPASupplicant.BSSID"
-
-def byte_array_to_string(s):
- import urllib
- r = ""
- for c in s:
- if c >= 32 and c < 127:
- r += "%c" % c
- else:
- r += urllib.quote(chr(c))
- return r
-
-def main():
- if len(sys.argv) != 2:
- print("Usage: wpas-test.py <interface>")
- os._exit(1)
-
- ifname = sys.argv[1]
-
- bus = dbus.SystemBus()
- wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH)
- wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE)
-
- # See if wpa_supplicant already knows about this interface
- path = None
- try:
- path = wpas.getInterface(ifname)
- except dbus.dbus_bindings.DBusException as exc:
- if str(exc) != "wpa_supplicant knows nothing about this interface.":
- raise exc
- try:
- path = wpas.addInterface(ifname, {'driver': dbus.Variant('wext')})
- except dbus.dbus_bindings.DBusException as exc:
- if str(exc) != "wpa_supplicant already controls this interface.":
- raise exc
-
- if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
- iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE)
- iface.scan()
- # Should really wait for the "scanResults" signal instead of sleeping
- time.sleep(5)
- res = iface.scanResults()
-
- print("Scanned wireless networks:")
- for opath in res:
- net_obj = bus.get_object(WPAS_DBUS_SERVICE, opath)
- net = dbus.Interface(net_obj, WPAS_DBUS_BSSID_INTERFACE)
- props = net.properties()
-
- # Convert the byte-array for SSID and BSSID to printable strings
- bssid = ""
- for item in props["bssid"]:
- bssid = bssid + ":%02x" % item
- bssid = bssid[1:]
- ssid = byte_array_to_string(props["ssid"])
- wpa = "no"
- if props.has_key("wpaie"):
- wpa = "yes"
- wpa2 = "no"
- if props.has_key("rsnie"):
- wpa2 = "yes"
- freq = 0
- if props.has_key("frequency"):
- freq = props["frequency"]
- caps = props["capabilities"]
- qual = props["quality"]
- level = props["level"]
- noise = props["noise"]
- maxrate = props["maxrate"] / 1000000
-
- print(" %s :: ssid='%s' wpa=%s wpa2=%s quality=%d%% rate=%d freq=%d" % (bssid, ssid, wpa, wpa2, qual, maxrate, freq))
-
- wpas.removeInterface(dbus.ObjectPath(path))
- # Should fail here with unknown interface error
- iface.scan()
-
-if __name__ == "__main__":
- main()
-
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index 00919d1..e96ea65 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -260,12 +260,14 @@ static void auth_logger(void *ctx, const u8 *addr, logger_level level,
static const u8 * auth_get_psk(void *ctx, const u8 *addr,
const u8 *p2p_dev_addr, const u8 *prev_psk,
- size_t *psk_len)
+ size_t *psk_len, int *vlan_id)
{
struct ibss_rsn *ibss_rsn = ctx;
if (psk_len)
*psk_len = PMK_LEN;
+ if (vlan_id)
+ *vlan_id = 0;
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
__func__, MAC2STR(addr), prev_psk);
if (prev_psk)
@@ -457,7 +459,7 @@ static int ibss_rsn_auth_init(struct ibss_rsn *ibss_rsn,
}
/* TODO: get peer RSN IE with Probe Request */
- if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth,
+ if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth, 0,
(u8 *) "\x30\x14\x01\x00"
"\x00\x0f\xac\x04"
"\x01\x00\x00\x0f\xac\x04"
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index e08c2fd..51a8a02 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -28,9 +28,9 @@ static void usage(void)
"s"
#endif /* CONFIG_DEBUG_SYSLOG */
"t"
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
"u"
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
"vW] [-P<pid file>] "
"[-g<global ctrl>] \\\n"
" [-G<group>] \\\n"
@@ -98,9 +98,9 @@ static void usage(void)
" -T = record to Linux tracing in addition to logging\n"
" (records all messages regardless of debug verbosity)\n"
#endif /* CONFIG_DEBUG_LINUX_TRACING */
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
" -u = enable DBus control interface\n"
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
" -v = show version\n"
" -W = wait for a control interface monitor before starting\n");
@@ -295,11 +295,11 @@ int main(int argc, char *argv[])
case 't':
params.wpa_debug_timestamp++;
break;
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
case 'u':
params.dbus_ctrl_interface = 1;
break;
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
case 'v':
printf("%s\n", wpa_supplicant_version);
exitcode = 0;
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index bd5020a..43b1fa7 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -98,6 +98,13 @@ static void wpas_mbo_non_pref_chan_attr_body(struct wpa_supplicant *wpa_s,
}
+static void wpas_mbo_non_pref_chan_attr_hdr(struct wpabuf *mbo, size_t size)
+{
+ wpabuf_put_u8(mbo, MBO_ATTR_ID_NON_PREF_CHAN_REPORT);
+ wpabuf_put_u8(mbo, size); /* Length */
+}
+
+
static void wpas_mbo_non_pref_chan_attr(struct wpa_supplicant *wpa_s,
struct wpabuf *mbo, u8 start, u8 end)
{
@@ -106,9 +113,7 @@ static void wpas_mbo_non_pref_chan_attr(struct wpa_supplicant *wpa_s,
if (size + 2 > wpabuf_tailroom(mbo))
return;
- wpabuf_put_u8(mbo, MBO_ATTR_ID_NON_PREF_CHAN_REPORT);
- wpabuf_put_u8(mbo, size); /* Length */
-
+ wpas_mbo_non_pref_chan_attr_hdr(mbo, size);
wpas_mbo_non_pref_chan_attr_body(wpa_s, mbo, start, end);
}
@@ -145,6 +150,8 @@ static void wpas_mbo_non_pref_chan_attrs(struct wpa_supplicant *wpa_s,
if (!wpa_s->non_pref_chan || !wpa_s->non_pref_chan_num) {
if (subelement)
wpas_mbo_non_pref_chan_subelem_hdr(mbo, 4);
+ else
+ wpas_mbo_non_pref_chan_attr_hdr(mbo, 0);
return;
}
start_pref = &wpa_s->non_pref_chan[0];
@@ -268,6 +275,7 @@ static void wpas_mbo_non_pref_chan_changed(struct wpa_supplicant *wpa_s)
wpas_mbo_non_pref_chan_attrs(wpa_s, buf, 1);
wpas_mbo_send_wnm_notification(wpa_s, wpabuf_head_u8(buf),
wpabuf_len(buf));
+ wpas_update_mbo_connect_params(wpa_s);
wpabuf_free(buf);
}
@@ -293,10 +301,10 @@ static int wpa_non_pref_chan_cmp(const void *_a, const void *_b)
const struct wpa_mbo_non_pref_channel *a = _a, *b = _b;
if (a->oper_class != b->oper_class)
- return a->oper_class - b->oper_class;
+ return (int) a->oper_class - (int) b->oper_class;
if (a->reason != b->reason)
- return a->reason - b->reason;
- return a->preference - b->preference;
+ return (int) a->reason - (int) b->reason;
+ return (int) a->preference - (int) b->preference;
}
@@ -558,6 +566,7 @@ void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa)
wpas_mbo_send_wnm_notification(wpa_s, cell_capa, 7);
wpa_supplicant_set_default_scan_ies(wpa_s);
+ wpas_update_mbo_connect_params(wpa_s);
}
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index e9457f0..9260021 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -197,7 +197,7 @@ static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
struct wpa_ssid *ssid = wpa_s->current_ssid;
int ret;
- if (!params || !ssid) {
+ if (!params || !ssid || !ifmsh) {
wpa_printf(MSG_ERROR, "mesh: %s called without active mesh",
__func__);
return -1;
@@ -217,13 +217,11 @@ static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
}
- if (ifmsh) {
- params->ies = ifmsh->mconf->rsn_ie;
- params->ie_len = ifmsh->mconf->rsn_ie_len;
- params->basic_rates = ifmsh->basic_rates;
- params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
- params->conf.ht_opmode = ifmsh->bss[0]->iface->ht_op_mode;
- }
+ params->ies = ifmsh->mconf->rsn_ie;
+ params->ie_len = ifmsh->mconf->rsn_ie_len;
+ params->basic_rates = ifmsh->basic_rates;
+ params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
+ params->conf.ht_opmode = ifmsh->bss[0]->iface->ht_op_mode;
wpa_msg(wpa_s, MSG_INFO, "joining mesh %s",
wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 4485939..9d6ab8d 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -189,7 +189,7 @@ static void mesh_mpm_init_link(struct wpa_supplicant *wpa_s,
do {
if (os_get_random((u8 *) &llid, sizeof(llid)) < 0)
- continue;
+ llid = 0; /* continue */
} while (!llid || llid_in_use(wpa_s, llid));
sta->my_lid = llid;
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index 04ac747..4b8d6c4 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -76,7 +76,7 @@ static void auth_logger(void *ctx, const u8 *addr, logger_level level,
static const u8 *auth_get_psk(void *ctx, const u8 *addr,
const u8 *p2p_dev_addr, const u8 *prev_psk,
- size_t *psk_len)
+ size_t *psk_len, int *vlan_id)
{
struct mesh_rsn *mesh_rsn = ctx;
struct hostapd_data *hapd = mesh_rsn->wpa_s->ifmsh->bss[0];
@@ -84,6 +84,8 @@ static const u8 *auth_get_psk(void *ctx, const u8 *addr,
if (psk_len)
*psk_len = PMK_LEN;
+ if (vlan_id)
+ *vlan_id = 0;
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
__func__, MAC2STR(addr), prev_psk);
@@ -641,7 +643,7 @@ int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
size_t crypt_len;
const u8 *aad[] = { sta->addr, wpa_s->own_addr, cat };
const size_t aad_len[] = { ETH_ALEN, ETH_ALEN,
- (elems->mic - 2) - cat };
+ elems->mic ? (elems->mic - 2) - cat : 0 };
size_t key_len;
if (!sta->sae) {
@@ -655,7 +657,9 @@ int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
mesh_rsn_auth_sae_sta(wpa_s, sta);
}
- if (chosen_pmk && os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN)) {
+ if (chosen_pmk &&
+ (!sta->sae ||
+ os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN) != 0)) {
wpa_msg(wpa_s, MSG_DEBUG,
"Mesh RSN: Invalid PMKID (Chosen PMK did not match calculated PMKID)");
return -1;
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index e5e45de..bedb74b 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -15,7 +15,6 @@
#include "wps_supplicant.h"
#include "binder/binder.h"
#include "dbus/dbus_common.h"
-#include "dbus/dbus_old.h"
#include "dbus/dbus_new.h"
#include "rsn_supp/wpa.h"
#include "fst/fst.h"
@@ -27,13 +26,13 @@
int wpas_notify_supplicant_initialized(struct wpa_global *global)
{
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
if (global->params.dbus_ctrl_interface) {
global->dbus = wpas_dbus_init(global);
if (global->dbus == NULL)
return -1;
}
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
#ifdef CONFIG_BINDER
global->binder = wpas_binder_init(global);
@@ -47,10 +46,10 @@ int wpas_notify_supplicant_initialized(struct wpa_global *global)
void wpas_notify_supplicant_deinitialized(struct wpa_global *global)
{
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
if (global->dbus)
wpas_dbus_deinit(global->dbus);
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
#ifdef CONFIG_BINDER
if (global->binder)
@@ -64,9 +63,6 @@ int wpas_notify_iface_added(struct wpa_supplicant *wpa_s)
if (wpa_s->p2p_mgmt)
return 0;
- if (wpas_dbus_register_iface(wpa_s))
- return -1;
-
if (wpas_dbus_register_interface(wpa_s))
return -1;
@@ -79,9 +75,6 @@ void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s)
if (wpa_s->p2p_mgmt)
return;
- /* unregister interface in old DBus ctrl iface */
- wpas_dbus_unregister_iface(wpa_s);
-
/* unregister interface in new DBus ctrl iface */
wpas_dbus_unregister_interface(wpa_s);
}
@@ -94,10 +87,6 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
if (wpa_s->p2p_mgmt)
return;
- /* notify the old DBus API */
- wpa_supplicant_dbus_notify_state_change(wpa_s, new_state,
- old_state);
-
/* notify the new DBus API */
wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
@@ -267,9 +256,6 @@ void wpas_notify_scanning(struct wpa_supplicant *wpa_s)
if (wpa_s->p2p_mgmt)
return;
- /* notify the old DBus API */
- wpa_supplicant_dbus_notify_scanning(wpa_s);
-
/* notify the new DBus API */
wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SCANNING);
}
@@ -289,9 +275,6 @@ void wpas_notify_scan_results(struct wpa_supplicant *wpa_s)
if (wpa_s->p2p_mgmt)
return;
- /* notify the old DBus API */
- wpa_supplicant_dbus_notify_scan_results(wpa_s);
-
wpas_wps_notify_scan_results(wpa_s);
}
@@ -303,8 +286,6 @@ void wpas_notify_wps_credential(struct wpa_supplicant *wpa_s,
return;
#ifdef CONFIG_WPS
- /* notify the old DBus API */
- wpa_supplicant_dbus_notify_wps_cred(wpa_s, cred);
/* notify the new DBus API */
wpas_dbus_signal_wps_cred(wpa_s, cred);
#endif /* CONFIG_WPS */
@@ -838,9 +819,6 @@ void wpas_notify_certification(struct wpa_supplicant *wpa_s, int depth,
"depth=%d %s", depth, altsubject[i]);
}
- /* notify the old DBus API */
- wpa_supplicant_dbus_notify_certification(wpa_s, depth, subject,
- cert_hash, cert);
/* notify the new DBus API */
wpas_dbus_signal_certification(wpa_s, depth, subject, altsubject,
num_altsubject, cert_hash, cert);
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 848299d..e7c1f5d 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -980,6 +980,7 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
os_free(wpa_s->p2p_group_common_freqs);
wpa_s->p2p_group_common_freqs = NULL;
wpa_s->p2p_group_common_freqs_num = 0;
+ wpa_s->p2p_go_do_acs = 0;
wpa_s->waiting_presence_resp = 0;
@@ -1584,20 +1585,27 @@ static int wpas_send_action_work(struct wpa_supplicant *wpa_s,
static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
const u8 *src, const u8 *bssid, const u8 *buf,
- size_t len, unsigned int wait_time)
+ size_t len, unsigned int wait_time, int *scheduled)
{
struct wpa_supplicant *wpa_s = ctx;
int listen_freq = -1, send_freq = -1;
+ if (scheduled)
+ *scheduled = 0;
if (wpa_s->p2p_listen_work)
listen_freq = wpa_s->p2p_listen_work->freq;
if (wpa_s->p2p_send_action_work)
send_freq = wpa_s->p2p_send_action_work->freq;
if (listen_freq != (int) freq && send_freq != (int) freq) {
- wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d)",
- listen_freq, send_freq);
- return wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
- len, wait_time);
+ int res;
+
+ wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d freq=%u)",
+ listen_freq, send_freq, freq);
+ res = wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
+ len, wait_time);
+ if (res == 0 && scheduled)
+ *scheduled = 1;
+ return res;
}
wpa_printf(MSG_DEBUG, "P2P: Use ongoing radio work for Action frame TX");
@@ -1649,7 +1657,7 @@ static void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s,
wpa_supplicant_ap_deinit(wpa_s);
wpas_copy_go_neg_results(wpa_s, res);
if (res->wps_method == WPS_PBC) {
- wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
+ wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1, 0);
#ifdef CONFIG_WPS_NFC
} else if (res->wps_method == WPS_NFC) {
wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
@@ -4180,6 +4188,9 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
return;
}
+ wpa_s->global->pending_p2ps_group = 0;
+ wpa_s->global->pending_p2ps_group_freq = 0;
+
if (conncap == P2PS_SETUP_GROUP_OWNER) {
/*
* We need to copy the interface name. Simply saving a
@@ -4190,8 +4201,10 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
go_ifname[0] = '\0';
if (!go_wpa_s) {
- wpa_s->global->pending_p2ps_group = 1;
- wpa_s->global->pending_p2ps_group_freq = freq;
+ if (!response_done) {
+ wpa_s->global->pending_p2ps_group = 1;
+ wpa_s->global->pending_p2ps_group_freq = freq;
+ }
if (!wpas_p2p_create_iface(wpa_s))
os_memcpy(go_ifname, wpa_s->ifname,
@@ -4498,7 +4511,10 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
* channel.
*/
if (p2p_config_get_random_social(&p2p, &p2p.reg_class,
- &p2p.channel) != 0) {
+ &p2p.channel,
+ &global->p2p_go_avoid_freq,
+ &global->p2p_disallow_freq) !=
+ 0) {
wpa_printf(MSG_INFO,
"P2P: No social channels supported by the driver - do not enable P2P");
return 0;
@@ -4523,10 +4539,14 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
* other preference is indicated.
*/
if (p2p_config_get_random_social(&p2p, &p2p.op_reg_class,
- &p2p.op_channel) != 0) {
- wpa_printf(MSG_ERROR,
+ &p2p.op_channel, NULL,
+ NULL) != 0) {
+ wpa_printf(MSG_INFO,
"P2P: Failed to select random social channel as operation channel");
- return -1;
+ p2p.op_reg_class = 0;
+ p2p.op_channel = 0;
+ /* This will be overridden during group setup in
+ * p2p_prepare_channel(), so allow setup to continue. */
}
p2p.cfg_op_channel = 0;
wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "
@@ -7200,7 +7220,7 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
u8 go_dev_addr[ETH_ALEN];
int persistent;
int freq;
- u8 ip[3 * 4];
+ u8 ip[3 * 4], *ip_ptr = NULL;
char ip_addr[100];
if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) {
@@ -7247,6 +7267,7 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
ip[8], ip[9], ip[10], ip[11]);
if (os_snprintf_error(sizeof(ip_addr), res))
ip_addr[0] = '\0';
+ ip_ptr = ip;
}
wpas_p2p_group_started(wpa_s, 0, ssid, freq,
@@ -7259,7 +7280,7 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
wpas_p2p_store_persistent_group(wpa_s->p2pdev,
ssid, go_dev_addr);
- wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 1, ip);
+ wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 1, ip_ptr);
}
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index ab5e6db..cb3c6c9 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -397,7 +397,10 @@ static int wpas_rrm_beacon_rep_update_last_frame(u8 *pos, size_t len)
struct rrm_measurement_report_element *msr_rep;
u8 *end = pos + len;
u8 *msr_rep_end;
+ struct rrm_measurement_beacon_report *rep = NULL;
+ u8 *subelem;
+ /* Find the last beacon report element */
while (end - pos >= (int) sizeof(*msr_rep)) {
msr_rep = (struct rrm_measurement_report_element *) pos;
msr_rep_end = pos + msr_rep->len + 2;
@@ -410,30 +413,27 @@ static int wpas_rrm_beacon_rep_update_last_frame(u8 *pos, size_t len)
return -1;
}
- if (msr_rep->type == MEASURE_TYPE_BEACON) {
- struct rrm_measurement_beacon_report *rep;
- u8 *subelem;
-
+ if (msr_rep->type == MEASURE_TYPE_BEACON)
rep = (struct rrm_measurement_beacon_report *)
msr_rep->variable;
- subelem = rep->variable;
- while (subelem + 2 < msr_rep_end &&
- subelem[0] !=
- WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION)
- subelem += 2 + subelem[1];
-
- if (subelem + 2 < msr_rep_end &&
- subelem[0] ==
- WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION &&
- subelem[1] == 1 &&
- subelem +
- BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end)
- subelem[2] = 1;
- }
pos += pos[1] + 2;
}
+ if (!rep)
+ return 0;
+
+ subelem = rep->variable;
+ while (subelem + 2 < msr_rep_end &&
+ subelem[0] != WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION)
+ subelem += 2 + subelem[1];
+
+ if (subelem + 2 < msr_rep_end &&
+ subelem[0] == WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION &&
+ subelem[1] == 1 &&
+ subelem + BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end)
+ subelem[2] = 1;
+
return 0;
}
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 727c49a..7abb028 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - Scanning
- * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -1993,7 +1993,8 @@ static int wpa_scan_result_compar(const void *a, const void *b)
/* if SNR is close, decide by max rate or frequency band */
if (snr_a && snr_b && abs(snr_b - snr_a) < 7) {
if (wa->est_throughput != wb->est_throughput)
- return wb->est_throughput - wa->est_throughput;
+ return (int) wb->est_throughput -
+ (int) wa->est_throughput;
}
if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
(wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index ba22a93..17a984d 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -16,6 +16,7 @@
#include "eapol_supp/eapol_supp_sm.h"
#include "common/wpa_common.h"
#include "common/sae.h"
+#include "common/dpp.h"
#include "rsn_supp/wpa.h"
#include "rsn_supp/pmksa_cache.h"
#include "config.h"
@@ -57,7 +58,7 @@ static int index_within_array(const int *array, int idx)
static int sme_set_sae_group(struct wpa_supplicant *wpa_s)
{
int *groups = wpa_s->conf->sae_groups;
- int default_groups[] = { 19, 20, 21, 25, 26, 0 };
+ int default_groups[] = { 19, 20, 21, 0 };
if (!groups || groups[0] <= 0)
groups = default_groups;
@@ -84,7 +85,8 @@ static int sme_set_sae_group(struct wpa_supplicant *wpa_s)
static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
- const u8 *bssid, int external)
+ const u8 *bssid, int external,
+ int reuse)
{
struct wpabuf *buf;
size_t len;
@@ -96,8 +98,10 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
buf = wpabuf_alloc(4 + wpabuf_len(wpa_s->sae_commit_override));
if (!buf)
return NULL;
- wpabuf_put_le16(buf, 1); /* Transaction seq# */
- wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+ if (!external) {
+ wpabuf_put_le16(buf, 1); /* Transaction seq# */
+ wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+ }
wpabuf_put_buf(buf, wpa_s->sae_commit_override);
return buf;
}
@@ -111,6 +115,12 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
return NULL;
}
+ if (reuse && wpa_s->sme.sae.tmp &&
+ os_memcmp(bssid, wpa_s->sme.sae.tmp->bssid, ETH_ALEN) == 0) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Reuse previously generated PWE on a retry with the same AP");
+ goto reuse_data;
+ }
if (sme_set_sae_group(wpa_s) < 0) {
wpa_printf(MSG_DEBUG, "SAE: Failed to select group");
return NULL;
@@ -123,7 +133,10 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
return NULL;
}
+ if (wpa_s->sme.sae.tmp)
+ os_memcpy(wpa_s->sme.sae.tmp->bssid, bssid, ETH_ALEN);
+reuse_data:
len = wpa_s->sme.sae_token ? wpabuf_len(wpa_s->sme.sae_token) : 0;
if (ssid->sae_password_id)
len += 4 + os_strlen(ssid->sae_password_id);
@@ -303,6 +316,12 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
if (!rsn) {
wpa_dbg(wpa_s, MSG_DEBUG,
"SAE enabled, but target BSS does not advertise RSN");
+#ifdef CONFIG_DPP
+ } else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
+ (ssid->key_mgmt & WPA_KEY_MGMT_DPP) &&
+ (ied.key_mgmt & WPA_KEY_MGMT_DPP)) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Prefer DPP over SAE when both are enabled");
+#endif /* CONFIG_DPP */
} else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
wpa_key_mgmt_sae(ied.key_mgmt)) {
wpa_dbg(wpa_s, MSG_DEBUG, "Using SAE auth_alg");
@@ -435,13 +454,14 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
md = ie + 2;
wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
+ if (md && (!wpa_key_mgmt_ft(ssid->key_mgmt) ||
+ !wpa_key_mgmt_ft(wpa_s->key_mgmt)))
+ md = NULL;
if (md) {
/* Prepare for the next transition */
wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
}
- if (md && !wpa_key_mgmt_ft(ssid->key_mgmt))
- md = NULL;
if (md) {
wpa_dbg(wpa_s, MSG_DEBUG, "SME: FT mobility domain %02x%02x",
md[0], md[1]);
@@ -620,7 +640,10 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_SAE
if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE &&
pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, 0,
- NULL, WPA_KEY_MGMT_SAE) == 0) {
+ NULL,
+ wpa_s->key_mgmt == WPA_KEY_MGMT_FT_SAE ?
+ WPA_KEY_MGMT_FT_SAE :
+ WPA_KEY_MGMT_SAE) == 0) {
wpa_dbg(wpa_s, MSG_DEBUG,
"PMKSA cache entry found - try to use PMKSA caching instead of new SAE authentication");
wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
@@ -631,7 +654,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE) {
if (start)
resp = sme_auth_build_sae_commit(wpa_s, ssid,
- bss->bssid, 0);
+ bss->bssid, 0,
+ start == 2);
else
resp = sme_auth_build_sae_confirm(wpa_s, 0);
if (resp == NULL) {
@@ -914,7 +938,7 @@ static void sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
{
struct wpabuf *resp, *buf;
- resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1);
+ resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0);
if (!resp)
return;
@@ -941,10 +965,9 @@ static void sme_send_external_auth_status(struct wpa_supplicant *wpa_s,
os_memset(&params, 0, sizeof(params));
params.status = status;
- os_memcpy(params.ssid, wpa_s->sme.ext_auth.ssid,
- wpa_s->sme.ext_auth.ssid_len);
+ params.ssid = wpa_s->sme.ext_auth.ssid;
params.ssid_len = wpa_s->sme.ext_auth.ssid_len;
- os_memcpy(params.bssid, wpa_s->sme.ext_auth.bssid, ETH_ALEN);
+ params.bssid = wpa_s->sme.ext_auth.bssid;
wpa_drv_send_external_auth_status(wpa_s, &params);
}
@@ -954,14 +977,14 @@ static void sme_handle_external_auth_start(struct wpa_supplicant *wpa_s,
{
struct wpa_ssid *ssid;
size_t ssid_str_len = data->external_auth.ssid_len;
- u8 *ssid_str = data->external_auth.ssid;
+ const u8 *ssid_str = data->external_auth.ssid;
/* Get the SSID conf from the ssid string obtained */
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
if (!wpas_network_disabled(wpa_s, ssid) &&
ssid_str_len == ssid->ssid_len &&
os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0 &&
- (ssid->key_mgmt & WPA_KEY_MGMT_SAE))
+ (ssid->key_mgmt & (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE)))
break;
}
if (ssid)
@@ -1037,7 +1060,7 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
wpa_s->sme.sae.state == SAE_COMMITTED &&
(external || wpa_s->current_bss) && wpa_s->current_ssid) {
- int default_groups[] = { 19, 20, 21, 25, 26, 0 };
+ int default_groups[] = { 19, 20, 21, 0 };
u16 group;
groups = wpa_s->conf->sae_groups;
@@ -1065,7 +1088,7 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
len - sizeof(le16));
if (!external)
sme_send_authentication(wpa_s, wpa_s->current_bss,
- wpa_s->current_ssid, 1);
+ wpa_s->current_ssid, 2);
else
sme_external_auth_send_sae_commit(
wpa_s, wpa_s->sme.ext_auth.bssid,
@@ -1554,6 +1577,36 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
}
#endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP2
+ if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && wpa_s->current_ssid &&
+ wpa_s->current_ssid->dpp_netaccesskey) {
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
+
+ dpp_pfs_free(wpa_s->dpp_pfs);
+ wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
+ ssid->dpp_netaccesskey_len);
+ if (!wpa_s->dpp_pfs) {
+ wpa_printf(MSG_DEBUG, "DPP: Could not initialize PFS");
+ /* Try to continue without PFS */
+ goto pfs_fail;
+ }
+ if (wpa_s->sme.assoc_req_ie_len +
+ wpabuf_len(wpa_s->dpp_pfs->ie) >
+ sizeof(wpa_s->sme.assoc_req_ie)) {
+ wpa_printf(MSG_ERROR,
+ "DPP: Not enough buffer room for own Association Request frame elements");
+ dpp_pfs_free(wpa_s->dpp_pfs);
+ wpa_s->dpp_pfs = NULL;
+ goto pfs_fail;
+ }
+ os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
+ wpabuf_head(wpa_s->dpp_pfs->ie),
+ wpabuf_len(wpa_s->dpp_pfs->ie));
+ wpa_s->sme.assoc_req_ie_len += wpabuf_len(wpa_s->dpp_pfs->ie);
+ }
+pfs_fail:
+#endif /* CONFIG_DPP2 */
+
if (wpa_s->current_ssid && wpa_s->current_ssid->multi_ap_backhaul_sta) {
size_t multi_ap_ie_len;
@@ -1932,17 +1985,14 @@ void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s)
if (wpa_s->sme.ft_ies || wpa_s->sme.ft_used)
sme_update_ft_ies(wpa_s, NULL, NULL, 0);
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ sme_stop_sa_query(wpa_s);
+#endif /* CONFIG_IEEE80211W */
}
void sme_deinit(struct wpa_supplicant *wpa_s)
{
- os_free(wpa_s->sme.ft_ies);
- wpa_s->sme.ft_ies = NULL;
- wpa_s->sme.ft_ies_len = 0;
-#ifdef CONFIG_IEEE80211W
- sme_stop_sa_query(wpa_s);
-#endif /* CONFIG_IEEE80211W */
sme_clear_on_disassoc(wpa_s);
eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
@@ -2347,6 +2397,8 @@ static void sme_start_sa_query(struct wpa_supplicant *wpa_s)
static void sme_stop_sa_query(struct wpa_supplicant *wpa_s)
{
+ if (wpa_s->sme.sa_query_trans_id)
+ wpa_dbg(wpa_s, MSG_DEBUG, "SME: Stop SA Query");
eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL);
os_free(wpa_s->sme.sa_query_trans_id);
wpa_s->sme.sa_query_trans_id = NULL;
diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in
index bc5d49a..75a37a8 100644
--- a/wpa_supplicant/systemd/wpa_supplicant.service.in
+++ b/wpa_supplicant/systemd/wpa_supplicant.service.in
@@ -5,9 +5,9 @@ Wants=network.target
[Service]
Type=dbus
-BusName=@DBUS_INTERFACE@
+BusName=fi.w1.wpa_supplicant1
ExecStart=@BINDIR@/wpa_supplicant -u
[Install]
WantedBy=multi-user.target
-Alias=dbus-@DBUS_INTERFACE@.service
+Alias=dbus-fi.w1.wpa_supplicant1.service
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 9881021..695fcbe 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -1411,9 +1411,11 @@ static const char *network_fields[] = {
"eap", "identity", "anonymous_identity", "password", "ca_cert",
"ca_path", "client_cert", "private_key", "private_key_passwd",
"dh_file", "subject_match", "altsubject_match",
+ "check_cert_subject",
"domain_suffix_match", "domain_match", "ca_cert2", "ca_path2",
"client_cert2", "private_key2", "private_key2_passwd",
"dh_file2", "subject_match2", "altsubject_match2",
+ "check_cert_subject2",
"domain_suffix_match2", "domain_match2", "phase1", "phase2",
"pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id",
"pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id",
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index e0ee553..96a3691 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -39,6 +39,7 @@
#include "common/ieee802_11_defs.h"
#include "common/hw_features_common.h"
#include "common/gas_server.h"
+#include "common/dpp.h"
#include "p2p/p2p.h"
#include "fst/fst.h"
#include "blacklist.h"
@@ -672,6 +673,8 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_DPP
wpas_dpp_deinit(wpa_s);
+ dpp_global_deinit(wpa_s->dpp);
+ wpa_s->dpp = NULL;
#endif /* CONFIG_DPP */
}
@@ -958,7 +961,7 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
wpa_supplicant_stop_bgscan(wpa_s);
#endif /* CONFIG_BGSCAN */
- if (state == WPA_AUTHENTICATING)
+ if (state > WPA_SCANNING)
wpa_supplicant_stop_autoscan(wpa_s);
if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
@@ -1189,6 +1192,18 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
}
+static int matching_ciphers(struct wpa_ssid *ssid, struct wpa_ie_data *ie,
+ int freq)
+{
+ if (!ie->has_group)
+ ie->group_cipher = wpa_default_rsn_cipher(freq);
+ if (!ie->has_pairwise)
+ ie->pairwise_cipher = wpa_default_rsn_cipher(freq);
+ return (ie->group_cipher & ssid->group_cipher) &&
+ (ie->pairwise_cipher & ssid->pairwise_cipher);
+}
+
+
/**
* wpa_supplicant_set_suites - Set authentication and encryption parameters
* @wpa_s: Pointer to wpa_supplicant data
@@ -1220,8 +1235,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
- (ie.group_cipher & ssid->group_cipher) &&
- (ie.pairwise_cipher & ssid->pairwise_cipher) &&
+ matching_ciphers(ssid, &ie, bss->freq) &&
(ie.key_mgmt & ssid->key_mgmt)) {
wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
proto = WPA_PROTO_RSN;
@@ -1361,6 +1375,9 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
#else /* CONFIG_NO_WPA */
sel = ie.group_cipher & ssid->group_cipher;
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WPA: AP group 0x%x network profile group 0x%x; available group 0x%x",
+ ie.group_cipher, ssid->group_cipher, sel);
wpa_s->group_cipher = wpa_pick_group_cipher(sel);
if (wpa_s->group_cipher < 0) {
wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
@@ -1371,6 +1388,9 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
wpa_cipher_txt(wpa_s->group_cipher));
sel = ie.pairwise_cipher & ssid->pairwise_cipher;
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WPA: AP pairwise 0x%x network profile pairwise 0x%x; available pairwise 0x%x",
+ ie.pairwise_cipher, ssid->pairwise_cipher, sel);
wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
if (wpa_s->pairwise_cipher < 0) {
wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
@@ -1382,11 +1402,29 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_NO_WPA */
sel = ie.key_mgmt & ssid->key_mgmt;
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WPA: AP key_mgmt 0x%x network profile key_mgmt 0x%x; available key_mgmt 0x%x",
+ ie.key_mgmt, ssid->key_mgmt, sel);
#ifdef CONFIG_SAE
if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
#endif /* CONFIG_SAE */
if (0) {
+#ifdef CONFIG_IEEE80211R
+#ifdef CONFIG_SHA384
+ } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) {
+ wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WPA: using KEY_MGMT FT/802.1X-SHA384");
+ if (pmksa_cache_get_current(wpa_s->wpa)) {
+ /* PMKSA caching with FT is not fully functional, so
+ * disable the case for now. */
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WPA: Disable PMKSA caching for FT/802.1X connection");
+ pmksa_cache_clear_current(wpa_s->wpa);
+ }
+#endif /* CONFIG_SHA384 */
+#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_SUITEB192
} else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
@@ -1416,19 +1454,6 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FILS-SHA256");
#endif /* CONFIG_FILS */
#ifdef CONFIG_IEEE80211R
-#ifdef CONFIG_SHA384
- } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using KEY_MGMT FT/802.1X-SHA384");
- if (pmksa_cache_get_current(wpa_s->wpa)) {
- /* PMKSA caching with FT is not fully functional, so
- * disable the case for now. */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: Disable PMKSA caching for FT/802.1X connection");
- pmksa_cache_clear_current(wpa_s->wpa);
- }
-#endif /* CONFIG_SHA384 */
} else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
@@ -1439,18 +1464,25 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
"WPA: Disable PMKSA caching for FT/802.1X connection");
pmksa_cache_clear_current(wpa_s->wpa);
}
- } else if (sel & WPA_KEY_MGMT_FT_PSK) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_DPP
+ } else if (sel & WPA_KEY_MGMT_DPP) {
+ wpa_s->key_mgmt = WPA_KEY_MGMT_DPP;
+ wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT DPP");
+#endif /* CONFIG_DPP */
#ifdef CONFIG_SAE
- } else if (sel & WPA_KEY_MGMT_SAE) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
} else if (sel & WPA_KEY_MGMT_FT_SAE) {
wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
+ } else if (sel & WPA_KEY_MGMT_SAE) {
+ wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
+ wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
#endif /* CONFIG_SAE */
+#ifdef CONFIG_IEEE80211R
+ } else if (sel & WPA_KEY_MGMT_FT_PSK) {
+ wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
+ wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
+#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_IEEE80211W
} else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
@@ -1480,11 +1512,6 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
wpa_s->key_mgmt = WPA_KEY_MGMT_OWE;
wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT OWE");
#endif /* CONFIG_OWE */
-#ifdef CONFIG_DPP
- } else if (sel & WPA_KEY_MGMT_DPP) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_DPP;
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT DPP");
-#endif /* CONFIG_DPP */
} else {
wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
"authenticated key management type");
@@ -1503,6 +1530,9 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
!(ie.capabilities & WPA_CAPABILITY_MFPC))
sel = 0;
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WPA: AP mgmt_group_cipher 0x%x network profile mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x",
+ ie.mgmt_group_cipher, ssid->group_mgmt_cipher, sel);
if (sel & WPA_CIPHER_AES_128_CMAC) {
wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
@@ -1537,7 +1567,13 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
return -1;
}
- if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
+ if (0) {
+#ifdef CONFIG_DPP
+ } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP) {
+ /* Use PMK from DPP network introduction (PMKSA entry) */
+ wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
+#endif /* CONFIG_DPP */
+ } else if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
int psk_set = 0;
int sae_only;
@@ -2485,6 +2521,9 @@ static u8 * wpas_populate_assoc_ies(
#ifdef CONFIG_MBO
const u8 *mbo_ie;
#endif
+#ifdef CONFIG_SAE
+ int sae_pmksa_cached = 0;
+#endif /* CONFIG_SAE */
#ifdef CONFIG_FILS
const u8 *realm, *username, *rrk;
size_t realm_len, username_len, rrk_len;
@@ -2522,8 +2561,12 @@ static u8 * wpas_populate_assoc_ies(
#endif /* CONFIG_FILS */
if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
ssid, try_opportunistic,
- cache_id, 0) == 0)
+ cache_id, 0) == 0) {
eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
+#ifdef CONFIG_SAE
+ sae_pmksa_cached = 1;
+#endif /* CONFIG_SAE */
+ }
wpa_ie_len = max_wpa_ie_len;
if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
wpa_ie, &wpa_ie_len)) {
@@ -2636,6 +2679,14 @@ static u8 * wpas_populate_assoc_ies(
"Overriding auth_alg selection: 0x%x", algs);
}
+#ifdef CONFIG_SAE
+ if (sae_pmksa_cached && algs == WPA_AUTH_ALG_SAE) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "SAE: Use WPA_AUTH_ALG_OPEN for PMKSA caching attempt");
+ algs = WPA_AUTH_ALG_OPEN;
+ }
+#endif /* CONFIG_SAE */
+
#ifdef CONFIG_P2P
if (wpa_s->global->p2p) {
u8 *pos;
@@ -2810,11 +2861,33 @@ static u8 * wpas_populate_assoc_ies(
os_memcpy(wpa_ie + wpa_ie_len,
wpabuf_head(owe_ie), wpabuf_len(owe_ie));
wpa_ie_len += wpabuf_len(owe_ie);
- wpabuf_free(owe_ie);
}
+ wpabuf_free(owe_ie);
}
#endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP2
+ if (wpa_sm_get_key_mgmt(wpa_s->wpa) == WPA_KEY_MGMT_DPP &&
+ ssid->dpp_netaccesskey) {
+ dpp_pfs_free(wpa_s->dpp_pfs);
+ wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
+ ssid->dpp_netaccesskey_len);
+ if (!wpa_s->dpp_pfs) {
+ wpa_printf(MSG_DEBUG, "DPP: Could not initialize PFS");
+ /* Try to continue without PFS */
+ goto pfs_fail;
+ }
+ if (wpabuf_len(wpa_s->dpp_pfs->ie) <=
+ max_wpa_ie_len - wpa_ie_len) {
+ os_memcpy(wpa_ie + wpa_ie_len,
+ wpabuf_head(wpa_s->dpp_pfs->ie),
+ wpabuf_len(wpa_s->dpp_pfs->ie));
+ wpa_ie_len += wpabuf_len(wpa_s->dpp_pfs->ie);
+ }
+ }
+pfs_fail:
+#endif /* CONFIG_DPP2 */
+
#ifdef CONFIG_IEEE80211R
/*
* Add MDIE under these conditions: the network profile allows FT,
@@ -2901,6 +2974,34 @@ static void wpas_update_fils_connect_params(struct wpa_supplicant *wpa_s)
#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
+#ifdef CONFIG_MBO
+void wpas_update_mbo_connect_params(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_driver_associate_params params;
+ u8 *wpa_ie;
+
+ /*
+ * Update MBO connect params only in case of change of MBO attributes
+ * when connected, if the AP support MBO.
+ */
+
+ if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid ||
+ !wpa_s->current_bss ||
+ !wpa_bss_get_vendor_ie(wpa_s->current_bss, MBO_IE_VENDOR_TYPE))
+ return;
+
+ os_memset(&params, 0, sizeof(params));
+ wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss,
+ wpa_s->current_ssid, &params, NULL);
+ if (!wpa_ie)
+ return;
+
+ wpa_drv_update_connect_params(wpa_s, &params, WPA_DRV_UPDATE_ASSOC_IES);
+ os_free(wpa_ie);
+}
+#endif /* CONFIG_MBO */
+
+
static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
{
struct wpa_connect_work *cwork = work->ctx;
@@ -3942,7 +4043,9 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
while (entry) {
if (!wpas_network_disabled(wpa_s, entry) &&
((ssid_len == entry->ssid_len &&
- os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
+ (!entry->ssid ||
+ os_memcmp(ssid, entry->ssid, ssid_len) == 0)) ||
+ wired) &&
(!entry->bssid_set ||
os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
return entry;
@@ -4428,11 +4531,11 @@ static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
{
le16 msk;
- wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
-
if (disabled == -1)
return 0;
+ wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
+
msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
htcaps_mask->ht_capabilities_info |= msk;
if (disabled)
@@ -4449,11 +4552,11 @@ static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
struct ieee80211_ht_capabilities *htcaps_mask,
int factor)
{
- wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
-
if (factor == -1)
return 0;
+ wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
+
if (factor < 0 || factor > 3) {
wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
"Must be 0-3 or -1", factor);
@@ -4473,11 +4576,11 @@ static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
struct ieee80211_ht_capabilities *htcaps_mask,
int density)
{
- wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
-
if (density == -1)
return 0;
+ wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
+
if (density < 0 || density > 7) {
wpa_msg(wpa_s, MSG_ERROR,
"ampdu_density: %d out of range. Must be 0-7 or -1.",
@@ -4498,7 +4601,8 @@ static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
struct ieee80211_ht_capabilities *htcaps_mask,
int disabled)
{
- wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
+ if (disabled)
+ wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
set_disable_ht40(htcaps, disabled);
set_disable_ht40(htcaps_mask, 0);
@@ -4516,7 +4620,8 @@ static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
HT_CAP_INFO_SHORT_GI40MHZ);
- wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
+ if (disabled)
+ wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
if (disabled)
htcaps->ht_capabilities_info &= ~msk;
@@ -4537,7 +4642,8 @@ static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
/* Masking these out disables LDPC */
le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
- wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
+ if (disabled)
+ wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
if (disabled)
htcaps->ht_capabilities_info &= ~msk;
@@ -4557,11 +4663,11 @@ static int wpa_set_tx_stbc(struct wpa_supplicant *wpa_s,
{
le16 msk = host_to_le16(HT_CAP_INFO_TX_STBC);
- wpa_msg(wpa_s, MSG_DEBUG, "set_tx_stbc: %d", tx_stbc);
-
if (tx_stbc == -1)
return 0;
+ wpa_msg(wpa_s, MSG_DEBUG, "set_tx_stbc: %d", tx_stbc);
+
if (tx_stbc < 0 || tx_stbc > 1) {
wpa_msg(wpa_s, MSG_ERROR,
"tx_stbc: %d out of range. Must be 0-1 or -1", tx_stbc);
@@ -4583,11 +4689,11 @@ static int wpa_set_rx_stbc(struct wpa_supplicant *wpa_s,
{
le16 msk = host_to_le16(HT_CAP_INFO_RX_STBC_MASK);
- wpa_msg(wpa_s, MSG_DEBUG, "set_rx_stbc: %d", rx_stbc);
-
if (rx_stbc == -1)
return 0;
+ wpa_msg(wpa_s, MSG_DEBUG, "set_rx_stbc: %d", rx_stbc);
+
if (rx_stbc < 0 || rx_stbc > 3) {
wpa_msg(wpa_s, MSG_ERROR,
"rx_stbc: %d out of range. Must be 0-3 or -1", rx_stbc);
@@ -6674,6 +6780,9 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
* TODO: if more than one possible AP is available in scan results,
* could try the other ones before requesting a new scan.
*/
+
+ /* speed up the connection attempt with normal scan */
+ wpa_s->normal_scans = 0;
wpa_supplicant_req_scan(wpa_s, timeout / 1000,
1000 * (timeout % 1000));
}
@@ -7059,6 +7168,8 @@ void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
wpa_supplicant_cancel_scan(wpa_s);
wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+ radio_remove_works(wpa_s, "connect", 0);
+ radio_remove_works(wpa_s, "sme-connect", 0);
}
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 1bd43b2..a9205f0 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -282,6 +282,14 @@ fast_reauth=1
# to external program(s)
#wps_cred_processing=0
+# Whether to enable SAE (WPA3-Personal transition mode) automatically for
+# WPA2-PSK credentials received using WPS.
+# 0 = only add the explicitly listed WPA2-PSK configuration (default)
+# 1 = add both the WPA2-PSK and SAE configuration and enable PMF so that the
+# station gets configured in WPA3-Personal transition mode (supports both
+# WPA2-Personal (PSK) and WPA3-Personal (SAE) APs).
+#wps_cred_add_sae=0
+
# Vendor attribute in WPS M1, e.g., Windows 7 Vertical Pairing
# The vendor attribute contents to be added in M1 (hex string)
#wps_vendor_ext_m1=000137100100020001
@@ -310,6 +318,15 @@ fast_reauth=1
# of APs when using ap_scan=1 mode.
#bss_max_count=200
+# BSS expiration age in seconds. A BSS will be removed from the local cache
+# if it is not in use and has not been seen for this time. Default is 180.
+#bss_expiration_age=180
+
+# BSS expiration after number of scans. A BSS will be removed from the local
+# cache if it is not seen in this number of scans.
+# Default is 2.
+#bss_expiration_scan_count=2
+
# Automatic scan
# This is an optional set of parameters for automatic scanning
# within an interface in following format:
@@ -377,11 +394,16 @@ fast_reauth=1
# Enabled SAE finite cyclic groups in preference order
# By default (if this parameter is not set), the mandatory group 19 (ECC group
-# defined over a 256-bit prime order field) is preferred, but other groups are
-# also enabled. If this parameter is set, the groups will be tried in the
-# indicated order. The group values are listed in the IANA registry:
+# defined over a 256-bit prime order field, NIST P-256) is preferred and groups
+# 20 (NIST P-384) and 21 (NIST P-521) are also enabled. If this parameter is
+# set, the groups will be tried in the indicated order.
+# The group values are listed in the IANA registry:
# http://www.iana.org/assignments/ipsec-registry/ipsec-registry.xml#ipsec-registry-9
-#sae_groups=21 20 19 26 25
+# Note that groups 1, 2, 5, 22, 23, and 24 should not be used in production
+# purposes due limited security (see RFC 8247). Groups that are not as strong as
+# group 19 (ECC, NIST P-256) are unlikely to be useful for production use cases
+# since all implementations are required to support group 19.
+#sae_groups=19 20 21
# Default value for DTIM period (if not overridden in network block)
#dtim_period=2
@@ -1167,6 +1189,12 @@ fast_reauth=1
# certificate may include additional sub-level labels in addition to the
# required labels.
#
+# More than one match string can be provided by using semicolons to
+# separate the strings (e.g., example.org;example.com). When multiple
+# strings are specified, a match with any one of the values is considered
+# a sufficient match for the certificate, i.e., the conditions are ORed
+# together.
+#
# For example, domain_suffix_match=example.com would match
# test.example.com but would not match test-example.com.
# domain_match: Constraint for server domain name
@@ -1179,6 +1207,12 @@ fast_reauth=1
# no subdomains or wildcard matches are allowed. Case-insensitive
# comparison is used, so "Example.com" matches "example.com", but would
# not match "test.Example.com".
+#
+# More than one match string can be provided by using semicolons to
+# separate the strings (e.g., example.org;example.com). When multiple
+# strings are specified, a match with any one of the values is considered
+# a sufficient match for the certificate, i.e., the conditions are ORed
+# together.
# phase1: Phase1 (outer authentication, i.e., TLS tunnel) parameters
# (string with field-value pairs, e.g., "peapver=0" or
# "peapver=1 peaplabel=1")
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index ee581e7..16e4db6 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -504,9 +504,6 @@ struct wpa_supplicant {
#ifdef CONFIG_MATCH_IFACE
int matched;
#endif /* CONFIG_MATCH_IFACE */
-#ifdef CONFIG_CTRL_IFACE_DBUS
- char *dbus_path;
-#endif /* CONFIG_CTRL_IFACE_DBUS */
#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
char *dbus_new_path;
char *dbus_groupobj_path;
@@ -751,6 +748,10 @@ struct wpa_supplicant {
unsigned int wnmsleep_used:1;
unsigned int owe_transition_select:1;
unsigned int owe_transition_search:1;
+ unsigned int connection_set:1;
+ unsigned int connection_ht:1;
+ unsigned int connection_vht:1;
+ unsigned int connection_he:1;
struct os_reltime last_mac_addr_change;
int last_mac_addr_style;
@@ -1206,9 +1207,7 @@ struct wpa_supplicant {
int last_auth_timeout_sec;
#ifdef CONFIG_DPP
- struct dl_list dpp_bootstrap; /* struct dpp_bootstrap_info */
- struct dl_list dpp_configurator; /* struct dpp_configurator */
- int dpp_init_done;
+ struct dpp_global *dpp;
struct dpp_authentication *dpp_auth;
struct wpa_radio_work *dpp_listen_work;
unsigned int dpp_pending_listen_freq;
@@ -1235,6 +1234,9 @@ struct wpa_supplicant {
unsigned int dpp_resp_wait_time;
unsigned int dpp_resp_max_tries;
unsigned int dpp_resp_retry_time;
+#ifdef CONFIG_DPP2
+ struct dpp_pfs *dpp_pfs;
+#endif /* CONFIG_DPP2 */
#ifdef CONFIG_TESTING_OPTIONS
char *dpp_config_obj_override;
char *dpp_discovery_override;
@@ -1400,6 +1402,7 @@ struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
void mbo_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss, const u8 *sa,
const u8 *data, size_t slen);
+void wpas_update_mbo_connect_params(struct wpa_supplicant *wpa_s);
/* op_classes.c */
enum chan_allowed {
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 1a2677b..0579274 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -530,11 +530,18 @@ static int wpa_supplicant_wps_cred(void *ctx,
case WPS_AUTH_WPA2PSK:
ssid->auth_alg = WPA_AUTH_ALG_OPEN;
ssid->key_mgmt = WPA_KEY_MGMT_PSK;
+ if (wpa_s->conf->wps_cred_add_sae &&
+ cred->key_len != 2 * PMK_LEN) {
+ ssid->key_mgmt |= WPA_KEY_MGMT_SAE;
+#ifdef CONFIG_IEEE80211W
+ ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
+#endif /* CONFIG_IEEE80211W */
+ }
ssid->proto = WPA_PROTO_RSN;
break;
}
- if (ssid->key_mgmt == WPA_KEY_MGMT_PSK) {
+ if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
if (cred->key_len == 2 * PMK_LEN) {
if (hexstr2bin((const char *) cred->key, ssid->psk,
PMK_LEN)) {
@@ -1137,9 +1144,10 @@ static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
- int p2p_group)
+ int p2p_group, int multi_ap_backhaul_sta)
{
struct wpa_ssid *ssid;
+ char phase1[32];
#ifdef CONFIG_AP
if (wpa_s->ap_iface) {
@@ -1177,10 +1185,14 @@ int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
}
}
#endif /* CONFIG_P2P */
- if (wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0) < 0)
+ os_snprintf(phase1, sizeof(phase1), "pbc=1%s",
+ multi_ap_backhaul_sta ? " multi_ap=1" : "");
+ if (wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
return -1;
if (wpa_s->wps_fragment_size)
ssid->eap.fragment_size = wpa_s->wps_fragment_size;
+ if (multi_ap_backhaul_sta)
+ ssid->multi_ap_backhaul_sta = 1;
wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
wpa_s, NULL);
diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h
index c8fe47e..0fbc851 100644
--- a/wpa_supplicant/wps_supplicant.h
+++ b/wpa_supplicant/wps_supplicant.h
@@ -30,7 +30,7 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s);
int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s);
enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid);
int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
- int p2p_group);
+ int p2p_group, int multi_ap_backhaul_sta);
int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
const char *pin, int p2p_group, u16 dev_pw_id);
void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s);