diff options
author | Andrej Shadura <andrewsh@debian.org> | 2019-04-27 10:46:08 +0200 |
---|---|---|
committer | Andrej Shadura <andrewsh@debian.org> | 2019-04-27 10:46:08 +0200 |
commit | 070dbdae8a92f0081104f7e7f5ef3b3067ed9cd4 (patch) | |
tree | 77b3437498154c7e7341e6dcf9cbd7e1c1b3d36d /wpa_supplicant | |
parent | bf44a8f269f77f3309920b07f126d2c9b1ee5682 (diff) |
New upstream version 2.8
Diffstat (limited to 'wpa_supplicant')
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(¶ms, 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, ¶ms); } @@ -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(¶ms, 0, sizeof(params)); + wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss, + wpa_s->current_ssid, ¶ms, NULL); + if (!wpa_ie) + return; + + wpa_drv_update_connect_params(wpa_s, ¶ms, 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); |