diff options
Diffstat (limited to 'wpa_supplicant')
104 files changed, 4340 insertions, 4395 deletions
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index a6809956d86f..529693131308 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -207,6 +207,12 @@ L_CFLAGS += -DCONFIG_SUITEB192 NEED_SHA384=y endif +ifdef CONFIG_OCV +L_CFLAGS += -DCONFIG_OCV +OBJS += src/common/ocv.c +CONFIG_IEEE80211W=y +endif + ifdef CONFIG_IEEE80211W L_CFLAGS += -DCONFIG_IEEE80211W NEED_SHA256=y @@ -253,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 @@ -1416,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 +OBJS += dbus/dbus_new_introspect.c +L_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO endif -DBUS_CFLAGS += $(DBUS_INCLUDE) +L_CFLAGS += $(DBUS_INCLUDE) endif -ifdef DBUS -DBUS_CFLAGS += -DCONFIG_DBUS -DBUS_OBJS += dbus/dbus_common.c -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 bf4daaa4cb1e..89119e7bd18f 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 c2e93e20b58a..e81238e3924e 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 @@ -240,6 +239,12 @@ CFLAGS += -DCONFIG_SUITEB192 NEED_SHA384=y endif +ifdef CONFIG_OCV +CFLAGS += -DCONFIG_OCV +OBJS += ../src/common/ocv.o +CONFIG_IEEE80211W=y +endif + ifdef CONFIG_IEEE80211W CFLAGS += -DCONFIG_IEEE80211W NEED_SHA256=y @@ -286,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 @@ -1526,6 +1534,9 @@ endif ifdef CONFIG_NO_RANDOM_POOL CFLAGS += -DCONFIG_NO_RANDOM_POOL else +ifdef CONFIG_GETRANDOM +CFLAGS += -DCONFIG_GETRANDOM +endif OBJS += ../src/crypto/random.o endif @@ -1567,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) @@ -1604,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 @@ -1981,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/README b/wpa_supplicant/README index 2a3265f21eaa..bbc86b137424 100644 --- a/wpa_supplicant/README +++ b/wpa_supplicant/README @@ -1,7 +1,7 @@ -WPA Supplicant +wpa_supplicant ============== -Copyright (c) 2003-2018, Jouni Malinen <j@w1.fi> and contributors +Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors All Rights Reserved. This program is licensed under the BSD license (the one with diff --git a/wpa_supplicant/README-DPP b/wpa_supplicant/README-DPP new file mode 100644 index 000000000000..6496733735d4 --- /dev/null +++ b/wpa_supplicant/README-DPP @@ -0,0 +1,195 @@ +Device Provisioning Protocol (DPP) +================================== + +This document describes how the Device Provisioning Protocol (DPP) +implementation in wpa_supplicant and hostapd can be configured and how +the STA device and AP can be configured to connect each other using DPP +Connector mechanism. + +Introduction to DPP +------------------- + +Device provisioning Protocol allows enrolling of interface-less devices +in a secure Wi-Fi network using many methods like QR code based +authentication( detailed below ), PKEX based authentication etc. In DPP +a Configurator is used to provide network credentials to the devices. +The three phases of DPP connection are authentication, configuration and +network introduction. + +Build config setup +------------------ + +The following changes must go in the config file used to compile hostapd +and wpa_supplicant. + +wpa_supplicant build config +--------------------------- + +Enable DPP and protected management frame in wpa_supplicant build config +file + +CONFIG_IEEE80211W=y +CONFIG_DPP=y + +hostapd build config +-------------------- + +Enable DPP and protected management frame in hostapd build config file + +CONFIG_IEEE80211W=y +CONFIG_DPP=y + +Configurator build config +------------------------- + +Any STA or AP device can act as a Configurator. Enable DPP and protected +managment frames in build config. For an AP to act as Configurator, +Interworking needs to be enabled. For wpa_supplicant it is not required. + +CONFIG_INTERWORKING=y + + +Sample supplicant config file before provisioning +------------------------------------------------- + +ctrl_interface=DIR=/var/run/wpa_supplicant +ctrl_interface_group=0 +update_config=1 +pmf=2 +dpp_config_processing=2 + +Sample hostapd config file before provisioning +---------------------------------------------- + +interface=wlan0 +driver=nl80211 +ctrl_interface=/var/run/hostapd +ssid=test +channel=1 +wpa=2 +wpa_key_mgmt=DPP +ieee80211w=1 +wpa_pairwise=CCMP +rsn_pairwise=CCMP + + +Pre-requisites +-------------- + +It is assumed that an AP and client station are up by running hostapd +and wpa_supplicant using respective config files. + + +Creating Configurator +--------------------- + +Add a Configurator over the control interface (wpa_cli/hostapd_cli) + +> dpp_configurator_add +(returns id) + +To get key of Configurator +> dpp_configurator_get_key <id> + + +How to configure an enrollee using Configurator +----------------------------------------------- + +On enrollee side: + +Generate QR code for the device. Store the qr code id returned by the +command. + +> dpp_bootstrap_gen type=qrcode mac=<mac-address-of-device> chan=<operating-channel> key=<key of the device> +(returns bootstrapping info id) + +Get QR Code of device using the bootstrap info id. +> dpp_bootstrap_get_uri <bootstrap-id> + +Make device listen to DPP request (The central frequency of channel 1 is +2412) in case if enrollee is a client device. + +> dpp_listen <frequency> + +On Configurator side: + +Enter the QR Code in the Configurator. +> dpp_qr_code "<QR-Code-read-from-enrollee>" + +On successfully adding QR Code, a bootstrapping info id is returned. + +Send provisioning request to enrollee. (conf is ap-dpp if enrollee is an +AP. conf is sta-dpp if enrollee is a client) +> dpp_auth_init peer=<qr-code-id> conf=<ap-dpp|sta-dpp> configurator=<configurator-id> + +The DPP values will be printed in the console. Save this values into the +config file. If the enrollee is an AP, we need to manually write these +values to the hostapd config file. If the enrollee is a client device, +these details can be automatically saved to config file using the +following command. + +> save_config + +To set values in runtime for AP enrollees + +> set dpp_connector <Connector-value-printed-on-console> +> set dpp_csign <csign-value-on-console> +> set dpp_netaccesskey <netaccess-value-on-console> + +To set values in runtime for client enrollees, set dpp_config_processing +to 2 in wpa_supplicant conf file. + +Once the values are set in run-time (if not set in run-time, but saved +in config files, they are taken up in next restart), the client device +will automatically connect to the already provisioned AP and connection +will be established. + + +Self-configuring a device +------------------------- + +It is possible for a device to configure itself if it is the +Configurator for the network. + +Create a Configurator in the device and use the dpp_configurator_sign +command to get DPP credentials. + +> dpp_configurator_add +(returns configurator id) +> dpp_configurator_sign conf=<ap-dpp|sta-dpp> configurator=<configurator-id> + + +Sample AP configuration files after provisioning +------------------------------------------------ + +interface=wlan0 +driver=nl80211 +ctrl_interface=/var/run/hostapd +ssid=test +channel=1 +wpa=2 +wpa_key_mgmt=DPP +ieee80211w=1 +wpa_pairwise=CCMP +rsn_pairwise=CCMP +dpp_connector=<Connector value provided by Configurator> +dpp_csign=<C-Sign-Key value provided by Configurator> +dpp_netaccesskey=<Net access key provided by Configurator> + + +Sample station configuration file after provisioning +---------------------------------------------------- + +ctrl_interface=DIR=/var/run/wpa_supplicant +ctrl_interface_group=0 +update_config=1 +pmf=2 +dpp_config_processing=2 +network={ + ssid="test" + key_mgmt=DPP + ieee80211w=2 + dpp_connector="<Connector value provided by Configurator>" + dpp_netaccesskey=<Net access key provided by Configurator> + dpp_csign=<C-sign-key value provided by Configurator> +} diff --git a/wpa_supplicant/README-P2P b/wpa_supplicant/README-P2P index 23ac7fa056a4..55a60a296ad7 100644 --- a/wpa_supplicant/README-P2P +++ b/wpa_supplicant/README-P2P @@ -150,7 +150,7 @@ join-a-group style PD instead of GO Negotiation style PD. p2p_connect <peer device address> <pbc|pin|PIN#|p2ps> [display|keypad|p2ps] [persistent|persistent=<network id>] [join|auth] - [go_intent=<0..15>] [freq=<in MHz>] [ht40] [vht] [provdisc] [auto] + [go_intent=<0..15>] [freq=<in MHz>] [ht40] [vht] [he] [provdisc] [auto] [ssid=<hexdump>] Start P2P group formation with a discovered P2P peer. This includes @@ -262,7 +262,7 @@ Parameters definition: session_mac - Mandatory MAC address that owns/initiated the session p2p_group_add [persistent|persistent=<network id>] [freq=<freq in MHz>] - [ht40] [vht] + [ht40] [vht] [he] Set up a P2P group owner manually (i.e., without group owner negotiation with a specific peer). This is also known as autonomous @@ -558,7 +558,7 @@ Remove all local services from internal SD query processing. Invitation p2p_invite [persistent=<network id>|group=<group ifname>] [peer=address] - [go_dev_addr=address] [freq=<freq in MHz>] [ht40] [vht] + [go_dev_addr=address] [freq=<freq in MHz>] [ht40] [vht] [he] [pref=<MHz>] Invite a peer to join a group (e.g., group=wlan1) or to reinvoke a diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config index c97f591311d3..6536c110a3ca 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 @@ -280,6 +277,9 @@ CONFIG_L2_PACKET=linux # Driver support is also needed for IEEE 802.11w. CONFIG_IEEE80211W=y +# Support Operating Channel Validation +#CONFIG_OCV=y + # Select TLS implementation # openssl = OpenSSL (default) # gnutls = GnuTLS @@ -327,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 @@ -487,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 @@ -517,8 +513,6 @@ CONFIG_WIFI_DISPLAY=y #CONFIG_MBO=y # Fast Initial Link Setup (FILS) (IEEE 802.11ai) -# Note: This is an experimental and not yet complete implementation. This -# should not be enabled for production use. #CONFIG_FILS=y # Support RSN on IBSS networks diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index ea846a0fad4b..4e191694296b 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -336,6 +336,12 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, 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; @@ -494,6 +500,10 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, bss->ieee80211w = ssid->ieee80211w; #endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_OCV + bss->ocv = ssid->ocv; +#endif /* CONFIG_OCV */ + #ifdef CONFIG_WPS /* * Enable WPS by default for open and WPA/WPA2-Personal network, but @@ -1379,13 +1389,16 @@ int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht, int offset, int width, int cf1, int cf2) { - if (!wpa_s->ap_iface) - return; + struct hostapd_iface *iface = wpa_s->ap_iface; + if (!iface) + iface = wpa_s->ifmsh; + if (!iface) + return; wpa_s->assoc_freq = freq; if (wpa_s->current_ssid) wpa_s->current_ssid->frequency = freq; - hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht, + hostapd_event_ch_switch(iface->bss[0], freq, ht, offset, width, cf1, cf2); } @@ -1582,10 +1595,14 @@ int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd) void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + struct hostapd_iface *iface = wpa_s->ap_iface; + + if (!iface) + iface = wpa_s->ifmsh; + if (!iface || !iface->bss[0]) return; wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq); - hostapd_dfs_radar_detected(wpa_s->ap_iface, radar->freq, + hostapd_dfs_radar_detected(iface, radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); @@ -1595,10 +1612,14 @@ void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s, void wpas_ap_event_dfs_cac_started(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + struct hostapd_iface *iface = wpa_s->ap_iface; + + if (!iface) + iface = wpa_s->ifmsh; + if (!iface || !iface->bss[0]) return; wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq); - hostapd_dfs_start_cac(wpa_s->ap_iface, radar->freq, + hostapd_dfs_start_cac(iface, radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); } @@ -1607,10 +1628,14 @@ void wpas_ap_event_dfs_cac_started(struct wpa_supplicant *wpa_s, void wpas_ap_event_dfs_cac_finished(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + struct hostapd_iface *iface = wpa_s->ap_iface; + + if (!iface) + iface = wpa_s->ifmsh; + if (!iface || !iface->bss[0]) return; wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq); - hostapd_dfs_complete_cac(wpa_s->ap_iface, 1, radar->freq, + hostapd_dfs_complete_cac(iface, 1, radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); } @@ -1619,10 +1644,14 @@ void wpas_ap_event_dfs_cac_finished(struct wpa_supplicant *wpa_s, void wpas_ap_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + struct hostapd_iface *iface = wpa_s->ap_iface; + + if (!iface) + iface = wpa_s->ifmsh; + if (!iface || !iface->bss[0]) return; wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq); - hostapd_dfs_complete_cac(wpa_s->ap_iface, 0, radar->freq, + hostapd_dfs_complete_cac(iface, 0, radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); } @@ -1631,10 +1660,14 @@ void wpas_ap_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s, void wpas_ap_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + struct hostapd_iface *iface = wpa_s->ap_iface; + + if (!iface) + iface = wpa_s->ifmsh; + if (!iface || !iface->bss[0]) return; wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq); - hostapd_dfs_nop_finished(wpa_s->ap_iface, radar->freq, + hostapd_dfs_nop_finished(iface, radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); } diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index 3a41db98e5ba..9b19f37affa0 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -1,6 +1,6 @@ /* * BSS table - * Copyright (c) 2009-2015, Jouni Malinen <j@w1.fi> + * Copyright (c) 2009-2019, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -1337,3 +1337,10 @@ const u8 * wpa_bss_get_fils_cache_id(struct wpa_bss *bss) return NULL; } #endif /* CONFIG_FILS */ + + +int wpa_bss_ext_capab(const struct wpa_bss *bss, unsigned int capab) +{ + return ieee802_11_ext_capab(wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB), + capab); +} diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h index 5251b2c354e3..3ce8cd3f429a 100644 --- a/wpa_supplicant/bss.h +++ b/wpa_supplicant/bss.h @@ -1,6 +1,6 @@ /* * BSS table - * Copyright (c) 2009-2015, Jouni Malinen <j@w1.fi> + * Copyright (c) 2009-2019, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -148,6 +148,7 @@ int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates); struct wpa_bss_anqp * wpa_bss_anqp_alloc(void); int wpa_bss_anqp_unshare_alloc(struct wpa_bss *bss); const u8 * wpa_bss_get_fils_cache_id(struct wpa_bss *bss); +int wpa_bss_ext_capab(const struct wpa_bss *bss, unsigned int capab); static inline int bss_is_dmg(const struct wpa_bss *bss) { diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index c43960697dc3..2058175f885e 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1043,6 +1043,30 @@ static char * wpa_config_write_key_mgmt(const struct parse_data *data, #endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_FILS */ +#ifdef CONFIG_DPP + if (ssid->key_mgmt & WPA_KEY_MGMT_DPP) { + ret = os_snprintf(pos, end - pos, "%sDPP", + pos == buf ? "" : " "); + if (os_snprintf_error(end - pos, ret)) { + end[-1] = '\0'; + return buf; + } + pos += ret; + } +#endif /* CONFIG_DPP */ + +#ifdef CONFIG_OWE + if (ssid->key_mgmt & WPA_KEY_MGMT_OWE) { + ret = os_snprintf(pos, end - pos, "%sOWE", + pos == buf ? "" : " "); + if (os_snprintf_error(end - pos, ret)) { + end[-1] = '\0'; + return buf; + } + pos += ret; + } +#endif /* CONFIG_OWE */ + if (pos == buf) { os_free(buf); buf = NULL; @@ -1978,16 +2002,21 @@ static int wpa_config_parse_mka_cak(const struct parse_data *data, struct wpa_ssid *ssid, int line, const char *value) { - if (hexstr2bin(value, ssid->mka_cak, MACSEC_CAK_LEN) || - value[MACSEC_CAK_LEN * 2] != '\0') { + size_t len; + + len = os_strlen(value); + if (len > 2 * MACSEC_CAK_MAX_LEN || + (len != 2 * 16 && len != 2 * 32) || + hexstr2bin(value, ssid->mka_cak, len / 2)) { wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CAK '%s'.", line, value); return -1; } - + ssid->mka_cak_len = len / 2; ssid->mka_psk_set |= MKA_PSK_SET_CAK; - wpa_hexdump_key(MSG_MSGDUMP, "MKA-CAK", ssid->mka_cak, MACSEC_CAK_LEN); + wpa_hexdump_key(MSG_MSGDUMP, "MKA-CAK", ssid->mka_cak, + ssid->mka_cak_len); return 0; } @@ -1996,8 +2025,18 @@ static int wpa_config_parse_mka_ckn(const struct parse_data *data, struct wpa_ssid *ssid, int line, const char *value) { - if (hexstr2bin(value, ssid->mka_ckn, MACSEC_CKN_LEN) || - value[MACSEC_CKN_LEN * 2] != '\0') { + size_t len; + + len = os_strlen(value); + if (len > 2 * MACSEC_CKN_MAX_LEN || /* too long */ + len < 2 || /* too short */ + len % 2 != 0 /* not an integral number of bytes */) { + wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CKN '%s'.", + line, value); + return -1; + } + ssid->mka_ckn_len = len / 2; + if (hexstr2bin(value, ssid->mka_ckn, ssid->mka_ckn_len)) { wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CKN '%s'.", line, value); return -1; @@ -2005,7 +2044,8 @@ static int wpa_config_parse_mka_ckn(const struct parse_data *data, ssid->mka_psk_set |= MKA_PSK_SET_CKN; - wpa_hexdump_key(MSG_MSGDUMP, "MKA-CKN", ssid->mka_ckn, MACSEC_CKN_LEN); + wpa_hexdump_key(MSG_MSGDUMP, "MKA-CKN", ssid->mka_ckn, + ssid->mka_ckn_len); return 0; } @@ -2018,7 +2058,7 @@ static char * wpa_config_write_mka_cak(const struct parse_data *data, if (!(ssid->mka_psk_set & MKA_PSK_SET_CAK)) return NULL; - return wpa_config_write_string_hex(ssid->mka_cak, MACSEC_CAK_LEN); + return wpa_config_write_string_hex(ssid->mka_cak, ssid->mka_cak_len); } @@ -2027,7 +2067,7 @@ static char * wpa_config_write_mka_ckn(const struct parse_data *data, { if (!(ssid->mka_psk_set & MKA_PSK_SET_CKN)) return NULL; - return wpa_config_write_string_hex(ssid->mka_ckn, MACSEC_CKN_LEN); + return wpa_config_write_string_hex(ssid->mka_ckn, ssid->mka_ckn_len); } #endif /* NO_CONFIG_WRITE */ @@ -2035,6 +2075,43 @@ static char * wpa_config_write_mka_ckn(const struct parse_data *data, #endif /* CONFIG_MACSEC */ +#ifdef CONFIG_OCV + +static int wpa_config_parse_ocv(const struct parse_data *data, + struct wpa_ssid *ssid, int line, + const char *value) +{ + char *end; + + ssid->ocv = strtol(value, &end, 0); + if (*end || ssid->ocv < 0 || ssid->ocv > 1) { + wpa_printf(MSG_ERROR, "Line %d: Invalid ocv value '%s'.", + line, value); + return -1; + } + if (ssid->ocv && ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION) + ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL; + return 0; +} + + +#ifndef NO_CONFIG_WRITE +static char * wpa_config_write_ocv(const struct parse_data *data, + struct wpa_ssid *ssid) +{ + char *value = os_malloc(20); + + if (!value) + return NULL; + os_snprintf(value, 20, "%d", ssid->ocv); + value[20 - 1] = '\0'; + return value; +} +#endif /* NO_CONFIG_WRITE */ + +#endif /* CONFIG_OCV */ + + static int wpa_config_parse_peerkey(const struct parse_data *data, struct wpa_ssid *ssid, int line, const char *value) @@ -2180,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) }, @@ -2190,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) }, @@ -2238,6 +2317,9 @@ static const struct parse_data ssid_fields[] = { #ifdef CONFIG_IEEE80211W { INT_RANGE(ieee80211w, 0, 2) }, #endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_OCV + { FUNC(ocv) }, +#endif /* CONFIG_OCV */ { FUNC(peerkey) /* obsolete - removed */ }, { INT_RANGE(mixed_cell, 0, 1) }, { INT_RANGE(frequency, 0, 65000) }, @@ -2267,6 +2349,8 @@ static const struct parse_data ssid_fields[] = { { INT_RANGE(disable_sgi, 0, 1) }, { INT_RANGE(disable_ldpc, 0, 1) }, { INT_RANGE(ht40_intolerant, 0, 1) }, + { INT_RANGE(tx_stbc, -1, 1) }, + { INT_RANGE(rx_stbc, -1, 3) }, { INT_RANGE(disable_max_amsdu, -1, 1) }, { INT_RANGE(ampdu_factor, -1, 3) }, { INT_RANGE(ampdu_density, -1, 7) }, @@ -2299,6 +2383,8 @@ static const struct parse_data ssid_fields[] = { #ifdef CONFIG_MACSEC { INT_RANGE(macsec_policy, 0, 1) }, { INT_RANGE(macsec_integ_only, 0, 1) }, + { INT_RANGE(macsec_replay_protect, 0, 1) }, + { INT(macsec_replay_window) }, { INT_RANGE(macsec_port, 1, 65534) }, { INT_RANGE(mka_priority, 0, 255) }, { FUNC_KEY(mka_cak) }, @@ -2320,6 +2406,7 @@ static const struct parse_data ssid_fields[] = { #endif /* CONFIG_DPP */ { INT_RANGE(owe_group, 0, 65535) }, { INT_RANGE(owe_only, 0, 1) }, + { INT_RANGE(multi_ap_backhaul_sta, 0, 1) }, }; #undef OFFSET @@ -2440,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); @@ -2450,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); @@ -2786,6 +2875,8 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid) ssid->disable_ht40 = DEFAULT_DISABLE_HT40; ssid->disable_sgi = DEFAULT_DISABLE_SGI; ssid->disable_ldpc = DEFAULT_DISABLE_LDPC; + ssid->tx_stbc = DEFAULT_TX_STBC; + ssid->rx_stbc = DEFAULT_RX_STBC; ssid->disable_max_amsdu = DEFAULT_DISABLE_MAX_AMSDU; ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR; ssid->ampdu_density = DEFAULT_AMPDU_DENSITY; @@ -2816,6 +2907,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid) ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER; #endif /* CONFIG_MACSEC */ ssid->mac_addr = -1; + ssid->max_oper_chwidth = DEFAULT_MAX_OPER_CHWIDTH; } @@ -4440,6 +4532,21 @@ static int wpa_config_process_p2p_no_go_freq( return 0; } + +static int wpa_config_process_p2p_device_persistent_mac_addr( + const struct global_parse_data *data, + struct wpa_config *config, int line, const char *pos) +{ + if (hwaddr_aton2(pos, config->p2p_device_persistent_mac_addr) < 0) { + wpa_printf(MSG_ERROR, + "Line %d: Invalid p2p_device_persistent_mac_addr '%s'", + line, pos); + return -1; + } + + return 0; +} + #endif /* CONFIG_P2P */ @@ -4650,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 @@ -4672,6 +4780,7 @@ static const struct global_parse_data global_fields[] = { { INT_RANGE(p2p_optimize_listen_chan, 0, 1), 0 }, { INT(p2p_go_ht40), 0 }, { INT(p2p_go_vht), 0 }, + { INT(p2p_go_he), 0 }, { INT(p2p_disabled), 0 }, { INT_RANGE(p2p_go_ctwindow, 0, 127), 0 }, { INT(p2p_no_group_iface), 0 }, @@ -4681,6 +4790,9 @@ static const struct global_parse_data global_fields[] = { { IPV4(ip_addr_start), 0 }, { IPV4(ip_addr_end), 0 }, { INT_RANGE(p2p_cli_probe, 0, 1), 0 }, + { INT(p2p_device_random_mac_addr), 0 }, + { FUNC(p2p_device_persistent_mac_addr), 0 }, + { INT(p2p_interface_random_mac_addr), 0 }, #endif /* CONFIG_P2P */ { FUNC(country), CFG_CHANGED_COUNTRY }, { INT(bss_max_count), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index cd7571f59329..abbd8c90e2b5 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) @@ -1079,6 +1089,16 @@ struct wpa_config { int p2p_go_vht; /** + * p2p_go_he - Default mode for 11ax HE enable when operating as GO + * + * This will take effect for p2p_group_add, p2p_connect, and p2p_invite. + * Note that regulatory constraints and driver capabilities are + * consulted anyway, so setting it to 1 can't do real harm. + * By default: 0 (disabled) + */ + int p2p_go_he; + + /** * p2p_go_ctwindow - CTWindow to use when operating as GO * * By default: 0 (no CTWindow). Values 0-127 can be used to indicate @@ -1478,6 +1498,35 @@ struct wpa_config { * 1 = enabled (true) */ int coloc_intf_reporting; + + /** + * p2p_device_random_mac_addr - P2P Device MAC address policy default + * + * 0 = use permanent MAC address + * 1 = use random MAC address on creating the interface if there is no + * persistent groups. + * + * By default, permanent MAC address is used. + */ + int p2p_device_random_mac_addr; + + /** + * p2p_device_persistent_mac_addr - Record last used MAC address + * + * If there are saved persistent groups, P2P cannot generate another + * random MAC address, and need to restore to last used MAC address. + */ + u8 p2p_device_persistent_mac_addr[ETH_ALEN]; + + /** + * p2p_interface_random_mac_addr - P2P Interface MAC address policy default + * + * 0 = use permanent MAC address + * 1 = use random MAC address on creating the interface. + * + * By default, permanent MAC address is used. + */ + int p2p_interface_random_mac_addr; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 09115e19dc2d..26f6ee147844 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -160,6 +160,15 @@ static int wpa_config_validate_network(struct wpa_ssid *ssid, int line) errors++; } +#ifdef CONFIG_OCV + if (ssid->ocv && ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION) { + wpa_printf(MSG_ERROR, + "Line %d: PMF needs to be enabled whenever using OCV", + line); + errors++; + } +#endif /* CONFIG_OCV */ + return errors; } @@ -484,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); } @@ -773,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); @@ -783,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); @@ -829,7 +840,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INT(vht); INT_DEF(ht, 1); INT(ht40); - INT(max_oper_chwidth); + INT_DEF(max_oper_chwidth, DEFAULT_MAX_OPER_CHWIDTH); INT(vht_center_freq1); INT(vht_center_freq2); INT(pbss); @@ -853,6 +864,8 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) write_mka_cak(f, ssid); write_mka_ckn(f, ssid); INT(macsec_integ_only); + INT(macsec_replay_protect); + INT(macsec_replay_window); INT(macsec_port); INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER); #endif /* CONFIG_MACSEC */ @@ -880,12 +893,15 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) #endif /* CONFIG_DPP */ INT(owe_group); INT(owe_only); + INT(multi_ap_backhaul_sta); #ifdef CONFIG_HT_OVERRIDES INT_DEF(disable_ht, DEFAULT_DISABLE_HT); INT_DEF(disable_ht40, DEFAULT_DISABLE_HT40); INT_DEF(disable_sgi, DEFAULT_DISABLE_SGI); INT_DEF(disable_ldpc, DEFAULT_DISABLE_LDPC); INT(ht40_intolerant); + INT_DEF(tx_stbc, DEFAULT_TX_STBC); + INT_DEF(rx_stbc, DEFAULT_RX_STBC); INT_DEF(disable_max_amsdu, DEFAULT_DISABLE_MAX_AMSDU); INT_DEF(ampdu_factor, DEFAULT_AMPDU_FACTOR); INT_DEF(ampdu_density, DEFAULT_AMPDU_DENSITY); @@ -1173,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); @@ -1248,6 +1267,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) fprintf(f, "p2p_go_ht40=%d\n", config->p2p_go_ht40); if (config->p2p_go_vht) fprintf(f, "p2p_go_vht=%d\n", config->p2p_go_vht); + if (config->p2p_go_he) + fprintf(f, "p2p_go_he=%d\n", config->p2p_go_he); if (config->p2p_go_ctwindow != DEFAULT_P2P_GO_CTWINDOW) fprintf(f, "p2p_go_ctwindow=%d\n", config->p2p_go_ctwindow); if (config->p2p_disabled) @@ -1514,6 +1535,15 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->coloc_intf_reporting) fprintf(f, "coloc_intf_reporting=%d\n", config->coloc_intf_reporting); + if (config->p2p_device_random_mac_addr) + fprintf(f, "p2p_device_random_mac_addr=%d\n", + config->p2p_device_random_mac_addr); + if (!is_zero_ether_addr(config->p2p_device_persistent_mac_addr)) + fprintf(f, "p2p_device_persistent_mac_addr=" MACSTR "\n", + MAC2STR(config->p2p_device_persistent_mac_addr)); + if (config->p2p_interface_random_mac_addr) + fprintf(f, "p2p_interface_random_mac_addr=%d\n", + config->p2p_interface_random_mac_addr); } #endif /* CONFIG_NO_CONFIG_WRITE */ diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index d2a52d760089..1b2b1f1a36f1 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -33,10 +33,13 @@ #define DEFAULT_DISABLE_HT40 0 #define DEFAULT_DISABLE_SGI 0 #define DEFAULT_DISABLE_LDPC 0 +#define DEFAULT_TX_STBC -1 /* no change */ +#define DEFAULT_RX_STBC -1 /* no change */ #define DEFAULT_DISABLE_MAX_AMSDU -1 /* no change */ #define DEFAULT_AMPDU_FACTOR -1 /* no change */ #define DEFAULT_AMPDU_DENSITY -1 /* no change */ #define DEFAULT_USER_SELECTED_SIM 1 +#define DEFAULT_MAX_OPER_CHWIDTH -1 struct psk_list_entry { struct dl_list list; @@ -457,6 +460,17 @@ struct wpa_ssid { enum mfp_options ieee80211w; #endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_OCV + /** + * ocv - Enable/disable operating channel validation + * + * If this parameter is set to 1, stations will exchange OCI element + * to cryptographically verify the operating channel. Setting this + * parameter to 0 disables this option. Default value: 0. + */ + int ocv; +#endif /* CONFIG_OCV */ + /** * frequency - Channel frequency in megahertz (MHz) for IBSS * @@ -505,6 +519,8 @@ struct wpa_ssid { int vht; + int he; + int max_oper_chwidth; unsigned int vht_center_freq1; @@ -682,6 +698,22 @@ struct wpa_ssid { * By default (empty string): Use whatever the OS has configured. */ char *ht_mcs; + + /** + * tx_stbc - Indicate STBC support for TX streams + * + * Value: -1..1, by default (-1): use whatever the OS or card has + * configured. See IEEE Std 802.11-2016, 9.4.2.56.2. + */ + int tx_stbc; + + /** + * rx_stbc - Indicate STBC support for RX streams + * + * Value: -1..3, by default (-1): use whatever the OS or card has + * configured. See IEEE Std 802.11-2016, 9.4.2.56.2. + */ + int rx_stbc; #endif /* CONFIG_HT_OVERRIDES */ #ifdef CONFIG_VHT_OVERRIDES @@ -774,6 +806,33 @@ struct wpa_ssid { int macsec_integ_only; /** + * macsec_replay_protect - Enable MACsec replay protection + * + * This setting applies only when MACsec is in use, i.e., + * - macsec_policy is enabled + * - the key server has decided to enable MACsec + * + * 0: Replay protection disabled (default) + * 1: Replay protection enabled + */ + int macsec_replay_protect; + + /** + * macsec_replay_window - MACsec replay protection window + * + * A window in which replay is tolerated, to allow receipt of frames + * that have been misordered by the network. + * + * This setting applies only when MACsec replay protection active, i.e., + * - macsec_replay_protect is enabled + * - the key server has decided to enable MACsec + * + * 0: No replay window, strict check (default) + * 1..2^32-1: number of packets that could be misordered + */ + u32 macsec_replay_window; + + /** * macsec_port - MACsec port (in SCI) * * Port component of the SCI. @@ -792,14 +851,16 @@ struct wpa_ssid { /** * mka_ckn - MKA pre-shared CKN */ -#define MACSEC_CKN_LEN 32 - u8 mka_ckn[MACSEC_CKN_LEN]; +#define MACSEC_CKN_MAX_LEN 32 + size_t mka_ckn_len; + u8 mka_ckn[MACSEC_CKN_MAX_LEN]; /** * mka_cak - MKA pre-shared CAK */ -#define MACSEC_CAK_LEN 16 - u8 mka_cak[MACSEC_CAK_LEN]; +#define MACSEC_CAK_MAX_LEN 32 + size_t mka_cak_len; + u8 mka_cak[MACSEC_CAK_MAX_LEN]; #define MKA_PSK_SET_CKN BIT(0) #define MKA_PSK_SET_CAK BIT(1) @@ -937,6 +998,13 @@ struct wpa_ssid { * the selection attempts for OWE BSS exceed the configured threshold. */ int owe_transition_bss_select_count; + + /** + * multi_ap_backhaul_sta - Multi-AP backhaul STA + * 0 = normal (non-Multi-AP) station + * 1 = Multi-AP backhaul station + */ + int multi_ap_backhaul_sta; }; #endif /* CONFIG_SSID_H */ diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c index 0ce1830b4ef2..6328e91b989e 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 77a3133d8d56..198ac562d8b6 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -1,6 +1,6 @@ /* * WPA Supplicant / Control interface (shared code for all backends) - * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> + * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -56,6 +56,7 @@ #include "drivers/driver.h" #include "mesh.h" #include "dpp_supplicant.h" +#include "sme.h" static int wpa_supplicant_global_iface_list(struct wpa_global *global, char *buf, int len); @@ -1167,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) { @@ -1180,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); } @@ -2117,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, @@ -2912,6 +2939,12 @@ static int wpa_supplicant_ctrl_iface_scan_result( pos += ret; } #endif /* CONFIG_FST */ + if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_UTF_8_SSID)) { + ret = os_snprintf(pos, end - pos, "[UTF-8]"); + if (os_snprintf_error(end - pos, ret)) + return -1; + pos += ret; + } ret = os_snprintf(pos, end - pos, "\t%s", wpa_ssid_txt(bss->ssid, bss->ssid_len)); @@ -3987,6 +4020,22 @@ 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"); + if (os_snprintf_error(end - pos, ret)) + return pos - buf; + pos += ret; + } +#endif /* CONFIG_SAE */ return pos - buf; } @@ -4387,6 +4436,26 @@ static int wpa_supplicant_ctrl_iface_get_capability( } #endif /* CONFIG_FILS */ + if (os_strcmp(field, "multibss") == 0 && wpa_s->multi_bss_support) { + res = os_snprintf(buf, buflen, "MULTIBSS-STA"); + if (os_snprintf_error(buflen, res)) + return -1; + 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); @@ -4717,6 +4786,20 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, pos += ret; } #endif /* CONFIG_FILS */ +#ifdef CONFIG_FST + if (wpa_bss_get_ie(bss, WLAN_EID_MULTI_BAND)) { + ret = os_snprintf(pos, end - pos, "[FST]"); + if (os_snprintf_error(end - pos, ret)) + return 0; + pos += ret; + } +#endif /* CONFIG_FST */ + if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_UTF_8_SSID)) { + ret = os_snprintf(pos, end - pos, "[UTF-8]"); + if (os_snprintf_error(end - pos, ret)) + return 0; + pos += ret; + } ret = os_snprintf(pos, end - pos, "\n"); if (os_snprintf_error(end - pos, ret)) @@ -5013,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--; } } @@ -5502,6 +5586,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, int ht40, vht, max_oper_chwidth, chwidth = 0, freq2 = 0; u8 _group_ssid[SSID_MAX_LEN], *group_ssid = NULL; size_t group_ssid_len = 0; + int he; if (!wpa_s->global->p2p_init_wpa_s) return -1; @@ -5514,7 +5599,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad|p2ps] * [persistent|persistent=<network id>] * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc] - * [ht40] [vht] [auto] [ssid=<hexdump>] */ + * [ht40] [vht] [he] [auto] [ssid=<hexdump>] */ if (hwaddr_aton(cmd, addr)) return -1; @@ -5545,6 +5630,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht; ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 || vht; + he = (os_strstr(cmd, " he") != NULL) || wpa_s->conf->p2p_go_he; pos2 = os_strstr(pos, " go_intent="); if (pos2) { @@ -5615,7 +5701,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, persistent_group, automatic, join, auth, go_intent, freq, freq2, persistent_id, - pd, ht40, vht, max_oper_chwidth, + pd, ht40, vht, max_oper_chwidth, he, group_ssid, group_ssid_len); if (new_pin == -2) { os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25); @@ -6171,7 +6257,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) struct wpa_ssid *ssid; u8 *_peer = NULL, peer[ETH_ALEN]; int freq = 0, pref_freq = 0; - int ht40, vht, max_oper_chwidth, chwidth = 0, freq2 = 0; + int ht40, vht, he, max_oper_chwidth, chwidth = 0, freq2 = 0; id = atoi(cmd); pos = os_strstr(cmd, " peer="); @@ -6208,6 +6294,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht; ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 || vht; + he = (os_strstr(cmd, " he") != NULL) || wpa_s->conf->p2p_go_he; pos = os_strstr(cmd, "freq2="); if (pos) @@ -6222,7 +6309,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) return -1; return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, freq2, ht40, vht, - max_oper_chwidth, pref_freq); + max_oper_chwidth, pref_freq, he); } @@ -6270,7 +6357,8 @@ static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd) static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, int id, int freq, int vht_center_freq2, - int ht40, int vht, int vht_chwidth) + int ht40, int vht, int vht_chwidth, + int he) { struct wpa_ssid *ssid; @@ -6284,7 +6372,7 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, vht_center_freq2, 0, ht40, vht, - vht_chwidth, NULL, 0, 0); + vht_chwidth, he, NULL, 0, 0); } @@ -6293,6 +6381,7 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) int freq = 0, persistent = 0, group_id = -1; int vht = wpa_s->conf->p2p_go_vht; int ht40 = wpa_s->conf->p2p_go_ht40 || vht; + int he = wpa_s->conf->p2p_go_he; int max_oper_chwidth, chwidth = 0, freq2 = 0; char *token, *context = NULL; #ifdef CONFIG_ACS @@ -6315,6 +6404,8 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) } else if (os_strcmp(token, "vht") == 0) { vht = 1; ht40 = 1; + } else if (os_strcmp(token, "he") == 0) { + he = 1; } else if (os_strcmp(token, "persistent") == 0) { persistent = 1; } else { @@ -6340,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 */ @@ -6350,10 +6443,10 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) if (group_id >= 0) return p2p_ctrl_group_add_persistent(wpa_s, group_id, freq, freq2, ht40, vht, - max_oper_chwidth); + max_oper_chwidth, he); return wpas_p2p_group_add(wpa_s, persistent, freq, freq2, ht40, vht, - max_oper_chwidth); + max_oper_chwidth, he); } @@ -7622,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) @@ -7941,6 +8034,10 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) wpabuf_free(wpa_s->ric_ies); wpa_s->ric_ies = NULL; + + wpa_supplicant_update_channel_list(wpa_s, NULL); + + free_bss_tmp_disallowed(wpa_s); } @@ -8763,26 +8860,39 @@ static void wpas_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf, struct iphdr ip; const u8 *pos; unsigned int i; + char extra[30]; - if (len != HWSIM_PACKETLEN) + if (len < sizeof(*eth) + sizeof(ip) || len > HWSIM_PACKETLEN) { + wpa_printf(MSG_DEBUG, + "test data: RX - ignore unexpected length %d", + (int) len); return; + } eth = (const struct ether_header *) buf; os_memcpy(&ip, eth + 1, sizeof(ip)); pos = &buf[sizeof(*eth) + sizeof(ip)]; if (ip.ihl != 5 || ip.version != 4 || - ntohs(ip.tot_len) != HWSIM_IP_LEN) + ntohs(ip.tot_len) > HWSIM_IP_LEN) { + wpa_printf(MSG_DEBUG, + "test data: RX - ignore unexpect IP header"); return; + } - for (i = 0; i < HWSIM_IP_LEN - sizeof(ip); i++) { - if (*pos != (u8) i) + for (i = 0; i < ntohs(ip.tot_len) - sizeof(ip); i++) { + if (*pos != (u8) i) { + wpa_printf(MSG_DEBUG, + "test data: RX - ignore mismatching payload"); return; + } pos++; } - - wpa_msg(wpa_s, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR, - MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost)); + extra[0] = '\0'; + if (ntohs(ip.tot_len) != HWSIM_IP_LEN) + os_snprintf(extra, sizeof(extra), " len=%d", ntohs(ip.tot_len)); + wpa_msg(wpa_s, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR "%s", + MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost), extra); } @@ -8826,7 +8936,7 @@ static int wpas_ctrl_iface_data_test_config(struct wpa_supplicant *wpa_s, static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd) { u8 dst[ETH_ALEN], src[ETH_ALEN]; - char *pos; + char *pos, *pos2; int used; long int val; u8 tos; @@ -8835,11 +8945,12 @@ static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd) struct iphdr *ip; u8 *dpos; unsigned int i; + size_t send_len = HWSIM_IP_LEN; if (wpa_s->l2_test == NULL) return -1; - /* format: <dst> <src> <tos> */ + /* format: <dst> <src> <tos> [len=<length>] */ pos = cmd; used = hwaddr_aton2(pos, dst); @@ -8853,11 +8964,19 @@ static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd) return -1; pos += used; - val = strtol(pos, NULL, 0); + val = strtol(pos, &pos2, 0); if (val < 0 || val > 0xff) return -1; tos = val; + pos = os_strstr(pos2, " len="); + if (pos) { + i = atoi(pos + 5); + if (i < sizeof(*ip) || i > HWSIM_IP_LEN) + return -1; + send_len = i; + } + eth = (struct ether_header *) &buf[2]; os_memcpy(eth->ether_dhost, dst, ETH_ALEN); os_memcpy(eth->ether_shost, src, ETH_ALEN); @@ -8868,17 +8987,17 @@ static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd) ip->version = 4; ip->ttl = 64; ip->tos = tos; - ip->tot_len = htons(HWSIM_IP_LEN); + ip->tot_len = htons(send_len); ip->protocol = 1; ip->saddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 1); ip->daddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 2); ip->check = ipv4_hdr_checksum(ip, sizeof(*ip)); dpos = (u8 *) (ip + 1); - for (i = 0; i < HWSIM_IP_LEN - sizeof(*ip); i++) + for (i = 0; i < send_len - sizeof(*ip); i++) *dpos++ = i; if (l2_packet_send(wpa_s->l2_test, dst, ETHERTYPE_IP, &buf[2], - HWSIM_PACKETLEN) < 0) + sizeof(struct ether_header) + send_len) < 0) return -1; wpa_dbg(wpa_s, MSG_DEBUG, "test data: TX dst=" MACSTR " src=" MACSTR @@ -9458,13 +9577,6 @@ static int wpas_ctrl_iface_mac_rand_scan(struct wpa_supplicant *wpa_s, return -1; } - if ((wpa_s->mac_addr_rand_supported & type) != type) { - wpa_printf(MSG_INFO, - "CTRL: MAC_RAND_SCAN types=%u != supported=%u", - type, wpa_s->mac_addr_rand_supported); - return -1; - } - if (enable > 1) { wpa_printf(MSG_INFO, "CTRL: MAC_RAND_SCAN enable=<0/1> not specified"); @@ -9498,21 +9610,25 @@ static int wpas_ctrl_iface_mac_rand_scan(struct wpa_supplicant *wpa_s, } if (type & MAC_ADDR_RAND_SCAN) { - wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCAN, - addr, mask); + if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCAN, + addr, mask)) + return -1; } if (type & MAC_ADDR_RAND_SCHED_SCAN) { - wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCHED_SCAN, - addr, mask); + if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCHED_SCAN, + addr, mask)) + return -1; if (wpa_s->sched_scanning && !wpa_s->pno) wpas_scan_restart_sched_scan(wpa_s); } if (type & MAC_ADDR_RAND_PNO) { - wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_PNO, - addr, mask); + if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_PNO, + addr, mask)) + return -1; + if (wpa_s->pno) { wpas_stop_pno(wpa_s); wpas_start_pno(wpa_s); @@ -9858,6 +9974,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, reply_len += eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, reply_size - reply_len); +#ifdef CONFIG_MACSEC + reply_len += ieee802_1x_kay_get_mib( + wpa_s->kay, reply + reply_len, + reply_size - reply_len); +#endif /* CONFIG_MACSEC */ } } else if (os_strncmp(buf, "STATUS", 6) == 0) { reply_len = wpa_supplicant_ctrl_iface_status( @@ -10506,6 +10627,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strcmp(buf, "RESEND_ASSOC") == 0) { if (wpas_ctrl_resend_assoc(wpa_s) < 0) reply_len = -1; +#ifdef CONFIG_IEEE80211W + } else if (os_strcmp(buf, "UNPROT_DEAUTH") == 0) { + sme_event_unprot_disconnect( + wpa_s, wpa_s->bssid, NULL, + WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA); +#endif /* CONFIG_IEEE80211W */ #endif /* CONFIG_TESTING_OPTIONS */ } else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) { if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0) @@ -10549,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 { @@ -10558,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 { @@ -10572,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; @@ -10586,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 { @@ -10595,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 + 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/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c index b88c80a99551..71fe7ed6bef5 100644 --- a/wpa_supplicant/ctrl_iface_unix.c +++ b/wpa_supplicant/ctrl_iface_unix.c @@ -570,8 +570,8 @@ static int wpas_ctrl_iface_open_sock(struct wpa_supplicant *wpa_s, } } - if (gid_set && chown(dir, -1, gid) < 0) { - wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s", + if (gid_set && lchown(dir, -1, gid) < 0) { + wpa_printf(MSG_ERROR, "lchown[ctrl_interface=%s,gid=%d]: %s", dir, (int) gid, strerror(errno)); goto fail; } @@ -638,8 +638,8 @@ static int wpas_ctrl_iface_open_sock(struct wpa_supplicant *wpa_s, } } - if (gid_set && chown(fname, -1, gid) < 0) { - wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s", + if (gid_set && lchown(fname, -1, gid) < 0) { + wpa_printf(MSG_ERROR, "lchown[ctrl_interface=%s,gid=%d]: %s", fname, (int) gid, strerror(errno)); goto fail; } @@ -1235,9 +1235,9 @@ static int wpas_global_ctrl_iface_open_sock(struct wpa_global *global, wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", (int) gid); } - if (chown(ctrl, -1, gid) < 0) { + if (lchown(ctrl, -1, gid) < 0) { wpa_printf(MSG_ERROR, - "chown[global_ctrl_interface=%s,gid=%d]: %s", + "lchown[global_ctrl_interface=%s,gid=%d]: %s", ctrl, (int) gid, strerror(errno)); goto fail; } diff --git a/wpa_supplicant/dbus/Makefile b/wpa_supplicant/dbus/Makefile index f355ebef51d2..4d8700428dcb 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 382dcb34318c..e81b495f4b99 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 7ef6cad62aaf..efa6c7b20595 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.c b/wpa_supplicant/dbus/dbus_new.c index d4deb0fe35f0..fc2fc2ef1b96 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -13,6 +13,7 @@ #include "common.h" #include "common/ieee802_11_defs.h" #include "wps/wps.h" +#include "ap/sta_info.h" #include "../config.h" #include "../wpa_supplicant_i.h" #include "../bss.h" @@ -128,7 +129,8 @@ void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv) * Notify listeners about event related with interface */ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s, - const char *sig_name, int properties) + const char *sig_name, + dbus_bool_t properties) { struct wpas_dbus_priv *iface; DBusMessage *msg; @@ -230,7 +232,7 @@ void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success) */ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s, const char *bss_obj_path, - const char *sig_name, int properties) + const char *sig_name, dbus_bool_t properties) { struct wpas_dbus_priv *iface; DBusMessage *msg; @@ -364,7 +366,7 @@ void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s, */ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s, int id, const char *sig_name, - int properties) + dbus_bool_t properties) { struct wpas_dbus_priv *iface; DBusMessage *msg; @@ -1077,6 +1079,79 @@ void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s, } +/** + * wpas_dbus_signal_station - Send an event signal related to a station object + * @wpa_s: %wpa_supplicant network interface data + * @station_obj_path: Station object path + * @sig_name: signal name - StationAdded or StationRemoved + * @properties: Whether to add second argument with object properties + * + * Notify listeners about event related with station. + */ +static void wpas_dbus_signal_station(struct wpa_supplicant *wpa_s, + const char *station_obj_path, + const char *sig_name, + dbus_bool_t properties) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (!iface || !wpa_s->dbus_new_path) + return; + + wpa_printf(MSG_DEBUG, "dbus: STA signal %s", sig_name); + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name); + if (!msg) + return; + + dbus_message_iter_init_append(msg, &iter); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, + &station_obj_path) || + (properties && + !wpa_dbus_get_object_properties(iface, station_obj_path, + WPAS_DBUS_NEW_IFACE_STA, + &iter))) + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + else + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_station_added - Send a Station added signal + * @wpa_s: %wpa_supplicant network interface data + * @station_obj_path: new Station object path + * + * Notify listeners about adding new Station + */ +static void wpas_dbus_signal_station_added(struct wpa_supplicant *wpa_s, + const char *station_obj_path) +{ + wpas_dbus_signal_station(wpa_s, station_obj_path, "StationAdded", TRUE); +} + + +/** + * wpas_dbus_signal_station_removed - Send a Station removed signal + * @wpa_s: %wpa_supplicant network interface data + * @station_obj_path: Station object path + * + * Notify listeners about removing Station + */ +static void wpas_dbus_signal_station_removed(struct wpa_supplicant *wpa_s, + const char *station_obj_path) +{ + wpas_dbus_signal_station(wpa_s, station_obj_path, "StationRemoved", + FALSE); +} + + #ifdef CONFIG_P2P /** @@ -1882,7 +1957,7 @@ void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s, */ static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s, int id, const char *sig_name, - int properties) + dbus_bool_t properties) { struct wpas_dbus_priv *iface; DBusMessage *msg; @@ -2146,6 +2221,9 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s, case WPAS_DBUS_PROP_BSSS: prop = "BSSs"; break; + case WPAS_DBUS_PROP_STATIONS: + prop = "Stations"; + break; case WPAS_DBUS_PROP_CURRENT_AUTH_MODE: prop = "CurrentAuthMode"; break; @@ -2153,10 +2231,26 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s, prop = "DisconnectReason"; flush = TRUE; break; + case WPAS_DBUS_PROP_AUTH_STATUS_CODE: + prop = "AuthStatusCode"; + flush = TRUE; + break; case WPAS_DBUS_PROP_ASSOC_STATUS_CODE: prop = "AssocStatusCode"; flush = TRUE; break; + case WPAS_DBUS_PROP_ROAM_TIME: + prop = "RoamTime"; + break; + case WPAS_DBUS_PROP_ROAM_COMPLETE: + prop = "RoamComplete"; + break; + case WPAS_DBUS_PROP_SESSION_LENGTH: + prop = "SessionLength"; + break; + case WPAS_DBUS_PROP_BSS_TM_STATUS: + prop = "BSSTMStatus"; + break; default: wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d", __func__, property); @@ -2239,6 +2333,41 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s, /** + * wpas_dbus_sta_signal_prop_changed - Signals change of STA property + * @wpa_s: %wpa_supplicant network interface data + * @property: indicates which property has changed + * @address: unique BSS identifier + * + * Sends PropertyChanged signals with path, interface, and arguments depending + * on which property has changed. + */ +void wpas_dbus_sta_signal_prop_changed(struct wpa_supplicant *wpa_s, + enum wpas_dbus_bss_prop property, + u8 address[ETH_ALEN]) +{ + char path[WPAS_DBUS_OBJECT_PATH_MAX]; + char *prop; + + switch (property) { + case WPAS_DBUS_STA_PROP_ADDRESS: + prop = "Address"; + break; + default: + wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d", + __func__, property); + return; + } + + os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR, + wpa_s->dbus_new_path, MAC2STR(address)); + + wpa_dbus_mark_property_changed(wpa_s->global->dbus, path, + WPAS_DBUS_NEW_IFACE_STA, prop); +} + + +/** * wpas_dbus_signal_debug_level_changed - Signals change of debug param * @global: wpa_global structure * @@ -2726,6 +2855,30 @@ static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = { NULL, NULL }, + { + "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", + wpas_dbus_getter_roam_time, + NULL, + NULL + }, + { + "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b", + wpas_dbus_getter_roam_complete, + NULL, + NULL + }, + { + "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", + wpas_dbus_getter_session_length, + NULL, + NULL + }, + { + "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", + wpas_dbus_getter_bss_tm_status, + NULL, + NULL + }, { NULL, NULL, NULL, NULL, NULL, NULL } }; @@ -2852,6 +3005,157 @@ err: } +static const struct wpa_dbus_property_desc wpas_dbus_sta_properties[] = { + { "Address", WPAS_DBUS_NEW_IFACE_STA, "ay", + wpas_dbus_getter_sta_address, + NULL, NULL + }, + { "AID", WPAS_DBUS_NEW_IFACE_STA, "q", + wpas_dbus_getter_sta_aid, + NULL, NULL + }, + { "Capabilities", WPAS_DBUS_NEW_IFACE_STA, "q", + wpas_dbus_getter_sta_caps, + NULL, NULL + }, + { "RxPackets", WPAS_DBUS_NEW_IFACE_STA, "t", + wpas_dbus_getter_sta_rx_packets, + NULL, NULL + }, + { "TxPackets", WPAS_DBUS_NEW_IFACE_STA, "t", + wpas_dbus_getter_sta_tx_packets, + NULL, NULL + }, + { "RxBytes", WPAS_DBUS_NEW_IFACE_STA, "t", + wpas_dbus_getter_sta_rx_bytes, + NULL, NULL + }, + { "TxBytes", WPAS_DBUS_NEW_IFACE_STA, "t", + wpas_dbus_getter_sta_tx_bytes, + NULL, NULL + }, + { NULL, NULL, NULL, NULL, NULL, NULL } +}; + + +static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals[] = { + /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */ + { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA, + { + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { NULL, NULL, { END_ARGS } } +}; + + +/** + * wpas_dbus_unregister_sta - Unregister a connected station from dbus + * @wpa_s: wpa_supplicant interface structure + * @sta: station MAC address + * Returns: 0 on success, -1 on failure + * + * Unregisters STA representing object from dbus. + */ +int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta) +{ + struct wpas_dbus_priv *ctrl_iface; + char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + + /* Do nothing if the control interface is not turned on */ + if (!wpa_s || !wpa_s->global) + return 0; + ctrl_iface = wpa_s->global->dbus; + if (!ctrl_iface) + return 0; + + os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR, + wpa_s->dbus_new_path, MAC2STR(sta)); + + wpa_printf(MSG_DEBUG, "dbus: Unregister STA object '%s'", + station_obj_path); + if (wpa_dbus_unregister_object_per_iface(ctrl_iface, + station_obj_path)) { + wpa_printf(MSG_ERROR, "dbus: Cannot unregister STA object %s", + station_obj_path); + return -1; + } + + wpas_dbus_signal_station_removed(wpa_s, station_obj_path); + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS); + + return 0; +} + + +/** + * wpas_dbus_register_sta - Register a connected station with dbus + * @wpa_s: wpa_supplicant interface structure + * @sta: station MAC address + * Returns: 0 on success, -1 on failure + * + * Registers STA representing object with dbus. + */ +int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta) +{ + struct wpas_dbus_priv *ctrl_iface; + struct wpa_dbus_object_desc *obj_desc; + char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + struct sta_handler_args *arg; + + /* Do nothing if the control interface is not turned on */ + if (!wpa_s || !wpa_s->global) + return 0; + ctrl_iface = wpa_s->global->dbus; + if (!ctrl_iface) + return 0; + + os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR, + wpa_s->dbus_new_path, MAC2STR(sta)); + + obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); + if (!obj_desc) { + wpa_printf(MSG_ERROR, + "Not enough memory to create object description"); + goto err; + } + + arg = os_zalloc(sizeof(struct sta_handler_args)); + if (!arg) { + wpa_printf(MSG_ERROR, + "Not enough memory to create arguments for handler"); + goto err; + } + arg->wpa_s = wpa_s; + arg->sta = sta; + + wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL, + wpas_dbus_sta_properties, wpas_dbus_sta_signals); + + wpa_printf(MSG_DEBUG, "dbus: Register STA object '%s'", + station_obj_path); + if (wpa_dbus_register_object_per_iface(ctrl_iface, station_obj_path, + wpa_s->ifname, obj_desc)) { + wpa_printf(MSG_ERROR, + "Cannot register STA dbus object %s", + station_obj_path); + goto err; + } + + wpas_dbus_signal_station_added(wpa_s, station_obj_path); + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS); + + return 0; + +err: + free_dbus_object_desc(obj_desc); + return -1; +} + + static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE, (WPADBusMethodHandler) wpas_dbus_handler_scan, @@ -3472,6 +3776,11 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { NULL, NULL }, + { "AuthStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i", + wpas_dbus_getter_auth_status_code, + NULL, + NULL + }, { "AssocStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i", wpas_dbus_getter_assoc_status_code, NULL, @@ -3489,6 +3798,11 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { NULL }, #endif /* CONFIG_MESH */ + { "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", + wpas_dbus_getter_stas, + NULL, + NULL + }, { NULL, NULL, NULL, NULL, NULL, NULL } }; @@ -3758,6 +4072,19 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { END_ARGS } }, + { "StationAdded", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "StationRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + END_ARGS + } + }, { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE, { { "path", "o", ARG_OUT }, @@ -4038,6 +4365,11 @@ static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = { NULL, NULL }, + { "VSIE", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay", + wpas_dbus_getter_p2p_peer_vsie, + NULL, + NULL + }, { NULL, NULL, NULL, NULL, NULL, NULL } }; @@ -4066,7 +4398,7 @@ static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = { */ static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr, const char *interface, - const char *sig_name, int properties) + const char *sig_name, dbus_bool_t properties) { struct wpas_dbus_priv *iface; DBusMessage *msg; diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h index 40ae133b225e..42db3892ed77 100644 --- a/wpa_supplicant/dbus/dbus_new.h +++ b/wpa_supplicant/dbus/dbus_new.h @@ -28,8 +28,14 @@ enum wpas_dbus_prop { WPAS_DBUS_PROP_CURRENT_NETWORK, WPAS_DBUS_PROP_CURRENT_AUTH_MODE, WPAS_DBUS_PROP_BSSS, + WPAS_DBUS_PROP_STATIONS, WPAS_DBUS_PROP_DISCONNECT_REASON, + WPAS_DBUS_PROP_AUTH_STATUS_CODE, WPAS_DBUS_PROP_ASSOC_STATUS_CODE, + WPAS_DBUS_PROP_ROAM_TIME, + WPAS_DBUS_PROP_ROAM_COMPLETE, + WPAS_DBUS_PROP_SESSION_LENGTH, + WPAS_DBUS_PROP_BSS_TM_STATUS, }; enum wpas_dbus_bss_prop { @@ -45,6 +51,10 @@ enum wpas_dbus_bss_prop { WPAS_DBUS_BSS_PROP_AGE, }; +enum wpas_dbus_sta_prop { + WPAS_DBUS_STA_PROP_ADDRESS, +}; + #define WPAS_DBUS_OBJECT_PATH_MAX 150 #define WPAS_DBUS_NEW_SERVICE "fi.w1.wpa_supplicant1" @@ -61,6 +71,9 @@ enum wpas_dbus_bss_prop { #define WPAS_DBUS_NEW_BSSIDS_PART "BSSs" #define WPAS_DBUS_NEW_IFACE_BSS WPAS_DBUS_NEW_INTERFACE ".BSS" +#define WPAS_DBUS_NEW_STAS_PART "Stations" +#define WPAS_DBUS_NEW_IFACE_STA WPAS_DBUS_NEW_INTERFACE ".Station" + #define WPAS_DBUS_NEW_IFACE_P2PDEVICE \ WPAS_DBUS_NEW_IFACE_INTERFACE ".P2PDevice" @@ -163,6 +176,8 @@ int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s, u8 bssid[ETH_ALEN], unsigned int id); int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, u8 bssid[ETH_ALEN], unsigned int id); +int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta); +int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta); void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s, const char *name); void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s, @@ -345,6 +360,18 @@ static inline int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, return 0; } +static inline int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, + const u8 *sta) +{ + return 0; +} + +static inline int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, + const u8 *sta) +{ + return 0; +} + static inline void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s, const char *name) { diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 94773b329133..6c36d91a0cf8 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -15,6 +15,9 @@ #include "eap_peer/eap_methods.h" #include "eapol_supp/eapol_supp_sm.h" #include "rsn_supp/wpa.h" +#include "ap/hostapd.h" +#include "ap/sta_info.h" +#include "ap/ap_drv_ops.h" #include "../config.h" #include "../wpa_supplicant_i.h" #include "../driver_i.h" @@ -22,6 +25,7 @@ #include "../bss.h" #include "../scan.h" #include "../autoscan.h" +#include "../ap.h" #include "dbus_new_helpers.h" #include "dbus_new.h" #include "dbus_new_handlers.h" @@ -3089,6 +3093,27 @@ dbus_bool_t wpas_dbus_getter_disconnect_reason( /** + * wpas_dbus_getter_auth_status_code - Get most recent auth status code + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "AuthStatusCode" property. + */ +dbus_bool_t wpas_dbus_getter_auth_status_code( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + dbus_int32_t reason = wpa_s->auth_status_code; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32, + &reason, error); +} + + +/** * wpas_dbus_getter_assoc_status_code - Get most recent failed assoc status code * @iter: Pointer to incoming dbus message iter * @error: Location to store error on failure @@ -3110,6 +3135,97 @@ dbus_bool_t wpas_dbus_getter_assoc_status_code( /** + * wpas_dbus_getter_roam_time - Get most recent roam time + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "RoamTime" property. + */ +dbus_bool_t wpas_dbus_getter_roam_time( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + dbus_uint32_t roam_time = wpa_s->roam_time.sec * 1000 + + wpa_s->roam_time.usec / 1000; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32, + &roam_time, error); +} + + +/** + * wpas_dbus_getter_roam_complete - Get most recent roam success or failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "RoamComplete" property. + */ +dbus_bool_t wpas_dbus_getter_roam_complete( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + dbus_bool_t roam_complete = os_reltime_initialized(&wpa_s->roam_time); + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN, + &roam_complete, error); +} + + +/** + * wpas_dbus_getter_session_length - Get most recent BSS session length + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "SessionLength" property. + */ +dbus_bool_t wpas_dbus_getter_session_length( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + dbus_uint32_t session_length = wpa_s->session_length.sec * 1000 + + wpa_s->session_length.usec / 1000; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32, + &session_length, error); +} + + +/** + * wpas_dbus_getter_bss_tm_status - Get most BSS Transition Management request + * status code + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "BSSTMStatus" property. + */ +dbus_bool_t wpas_dbus_getter_bss_tm_status( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ +#ifdef CONFIG_WNM + struct wpa_supplicant *wpa_s = user_data; + dbus_uint32_t bss_tm_status = wpa_s->bss_tm_status; +#else /* CONFIG_WNM */ + dbus_uint32_t bss_tm_status = 0; +#endif /* CONFIG_WNM */ + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32, + &bss_tm_status, error); +} + + +/** * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age * @iter: Pointer to incoming dbus message iter * @error: Location to store error on failure @@ -3805,6 +3921,320 @@ dbus_bool_t wpas_dbus_setter_iface_global( } +/** + * wpas_dbus_getter_stas - Get connected stations for an interface + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: a list of stations + * + * Getter for "Stations" property. + */ +dbus_bool_t wpas_dbus_getter_stas( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + struct sta_info *sta = NULL; + char **paths = NULL; + unsigned int i = 0, num = 0; + dbus_bool_t success = FALSE; + + if (!wpa_s->dbus_new_path) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: no D-Bus interface", __func__); + return FALSE; + } + +#ifdef CONFIG_AP + if (wpa_s->ap_iface) { + struct hostapd_data *hapd; + + hapd = wpa_s->ap_iface->bss[0]; + sta = hapd->sta_list; + num = hapd->num_sta; + } +#endif /* CONFIG_AP */ + + paths = os_calloc(num, sizeof(char *)); + if (!paths) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; + } + + /* Loop through scan results and append each result's object path */ + for (; sta; sta = sta->next) { + paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); + if (!paths[i]) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, + "no memory"); + goto out; + } + /* Construct the object path for this BSS. */ + os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR, + wpa_s->dbus_new_path, MAC2STR(sta->addr)); + } + + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_OBJECT_PATH, + paths, num, + error); + +out: + while (i) + os_free(paths[--i]); + os_free(paths); + return success; +} + + +/** + * wpas_dbus_getter_sta_address - Return the address of a connected station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "Address" property. + */ +dbus_bool_t wpas_dbus_getter_sta_address( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ +#ifdef CONFIG_AP + struct sta_handler_args *args = user_data; + struct sta_info *sta; + + sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta); + if (!sta) + return FALSE; + + return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE, + sta->addr, ETH_ALEN, + error); +#else /* CONFIG_AP */ + return FALSE; +#endif /* CONFIG_AP */ +} + + +/** + * wpas_dbus_getter_sta_aid - Return the AID of a connected station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "AID" property. + */ +dbus_bool_t wpas_dbus_getter_sta_aid( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ +#ifdef CONFIG_AP + struct sta_handler_args *args = user_data; + struct sta_info *sta; + + sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta); + if (!sta) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16, + &sta->aid, + error); +#else /* CONFIG_AP */ + return FALSE; +#endif /* CONFIG_AP */ +} + + +/** + * wpas_dbus_getter_sta_caps - Return the capabilities of a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "Capabilities" property. + */ +dbus_bool_t wpas_dbus_getter_sta_caps( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ +#ifdef CONFIG_AP + struct sta_handler_args *args = user_data; + struct sta_info *sta; + + sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta); + if (!sta) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16, + &sta->capability, + error); +#else /* CONFIG_AP */ + return FALSE; +#endif /* CONFIG_AP */ +} + + +/** + * wpas_dbus_getter_rx_packets - Return the received packets for a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "RxPackets" property. + */ +dbus_bool_t wpas_dbus_getter_sta_rx_packets( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ +#ifdef CONFIG_AP + struct sta_handler_args *args = user_data; + struct sta_info *sta; + struct hostap_sta_driver_data data; + struct hostapd_data *hapd; + + if (!args->wpa_s->ap_iface) + return FALSE; + + hapd = args->wpa_s->ap_iface->bss[0]; + sta = ap_get_sta(hapd, args->sta); + if (!sta) + return FALSE; + + if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64, + &data.rx_packets, + error); +#else /* CONFIG_AP */ + return FALSE; +#endif /* CONFIG_AP */ +} + + +/** + * wpas_dbus_getter_tx_packets - Return the transmitted packets for a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "TxPackets" property. + */ +dbus_bool_t wpas_dbus_getter_sta_tx_packets( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ +#ifdef CONFIG_AP + struct sta_handler_args *args = user_data; + struct sta_info *sta; + struct hostap_sta_driver_data data; + struct hostapd_data *hapd; + + if (!args->wpa_s->ap_iface) + return FALSE; + + hapd = args->wpa_s->ap_iface->bss[0]; + sta = ap_get_sta(hapd, args->sta); + if (!sta) + return FALSE; + + if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64, + &data.tx_packets, + error); +#else /* CONFIG_AP */ + return FALSE; +#endif /* CONFIG_AP */ +} + + +/** + * wpas_dbus_getter_tx_bytes - Return the transmitted bytes for a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "TxBytes" property. + */ +dbus_bool_t wpas_dbus_getter_sta_tx_bytes( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ +#ifdef CONFIG_AP + struct sta_handler_args *args = user_data; + struct sta_info *sta; + struct hostap_sta_driver_data data; + struct hostapd_data *hapd; + + if (!args->wpa_s->ap_iface) + return FALSE; + + hapd = args->wpa_s->ap_iface->bss[0]; + sta = ap_get_sta(hapd, args->sta); + if (!sta) + return FALSE; + + if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64, + &data.tx_bytes, + error); +#else /* CONFIG_AP */ + return FALSE; +#endif /* CONFIG_AP */ +} + + +/** + * wpas_dbus_getter_rx_bytes - Return the received bytes for a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "RxBytes" property. + */ +dbus_bool_t wpas_dbus_getter_sta_rx_bytes( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ +#ifdef CONFIG_AP + struct sta_handler_args *args = user_data; + struct sta_info *sta; + struct hostap_sta_driver_data data; + struct hostapd_data *hapd; + + if (!args->wpa_s->ap_iface) + return FALSE; + + hapd = args->wpa_s->ap_iface->bss[0]; + sta = ap_get_sta(hapd, args->sta); + if (!sta) + return FALSE; + + if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64, + &data.rx_bytes, + error); +#else /* CONFIG_AP */ + return FALSE; +#endif /* CONFIG_AP */ +} + + static struct wpa_bss * get_bss_helper(struct bss_handler_args *args, DBusError *error, const char *func_name) { @@ -4067,7 +4497,7 @@ static dbus_bool_t wpas_dbus_get_bss_security_prop( DBusMessageIter iter_dict, variant_iter; const char *group; const char *pairwise[5]; /* max 5 pairwise ciphers is supported */ - const char *key_mgmt[13]; /* max 13 key managements may be supported */ + const char *key_mgmt[15]; /* max 15 key managements may be supported */ int n; if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, @@ -4077,7 +4507,12 @@ static dbus_bool_t wpas_dbus_get_bss_security_prop( if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict)) goto nomem; - /* KeyMgmt */ + /* + * KeyMgmt + * + * When adding a new entry here, please take care to extend key_mgmt[] + * and keep documentation in doc/dbus.doxygen up to date. + */ n = 0; if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK) key_mgmt[n++] = "wpa-psk"; @@ -4109,6 +4544,12 @@ static dbus_bool_t wpas_dbus_get_bss_security_prop( if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) key_mgmt[n++] = "wpa-ft-fils-sha384"; #endif /* CONFIG_FILS */ +#ifdef CONFIG_SAE + if (ie_data->key_mgmt & WPA_KEY_MGMT_SAE) + key_mgmt[n++] = "sae"; + if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_SAE) + key_mgmt[n++] = "ft-sae"; +#endif /* CONFIG_SAE */ if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE) key_mgmt[n++] = "wpa-none"; diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index 6f952cc39091..d922ce1b4189 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -22,6 +22,11 @@ struct bss_handler_args { unsigned int id; }; +struct sta_handler_args { + struct wpa_supplicant *wpa_s; + const u8 *sta; +}; + dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter, const int type, const void *val, @@ -145,7 +150,12 @@ DECLARE_ACCESSOR(wpas_dbus_getter_fast_reauth); DECLARE_ACCESSOR(wpas_dbus_setter_fast_reauth); DECLARE_ACCESSOR(wpas_dbus_getter_disconnect_reason); DECLARE_ACCESSOR(wpas_dbus_getter_disassociate_reason); +DECLARE_ACCESSOR(wpas_dbus_getter_auth_status_code); DECLARE_ACCESSOR(wpas_dbus_getter_assoc_status_code); +DECLARE_ACCESSOR(wpas_dbus_getter_roam_time); +DECLARE_ACCESSOR(wpas_dbus_getter_roam_complete); +DECLARE_ACCESSOR(wpas_dbus_getter_session_length); +DECLARE_ACCESSOR(wpas_dbus_getter_bss_tm_status); DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_age); DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_age); DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_count); @@ -166,6 +176,14 @@ DECLARE_ACCESSOR(wpas_dbus_getter_networks); DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_engine_path); DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_module_path); DECLARE_ACCESSOR(wpas_dbus_getter_blobs); +DECLARE_ACCESSOR(wpas_dbus_getter_stas); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_address); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_aid); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_caps); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_packets); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_packets); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_bytes); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_bytes); DECLARE_ACCESSOR(wpas_dbus_getter_bss_bssid); DECLARE_ACCESSOR(wpas_dbus_getter_bss_ssid); DECLARE_ACCESSOR(wpas_dbus_getter_bss_privacy); diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index 9305b9a4f37d..8cdd885644af 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -384,14 +384,14 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, goto inv_args; if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0, - 0, 0, NULL, 0, 0)) { + 0, 0, 0, NULL, 0, 0)) { reply = wpas_dbus_error_unknown_error( message, "Failed to reinvoke a persistent group"); goto out; } } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0, 0, 0, - 0)) + 0, 0)) goto inv_args; out: @@ -505,6 +505,7 @@ DBusMessage * wpas_dbus_handler_p2p_flush(DBusMessage *message, wpa_s = wpa_s->global->p2p_init_wpa_s; + wpas_p2p_stop_find(wpa_s); os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); wpa_s->force_long_sd = 0; p2p_flush(wpa_s->global->p2p); @@ -532,6 +533,7 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message, int new_pin; char *err_msg = NULL; char *iface = NULL; + int ret; if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL)) return reply; @@ -603,13 +605,19 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message, new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, persistent_group, 0, join, authorize_only, - go_intent, freq, 0, -1, 0, 0, 0, 0, NULL, 0); + go_intent, freq, 0, -1, 0, 0, 0, 0, 0, + NULL, 0); if (new_pin >= 0) { char npin[9]; char *generated_pin; - os_snprintf(npin, sizeof(npin), "%08d", new_pin); + ret = os_snprintf(npin, sizeof(npin), "%08d", new_pin); + if (os_snprintf_error(sizeof(npin), ret)) { + reply = wpas_dbus_error_unknown_error(message, + "invalid PIN"); + goto out; + } generated_pin = npin; reply = dbus_message_new_method_return(message); dbus_message_append_args(reply, DBUS_TYPE_STRING, @@ -755,7 +763,7 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, goto err; if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0, 0, - 0) < 0) { + 0, 0) < 0) { reply = wpas_dbus_error_unknown_error( message, "Failed to reinvoke a persistent group"); @@ -1910,6 +1918,30 @@ out: return success; } +dbus_bool_t wpas_dbus_getter_p2p_peer_vsie( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct peer_handler_args *peer_args = user_data; + const struct p2p_peer_info *info; + + info = p2p_get_peer_found(peer_args->wpa_s->global->p2p, + peer_args->p2p_device_addr, 0); + if (!info) { + dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer"); + return FALSE; + } + + if (!info->vendor_elems) + return wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_BYTE, + NULL, 0, error); + + return wpas_dbus_simple_array_property_getter( + iter, DBUS_TYPE_BYTE, (char *) info->vendor_elems->buf, + info->vendor_elems->used, error); +} + /** * wpas_dbus_getter_persistent_groups - Get array of persistent group objects @@ -2661,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; @@ -2673,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; @@ -2700,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_p2p.h b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h index c4c02615dbc3..b3c45c11012c 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h @@ -114,6 +114,7 @@ DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_vendor_extension); DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_ies); DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_device_address); DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_groups); +DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_vsie); /* * P2P Group properties diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c index f762b3f2ef5c..1594dafc7bb5 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c @@ -286,10 +286,14 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, ret = wpas_wps_start_pin(wpa_s, params.bssid, params.pin, 0, DEV_PW_DEFAULT); - if (ret > 0) - os_snprintf(npin, sizeof(npin), "%08d", ret); + if (ret > 0) { + ret = os_snprintf(npin, sizeof(npin), "%08d", ret); + if (os_snprintf_error(sizeof(npin), ret)) + return wpas_dbus_error_unknown_error( + 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 88227af7c03b..000000000000 --- 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 451a9f827aa9..000000000000 --- 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 e540832f254b..000000000000 --- 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 e60ad06a032e..000000000000 --- 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 5309a5301fc2..000000000000 --- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c +++ /dev/null @@ -1,152 +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 = 0; - 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) { - os_snprintf(npin, sizeof(npin), "%08d", ret); - 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 a75918f9380b..000000000000 --- 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 af281e56d2e1..88cd79085f6d 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,10 @@ 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 # Select TLS implementation # openssl = OpenSSL (default) @@ -349,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 @@ -382,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 @@ -458,12 +457,17 @@ CONFIG_BACKEND=file # that meet the requirements described above. #CONFIG_NO_RANDOM_POOL=y +# Should we attempt to use the getrandom(2) call that provides more reliable +# yet secure randomness source than /dev/random on Linux 3.17 and newer. +# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. +#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. @@ -473,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 @@ -489,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. @@ -561,8 +565,6 @@ CONFIG_BACKEND=file #CONFIG_MBO=y # Fast Initial Link Setup (FILS) (IEEE 802.11ai) -# Note: This is an experimental and not yet complete implementation. This -# should not be enabled for production use. #CONFIG_FILS=y # FILS shared key authentication with PFS #CONFIG_FILS_SK_PFS=y @@ -570,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 @@ -585,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 @@ -593,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/eapol_test.8 b/wpa_supplicant/doc/docbook/eapol_test.8 index 1ae1ac1c93ea..717f79f8d8dc 100644 --- a/wpa_supplicant/doc/docbook/eapol_test.8 +++ b/wpa_supplicant/doc/docbook/eapol_test.8 @@ -3,7 +3,7 @@ .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng <steve@ggi-project.org>. -.TH "EAPOL_TEST" "8" "02 December 2018" "" "" +.TH "EAPOL_TEST" "8" "21 April 2019" "" "" .SH NAME eapol_test \- EAP peer and RADIUS client testing @@ -115,7 +115,7 @@ Save configuration after authentication. \fBwpa_supplicant\fR(8) .SH "LEGAL" .PP -wpa_supplicant is copyright (c) 2003-2018, +wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors. All Rights Reserved. diff --git a/wpa_supplicant/doc/docbook/eapol_test.sgml b/wpa_supplicant/doc/docbook/eapol_test.sgml index ae6bafecfa15..e7705abf16fb 100644 --- a/wpa_supplicant/doc/docbook/eapol_test.sgml +++ b/wpa_supplicant/doc/docbook/eapol_test.sgml @@ -194,7 +194,7 @@ eapol_test -ctest.conf -a127.0.0.1 -p1812 -ssecret -r1 </refsect1> <refsect1> <title>Legal</title> - <para>wpa_supplicant is copyright (c) 2003-2018, + <para>wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <email>j@w1.fi</email> and contributors. All Rights Reserved.</para> diff --git a/wpa_supplicant/doc/docbook/wpa_background.8 b/wpa_supplicant/doc/docbook/wpa_background.8 index e2b894b6ae24..4312f73c02c2 100644 --- a/wpa_supplicant/doc/docbook/wpa_background.8 +++ b/wpa_supplicant/doc/docbook/wpa_background.8 @@ -3,7 +3,7 @@ .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng <steve@ggi-project.org>. -.TH "WPA_BACKGROUND" "8" "02 December 2018" "" "" +.TH "WPA_BACKGROUND" "8" "21 April 2019" "" "" .SH NAME wpa_background \- Background information on Wi-Fi Protected Access and IEEE 802.11i @@ -75,7 +75,7 @@ pre-authentication, and PMKSA caching). \fBwpa_supplicant\fR(8) .SH "LEGAL" .PP -wpa_supplicant is copyright (c) 2003-2018, +wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors. All Rights Reserved. diff --git a/wpa_supplicant/doc/docbook/wpa_background.sgml b/wpa_supplicant/doc/docbook/wpa_background.sgml index d3e4dbe2a5a8..f6a0ca8b5b55 100644 --- a/wpa_supplicant/doc/docbook/wpa_background.sgml +++ b/wpa_supplicant/doc/docbook/wpa_background.sgml @@ -90,7 +90,7 @@ <refsect1> <title>Legal</title> - <para>wpa_supplicant is copyright (c) 2003-2018, + <para>wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <email>j@w1.fi</email> and contributors. All Rights Reserved.</para> diff --git a/wpa_supplicant/doc/docbook/wpa_cli.8 b/wpa_supplicant/doc/docbook/wpa_cli.8 index ec96a4dfa93e..600a8f6ca7ed 100644 --- a/wpa_supplicant/doc/docbook/wpa_cli.8 +++ b/wpa_supplicant/doc/docbook/wpa_cli.8 @@ -3,7 +3,7 @@ .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng <steve@ggi-project.org>. -.TH "WPA_CLI" "8" "02 December 2018" "" "" +.TH "WPA_CLI" "8" "21 April 2019" "" "" .SH NAME wpa_cli \- WPA command line client @@ -210,7 +210,7 @@ exit wpa_cli \fBwpa_supplicant\fR(8) .SH "LEGAL" .PP -wpa_supplicant is copyright (c) 2003-2018, +wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors. All Rights Reserved. diff --git a/wpa_supplicant/doc/docbook/wpa_cli.sgml b/wpa_supplicant/doc/docbook/wpa_cli.sgml index 766dd2cc1370..dc7fee46a27f 100644 --- a/wpa_supplicant/doc/docbook/wpa_cli.sgml +++ b/wpa_supplicant/doc/docbook/wpa_cli.sgml @@ -345,7 +345,7 @@ CTRL-REQ-OTP-2:Challenge 1235663 needed for SSID foobar </refsect1> <refsect1> <title>Legal</title> - <para>wpa_supplicant is copyright (c) 2003-2018, + <para>wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <email>j@w1.fi</email> and contributors. All Rights Reserved.</para> diff --git a/wpa_supplicant/doc/docbook/wpa_gui.8 b/wpa_supplicant/doc/docbook/wpa_gui.8 index 2d7e74e48e61..c4c133b70370 100644 --- a/wpa_supplicant/doc/docbook/wpa_gui.8 +++ b/wpa_supplicant/doc/docbook/wpa_gui.8 @@ -3,7 +3,7 @@ .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng <steve@ggi-project.org>. -.TH "WPA_GUI" "8" "02 December 2018" "" "" +.TH "WPA_GUI" "8" "21 April 2019" "" "" .SH NAME wpa_gui \- WPA Graphical User Interface @@ -51,7 +51,7 @@ icon pop-up messages. \fBwpa_supplicant\fR(8) .SH "LEGAL" .PP -wpa_supplicant is copyright (c) 2003-2018, +wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors. All Rights Reserved. diff --git a/wpa_supplicant/doc/docbook/wpa_gui.sgml b/wpa_supplicant/doc/docbook/wpa_gui.sgml index 91662d54a1fc..31214e3ed020 100644 --- a/wpa_supplicant/doc/docbook/wpa_gui.sgml +++ b/wpa_supplicant/doc/docbook/wpa_gui.sgml @@ -91,7 +91,7 @@ </refsect1> <refsect1> <title>Legal</title> - <para>wpa_supplicant is copyright (c) 2003-2018, + <para>wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <email>j@w1.fi</email> and contributors. All Rights Reserved.</para> diff --git a/wpa_supplicant/doc/docbook/wpa_passphrase.8 b/wpa_supplicant/doc/docbook/wpa_passphrase.8 index 20e7155cf725..a56bcf57b8f4 100644 --- a/wpa_supplicant/doc/docbook/wpa_passphrase.8 +++ b/wpa_supplicant/doc/docbook/wpa_passphrase.8 @@ -3,7 +3,7 @@ .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng <steve@ggi-project.org>. -.TH "WPA_PASSPHRASE" "8" "02 December 2018" "" "" +.TH "WPA_PASSPHRASE" "8" "21 April 2019" "" "" .SH NAME wpa_passphrase \- Generate a WPA PSK from an ASCII passphrase for a SSID @@ -31,7 +31,7 @@ passphrase will be read from standard input. \fBwpa_supplicant\fR(8) .SH "LEGAL" .PP -wpa_supplicant is copyright (c) 2003-2018, +wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors. All Rights Reserved. diff --git a/wpa_supplicant/doc/docbook/wpa_passphrase.sgml b/wpa_supplicant/doc/docbook/wpa_passphrase.sgml index 2f86b0bdf987..ed9baf1eac85 100644 --- a/wpa_supplicant/doc/docbook/wpa_passphrase.sgml +++ b/wpa_supplicant/doc/docbook/wpa_passphrase.sgml @@ -62,7 +62,7 @@ </refsect1> <refsect1> <title>Legal</title> - <para>wpa_supplicant is copyright (c) 2003-2018, + <para>wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <email>j@w1.fi</email> and contributors. All Rights Reserved.</para> diff --git a/wpa_supplicant/doc/docbook/wpa_priv.8 b/wpa_supplicant/doc/docbook/wpa_priv.8 index 4064d1ba9164..6388293e28b4 100644 --- a/wpa_supplicant/doc/docbook/wpa_priv.8 +++ b/wpa_supplicant/doc/docbook/wpa_priv.8 @@ -3,7 +3,7 @@ .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng <steve@ggi-project.org>. -.TH "WPA_PRIV" "8" "02 December 2018" "" "" +.TH "WPA_PRIV" "8" "21 April 2019" "" "" .SH NAME wpa_priv \- wpa_supplicant privilege separation helper @@ -111,7 +111,7 @@ processes at the same time, if desired. \fBwpa_supplicant\fR(8) .SH "LEGAL" .PP -wpa_supplicant is copyright (c) 2003-2018, +wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors. All Rights Reserved. diff --git a/wpa_supplicant/doc/docbook/wpa_priv.sgml b/wpa_supplicant/doc/docbook/wpa_priv.sgml index 4a5f319db3b2..dd445651ac0a 100644 --- a/wpa_supplicant/doc/docbook/wpa_priv.sgml +++ b/wpa_supplicant/doc/docbook/wpa_priv.sgml @@ -137,7 +137,7 @@ wpa_supplicant -i ath0 -c wpa_supplicant.conf </refsect1> <refsect1> <title>Legal</title> - <para>wpa_supplicant is copyright (c) 2003-2018, + <para>wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <email>j@w1.fi</email> and contributors. All Rights Reserved.</para> diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.8 b/wpa_supplicant/doc/docbook/wpa_supplicant.8 index 16a94058be90..e91e6ed61d5a 100644 --- a/wpa_supplicant/doc/docbook/wpa_supplicant.8 +++ b/wpa_supplicant/doc/docbook/wpa_supplicant.8 @@ -3,7 +3,7 @@ .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng <steve@ggi-project.org>. -.TH "WPA_SUPPLICANT" "8" "02 December 2018" "" "" +.TH "WPA_SUPPLICANT" "8" "21 April 2019" "" "" .SH NAME wpa_supplicant \- Wi-Fi Protected Access client and IEEE 802.1X supplicant @@ -217,8 +217,13 @@ list of supported driver backends that may be used with the -D option on your system, refer to the help output of wpa_supplicant (\fBwpa_supplicant -h\fR). .TP +\fBnl80211\fR +Uses the modern Linux nl80211/cfg80211 netlink-based +interface (most new drivers). +.TP \fBwext\fR -Linux wireless extensions (generic). +Uses the legacy Linux wireless extensions ioctl-based +interface (older hardware/drivers). .TP \fBwired\fR wpa_supplicant wired Ethernet driver @@ -325,7 +330,7 @@ Include timestamp in debug messages. Enable DBus control interface. If enabled, interface definitions may be omitted. (This is only available if \fBwpa_supplicant\fR was built with -the CONFIG_DBUS option.) +the CONFIG_CTRL_IFACE_DBUS_NEW option.) .TP \fB-v\fR Show version. @@ -392,7 +397,11 @@ wpa_supplicant \\ Current hardware/software requirements: .TP 0.2i \(bu -Linux kernel 2.4.x or 2.6.x with Linux Wireless +Linux kernel 2.6.30 or higher with +nl80211/cfg80211 support +.TP 0.2i +\(bu +Linux kernel 2.4.x or higher with Linux Wireless Extensions v15 or newer .TP 0.2i \(bu @@ -403,6 +412,9 @@ Microsoft Windows with WinPcap (at least WinXP, may work with other versions) .SH "SUPPORTED DRIVERS" .TP +\fBLinux nl80211/cfg80211\fR +This is the preferred driver for Linux. +.TP \fBLinux wireless extensions\fR In theory, any driver that supports Linux wireless extensions can be used with IEEE 802.1X (i.e., not WPA) when @@ -532,7 +544,7 @@ in. \fBwpa_passphrase\fR(8) .SH "LEGAL" .PP -wpa_supplicant is copyright (c) 2003-2018, +wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors. All Rights Reserved. diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5 b/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5 index 07461130085e..43649238e310 100644 --- a/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5 +++ b/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5 @@ -3,7 +3,7 @@ .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng <steve@ggi-project.org>. -.TH "WPA_SUPPLICANT.CONF" "5" "02 December 2018" "" "" +.TH "WPA_SUPPLICANT.CONF" "5" "21 April 2019" "" "" .SH NAME wpa_supplicant.conf \- configuration file for wpa_supplicant diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml index eeb9c07305b9..aaff15002784 100644 --- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml +++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml @@ -246,9 +246,18 @@ <variablelist> <varlistentry> + <term>nl80211</term> + <listitem> + <para>Uses the modern Linux nl80211/cfg80211 netlink-based + interface (most new drivers).</para> + </listitem> + </varlistentry> + + <varlistentry> <term>wext</term> <listitem> - <para>Linux wireless extensions (generic).</para> + <para>Uses the legacy Linux wireless extensions ioctl-based + interface (older hardware/drivers).</para> </listitem> </varlistentry> @@ -462,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> @@ -538,10 +547,14 @@ wpa_supplicant \ <itemizedlist> <listitem> - <para>Linux kernel 2.4.x or 2.6.x with Linux Wireless - Extensions v15 or newer</para> + <para>Linux kernel 2.6.30 or higher with + nl80211/cfg80211 support</para> </listitem> + <listitem> + <para>Linux kernel 2.4.x or higher with Linux Wireless + Extensions v15 or newer</para> + </listitem> <listitem> <para>FreeBSD 6-CURRENT</para> @@ -558,6 +571,13 @@ wpa_supplicant \ <title>Supported Drivers</title> <variablelist> <varlistentry> + <term>Linux nl80211/cfg80211</term> + <listitem> + <para>This is the preferred driver for Linux.</para> + </listitem> + </varlistentry> + + <varlistentry> <term>Linux wireless extensions</term> <listitem> <para>In theory, any driver that supports Linux wireless @@ -729,7 +749,7 @@ fi </refsect1> <refsect1> <title>Legal</title> - <para>wpa_supplicant is copyright (c) 2003-2018, + <para>wpa_supplicant is copyright (c) 2003-2019, Jouni Malinen <email>j@w1.fi</email> and contributors. All Rights Reserved.</para> diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index 7bc46610a971..e003a8514edb 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 5a4f06e2e97e..ecb7a7d684fa 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/driver_i.h b/wpa_supplicant/driver_i.h index 078de23f794f..4a9f472e84ee 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -492,6 +492,14 @@ static inline int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s, return -1; } +static inline int wpa_drv_channel_info(struct wpa_supplicant *wpa_s, + struct wpa_channel_info *ci) +{ + if (wpa_s->driver->channel_info) + return wpa_s->driver->channel_info(wpa_s->drv_priv, ci); + return -1; +} + static inline int wpa_drv_pktcnt_poll(struct wpa_supplicant *wpa_s, struct hostap_sta_driver_data *sta) { @@ -796,6 +804,14 @@ static inline int wpa_drv_set_transmit_next_pn(struct wpa_supplicant *wpa_s, return wpa_s->driver->set_transmit_next_pn(wpa_s->drv_priv, sa); } +static inline int wpa_drv_set_receive_lowest_pn(struct wpa_supplicant *wpa_s, + struct receive_sa *sa) +{ + if (!wpa_s->driver->set_receive_lowest_pn) + return -1; + return wpa_s->driver->set_receive_lowest_pn(wpa_s->drv_priv, sa); +} + static inline int wpa_drv_create_receive_sc(struct wpa_supplicant *wpa_s, struct receive_sc *sc, unsigned int conf_offset, int validation) @@ -1046,4 +1062,12 @@ wpa_drv_send_external_auth_status(struct wpa_supplicant *wpa_s, params); } +static inline int wpa_drv_set_4addr_mode(struct wpa_supplicant *wpa_s, int val) +{ + if (!wpa_s->driver->set_4addr_mode) + return -1; + return wpa_s->driver->set_4addr_mode(wpa_s->drv_priv, + wpa_s->bridge_ifname, val); +} + #endif /* DRIVER_I_H */ diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c index 6548bd17b11f..3fd4ce61a1c2 100644 --- a/wpa_supplicant/eapol_test.c +++ b/wpa_supplicant/eapol_test.c @@ -711,7 +711,8 @@ static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx) eap = (struct eap_hdr *) (hdr + 1); eap->code = EAP_CODE_REQUEST; - eap->identifier = 0; + if (os_get_random((u8 *) &eap->identifier, sizeof(eap->identifier)) < 0) + eap->identifier = os_random() & 0xff; eap->length = htons(5); pos = (u8 *) (eap + 1); *pos = EAP_TYPE_IDENTITY; diff --git a/wpa_supplicant/eapol_test.py b/wpa_supplicant/eapol_test.py index 80e7dfcf531d..734428d29e66 100755 --- a/wpa_supplicant/eapol_test.py +++ b/wpa_supplicant/eapol_test.py @@ -136,7 +136,7 @@ def main(): results = res[i].get(False) except: results = "N/A" - print "%d: %s" % (i, results) + print("%d: %s" % (i, results)) if __name__ == "__main__": main() diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 37d429d33022..f6ec111b77b6 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" @@ -293,6 +294,13 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) return; + if (os_reltime_initialized(&wpa_s->session_start)) { + os_reltime_age(&wpa_s->session_start, &wpa_s->session_length); + wpa_s->session_start.sec = 0; + wpa_s->session_start.usec = 0; + wpas_notify_session_length(wpa_s); + } + wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); bssid_changed = !is_zero_ether_addr(wpa_s->bssid); os_memset(wpa_s->bssid, 0, ETH_ALEN); @@ -324,6 +332,9 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) os_memset(wpa_s->last_tk, 0, sizeof(wpa_s->last_tk)); #endif /* CONFIG_TESTING_OPTIONS */ wpa_s->ieee80211ac = 0; + + if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0) + wpa_s->enabled_4addr_mode = 0; } @@ -549,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))) @@ -1335,10 +1350,10 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, continue; } - if (wpa_is_bss_tmp_disallowed(wpa_s, bss->bssid)) { + if (wpa_is_bss_tmp_disallowed(wpa_s, bss)) { if (debug_print) wpa_dbg(wpa_s, MSG_DEBUG, - " skip - MBO retry delay has not passed yet"); + " skip - AP temporarily disallowed"); continue; } #ifdef CONFIG_TESTING_OPTIONS @@ -1889,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; @@ -2267,6 +2282,57 @@ static void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s, #endif /* CONFIG_INTERWORKING */ +static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s, + const u8 *ies, size_t ies_len) +{ + struct ieee802_11_elems elems; + const u8 *map_sub_elem, *pos; + size_t len; + + if (!wpa_s->current_ssid || + !wpa_s->current_ssid->multi_ap_backhaul_sta || + !ies || + ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) + return; + + if (!elems.multi_ap || elems.multi_ap_len < 7) { + wpa_printf(MSG_INFO, "AP doesn't support Multi-AP protocol"); + goto fail; + } + + pos = elems.multi_ap + 4; + len = elems.multi_ap_len - 4; + + map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE); + if (!map_sub_elem || map_sub_elem[1] < 1) { + wpa_printf(MSG_INFO, "invalid Multi-AP sub elem type"); + goto fail; + } + + 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; + } + + if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) { + wpa_printf(MSG_ERROR, "Failed to set 4addr mode"); + goto fail; + } + wpa_s->enabled_4addr_mode = 1; + return; + +fail: + wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); +} + + #ifdef CONFIG_FST static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s, const u8 *ie, size_t ie_len) @@ -2343,6 +2409,9 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, get_ie(data->assoc_info.resp_ies, data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP)) wpa_s->ieee80211ac = 1; + + multi_ap_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len); } if (data->assoc_info.beacon_ies) wpa_hexdump(MSG_DEBUG, "beacon_ies", @@ -2352,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; @@ -2410,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) { @@ -2648,6 +2759,16 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED); if (os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) { + if (os_reltime_initialized(&wpa_s->session_start)) { + os_reltime_age(&wpa_s->session_start, + &wpa_s->session_length); + wpa_s->session_start.sec = 0; + wpa_s->session_start.usec = 0; + wpas_notify_session_length(wpa_s); + } else { + wpas_notify_auth_changed(wpa_s); + os_get_reltime(&wpa_s->session_start); + } wpa_dbg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID=" MACSTR, MAC2STR(bssid)); new_bss = 1; @@ -2738,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) && - 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. @@ -2748,7 +2878,7 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *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) && + } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) && wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { /* * The driver will take care of RSN 4-way handshake, so we need @@ -2756,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; @@ -3010,7 +3131,7 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, !disallowed_ssid(wpa_s, fast_reconnect->ssid, fast_reconnect->ssid_len) && !wpas_temp_disabled(wpa_s, fast_reconnect_ssid) && - !wpa_is_bss_tmp_disallowed(wpa_s, fast_reconnect->bssid)) { + !wpa_is_bss_tmp_disallowed(wpa_s, fast_reconnect)) { #ifndef CONFIG_NO_SCAN_PROCESSING wpa_dbg(wpa_s, MSG_DEBUG, "Try to reconnect to the same BSS"); if (wpa_supplicant_connect(wpa_s, fast_reconnect, @@ -3583,8 +3704,8 @@ static const char * reg_type_str(enum reg_type type) } -static void wpa_supplicant_update_channel_list( - struct wpa_supplicant *wpa_s, struct channel_list_changed *info) +void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s, + struct channel_list_changed *info) { struct wpa_supplicant *ifs; u8 dfs_domain; @@ -3598,10 +3719,13 @@ static void wpa_supplicant_update_channel_list( for (ifs = wpa_s; ifs->parent && ifs != ifs->parent; ifs = ifs->parent) ; - wpa_msg(ifs, MSG_INFO, WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s", - reg_init_str(info->initiator), reg_type_str(info->type), - info->alpha2[0] ? " alpha2=" : "", - info->alpha2[0] ? info->alpha2 : ""); + if (info) { + wpa_msg(ifs, MSG_INFO, + WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s", + reg_init_str(info->initiator), reg_type_str(info->type), + info->alpha2[0] ? " alpha2=" : "", + info->alpha2[0] ? info->alpha2 : ""); + } if (wpa_s->drv_priv == NULL) return; /* Ignore event during drv initialization */ @@ -3840,7 +3964,7 @@ static void wpas_event_dfs_cac_started(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { #if defined(NEED_AP_MLME) && defined(CONFIG_AP) - if (wpa_s->ap_iface) { + if (wpa_s->ap_iface || wpa_s->ifmsh) { wpas_ap_event_dfs_cac_started(wpa_s, radar); } else #endif /* NEED_AP_MLME && CONFIG_AP */ @@ -3861,7 +3985,7 @@ static void wpas_event_dfs_cac_finished(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { #if defined(NEED_AP_MLME) && defined(CONFIG_AP) - if (wpa_s->ap_iface) { + if (wpa_s->ap_iface || wpa_s->ifmsh) { wpas_ap_event_dfs_cac_finished(wpa_s, radar); } else #endif /* NEED_AP_MLME && CONFIG_AP */ @@ -3877,7 +4001,7 @@ static void wpas_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { #if defined(NEED_AP_MLME) && defined(CONFIG_AP) - if (wpa_s->ap_iface) { + if (wpa_s->ap_iface || wpa_s->ifmsh) { wpas_ap_event_dfs_cac_aborted(wpa_s, radar); } else #endif /* NEED_AP_MLME && CONFIG_AP */ @@ -3984,6 +4108,32 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_OWE */ +#ifdef CONFIG_MBO + if (data->assoc_reject.status_code == + WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS && + wpa_s->current_bss && data->assoc_reject.bssid && + data->assoc_reject.resp_ies) { + const u8 *rssi_rej; + + rssi_rej = mbo_get_attr_from_ies( + data->assoc_reject.resp_ies, + data->assoc_reject.resp_ies_len, + OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT); + if (rssi_rej && rssi_rej[1] == 2) { + wpa_printf(MSG_DEBUG, + "OCE: RSSI-based association rejection from " + MACSTR " (Delta RSSI: %u, Retry Delay: %u)", + MAC2STR(data->assoc_reject.bssid), + rssi_rej[2], rssi_rej[3]); + wpa_bss_tmp_disallow(wpa_s, + data->assoc_reject.bssid, + rssi_rej[3], + rssi_rej[2] + + wpa_s->current_bss->level); + } + } +#endif /* CONFIG_MBO */ + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) { sme_event_assoc_reject(wpa_s, data); return; @@ -4070,6 +4220,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, "FST: MB IEs updated from auth IE"); #endif /* CONFIG_FST */ sme_event_auth(wpa_s, data); + wpa_s->auth_status_code = data->auth.status_code; + wpas_notify_auth_status_code(wpa_s); break; case EVENT_ASSOC: #ifdef CONFIG_TESTING_OPTIONS @@ -4328,6 +4480,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, #ifdef CONFIG_AP if (wpa_s->current_ssid->mode == WPAS_MODE_AP || wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO || + wpa_s->current_ssid->mode == WPAS_MODE_MESH || wpa_s->current_ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) { wpas_ap_ch_switch(wpa_s, data->ch_switch.freq, @@ -4339,6 +4492,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, } #endif /* CONFIG_AP */ +#ifdef CONFIG_IEEE80211W + sme_event_ch_switch(wpa_s); +#endif /* CONFIG_IEEE80211W */ wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_CS); wnm_clear_coloc_intf_reporting(wpa_s); break; @@ -4707,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/dbus-listen-preq.py b/wpa_supplicant/examples/dbus-listen-preq.py index 5ac9859f7b72..337519f4e927 100755 --- a/wpa_supplicant/examples/dbus-listen-preq.py +++ b/wpa_supplicant/examples/dbus-listen-preq.py @@ -1,5 +1,6 @@ #!/usr/bin/python +from __future__ import print_function import dbus import sys import time @@ -12,21 +13,24 @@ WPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1" WPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface" def usage(): - print "Usage: %s <ifname>" % sys.argv[0] - print "Press Ctrl-C to stop" + print("Usage: %s <ifname>" % sys.argv[0]) + print("Press Ctrl-C to stop") def ProbeRequest(args): if 'addr' in args: - print '%.2x:%.2x:%.2x:%.2x:%.2x:%.2x' % tuple(args['addr']), + print('%.2x:%.2x:%.2x:%.2x:%.2x:%.2x' % tuple(args['addr']), + end=' ') if 'dst' in args: - print '-> %.2x:%.2x:%.2x:%.2x:%.2x:%.2x' % tuple(args['dst']), + print('-> %.2x:%.2x:%.2x:%.2x:%.2x:%.2x' % tuple(args['dst']), + end=' ') if 'bssid' in args: - print '(bssid %.2x:%.2x:%.2x:%.2x:%.2x:%.2x)' % tuple(args['dst']), + print('(bssid %.2x:%.2x:%.2x:%.2x:%.2x:%.2x)' % tuple(args['dst']), + end=' ') if 'signal' in args: - print 'signal:%d' % args['signal'], + print('signal:%d' % args['signal'], end=' ') if 'ies' in args: - print 'have IEs (%d bytes)' % len(args['ies']), - print '' + print('have IEs (%d bytes)' % len(args['ies']), end=' ') + print('') if __name__ == "__main__": global bus diff --git a/wpa_supplicant/examples/dpp-qrcode.py b/wpa_supplicant/examples/dpp-qrcode.py index e2a00c910812..b468d15cf9cd 100755 --- a/wpa_supplicant/examples/dpp-qrcode.py +++ b/wpa_supplicant/examples/dpp-qrcode.py @@ -24,19 +24,19 @@ def wpas_connect(): if os.path.isdir(wpas_ctrl): try: ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] - except OSError, error: - print "Could not find wpa_supplicant: ", error + except OSError as error: + print("Could not find wpa_supplicant: ", error) return None if len(ifaces) < 1: - print "No wpa_supplicant control interface found" + print("No wpa_supplicant control interface found") return None for ctrl in ifaces: try: wpas = wpaspy.Ctrl(ctrl) return wpas - except Exception, e: + except Exception as e: pass return None @@ -55,27 +55,27 @@ def dpp_logcat(): continue if not uri.startswith('DPP:'): continue - print "Found DPP bootstrap info URI:" - print uri + print("Found DPP bootstrap info URI:") + print(uri) wpas = wpas_connect() if not wpas: - print "Could not connect to wpa_supplicant" - print + print("Could not connect to wpa_supplicant") + print('') continue res = wpas.request("DPP_QR_CODE " + uri); try: id = int(res) except ValueError: - print "QR Code URI rejected" + print("QR Code URI rejected") continue - print "QR Code URI accepted - ID=%d" % id - print wpas.request("DPP_BOOTSTRAP_INFO %d" % id) + print("QR Code URI accepted - ID=%d" % id) + print(wpas.request("DPP_BOOTSTRAP_INFO %d" % id)) del wpas def dpp_display(curve): wpas = wpas_connect() if not wpas: - print "Could not connect to wpa_supplicant" + print("Could not connect to wpa_supplicant") return res = wpas.request("STATUS") addr = None @@ -93,18 +93,18 @@ def dpp_display(curve): try: id = int(res) except ValueError: - print "Failed to generate bootstrap info URI" + print("Failed to generate bootstrap info URI") return - print "Bootstrap information - ID=%d" % id - print wpas.request("DPP_BOOTSTRAP_INFO %d" % id) + print("Bootstrap information - ID=%d" % id) + print(wpas.request("DPP_BOOTSTRAP_INFO %d" % id)) uri = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % id) - print uri - print "ID=%d" % id + print(uri) + print("ID=%d" % id) qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_M, border=3) qr.add_data(uri, optimize=5) qr.print_ascii(tty=True) - print "ID=%d" % id + print("ID=%d" % id) del wpas def main(): diff --git a/wpa_supplicant/examples/p2p-nfc.py b/wpa_supplicant/examples/p2p-nfc.py index 91eba28908ed..889ac8bff155 100755 --- a/wpa_supplicant/examples/p2p-nfc.py +++ b/wpa_supplicant/examples/p2p-nfc.py @@ -37,7 +37,7 @@ summary_file = None success_file = None def summary(txt): - print txt + print(txt) if summary_file: with open(summary_file, 'a') as f: f.write(txt + "\n") @@ -53,12 +53,12 @@ def wpas_connect(): if os.path.isdir(wpas_ctrl): try: ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] - except OSError, error: - print "Could not find wpa_supplicant: ", error + except OSError as error: + print("Could not find wpa_supplicant: ", error) return None if len(ifaces) < 1: - print "No wpa_supplicant control interface found" + print("No wpa_supplicant control interface found") return None for ctrl in ifaces: @@ -66,10 +66,10 @@ def wpas_connect(): if ifname not in ctrl: continue try: - print "Trying to use control interface " + ctrl + print("Trying to use control interface " + ctrl) wpas = wpaspy.Ctrl(ctrl) return wpas - except Exception, e: + except Exception as e: pass return None @@ -160,30 +160,30 @@ def p2p_handover_client(llc): if (data == None): summary("Could not get handover request carrier record from wpa_supplicant") return - print "Handover request carrier record from wpa_supplicant: " + data.encode("hex") + print("Handover request carrier record from wpa_supplicant: " + data.encode("hex")) datamsg = nfc.ndef.Message(data) message.add_carrier(datamsg[0], "active", datamsg[1:]) global include_wps_req if include_wps_req: - print "Handover request (pre-WPS):" + print("Handover request (pre-WPS):") try: - print message.pretty() - except Exception, e: - print e + print(message.pretty()) + except Exception as e: + print(e) data = wpas_get_handover_req_wps() if data: - print "Add WPS request in addition to P2P" + print("Add WPS request in addition to P2P") datamsg = nfc.ndef.Message(data) message.add_carrier(datamsg[0], "active", datamsg[1:]) - print "Handover request:" + print("Handover request:") try: - print message.pretty() - except Exception, e: - print e - print str(message).encode("hex") + print(message.pretty()) + except Exception as e: + print(e) + print(str(message).encode("hex")) client = nfc.handover.HandoverClient(llc) try: @@ -194,7 +194,7 @@ def p2p_handover_client(llc): summary("Handover connection refused") client.close() return - except Exception, e: + except Exception as e: summary("Other exception: " + str(e)) client.close() return @@ -217,41 +217,41 @@ def p2p_handover_client(llc): client.close() return - print "Received message" + print("Received message") try: - print message.pretty() - except Exception, e: - print e - print str(message).encode("hex") + print(message.pretty()) + except Exception as e: + print(e) + print(str(message).encode("hex")) message = nfc.ndef.HandoverSelectMessage(message) summary("Handover select received") try: - print message.pretty() - except Exception, e: - print e + print(message.pretty()) + except Exception as e: + print(e) for carrier in message.carriers: - print "Remote carrier type: " + carrier.type + print("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.p2p": - print "P2P carrier type match - send to wpa_supplicant" + print("P2P carrier type match - send to wpa_supplicant") if "OK" in wpas_report_handover(data, carrier.record, "INIT"): success_report("P2P handover reported successfully (initiator)") else: summary("P2P handover report rejected") break - print "Remove peer" + print("Remove peer") client.close() - print "Done with handover" + print("Done with handover") global only_one if only_one: - print "only_one -> stop loop" + print("only_one -> stop loop") global continue_loop continue_loop = False global no_wait if no_wait: - print "Trying to exit.." + print("Trying to exit..") global terminate_now terminate_now = True @@ -283,33 +283,33 @@ class HandoverServer(nfc.handover.HandoverServer): def process_request(self, request): self.ho_server_processing = True clear_raw_mode() - print "HandoverServer - request received" + print("HandoverServer - request received") try: - print "Parsed handover request: " + request.pretty() - except Exception, e: - print e + print("Parsed handover request: " + request.pretty()) + except Exception as e: + print(e) sel = nfc.ndef.HandoverSelectMessage(version="1.2") found = False for carrier in request.carriers: - print "Remote carrier type: " + carrier.type + print("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.p2p": - print "P2P carrier type match - add P2P carrier record" + print("P2P carrier type match - add P2P carrier record") found = True self.received_carrier = carrier.record - print "Carrier record:" + print("Carrier record:") try: - print carrier.record.pretty() - except Exception, e: - print e + print(carrier.record.pretty()) + except Exception as e: + print(e) data = wpas_get_handover_sel() if data is None: - print "Could not get handover select carrier record from wpa_supplicant" + print("Could not get handover select carrier record from wpa_supplicant") continue - print "Handover select carrier record from wpa_supplicant:" - print data.encode("hex") + print("Handover select carrier record from wpa_supplicant:") + print(data.encode("hex")) self.sent_carrier = data if "OK" in wpas_report_handover(self.received_carrier, self.sent_carrier, "RESP"): success_report("P2P handover reported successfully (responder)") @@ -324,22 +324,22 @@ class HandoverServer(nfc.handover.HandoverServer): for carrier in request.carriers: if found: break - print "Remote carrier type: " + carrier.type + print("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.wsc": - print "WSC carrier type match - add WSC carrier record" + print("WSC carrier type match - add WSC carrier record") found = True self.received_carrier = carrier.record - print "Carrier record:" + print("Carrier record:") try: - print carrier.record.pretty() - except Exception, e: - print e + print(carrier.record.pretty()) + except Exception as e: + print(e) data = wpas_get_handover_sel_wps() if data is None: - print "Could not get handover select carrier record from wpa_supplicant" + print("Could not get handover select carrier record from wpa_supplicant") continue - print "Handover select carrier record from wpa_supplicant:" - print data.encode("hex") + print("Handover select carrier record from wpa_supplicant:") + print(data.encode("hex")) self.sent_carrier = data if "OK" in wpas_report_handover_wsc(self.received_carrier, self.sent_carrier, "RESP"): success_report("WSC handover reported successfully") @@ -352,12 +352,12 @@ class HandoverServer(nfc.handover.HandoverServer): found = True break - print "Handover select:" + print("Handover select:") try: - print sel.pretty() - except Exception, e: - print e - print str(sel).encode("hex") + print(sel.pretty()) + except Exception as e: + print(e) + print(str(sel).encode("hex")) summary("Sending handover select") self.success = True @@ -396,7 +396,7 @@ def p2p_tag_read(tag): success = False if len(tag.ndef.message): for record in tag.ndef.message: - print "record type " + record.type + print("record type " + record.type) if record.type == "application/vnd.wfa.wsc": summary("WPS tag - send to wpa_supplicant") success = wpas_tag_read(tag.ndef.message) @@ -419,7 +419,7 @@ def rdwr_connected_p2p_write(tag): global p2p_sel_data tag.ndef.message = str(p2p_sel_data) success_report("Tag write succeeded") - print "Done - remove tag" + print("Done - remove tag") global only_one if only_one: global continue_loop @@ -428,7 +428,7 @@ def rdwr_connected_p2p_write(tag): return p2p_sel_wait_remove def wps_write_p2p_handover_sel(clf, wait_remove=True): - print "Write P2P handover select" + print("Write P2P handover select") data = wpas_get_handover_sel(tag=True) if (data == None): summary("Could not get P2P handover select from wpa_supplicant") @@ -440,14 +440,14 @@ def wps_write_p2p_handover_sel(clf, wait_remove=True): p2p_sel_data = nfc.ndef.HandoverSelectMessage(version="1.2") message = nfc.ndef.Message(data); p2p_sel_data.add_carrier(message[0], "active", message[1:]) - print "Handover select:" + print("Handover select:") try: - print p2p_sel_data.pretty() - except Exception, e: - print e - print str(p2p_sel_data).encode("hex") + print(p2p_sel_data.pretty()) + except Exception as e: + print(e) + print(str(p2p_sel_data).encode("hex")) - print "Touch an NFC tag" + print("Touch an NFC tag") clf.connect(rdwr={'on-connect': rdwr_connected_p2p_write}) @@ -456,11 +456,11 @@ def rdwr_connected(tag): summary("Tag connected: " + str(tag)) if tag.ndef: - print "NDEF tag: " + tag.type + print("NDEF tag: " + tag.type) try: - print tag.ndef.message.pretty() - except Exception, e: - print e + print(tag.ndef.message.pretty()) + except Exception as e: + print(e) success = p2p_tag_read(tag) if only_one and success: global continue_loop @@ -475,15 +475,15 @@ def rdwr_connected(tag): def llcp_worker(llc): global init_on_touch if init_on_touch: - print "Starting handover client" + print("Starting handover client") p2p_handover_client(llc) return global no_input if no_input: - print "Wait for handover to complete" + print("Wait for handover to complete") else: - print "Wait for handover to complete - press 'i' to initiate ('w' for WPS only, 'p' for P2P only)" + print("Wait for handover to complete - press 'i' to initiate ('w' for WPS only, 'p' for P2P only)") global srv global wait_connection while not wait_connection and srv.sent_carrier is None: @@ -506,21 +506,21 @@ def llcp_worker(llc): else: continue clear_raw_mode() - print "Starting handover client" + print("Starting handover client") p2p_handover_client(llc) return clear_raw_mode() - print "Exiting llcp_worker thread" + print("Exiting llcp_worker thread") def llcp_startup(clf, llc): - print "Start LLCP server" + print("Start LLCP server") global srv srv = HandoverServer(llc) return llc def llcp_connected(llc): - print "P2P LLCP connected" + print("P2P LLCP connected") global wait_connection wait_connection = False global init_on_touch @@ -587,7 +587,7 @@ def main(): if args.ifname: global ifname ifname = args.ifname - print "Selected ifname " + ifname + print("Selected ifname " + ifname) if args.no_wps_req: global include_wps_req @@ -610,7 +610,7 @@ def main(): try: if not clf.open("usb"): - print "Could not open connection with an NFC device" + print("Could not open connection with an NFC device") raise SystemExit if args.command == "write-p2p-sel": @@ -619,7 +619,7 @@ def main(): global continue_loop while continue_loop: - print "Waiting for a tag or peer to be touched" + print("Waiting for a tag or peer to be touched") wait_connection = True try: if args.tag_read_only: @@ -636,8 +636,8 @@ def main(): 'on-connect': llcp_connected}, terminate=terminate_loop): break - except Exception, e: - print "clf.connect failed" + except Exception as e: + print("clf.connect failed") global srv if only_one and srv and srv.success: diff --git a/wpa_supplicant/examples/p2p/p2p_connect.py b/wpa_supplicant/examples/p2p/p2p_connect.py index 59b0a9d36462..6e3d94e20ca3 100644 --- a/wpa_supplicant/examples/p2p/p2p_connect.py +++ b/wpa_supplicant/examples/p2p/p2p_connect.py @@ -13,40 +13,40 @@ from dbus.mainloop.glib import DBusGMainLoop def usage(): - print "Usage:" - print " %s -i <interface_name> -m <wps_method> \ " \ - % sys.argv[0] - print " -a <addr> [-p <pin>] [-g <go_intent>] \ " - print " [-w <wpas_dbus_interface>]" - print "Options:" - print " -i = interface name" - print " -m = wps method" - print " -a = peer address" - print " -p = pin number (8 digits)" - print " -g = group owner intent" - print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" - print "Example:" - print " %s -i wlan0 -a 0015008352c0 -m display -p 12345670" % sys.argv[0] + print("Usage:") + print(" %s -i <interface_name> -m <wps_method> \ " \ + % sys.argv[0]) + print(" -a <addr> [-p <pin>] [-g <go_intent>] \ ") + print(" [-w <wpas_dbus_interface>]") + print("Options:") + print(" -i = interface name") + print(" -m = wps method") + print(" -a = peer address") + print(" -p = pin number (8 digits)") + print(" -g = group owner intent") + print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1") + print("Example:") + print(" %s -i wlan0 -a 0015008352c0 -m display -p 12345670" % sys.argv[0]) # Required Signals def GONegotiationSuccess(status): - print "Go Negotiation Success" + print("Go Negotiation Success") def GONegotiationFailure(status): - print 'Go Negotiation Failed. Status:' - print format(status) + print('Go Negotiation Failed. Status:') + print(format(status)) os._exit(0) def GroupStarted(properties): if properties.has_key("group_object"): - print 'Group Formation Complete %s' \ - % properties["group_object"] + print('Group Formation Complete %s' \ + % properties["group_object"]) os._exit(0) def WpsFailure(status, etc): - print "WPS Authentication Failure".format(status) - print etc + print("WPS Authentication Failure".format(status)) + print(etc) os._exit(0) class P2P_Connect(): @@ -118,7 +118,7 @@ class P2P_Connect(): {'Ifname': ifname, 'Driver': 'test'}) time.sleep(1) - except dbus.DBusException, exc: + except dbus.DBusException as exc: if not str(exc).startswith( self.wpas_dbus_interface + \ ".InterfaceExists:"): @@ -157,12 +157,12 @@ class P2P_Connect(): if (self.pin != None): self.p2p_connect_arguements.update({'pin':self.pin}) else: - print "Error:\n Pin required for wps_method=display" + print("Error:\n Pin required for wps_method=display") usage() quit() if (self.go_intent != None and int(self.go_intent) != 15): - print "go_intent overwritten to 15" + print("go_intent overwritten to 15") self.go_intent = '15' @@ -171,14 +171,14 @@ class P2P_Connect(): if (self.pin != None): self.p2p_connect_arguements.update({'pin':self.pin}) else: - print "Error:\n Pin required for wps_method=keypad" + print("Error:\n Pin required for wps_method=keypad") usage() quit() if (self.go_intent != None and int(self.go_intent) == 15): error = "Error :\n Group Owner intent cannot be" + \ " 15 for wps_method=keypad" - print error + print(error) usage() quit() @@ -186,15 +186,15 @@ class P2P_Connect(): # for ./wpa_cli, p2p_connect [mac] [pin#], wps_method=keypad elif (self.wps_method == 'pin'): if (self.pin != None): - print "pin ignored" + print("pin ignored") # No pin is required for pbc so it is ignored elif (self.wps_method == 'pbc'): if (self.pin != None): - print "pin ignored" + print("pin ignored") else: - print "Error:\n wps_method not supported or does not exist" + print("Error:\n wps_method not supported or does not exist") usage() quit() @@ -209,12 +209,12 @@ class P2P_Connect(): result_pin = self.p2p_interface.Connect( self.p2p_connect_arguements) - except dbus.DBusException, exc: + except dbus.DBusException as exc: raise exc if (self.wps_method == 'pin' and \ not self.p2p_connect_arguements.has_key('pin') ): - print "Connect return with pin value of %d " % int(result_pin) + print("Connect return with pin value of %d " % int(result_pin)) gobject.MainLoop().run() if __name__ == "__main__": @@ -268,19 +268,19 @@ if __name__ == "__main__": # Required Arguements check if (interface_name == None or wps_method == None or addr == None): - print "Error:\n Required arguements not specified" + print("Error:\n Required arguements not specified") usage() quit() # Group Owner Intent Check if (go_intent != None and (int(go_intent) > 15 or int(go_intent) < 0) ): - print "Error:\n Group Owner Intent must be between 0 and 15 inclusive" + print("Error:\n Group Owner Intent must be between 0 and 15 inclusive") usage() quit() # Pin Check if (pin != None and len(pin) != 8): - print "Error:\n Pin is not 8 digits" + print("Error:\n Pin is not 8 digits") usage() quit() @@ -289,7 +289,7 @@ if __name__ == "__main__": addr,pin,wps_method,go_intent) except: - print "Error:\n Invalid Arguements" + print("Error:\n Invalid Arguements") usage() quit() diff --git a/wpa_supplicant/examples/p2p/p2p_disconnect.py b/wpa_supplicant/examples/p2p/p2p_disconnect.py index c3e39b3de285..85b5a8b39f5e 100644 --- a/wpa_supplicant/examples/p2p/p2p_disconnect.py +++ b/wpa_supplicant/examples/p2p/p2p_disconnect.py @@ -12,19 +12,19 @@ import getopt from dbus.mainloop.glib import DBusGMainLoop def usage(): - print "Usage:" - print " %s -i <interface_name> \ " \ - % sys.argv[0] - print " [-w <wpas_dbus_interface>]" - print "Options:" - print " -i = interface name" - print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" - print "Example:" - print " %s -i p2p-wlan0-0" % sys.argv[0] + print("Usage:") + print(" %s -i <interface_name> \ " \ + % sys.argv[0]) + print(" [-w <wpas_dbus_interface>]") + print("Options:") + print(" -i = interface name") + print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1") + print("Example:") + print(" %s -i p2p-wlan0-0" % sys.argv[0]) # Required Signals def GroupFinished(status, etc): - print "Disconnected" + print("Disconnected") os._exit(0) class P2P_Disconnect (threading.Thread): @@ -81,10 +81,10 @@ class P2P_Disconnect (threading.Thread): try: self.path = self.wpas.GetInterface( self.interface_name) - except dbus.DBusException, exc: + except dbus.DBusException as exc: error = 'Error:\n Interface ' + self.interface_name \ + ' was not found' - print error + print(error) usage() os._exit(0) @@ -142,7 +142,7 @@ if __name__ == "__main__": # Interface name is required and was not given if (interface_name == None): - print "Error:\n interface_name is required" + print("Error:\n interface_name is required") usage() quit() @@ -152,7 +152,7 @@ if __name__ == "__main__": wpas_dbus_interface,timeout) except: - print "Error:\n Invalid wpas_dbus_interface" + print("Error:\n Invalid wpas_dbus_interface") usage() quit() @@ -165,5 +165,5 @@ if __name__ == "__main__": except: pass - print "Disconnect timed out" + print("Disconnect timed out") quit() diff --git a/wpa_supplicant/examples/p2p/p2p_find.py b/wpa_supplicant/examples/p2p/p2p_find.py index 973d46ab0f4b..e2df52896991 100644 --- a/wpa_supplicant/examples/p2p/p2p_find.py +++ b/wpa_supplicant/examples/p2p/p2p_find.py @@ -13,23 +13,23 @@ import getopt from dbus.mainloop.glib import DBusGMainLoop def usage(): - print "Usage:" - print " %s -i <interface_name> [-t <timeout>] \ " \ - % sys.argv[0] - print " [-w <wpas_dbus_interface>]" - print "Options:" - print " -i = interface name" - print " -t = timeout = 0s (infinite)" - print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" - print "Example:" - print " %s -i wlan0 -t 10" % sys.argv[0] + print("Usage:") + print(" %s -i <interface_name> [-t <timeout>] \ " \ + % sys.argv[0]) + print(" [-w <wpas_dbus_interface>]") + print("Options:") + print(" -i = interface name") + print(" -t = timeout = 0s (infinite)") + print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1") + print("Example:") + print(" %s -i wlan0 -t 10" % sys.argv[0]) # Required Signals def deviceFound(devicepath): - print "Device found: %s" % (devicepath) + print("Device found: %s" % (devicepath)) def deviceLost(devicepath): - print "Device lost: %s" % (devicepath) + print("Device lost: %s" % (devicepath)) class P2P_Find (threading.Thread): # Needed Variables @@ -85,10 +85,10 @@ class P2P_Find (threading.Thread): try: self.path = self.wpas.GetInterface( self.interface_name) - except dbus.DBusException, exc: + except dbus.DBusException as exc: error = 'Error:\n Interface ' + self.interface_name \ + ' was not found' - print error + print(error) usage() os._exit(0) @@ -150,7 +150,7 @@ if __name__ == "__main__": if ( int(value) >= 0): timeout = value else: - print "Error:\n Timeout cannot be negative" + print("Error:\n Timeout cannot be negative") usage() quit() # Dbus interface @@ -161,7 +161,7 @@ if __name__ == "__main__": # Interface name is required and was not given if (interface_name == None): - print "Error:\n interface_name is required" + print("Error:\n interface_name is required") usage() quit() @@ -170,7 +170,7 @@ if __name__ == "__main__": p2p_find_test = P2P_Find(interface_name, wpas_dbus_interface, timeout) except: - print "Error:\n Invalid wpas_dbus_interface" + print("Error:\n Invalid wpas_dbus_interface") usage() quit() diff --git a/wpa_supplicant/examples/p2p/p2p_flush.py b/wpa_supplicant/examples/p2p/p2p_flush.py index ff8509d6053d..42fc7a3e915a 100644 --- a/wpa_supplicant/examples/p2p/p2p_flush.py +++ b/wpa_supplicant/examples/p2p/p2p_flush.py @@ -13,19 +13,19 @@ import getopt from dbus.mainloop.glib import DBusGMainLoop def usage(): - print "Usage:" - print " %s -i <interface_name> \ " \ - % sys.argv[0] - print " [-w <wpas_dbus_interface>]" - print "Options:" - print " -i = interface name" - print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" - print "Example:" - print " %s -i wlan0" % sys.argv[0] + print("Usage:") + print(" %s -i <interface_name> \ " \ + % sys.argv[0]) + print(" [-w <wpas_dbus_interface>]") + print("Options:") + print(" -i = interface name") + print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1") + print("Example:") + print(" %s -i wlan0" % sys.argv[0]) # Required Signals\ def deviceLost(devicepath): - print "Device lost: %s" % (devicepath) + print("Device lost: %s" % (devicepath)) class P2P_Flush (threading.Thread): # Needed Variables @@ -81,10 +81,10 @@ class P2P_Flush (threading.Thread): try: self.path = self.wpas.GetInterface( self.interface_name) - except dbus.DBusException, exc: + except dbus.DBusException as exc: error = 'Error:\n Interface ' + self.interface_name \ + ' was not found' - print error + print(error) usage() os._exit(0) @@ -142,7 +142,7 @@ if __name__ == "__main__": # Interface name is required and was not given if (interface_name == None): - print "Error:\n interface_name is required" + print("Error:\n interface_name is required") usage() quit() @@ -151,7 +151,7 @@ if __name__ == "__main__": p2p_flush_test = P2P_Flush(interface_name, wpas_dbus_interface,timeout) except: - print "Error:\n Invalid wpas_dbus_interface" + print("Error:\n Invalid wpas_dbus_interface") usage() quit() @@ -164,5 +164,5 @@ if __name__ == "__main__": except: pass - print "p2p_flush complete" + print("p2p_flush complete") quit() diff --git a/wpa_supplicant/examples/p2p/p2p_group_add.py b/wpa_supplicant/examples/p2p/p2p_group_add.py index 5c8fdafdfd9a..6d408218a25e 100644 --- a/wpa_supplicant/examples/p2p/p2p_group_add.py +++ b/wpa_supplicant/examples/p2p/p2p_group_add.py @@ -11,30 +11,30 @@ import threading from dbus.mainloop.glib import DBusGMainLoop def usage(): - print "Usage:" - print " %s -i <interface_name> [-p <persistent>] \ " \ - % sys.argv[0] - print " [-f <frequency>] [-o <group_object_path>] \ " - print " [-w <wpas_dbus_interface>]" - print "Options:" - print " -i = interface name" - print " -p = persistant group = 0 (0=false, 1=true)" - print " -f = frequency" - print " -o = persistent group object path" - print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" - print "Example:" - print " %s -i wlan0" % sys.argv[0] + print("Usage:") + print(" %s -i <interface_name> [-p <persistent>] \ " \ + % sys.argv[0]) + print(" [-f <frequency>] [-o <group_object_path>] \ ") + print(" [-w <wpas_dbus_interface>]") + print("Options:") + print(" -i = interface name") + print(" -p = persistant group = 0 (0=false, 1=true)") + print(" -f = frequency") + print(" -o = persistent group object path") + print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1") + print("Example:") + print(" %s -i wlan0" % sys.argv[0]) # Required Signals def GroupStarted(properties): if properties.has_key("group_object"): - print 'Group Formation Complete %s' \ - % properties["group_object"] + print('Group Formation Complete %s' \ + % properties["group_object"]) os._exit(0) def WpsFailure(status, etc): - print "WPS Authentication Failure".format(status) - print etc + print("WPS Authentication Failure".format(status)) + print(etc) os._exit(0) class P2P_Group_Add (threading.Thread): @@ -99,10 +99,10 @@ class P2P_Group_Add (threading.Thread): try: self.path = self.wpas.GetInterface( self.interface_name) - except dbus.DBusException, exc: + except dbus.DBusException as exc: error = 'Error:\n Interface ' + self.interface_name \ + ' was not found' - print error + print(error) usage() os._exit(0) @@ -127,7 +127,7 @@ class P2P_Group_Add (threading.Thread): if (int(self.frequency) > 0): self.P2PDictionary.update({'frequency':int(self.frequency)}) else: - print "Error:\n Frequency must be greater than 0" + print("Error:\n Frequency must be greater than 0") usage() os._exit(0) @@ -141,7 +141,7 @@ class P2P_Group_Add (threading.Thread): self.p2p_interface.GroupAdd(self.P2PDictionary) except: - print "Error:\n Could not preform group add" + print("Error:\n Could not preform group add") usage() os._exit(0) @@ -188,7 +188,7 @@ if __name__ == "__main__": elif (value == '1'): persistent = True else: - print "Error:\n Persistent can only be 1 or 0" + print("Error:\n Persistent can only be 1 or 0") usage() os._exit(0) # Frequency @@ -205,7 +205,7 @@ if __name__ == "__main__": # Interface name is required and was not given if (interface_name == None): - print "Error:\n interface_name is required" + print("Error:\n interface_name is required") usage() quit() @@ -213,10 +213,10 @@ if __name__ == "__main__": p2p_group_add_test = P2P_Group_Add(interface_name,wpas_dbus_interface, persistent,frequency,persistent_group_object) except: - print "Error:\n Invalid Arguements" + print("Error:\n Invalid Arguements") p2p_group_add_test.constructArguements() p2p_group_add_test.start() time.sleep(5) - print "Error:\n Group formation timed out" + print("Error:\n Group formation timed out") os._exit(0) diff --git a/wpa_supplicant/examples/p2p/p2p_invite.py b/wpa_supplicant/examples/p2p/p2p_invite.py index 6deb397eca83..341dcd0a983d 100644 --- a/wpa_supplicant/examples/p2p/p2p_invite.py +++ b/wpa_supplicant/examples/p2p/p2p_invite.py @@ -11,29 +11,29 @@ import threading from dbus.mainloop.glib import DBusGMainLoop def usage(): - print "Usage:" - print " %s -i <interface_name> -a <addr> \ " \ - % sys.argv[0] - print " [-o <persistent_group_object>] [-w <wpas_dbus_interface>]" - print "Options:" - print " -i = interface name" - print " -a = address of peer" - print " -o = persistent group object path" - print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" - print "Example:" - print " %s -i p2p-wlan0-0 -a 00150083523c" % sys.argv[0] + print("Usage:") + print(" %s -i <interface_name> -a <addr> \ " \ + % sys.argv[0]) + print(" [-o <persistent_group_object>] [-w <wpas_dbus_interface>]") + print("Options:") + print(" -i = interface name") + print(" -a = address of peer") + print(" -o = persistent group object path") + print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1") + print("Example:") + print(" %s -i p2p-wlan0-0 -a 00150083523c" % sys.argv[0]) # Required Signals def InvitationResult(invite_result): - print "Inviation Result signal :" + print("Inviation Result signal :") status = invite_result['status'] - print "status = ", status + print("status = ", status) if invite_result.has_key('BSSID'): bssid = invite_result['BSSID'] - print "BSSID = ", hex(bssid[0]) , ":" , \ + print("BSSID = ", hex(bssid[0]) , ":" , \ hex(bssid[1]) , ":" , hex(bssid[2]) , ":", \ hex(bssid[3]) , ":" , hex(bssid[4]) , ":" , \ - hex(bssid[5]) + hex(bssid[5])) os._exit(0) class P2P_Invite (threading.Thread): @@ -96,10 +96,10 @@ class P2P_Invite (threading.Thread): try: self.path = self.wpas.GetInterface( self.interface_name) - except dbus.DBusException, exc: + except dbus.DBusException as exc: error = 'Error:\n Interface ' + self.interface_name \ + ' was not found' - print error + print(error) usage() os._exit(0) @@ -127,7 +127,7 @@ class P2P_Invite (threading.Thread): self.p2p_interface.Invite(self.P2PDictionary) except: - print "Error:\n Invalid Arguements" + print("Error:\n Invalid Arguements") usage() os._exit(0) @@ -176,12 +176,12 @@ if __name__ == "__main__": # Interface name is required and was not given if (interface_name == None): - print "Error:\n interface_name is required" + print("Error:\n interface_name is required") usage() quit() if (addr == None): - print "Error:\n peer address is required" + print("Error:\n peer address is required") usage() quit() @@ -190,12 +190,12 @@ if __name__ == "__main__": P2P_Invite(interface_name,wpas_dbus_interface, addr,persistent_group_object) except: - print "Error:\n Invalid Arguements" + print("Error:\n Invalid Arguements") usage() os._exit(1) p2p_invite_test.constructArguements() p2p_invite_test.start() time.sleep(10) - print "Error:\n p2p_invite timed out" + print("Error:\n p2p_invite timed out") os._exit(0) diff --git a/wpa_supplicant/examples/p2p/p2p_listen.py b/wpa_supplicant/examples/p2p/p2p_listen.py index bb3c1e49d5f1..b0837d9df5d2 100644 --- a/wpa_supplicant/examples/p2p/p2p_listen.py +++ b/wpa_supplicant/examples/p2p/p2p_listen.py @@ -13,20 +13,20 @@ import getopt from dbus.mainloop.glib import DBusGMainLoop def usage(): - print "Usage:" - print " %s -i <interface_name> [-t <timeout>] \ " \ - % sys.argv[0] - print " [-w <wpas_dbus_interface>]" - print "Options:" - print " -i = interface name" - print " -t = timeout = 0s (infinite)" - print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" - print "Example:" - print " %s -i wlan0 -t 5" % sys.argv[0] + print("Usage:") + print(" %s -i <interface_name> [-t <timeout>] \ " \ + % sys.argv[0]) + print(" [-w <wpas_dbus_interface>]") + print("Options:") + print(" -i = interface name") + print(" -t = timeout = 0s (infinite)") + print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1") + print("Example:") + print(" %s -i wlan0 -t 5" % sys.argv[0]) # Required Signals def p2pStateChange(status): - print status + print(status) class P2P_Listen(threading.Thread): # Needed Variables @@ -82,10 +82,10 @@ class P2P_Listen(threading.Thread): try: self.path = self.wpas.GetInterface( self.interface_name) - except dbus.DBusException, exc: + except dbus.DBusException as exc: error = 'Error:\n Interface ' + self.interface_name \ + ' was not found' - print error + print(error) usage() os._exit(0) @@ -140,7 +140,7 @@ if __name__ == "__main__": if ( int(value) >= 0): timeout = value else: - print "Error:\n Timeout cannot be negative" + print("Error:\n Timeout cannot be negative") usage() quit() # Dbus interface @@ -151,7 +151,7 @@ if __name__ == "__main__": # Interface name is required and was not given if (interface_name == None): - print "Error:\n interface_name is required" + print("Error:\n interface_name is required") usage() quit() @@ -160,7 +160,7 @@ if __name__ == "__main__": p2p_listen_test = P2P_Listen(interface_name, wpas_dbus_interface, timeout) except: - print "Error:\n Invalid wpas_dbus_interface" + print("Error:\n Invalid wpas_dbus_interface") usage() quit() diff --git a/wpa_supplicant/examples/p2p/p2p_stop_find.py b/wpa_supplicant/examples/p2p/p2p_stop_find.py index f6c03b027228..bdb4c0e3221d 100644 --- a/wpa_supplicant/examples/p2p/p2p_stop_find.py +++ b/wpa_supplicant/examples/p2p/p2p_stop_find.py @@ -11,22 +11,22 @@ import getopt from dbus.mainloop.glib import DBusGMainLoop def usage(): - print "Usage:" - print " %s -i <interface_name> \ " \ - % sys.argv[0] - print " [-w <wpas_dbus_interface>]" - print "Options:" - print " -i = interface name" - print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" - print "Example:" - print " %s -i wlan0" % sys.argv[0] + print("Usage:") + print(" %s -i <interface_name> \ " \ + % sys.argv[0]) + print(" [-w <wpas_dbus_interface>]") + print("Options:") + print(" -i = interface name") + print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1") + print("Example:") + print(" %s -i wlan0" % sys.argv[0]) # Required Signals def deviceLost(devicepath): - print "Device lost: %s" % (devicepath) + print("Device lost: %s" % (devicepath)) def p2pStateChange(status): - print status + print(status) os._exit(0) class P2P_Stop_Find (threading.Thread): @@ -83,10 +83,10 @@ class P2P_Stop_Find (threading.Thread): try: self.path = self.wpas.GetInterface( self.interface_name) - except dbus.DBusException, exc: + except dbus.DBusException as exc: error = 'Error:\n Interface ' + self.interface_name \ + ' was not found' - print error + print(error) usage() os._exit(0) @@ -147,7 +147,7 @@ if __name__ == "__main__": # Interface name is required and was not given if (interface_name == None): - print "Error:\n interface_name is required" + print("Error:\n interface_name is required") usage() quit() @@ -157,7 +157,7 @@ if __name__ == "__main__": wpas_dbus_interface,timeout) except: - print "Error:\n Invalid wpas_dbus_interface" + print("Error:\n Invalid wpas_dbus_interface") usage() quit() @@ -170,5 +170,5 @@ if __name__ == "__main__": except: pass - print "p2p find stopped" + print("p2p find stopped") quit() diff --git a/wpa_supplicant/examples/wpas-dbus-new-getall.py b/wpa_supplicant/examples/wpas-dbus-new-getall.py index 03da187c8908..732f54d20f8b 100755 --- a/wpa_supplicant/examples/wpas-dbus-new-getall.py +++ b/wpa_supplicant/examples/wpas-dbus-new-getall.py @@ -11,8 +11,8 @@ def main(): "/fi/w1/wpa_supplicant1") props = wpas_obj.GetAll("fi.w1.wpa_supplicant1", dbus_interface=dbus.PROPERTIES_IFACE) - print "GetAll(fi.w1.wpa_supplicant1, /fi/w1/wpa_supplicant1):" - print props + print("GetAll(fi.w1.wpa_supplicant1, /fi/w1/wpa_supplicant1):") + print(props) if len(sys.argv) != 2: os._exit(1) @@ -24,15 +24,15 @@ def main(): if_obj = bus.get_object("fi.w1.wpa_supplicant1", path) props = if_obj.GetAll("fi.w1.wpa_supplicant1.Interface", dbus_interface=dbus.PROPERTIES_IFACE) - print - print "GetAll(fi.w1.wpa_supplicant1.Interface, %s):" % (path) - print props + print('') + print("GetAll(fi.w1.wpa_supplicant1.Interface, %s):" % (path)) + print(props) props = if_obj.GetAll("fi.w1.wpa_supplicant1.Interface.WPS", dbus_interface=dbus.PROPERTIES_IFACE) - print - print "GetAll(fi.w1.wpa_supplicant1.Interface.WPS, %s):" % (path) - print props + print('') + print("GetAll(fi.w1.wpa_supplicant1.Interface.WPS, %s):" % (path)) + print(props) res = if_obj.Get("fi.w1.wpa_supplicant1.Interface", 'BSSs', dbus_interface=dbus.PROPERTIES_IFACE) @@ -40,9 +40,9 @@ def main(): bss_obj = bus.get_object("fi.w1.wpa_supplicant1", res[0]) props = bss_obj.GetAll("fi.w1.wpa_supplicant1.BSS", dbus_interface=dbus.PROPERTIES_IFACE) - print - print "GetAll(fi.w1.wpa_supplicant1.BSS, %s):" % (res[0]) - print props + print('') + print("GetAll(fi.w1.wpa_supplicant1.BSS, %s):" % (res[0])) + print(props) res = if_obj.Get("fi.w1.wpa_supplicant1.Interface", 'Networks', dbus_interface=dbus.PROPERTIES_IFACE) @@ -50,10 +50,9 @@ def main(): net_obj = bus.get_object("fi.w1.wpa_supplicant1", res[0]) props = net_obj.GetAll("fi.w1.wpa_supplicant1.Network", dbus_interface=dbus.PROPERTIES_IFACE) - print - print "GetAll(fi.w1.wpa_supplicant1.Network, %s):" % (res[0]) - print props + print('') + print("GetAll(fi.w1.wpa_supplicant1.Network, %s):" % (res[0])) + print(props) if __name__ == "__main__": main() - diff --git a/wpa_supplicant/examples/wpas-dbus-new-signals.py b/wpa_supplicant/examples/wpas-dbus-new-signals.py index d90ef1878ca7..366a65546af6 100755 --- a/wpa_supplicant/examples/wpas-dbus-new-signals.py +++ b/wpa_supplicant/examples/wpas-dbus-new-signals.py @@ -32,17 +32,17 @@ def list_interfaces(wpas_obj): if_obj = bus.get_object(WPAS_DBUS_SERVICE, path) ifname = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'Ifname', dbus_interface=dbus.PROPERTIES_IFACE) - print ifname + print(ifname) def interfaceAdded(interface, properties): - print "InterfaceAdded(%s): Ifname=%s" % (interface, properties['Ifname']) + print("InterfaceAdded(%s): Ifname=%s" % (interface, properties['Ifname'])) def interfaceRemoved(interface): - print "InterfaceRemoved(%s)" % (interface) + print("InterfaceRemoved(%s)" % (interface)) def propertiesChanged(properties): for i in properties: - print "PropertiesChanged: %s=%s" % (i, properties[i]) + print("PropertiesChanged: %s=%s" % (i, properties[i])) def showBss(bss): net_obj = bus.get_object(WPAS_DBUS_SERVICE, bss) @@ -80,48 +80,48 @@ def showBss(bss): else: maxrate = 0 - print " %s :: ssid='%s' wpa=%s wpa2=%s signal=%d rate=%d freq=%d" % (bssid, ssid, wpa, wpa2, signal, maxrate, freq) + print(" %s :: ssid='%s' wpa=%s wpa2=%s signal=%d rate=%d freq=%d" % (bssid, ssid, wpa, wpa2, signal, maxrate, freq)) def scanDone(success): gobject.MainLoop().quit() - print "Scan done: success=%s" % success + print("Scan done: success=%s" % success) def scanDone2(success, path=None): - print "Scan done: success=%s [path=%s]" % (success, path) + print("Scan done: success=%s [path=%s]" % (success, path)) def bssAdded(bss, properties): - print "BSS added: %s" % (bss) + print("BSS added: %s" % (bss)) showBss(bss) def bssRemoved(bss): - print "BSS removed: %s" % (bss) + print("BSS removed: %s" % (bss)) def blobAdded(blob): - print "BlobAdded(%s)" % (blob) + print("BlobAdded(%s)" % (blob)) def blobRemoved(blob): - print "BlobRemoved(%s)" % (blob) + print("BlobRemoved(%s)" % (blob)) def networkAdded(network, properties): - print "NetworkAdded(%s)" % (network) + print("NetworkAdded(%s)" % (network)) def networkRemoved(network): - print "NetworkRemoved(%s)" % (network) + print("NetworkRemoved(%s)" % (network)) def networkSelected(network): - print "NetworkSelected(%s)" % (network) + print("NetworkSelected(%s)" % (network)) def propertiesChangedInterface(properties): for i in properties: - print "PropertiesChanged(interface): %s=%s" % (i, properties[i]) + print("PropertiesChanged(interface): %s=%s" % (i, properties[i])) def propertiesChangedBss(properties): for i in properties: - print "PropertiesChanged(BSS): %s=%s" % (i, properties[i]) + print("PropertiesChanged(BSS): %s=%s" % (i, properties[i])) def propertiesChangedNetwork(properties): for i in properties: - print "PropertiesChanged(Network): %s=%s" % (i, properties[i]) + print("PropertiesChanged(Network): %s=%s" % (i, properties[i])) def main(): dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) diff --git a/wpa_supplicant/examples/wpas-dbus-new-wps.py b/wpa_supplicant/examples/wpas-dbus-new-wps.py index b8863858fe8c..7d87b1efd5dc 100755 --- a/wpa_supplicant/examples/wpas-dbus-new-wps.py +++ b/wpa_supplicant/examples/wpas-dbus-new-wps.py @@ -15,23 +15,23 @@ WPAS_DBUS_WPS_INTERFACE = "fi.w1.wpa_supplicant1.Interface.WPS" def propertiesChanged(properties): if properties.has_key("State"): - print "PropertiesChanged: State: %s" % (properties["State"]) + print("PropertiesChanged: State: %s" % (properties["State"])) def scanDone(success): - print "Scan done: success=%s" % success + print("Scan done: success=%s" % success) def bssAdded(bss, properties): - print "BSS added: %s" % (bss) + print("BSS added: %s" % (bss)) def bssRemoved(bss): - print "BSS removed: %s" % (bss) + print("BSS removed: %s" % (bss)) def wpsEvent(name, args): - print "WPS event: %s" % (name) - print args + print("WPS event: %s" % (name)) + print(args) def credentials(cred): - print "WPS credentials: %s" % (cred) + print("WPS credentials: %s" % (cred)) def main(): dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) @@ -40,7 +40,7 @@ def main(): wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH) if len(sys.argv) != 2: - print "Missing ifname argument" + print("Missing ifname argument") os._exit(1) wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE) diff --git a/wpa_supplicant/examples/wpas-dbus-new.py b/wpa_supplicant/examples/wpas-dbus-new.py index 25072ce9a2df..6bf74ae44122 100755 --- a/wpa_supplicant/examples/wpas-dbus-new.py +++ b/wpa_supplicant/examples/wpas-dbus-new.py @@ -31,11 +31,11 @@ def list_interfaces(wpas_obj): if_obj = bus.get_object(WPAS_DBUS_SERVICE, path) ifname = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'Ifname', dbus_interface=dbus.PROPERTIES_IFACE) - print ifname + print(ifname) def propertiesChanged(properties): if properties.has_key("State"): - print "PropertiesChanged: State: %s" % (properties["State"]) + print("PropertiesChanged: State: %s" % (properties["State"])) def showBss(bss): net_obj = bus.get_object(WPAS_DBUS_SERVICE, bss) @@ -73,25 +73,25 @@ def showBss(bss): else: maxrate = 0 - print " %s :: ssid='%s' wpa=%s wpa2=%s signal=%d rate=%d freq=%d" % (bssid, ssid, wpa, wpa2, signal, maxrate, freq) + print(" %s :: ssid='%s' wpa=%s wpa2=%s signal=%d rate=%d freq=%d" % (bssid, ssid, wpa, wpa2, signal, maxrate, freq)) def scanDone(success): - print "Scan done: success=%s" % success + print("Scan done: success=%s" % success) res = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'BSSs', dbus_interface=dbus.PROPERTIES_IFACE) - print "Scanned wireless networks:" + print("Scanned wireless networks:") for opath in res: - print opath + print(opath) showBss(opath) def bssAdded(bss, properties): - print "BSS added: %s" % (bss) + print("BSS added: %s" % (bss)) showBss(bss) def bssRemoved(bss): - print "BSS removed: %s" % (bss) + print("BSS removed: %s" % (bss)) def main(): dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) @@ -123,14 +123,14 @@ def main(): path = None try: path = wpas.GetInterface(ifname) - except dbus.DBusException, exc: + except dbus.DBusException as exc: if not str(exc).startswith("fi.w1.wpa_supplicant1.InterfaceUnknown:"): raise exc try: path = wpas.CreateInterface({'Ifname': ifname, 'Driver': 'test'}) time.sleep(1) - except dbus.DBusException, exc: + except dbus.DBusException as exc: if not str(exc).startswith("fi.w1.wpa_supplicant1.InterfaceExists:"): raise exc diff --git a/wpa_supplicant/examples/wpas-test.py b/wpa_supplicant/examples/wpas-test.py deleted file mode 100755 index fd7f73d428b8..000000000000 --- 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, 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, 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/examples/wps-nfc.py b/wpa_supplicant/examples/wps-nfc.py index 7459eb9ae574..bb458fb37a84 100755 --- a/wpa_supplicant/examples/wps-nfc.py +++ b/wpa_supplicant/examples/wps-nfc.py @@ -30,7 +30,7 @@ summary_file = None success_file = None def summary(txt): - print txt + print(txt) if summary_file: with open(summary_file, 'a') as f: f.write(txt + "\n") @@ -46,19 +46,19 @@ def wpas_connect(): if os.path.isdir(wpas_ctrl): try: ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] - except OSError, error: - print "Could not find wpa_supplicant: ", error + except OSError as error: + print("Could not find wpa_supplicant: ", error) return None if len(ifaces) < 1: - print "No wpa_supplicant control interface found" + print("No wpa_supplicant control interface found") return None for ctrl in ifaces: try: wpas = wpaspy.Ctrl(ctrl) return wpas - except Exception, e: + except Exception as e: pass return None @@ -163,22 +163,22 @@ class HandoverServer(nfc.handover.HandoverServer): self.ho_server_processing = True summary("HandoverServer - request received") try: - print "Parsed handover request: " + request.pretty() - except Exception, e: - print e + print("Parsed handover request: " + request.pretty()) + except Exception as e: + print(e) sel = nfc.ndef.HandoverSelectMessage(version="1.2") for carrier in request.carriers: - print "Remote carrier type: " + carrier.type + print("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.wsc": summary("WPS carrier type match - add WPS carrier record") data = wpas_get_handover_sel(self.uuid) if data is None: summary("Could not get handover select carrier record from wpa_supplicant") continue - print "Handover select carrier record from wpa_supplicant:" - print data.encode("hex") + print("Handover select carrier record from wpa_supplicant:") + print(data.encode("hex")) self.sent_carrier = data if "OK" in wpas_report_handover(carrier.record, self.sent_carrier, "RESP"): success_report("Handover reported successfully (responder)") @@ -188,12 +188,12 @@ class HandoverServer(nfc.handover.HandoverServer): message = nfc.ndef.Message(data); sel.add_carrier(message[0], "active", message[1:]) - print "Handover select:" + print("Handover select:") try: - print sel.pretty() - except Exception, e: - print e - print str(sel).encode("hex") + print(sel.pretty()) + except Exception as e: + print(e) + print(str(sel).encode("hex")) summary("Sending handover select") self.success = True @@ -207,19 +207,19 @@ def wps_handover_init(llc): if (data == None): summary("Could not get handover request carrier record from wpa_supplicant") return - print "Handover request carrier record from wpa_supplicant: " + data.encode("hex") + print("Handover request carrier record from wpa_supplicant: " + data.encode("hex")) message = nfc.ndef.HandoverRequestMessage(version="1.2") message.nonce = random.randint(0, 0xffff) datamsg = nfc.ndef.Message(data) message.add_carrier(datamsg[0], "active", datamsg[1:]) - print "Handover request:" + print("Handover request:") try: - print message.pretty() - except Exception, e: - print e - print str(message).encode("hex") + print(message.pretty()) + except Exception as e: + print(e) + print(str(message).encode("hex")) client = nfc.handover.HandoverClient(llc) try: @@ -230,7 +230,7 @@ def wps_handover_init(llc): summary("Handover connection refused") client.close() return - except Exception, e: + except Exception as e: summary("Other exception: " + str(e)) client.close() return @@ -253,23 +253,23 @@ def wps_handover_init(llc): client.close() return - print "Received message" + print("Received message") try: - print message.pretty() - except Exception, e: - print e - print str(message).encode("hex") + print(message.pretty()) + except Exception as e: + print(e) + print(str(message).encode("hex")) message = nfc.ndef.HandoverSelectMessage(message) summary("Handover select received") try: - print message.pretty() - except Exception, e: - print e + print(message.pretty()) + except Exception as e: + print(e) for carrier in message.carriers: - print "Remote carrier type: " + carrier.type + print("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.wsc": - print "WPS carrier type match - send to wpa_supplicant" + print("WPS carrier type match - send to wpa_supplicant") if "OK" in wpas_report_handover(data, carrier.record, "INIT"): success_report("Handover reported successfully (initiator)") else: @@ -278,9 +278,9 @@ def wps_handover_init(llc): #wifi = nfc.ndef.WifiConfigRecord(carrier.record) #print wifi.pretty() - print "Remove peer" + print("Remove peer") client.close() - print "Done with handover" + print("Done with handover") global only_one if only_one: global continue_loop @@ -288,7 +288,7 @@ def wps_handover_init(llc): global no_wait if no_wait: - print "Trying to exit.." + print("Trying to exit..") global terminate_now terminate_now = True @@ -296,7 +296,7 @@ def wps_tag_read(tag, wait_remove=True): success = False if len(tag.ndef.message): for record in tag.ndef.message: - print "record type " + record.type + print("record type " + record.type) if record.type == "application/vnd.wfa.wsc": summary("WPS tag - send to wpa_supplicant") success = wpas_tag_read(tag.ndef.message) @@ -308,7 +308,7 @@ def wps_tag_read(tag, wait_remove=True): success_report("Tag read succeeded") if wait_remove: - print "Remove tag" + print("Remove tag") while tag.is_present: time.sleep(0.1) @@ -320,7 +320,7 @@ def rdwr_connected_write(tag): global write_data tag.ndef.message = str(write_data) success_report("Tag write succeeded") - print "Done - remove tag" + print("Done - remove tag") global only_one if only_one: global continue_loop @@ -330,41 +330,41 @@ def rdwr_connected_write(tag): time.sleep(0.1) def wps_write_config_tag(clf, id=None, wait_remove=True): - print "Write WPS config token" + print("Write WPS config token") global write_data, write_wait_remove write_wait_remove = wait_remove write_data = wpas_get_config_token(id) if write_data == None: - print "Could not get WPS config token from wpa_supplicant" + print("Could not get WPS config token from wpa_supplicant") sys.exit(1) return - print "Touch an NFC tag" + print("Touch an NFC tag") clf.connect(rdwr={'on-connect': rdwr_connected_write}) def wps_write_er_config_tag(clf, uuid, wait_remove=True): - print "Write WPS ER config token" + print("Write WPS ER config token") global write_data, write_wait_remove write_wait_remove = wait_remove write_data = wpas_get_er_config_token(uuid) if write_data == None: - print "Could not get WPS config token from wpa_supplicant" + print("Could not get WPS config token from wpa_supplicant") return - print "Touch an NFC tag" + print("Touch an NFC tag") clf.connect(rdwr={'on-connect': rdwr_connected_write}) def wps_write_password_tag(clf, wait_remove=True): - print "Write WPS password token" + print("Write WPS password token") global write_data, write_wait_remove write_wait_remove = wait_remove write_data = wpas_get_password_token() if write_data == None: - print "Could not get WPS password token from wpa_supplicant" + print("Could not get WPS password token from wpa_supplicant") return - print "Touch an NFC tag" + print("Touch an NFC tag") clf.connect(rdwr={'on-connect': rdwr_connected_write}) @@ -373,11 +373,11 @@ def rdwr_connected(tag): summary("Tag connected: " + str(tag)) if tag.ndef: - print "NDEF tag: " + tag.type + print("NDEF tag: " + tag.type) try: - print tag.ndef.message.pretty() - except Exception, e: - print e + print(tag.ndef.message.pretty()) + except Exception as e: + print(e) success = wps_tag_read(tag, not only_one) if only_one and success: global continue_loop @@ -393,7 +393,7 @@ def llcp_worker(llc): global arg_uuid if arg_uuid is None: wps_handover_init(llc) - print "Exiting llcp_worker thread" + print("Exiting llcp_worker thread") return global srv @@ -405,19 +405,19 @@ def llcp_worker(llc): def llcp_startup(clf, llc): global arg_uuid if arg_uuid: - print "Start LLCP server" + print("Start LLCP server") global srv srv = HandoverServer(llc) if arg_uuid is "ap": - print "Trying to handle WPS handover" + print("Trying to handle WPS handover") srv.uuid = None else: - print "Trying to handle WPS handover with AP " + arg_uuid + print("Trying to handle WPS handover with AP " + arg_uuid) srv.uuid = arg_uuid return llc def llcp_connected(llc): - print "P2P LLCP connected" + print("P2P LLCP connected") global wait_connection wait_connection = False global arg_uuid @@ -426,7 +426,7 @@ def llcp_connected(llc): srv.start() else: threading.Thread(target=llcp_worker, args=(llc,)).start() - print "llcp_connected returning" + print("llcp_connected returning") return True @@ -482,7 +482,7 @@ def main(): try: if not clf.open("usb"): - print "Could not open connection with an NFC device" + print("Could not open connection with an NFC device") raise SystemExit if args.command == "write-config": @@ -499,7 +499,7 @@ def main(): global continue_loop while continue_loop: - print "Waiting for a tag or peer to be touched" + print("Waiting for a tag or peer to be touched") wait_connection = True try: if not clf.connect(rdwr={'on-connect': rdwr_connected}, @@ -507,8 +507,8 @@ def main(): 'on-connect': llcp_connected}, terminate=terminate_loop): break - except Exception, e: - print "clf.connect failed" + except Exception as e: + print("clf.connect failed") global srv if only_one and srv and srv.success: diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c index f4f60c58bee5..8e977a3eccb3 100644 --- a/wpa_supplicant/gas_query.c +++ b/wpa_supplicant/gas_query.c @@ -272,7 +272,7 @@ static void gas_query_tx_status(struct wpa_supplicant *wpa_s, } -static int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr) +int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr) { if (wpa_s->current_ssid == NULL || wpa_s->wpa_state < WPA_4WAY_HANDSHAKE || diff --git a/wpa_supplicant/gas_query.h b/wpa_supplicant/gas_query.h index 982c0f7ce60e..d2b455442f0a 100644 --- a/wpa_supplicant/gas_query.h +++ b/wpa_supplicant/gas_query.h @@ -19,6 +19,7 @@ void gas_query_deinit(struct gas_query *gas); int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa, const u8 *bssid, u8 categ, const u8 *data, size_t len, int freq); +int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr); /** * enum gas_query_result - GAS query result diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c index f4187900ed42..cb236df18d86 100644 --- a/wpa_supplicant/hs20_supplicant.c +++ b/wpa_supplicant/hs20_supplicant.c @@ -95,8 +95,7 @@ void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s) return; } - /* Check if Proxy ARP is enabled (2nd byte in the IE) */ - if (ext_capa[3] & BIT(4)) + if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_PROXY_ARP)) filter |= WPA_DATA_FRAME_FILTER_FLAG_ARP | WPA_DATA_FRAME_FILTER_FLAG_NA; @@ -104,15 +103,22 @@ void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s) } -void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id) +void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id, int ap_release) { + int release; u8 conf; + release = (HS20_VERSION >> 4) + 1; + if (ap_release > 0 && release > ap_release) + release = ap_release; + if (release < 2) + pps_mo_id = -1; + wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); wpabuf_put_u8(buf, pps_mo_id >= 0 ? 7 : 5); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_INDICATION_OUI_TYPE); - conf = HS20_VERSION; + conf = (release - 1) << 4; if (pps_mo_id >= 0) conf |= HS20_PPS_MO_ID_PRESENT; wpabuf_put_u8(buf, conf); @@ -137,6 +143,21 @@ void wpas_hs20_add_roam_cons_sel(struct wpabuf *buf, } +int get_hs20_version(struct wpa_bss *bss) +{ + const u8 *ie; + + if (!bss) + return 0; + + ie = wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE); + if (!ie || ie[1] < 5) + return 0; + + return ((ie[6] >> 4) & 0x0f) + 1; +} + + int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_bss *bss) { @@ -410,7 +431,7 @@ static void hs20_set_osu_access_permission(const char *osu_dir, return; } - if (chown(fname, statbuf.st_uid, statbuf.st_gid) < 0) { + if (lchown(fname, statbuf.st_uid, statbuf.st_gid) < 0) { wpa_printf(MSG_WARNING, "Cannot change the ownership for %s", fname); } diff --git a/wpa_supplicant/hs20_supplicant.h b/wpa_supplicant/hs20_supplicant.h index 66fc540be3e4..e43414bc65c5 100644 --- a/wpa_supplicant/hs20_supplicant.h +++ b/wpa_supplicant/hs20_supplicant.h @@ -9,7 +9,8 @@ #define HS20_SUPPLICANT_H void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s); -void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id); +void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id, + int ap_release); void wpas_hs20_add_roam_cons_sel(struct wpabuf *buf, const struct wpa_ssid *ssid); @@ -20,6 +21,7 @@ void hs20_put_anqp_req(u32 stypes, const u8 *payload, size_t payload_len, void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, const u8 *sa, const u8 *data, size_t slen, u8 dialog_token); +int get_hs20_version(struct wpa_bss *bss); int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_bss *bss); int hs20_get_pps_mo_id(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c index 00919d14a55e..e96ea65a7887 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/interworking.c b/wpa_supplicant/interworking.c index 60c8be9a6c6a..f94cd1614c60 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -958,6 +958,7 @@ static int interworking_set_hs20_params(struct wpa_supplicant *wpa_s, "WPA-EAP WPA-EAP-SHA256" : "WPA-EAP"; if (wpa_config_set(ssid, "key_mgmt", key_mgmt, 0) < 0 || wpa_config_set(ssid, "proto", "RSN", 0) < 0 || + wpa_config_set(ssid, "ieee80211w", "1", 0) < 0 || wpa_config_set(ssid, "pairwise", "CCMP", 0) < 0) return -1; return 0; @@ -2625,7 +2626,6 @@ static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s) { struct wpa_bss *bss; int found = 0; - const u8 *ie; wpa_printf(MSG_DEBUG, "Interworking: next_anqp_fetch - " "fetch_anqp_in_progress=%d fetch_osu_icon_in_progress=%d", @@ -2648,8 +2648,7 @@ static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s) dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { if (!(bss->caps & IEEE80211_CAP_ESS)) continue; - ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB); - if (ie == NULL || ie[1] < 4 || !(ie[5] & 0x80)) + if (!wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_INTERWORKING)) continue; /* AP does not support Interworking */ if (disallowed_bssid(wpa_s, bss->bssid) || disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) @@ -2982,7 +2981,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, MAC2STR(sa)); anqp_add_extra(wpa_s, anqp, info_id, pos, slen); - if (!wpa_sm_pmf_enabled(wpa_s->wpa)) { + if (!pmf_in_use(wpa_s, sa)) { wpa_printf(MSG_DEBUG, "ANQP: Ignore Venue URL since PMF was not enabled"); break; diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c index e08c2fd266f1..51a8a0298a9b 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 5adf61e58bd0..43b1fa7beb38 100644 --- a/wpa_supplicant/mbo.c +++ b/wpa_supplicant/mbo.c @@ -51,6 +51,19 @@ const u8 * mbo_attr_from_mbo_ie(const u8 *mbo_ie, enum mbo_attr_id attr) } +const u8 * mbo_get_attr_from_ies(const u8 *ies, size_t ies_len, + enum mbo_attr_id attr) +{ + const u8 *mbo_ie; + + mbo_ie = get_vendor_ie(ies, ies_len, MBO_IE_VENDOR_TYPE); + if (!mbo_ie) + return NULL; + + return mbo_attr_from_mbo_ie(mbo_ie, attr); +} + + const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr) { const u8 *mbo, *end; @@ -85,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) { @@ -93,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); } @@ -132,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]; @@ -255,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); } @@ -280,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; } @@ -501,7 +522,7 @@ void wpas_mbo_ie_trans_req(struct wpa_supplicant *wpa_s, const u8 *mbo_ie, if (disallowed_sec && wpa_s->current_bss) wpa_bss_tmp_disallow(wpa_s, wpa_s->current_bss->bssid, - disallowed_sec); + disallowed_sec, 0); return; fail: @@ -545,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 38b9fb320ca9..92600211ac2d 100644 --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -34,6 +34,8 @@ static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s) wpa_s->current_ssid = NULL; os_free(wpa_s->mesh_rsn); wpa_s->mesh_rsn = NULL; + os_free(wpa_s->mesh_params); + wpa_s->mesh_params = NULL; /* TODO: leave mesh (stop beacon). This will happen on link down * anyway, so it's not urgent */ } @@ -93,6 +95,9 @@ static struct mesh_conf * mesh_config_create(struct wpa_supplicant *wpa_s, conf->ieee80211w = NO_MGMT_FRAME_PROTECTION; } #endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_OCV + conf->ocv = ssid->ocv; +#endif /* CONFIG_OCV */ cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher, 0); if (cipher < 0 || cipher == WPA_CIPHER_TKIP) { @@ -147,6 +152,93 @@ static void wpas_mesh_copy_groups(struct hostapd_data *bss, } +static int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s) +{ + struct hostapd_iface *ifmsh = wpa_s->ifmsh; + struct wpa_ssid *ssid = wpa_s->current_ssid; + struct hostapd_data *bss = ifmsh->bss[0]; + static int default_groups[] = { 19, 20, 21, 25, 26, -1 }; + const char *password; + size_t len; + + password = ssid->sae_password; + if (!password) + password = ssid->passphrase; + if (!password) { + wpa_printf(MSG_ERROR, + "mesh: Passphrase for SAE not configured"); + return -1; + } + + bss->conf->wpa = ssid->proto; + bss->conf->wpa_key_mgmt = ssid->key_mgmt; + + if (wpa_s->conf->sae_groups && wpa_s->conf->sae_groups[0] > 0) { + wpas_mesh_copy_groups(bss, wpa_s); + } else { + bss->conf->sae_groups = os_memdup(default_groups, + sizeof(default_groups)); + if (!bss->conf->sae_groups) + return -1; + } + + len = os_strlen(password); + bss->conf->ssid.wpa_passphrase = dup_binstr(password, len); + + wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, ifmsh->mconf); + return !wpa_s->mesh_rsn ? -1 : 0; +} + + +static int wpas_mesh_complete(struct wpa_supplicant *wpa_s) +{ + struct hostapd_iface *ifmsh = wpa_s->ifmsh; + struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params; + struct wpa_ssid *ssid = wpa_s->current_ssid; + int ret; + + if (!params || !ssid || !ifmsh) { + wpa_printf(MSG_ERROR, "mesh: %s called without active mesh", + __func__); + return -1; + } + + if (ifmsh->mconf->security != MESH_CONF_SEC_NONE && + wpas_mesh_init_rsn(wpa_s)) { + wpa_printf(MSG_ERROR, + "mesh: RSN initialization failed - deinit mesh"); + wpa_supplicant_mesh_deinit(wpa_s); + return -1; + } + + if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) { + wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher; + wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher; + wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher; + } + + 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)); + ret = wpa_drv_join_mesh(wpa_s, params); + if (ret) + wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret); + + /* hostapd sets the interface down until we associate */ + wpa_drv_set_operstate(wpa_s, 1); + + if (!ret) + wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); + + return ret; +} + + static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct hostapd_freq_params *freq) @@ -156,9 +248,6 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, struct hostapd_config *conf; struct mesh_conf *mconf; int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 }; - static int default_groups[] = { 19, 20, 21, 25, 26, -1 }; - const char *password; - size_t len; int rate_len; int frequency; @@ -208,6 +297,16 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, bss->conf->start_disabled = 1; bss->conf->mesh = MESH_ENABLED; bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity; + + if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes, + wpa_s->hw.num_modes) && wpa_s->conf->country[0]) { + conf->ieee80211h = 1; + conf->ieee80211d = 1; + conf->country[0] = wpa_s->conf->country[0]; + conf->country[1] = wpa_s->conf->country[1]; + conf->country[2] = ' '; + } + bss->iconf = conf; ifmsh->conf = conf; @@ -231,7 +330,8 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, if (ssid->ht40) conf->secondary_channel = ssid->ht40; if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) { - conf->vht_oper_chwidth = ssid->max_oper_chwidth; + if (ssid->max_oper_chwidth != DEFAULT_MAX_OPER_CHWIDTH) + conf->vht_oper_chwidth = ssid->max_oper_chwidth; switch (conf->vht_oper_chwidth) { case VHT_CHANWIDTH_80MHZ: case VHT_CHANWIDTH_80P80MHZ: @@ -281,48 +381,15 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, conf->basic_rates[rate_len] = -1; } - if (hostapd_setup_interface(ifmsh)) { - wpa_printf(MSG_ERROR, - "Failed to initialize hostapd interface for mesh"); - return -1; - } - if (wpa_drv_init_mesh(wpa_s)) { wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver"); return -1; } - if (mconf->security != MESH_CONF_SEC_NONE) { - password = ssid->sae_password; - if (!password) - password = ssid->passphrase; - if (!password) { - wpa_printf(MSG_ERROR, - "mesh: Passphrase for SAE not configured"); - goto out_free; - } - - bss->conf->wpa = ssid->proto; - bss->conf->wpa_key_mgmt = ssid->key_mgmt; - - if (wpa_s->conf->sae_groups && - wpa_s->conf->sae_groups[0] > 0) { - wpas_mesh_copy_groups(bss, wpa_s); - } else { - bss->conf->sae_groups = - os_memdup(default_groups, - sizeof(default_groups)); - if (!bss->conf->sae_groups) - goto out_free; - } - - len = os_strlen(password); - bss->conf->ssid.wpa_passphrase = - dup_binstr(password, len); - - wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf); - if (!wpa_s->mesh_rsn) - goto out_free; + if (hostapd_setup_interface(ifmsh)) { + wpa_printf(MSG_ERROR, + "Failed to initialize hostapd interface for mesh"); + return -1; } wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf); @@ -367,11 +434,13 @@ void wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant *wpa_s, int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { - struct wpa_driver_mesh_join_params params; + struct wpa_driver_mesh_join_params *params = os_zalloc(sizeof(*params)); int ret = 0; - if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency) { + if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency || + !params) { ret = -ENOENT; + os_free(params); goto out; } @@ -381,22 +450,23 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, wpa_s->group_cipher = WPA_CIPHER_NONE; wpa_s->mgmt_group_cipher = 0; - os_memset(¶ms, 0, sizeof(params)); - params.meshid = ssid->ssid; - params.meshid_len = ssid->ssid_len; - ibss_mesh_setup_freq(wpa_s, ssid, ¶ms.freq); - wpa_s->mesh_ht_enabled = !!params.freq.ht_enabled; - wpa_s->mesh_vht_enabled = !!params.freq.vht_enabled; - if (params.freq.ht_enabled && params.freq.sec_channel_offset) - ssid->ht40 = params.freq.sec_channel_offset; + params->meshid = ssid->ssid; + params->meshid_len = ssid->ssid_len; + ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq); + wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; + wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; + if (params->freq.ht_enabled && params->freq.sec_channel_offset) + ssid->ht40 = params->freq.sec_channel_offset; + if (wpa_s->mesh_vht_enabled) { ssid->vht = 1; - switch (params.freq.bandwidth) { + ssid->vht_center_freq1 = params->freq.center_freq1; + switch (params->freq.bandwidth) { case 80: - if (params.freq.center_freq2) { + if (params->freq.center_freq2) { ssid->max_oper_chwidth = VHT_CHANWIDTH_80P80MHZ; ssid->vht_center_freq2 = - params.freq.center_freq2; + params->freq.center_freq2; } else { ssid->max_oper_chwidth = VHT_CHANWIDTH_80MHZ; } @@ -410,67 +480,44 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, } } if (ssid->beacon_int > 0) - params.beacon_int = ssid->beacon_int; + params->beacon_int = ssid->beacon_int; else if (wpa_s->conf->beacon_int > 0) - params.beacon_int = wpa_s->conf->beacon_int; + params->beacon_int = wpa_s->conf->beacon_int; if (ssid->dtim_period > 0) - params.dtim_period = ssid->dtim_period; + params->dtim_period = ssid->dtim_period; else if (wpa_s->conf->dtim_period > 0) - params.dtim_period = wpa_s->conf->dtim_period; - params.conf.max_peer_links = wpa_s->conf->max_peer_links; + params->dtim_period = wpa_s->conf->dtim_period; + params->conf.max_peer_links = wpa_s->conf->max_peer_links; if (ssid->mesh_rssi_threshold < DEFAULT_MESH_RSSI_THRESHOLD) { - params.conf.rssi_threshold = ssid->mesh_rssi_threshold; - params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD; + params->conf.rssi_threshold = ssid->mesh_rssi_threshold; + params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD; } if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) { - params.flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH; - params.flags |= WPA_DRIVER_MESH_FLAG_AMPE; + params->flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH; + params->flags |= WPA_DRIVER_MESH_FLAG_AMPE; wpa_s->conf->user_mpm = 1; } if (wpa_s->conf->user_mpm) { - params.flags |= WPA_DRIVER_MESH_FLAG_USER_MPM; - params.conf.auto_plinks = 0; + params->flags |= WPA_DRIVER_MESH_FLAG_USER_MPM; + params->conf.auto_plinks = 0; } else { - params.flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM; - params.conf.auto_plinks = 1; + params->flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM; + params->conf.auto_plinks = 1; } - params.conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity; + params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity; - if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms.freq)) { + os_free(wpa_s->mesh_params); + wpa_s->mesh_params = params; + if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms->freq)) { wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh"); wpa_drv_leave_mesh(wpa_s); ret = -1; goto out; } - if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) { - wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher; - wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher; - wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher; - } - - if (wpa_s->ifmsh) { - params.ies = wpa_s->ifmsh->mconf->rsn_ie; - params.ie_len = wpa_s->ifmsh->mconf->rsn_ie_len; - params.basic_rates = wpa_s->ifmsh->basic_rates; - params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE; - params.conf.ht_opmode = wpa_s->ifmsh->bss[0]->iface->ht_op_mode; - } - - wpa_msg(wpa_s, MSG_INFO, "joining mesh %s", - wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); - ret = wpa_drv_join_mesh(wpa_s, ¶ms); - if (ret) - wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret); - - /* hostapd sets the interface down until we associate */ - wpa_drv_set_operstate(wpa_s, 1); - - if (!ret) - wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); - + ret = wpas_mesh_complete(wpa_s); out: return ret; } diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c index eafb0af7b82a..9d6ab8da1ebe 100644 --- a/wpa_supplicant/mesh_mpm.c +++ b/wpa_supplicant/mesh_mpm.c @@ -12,6 +12,7 @@ #include "utils/eloop.h" #include "common/ieee802_11_defs.h" #include "common/hw_features_common.h" +#include "common/ocv.h" #include "ap/hostapd.h" #include "ap/sta_info.h" #include "ap/ieee802_11.h" @@ -188,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; @@ -246,6 +247,11 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s, #endif /* CONFIG_IEEE80211AC */ if (type != PLINK_CLOSE) buf_len += conf->rsn_ie_len; /* RSN IE */ +#ifdef CONFIG_OCV + /* OCI is included even when the other STA doesn't support OCV */ + if (type != PLINK_CLOSE && conf->ocv) + buf_len += OCV_OCI_EXTENDED_LEN; +#endif /* CONFIG_OCV */ buf = wpabuf_alloc(buf_len); if (!buf) @@ -357,6 +363,22 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_IEEE80211AC */ +#ifdef CONFIG_OCV + if (type != PLINK_CLOSE && conf->ocv) { + struct wpa_channel_info ci; + + if (wpa_drv_channel_info(wpa_s, &ci) != 0) { + wpa_printf(MSG_WARNING, + "Mesh MPM: Failed to get channel info for OCI element"); + goto fail; + } + + pos = wpabuf_put(buf, OCV_OCI_EXTENDED_LEN); + if (ocv_insert_extended_oci(&ci, pos) < 0) + goto fail; + } +#endif /* CONFIG_OCV */ + if (ampe && mesh_rsn_protect_frame(wpa_s->mesh_rsn, sta, cat, buf)) { wpa_msg(wpa_s, MSG_INFO, "Mesh MPM: failed to add AMPE and MIC IE"); @@ -699,6 +721,7 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s, #ifdef CONFIG_IEEE80211AC copy_sta_vht_capab(data, sta, elems->vht_capabilities); + copy_sta_vht_oper(data, sta, elems->vht_operation); set_sta_vht_opmode(data, sta, elems->vht_opmode_notif); #endif /* CONFIG_IEEE80211AC */ @@ -1196,6 +1219,56 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s, } return; } + +#ifdef CONFIG_OCV + if (action_field == PLINK_OPEN && elems.rsn_ie) { + struct wpa_state_machine *sm = sta->wpa_sm; + struct wpa_ie_data data; + + res = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, + elems.rsn_ie_len + 2, + &data); + if (res) { + wpa_printf(MSG_DEBUG, + "Failed to parse RSN IE (res=%d)", + res); + wpa_hexdump(MSG_DEBUG, "RSN IE", elems.rsn_ie, + elems.rsn_ie_len); + return; + } + + wpa_auth_set_ocv(sm, mconf->ocv && + (data.capabilities & + WPA_CAPABILITY_OCVC)); + } + + if (action_field != PLINK_CLOSE && + wpa_auth_uses_ocv(sta->wpa_sm)) { + struct wpa_channel_info ci; + int tx_chanwidth; + int tx_seg1_idx; + + if (wpa_drv_channel_info(wpa_s, &ci) != 0) { + wpa_printf(MSG_WARNING, + "MPM: Failed to get channel info to validate received OCI in MPM Confirm"); + return; + } + + if (get_tx_parameters( + sta, channel_width_to_int(ci.chanwidth), + ci.seg1_idx, &tx_chanwidth, + &tx_seg1_idx) < 0) + return; + + if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, + tx_chanwidth, tx_seg1_idx) != + 0) { + wpa_printf(MSG_WARNING, "MPM: %s", + ocv_errorstr); + return; + } + } +#endif /* CONFIG_OCV */ } if (sta->plink_state == PLINK_BLOCKED) { diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c index e74cb16b0725..4b8d6c469173 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); @@ -140,7 +142,7 @@ static int auth_start_ampe(void *ctx, const u8 *addr) static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr, - enum mfp_options ieee80211w) + enum mfp_options ieee80211w, int ocv) { struct wpa_auth_config conf; static const struct wpa_auth_callbacks cb = { @@ -168,6 +170,9 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr, if (ieee80211w != NO_MGMT_FRAME_PROTECTION) conf.group_mgmt_cipher = rsn->mgmt_group_cipher; #endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_OCV + conf.ocv = ocv; +#endif /* CONFIG_OCV */ rsn->auth = wpa_init(addr, &conf, &cb, rsn); if (rsn->auth == NULL) { @@ -240,7 +245,7 @@ struct mesh_rsn *mesh_rsn_auth_init(struct wpa_supplicant *wpa_s, mesh_rsn->mgmt_group_cipher = conf->mgmt_group_cipher; if (__mesh_rsn_auth_init(mesh_rsn, wpa_s->own_addr, - conf->ieee80211w) < 0) { + conf->ieee80211w, conf->ocv) < 0) { mesh_rsn_deinit(mesh_rsn); os_free(mesh_rsn); return NULL; @@ -638,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) { @@ -652,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 83df04f394c7..bedb74b34440 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); @@ -140,6 +129,15 @@ void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s) } +void wpas_notify_auth_status_code(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->p2p_mgmt) + return; + + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_AUTH_STATUS_CODE); +} + + void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s) { if (wpa_s->p2p_mgmt) @@ -149,6 +147,42 @@ void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s) } +void wpas_notify_roam_time(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->p2p_mgmt) + return; + + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_TIME); +} + + +void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->p2p_mgmt) + return; + + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_COMPLETE); +} + + +void wpas_notify_session_length(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->p2p_mgmt) + return; + + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SESSION_LENGTH); +} + + +void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->p2p_mgmt) + return; + + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSS_TM_STATUS); +} + + void wpas_notify_network_changed(struct wpa_supplicant *wpa_s) { if (wpa_s->p2p_mgmt) @@ -222,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); } @@ -244,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); } @@ -258,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 */ @@ -720,6 +746,9 @@ static void wpas_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s, wpas_dbus_signal_p2p_peer_joined(wpa_s, p2p_dev_addr); #endif /* CONFIG_P2P */ + /* Register the station */ + wpas_dbus_register_sta(wpa_s, sta); + /* Notify listeners a new station has been authorized */ wpas_dbus_signal_sta_authorized(wpa_s, sta); } @@ -740,6 +769,9 @@ static void wpas_notify_ap_sta_deauthorized(struct wpa_supplicant *wpa_s, /* Notify listeners a station has been deauthorized */ wpas_dbus_signal_sta_deauthorized(wpa_s, sta); + + /* Unregister the station */ + wpas_dbus_unregister_sta(wpa_s, sta); } @@ -787,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/notify.h b/wpa_supplicant/notify.h index 3ca933c7621a..65f513ea9770 100644 --- a/wpa_supplicant/notify.h +++ b/wpa_supplicant/notify.h @@ -23,7 +23,12 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s, enum wpa_states new_state, enum wpa_states old_state); void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s); +void wpas_notify_auth_status_code(struct wpa_supplicant *wpa_s); void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s); +void wpas_notify_roam_time(struct wpa_supplicant *wpa_s); +void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s); +void wpas_notify_session_length(struct wpa_supplicant *wpa_s); +void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s); void wpas_notify_network_changed(struct wpa_supplicant *wpa_s); void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s); void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c index d23b0094c440..947917bb05f4 100644 --- a/wpa_supplicant/op_classes.c +++ b/wpa_supplicant/op_classes.c @@ -208,17 +208,78 @@ enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 channel, static int wpas_op_class_supported(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, const struct oper_class_map *op_class) { int chan; size_t i; struct hostapd_hw_modes *mode; int found; + int z; + int freq2 = 0; + int freq5 = 0; mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op_class->mode); if (!mode) return 0; + /* If we are configured to disable certain things, take that into + * account here. */ + if (ssid->freq_list && ssid->freq_list[0]) { + for (z = 0; ; z++) { + int f = ssid->freq_list[z]; + + if (f == 0) + break; /* end of list */ + if (f > 4000 && f < 6000) + freq5 = 1; + else if (f > 2400 && f < 2500) + freq2 = 1; + } + } else { + /* No frequencies specified, can use anything hardware supports. + */ + freq2 = freq5 = 1; + } + + if (op_class->op_class >= 115 && op_class->op_class <= 130 && !freq5) + return 0; + if (op_class->op_class >= 81 && op_class->op_class <= 84 && !freq2) + return 0; + +#ifdef CONFIG_HT_OVERRIDES + if (ssid->disable_ht) { + switch (op_class->op_class) { + case 83: + case 84: + case 104: + case 105: + case 116: + case 117: + case 119: + case 120: + case 122: + case 123: + case 126: + case 127: + case 128: + case 129: + case 130: + /* Disable >= 40 MHz channels if HT is disabled */ + return 0; + } + } +#endif /* CONFIG_HT_OVERRIDES */ + +#ifdef CONFIG_VHT_OVERRIDES + if (ssid->disable_vht) { + if (op_class->op_class >= 128 && op_class->op_class <= 130) { + /* Disable >= 80 MHz channels if VHT is disabled */ + return 0; + } + } +#endif /* CONFIG_VHT_OVERRIDES */ + if (op_class->op_class == 128) { u8 channels[] = { 42, 58, 106, 122, 138, 155 }; @@ -273,8 +334,9 @@ static int wpas_op_class_supported(struct wpa_supplicant *wpa_s, } -size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s, int freq, u8 *pos, - size_t len) +size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, + int freq, u8 *pos, size_t len) { struct wpabuf *buf; u8 op, current, chan; @@ -304,7 +366,7 @@ size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s, int freq, u8 *pos, wpabuf_put_u8(buf, current); for (op = 0; global_op_class[op].op_class; op++) { - if (wpas_op_class_supported(wpa_s, &global_op_class[op])) + if (wpas_op_class_supported(wpa_s, ssid, &global_op_class[op])) wpabuf_put_u8(buf, global_op_class[op].op_class); } diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index c596d5ab6148..e7c1f5d5aca4 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, @@ -1912,6 +1920,7 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s, ssid->vht = params->vht; ssid->max_oper_chwidth = params->max_oper_chwidth; ssid->vht_center_freq2 = params->vht_center_freq2; + ssid->he = params->he; ssid->ssid = os_zalloc(params->ssid_len + 1); if (ssid->ssid) { os_memcpy(ssid->ssid, params->ssid, params->ssid_len); @@ -2075,6 +2084,13 @@ static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s, return -1; } + if (wpa_s->conf->p2p_interface_random_mac_addr) { + random_mac_addr(wpa_s->pending_interface_addr); + wpa_printf(MSG_DEBUG, "P2P: Generate random MAC address " MACSTR + " for the group", + MAC2STR(wpa_s->pending_interface_addr)); + } + if (force_ifname[0]) { wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s", force_ifname); @@ -2153,6 +2169,29 @@ wpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go) wpas_p2p_clone_config(group_wpa_s, wpa_s); + if (wpa_s->conf->p2p_interface_random_mac_addr) { + if (wpa_drv_set_mac_addr(group_wpa_s, + wpa_s->pending_interface_addr) < 0) { + wpa_msg(group_wpa_s, MSG_INFO, + "Failed to set random MAC address"); + wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s, + 0); + return NULL; + } + + if (wpa_supplicant_update_mac_addr(group_wpa_s) < 0) { + wpa_msg(group_wpa_s, MSG_INFO, + "Could not update MAC address information"); + wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s, + 0); + return NULL; + } + + wpa_printf(MSG_DEBUG, "P2P: Using random MAC address " MACSTR + " for the group", + MAC2STR(wpa_s->pending_interface_addr)); + } + return group_wpa_s; } @@ -3048,7 +3087,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, MAC2STR(sa), s->id); } wpas_p2p_group_add_persistent( - wpa_s, s, go, 0, op_freq, 0, 0, 0, 0, NULL, + wpa_s, s, go, 0, op_freq, 0, 0, 0, 0, 0, NULL, go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 1); } else if (bssid) { @@ -3274,6 +3313,7 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid, wpa_s->p2p_go_vht_center_freq2, wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht, wpa_s->p2p_go_max_oper_chwidth, + wpa_s->p2p_go_he, channels, ssid->mode == WPAS_MODE_P2P_GO ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : @@ -3918,6 +3958,10 @@ static int wpas_remove_stale_groups(void *ctx, const u8 *peer, const u8 *go, /* Remove stale persistent group */ if (s->mode != WPAS_MODE_P2P_GO || s->num_p2p_clients <= 1) { + wpa_dbg(wpa_s, MSG_DEBUG, + "P2P: Remove stale persistent group id=%d", + s->id); + wpas_notify_persistent_group_removed(wpa_s, s); wpa_config_remove_network(wpa_s->conf, s->id); save_config = 1; continue; @@ -4041,6 +4085,11 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, if (persistent_go && !persistent_go->num_p2p_clients) { /* remove empty persistent GO */ + wpa_dbg(wpa_s, MSG_DEBUG, + "P2P: Remove empty persistent group id=%d", + persistent_go->id); + wpas_notify_persistent_group_removed(wpa_s, + persistent_go); wpa_config_remove_network(wpa_s->conf, persistent_go->id); } @@ -4081,6 +4130,10 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, /* Remove stale persistent group */ if (stale->mode != WPAS_MODE_P2P_GO || stale->num_p2p_clients <= 1) { + wpa_dbg(wpa_s, MSG_DEBUG, + "P2P: Remove stale persistent group id=%d", + stale->id); + wpas_notify_persistent_group_removed(wpa_s, stale); wpa_config_remove_network(wpa_s->conf, stale->id); } else { size_t i; @@ -4113,6 +4166,11 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, if (persistent_go && s != persistent_go && !persistent_go->num_p2p_clients) { /* remove empty persistent GO */ + wpa_dbg(wpa_s, MSG_DEBUG, + "P2P: Remove empty persistent group id=%d", + persistent_go->id); + wpas_notify_persistent_group_removed(wpa_s, + persistent_go); wpa_config_remove_network(wpa_s->conf, persistent_go->id); /* Save config */ @@ -4130,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 @@ -4140,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, @@ -4165,13 +4228,14 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, if (response_done && persistent_go) { wpas_p2p_group_add_persistent( wpa_s, persistent_go, - 0, 0, freq, 0, 0, 0, 0, NULL, + 0, 0, freq, 0, 0, 0, 0, 0, NULL, persistent_go->mode == WPAS_MODE_P2P_GO ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0); } else if (response_done) { - wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0); + wpas_p2p_group_add(wpa_s, 1, freq, + 0, 0, 0, 0, 0); } if (passwd_id == DEV_PW_P2PS_DEFAULT) { @@ -4220,6 +4284,10 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, if (persistent_go && !persistent_go->num_p2p_clients) { /* remove empty persistent GO */ + wpa_dbg(wpa_s, MSG_DEBUG, + "P2P: Remove empty persistent group id=%d", + persistent_go->id); + wpas_notify_persistent_group_removed(wpa_s, persistent_go); wpa_config_remove_network(wpa_s->conf, persistent_go->id); } @@ -4283,11 +4351,11 @@ static int wpas_prov_disc_resp_cb(void *ctx) if (persistent_go) { wpas_p2p_group_add_persistent( - wpa_s, persistent_go, 0, 0, 0, 0, 0, 0, 0, NULL, + wpa_s, persistent_go, 0, 0, 0, 0, 0, 0, 0, 0, NULL, persistent_go->mode == WPAS_MODE_P2P_GO ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0); } else { - wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0); + wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0); } return 1; @@ -4305,6 +4373,54 @@ static int wpas_p2p_get_pref_freq_list(void *ctx, int go, } +int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s) +{ + u8 addr[ETH_ALEN] = {0}; + + if (wpa_s->conf->p2p_device_random_mac_addr == 0) + return 0; + + if (!wpa_s->conf->ssid) { + if (random_mac_addr(addr) < 0) { + wpa_msg(wpa_s, MSG_INFO, + "Failed to generate random MAC address"); + return -EINVAL; + } + + /* Store generated MAC address. */ + os_memcpy(wpa_s->conf->p2p_device_persistent_mac_addr, addr, + ETH_ALEN); + } else { + /* If there are existing saved groups, restore last MAC address. + * if there is no last used MAC address, the last one is + * factory MAC. */ + if (is_zero_ether_addr( + wpa_s->conf->p2p_device_persistent_mac_addr)) + return 0; + os_memcpy(addr, wpa_s->conf->p2p_device_persistent_mac_addr, + ETH_ALEN); + wpa_msg(wpa_s, MSG_DEBUG, "Restore last used MAC address."); + } + + if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) { + wpa_msg(wpa_s, MSG_INFO, + "Failed to set random MAC address"); + return -EINVAL; + } + + if (wpa_supplicant_update_mac_addr(wpa_s) < 0) { + wpa_msg(wpa_s, MSG_INFO, + "Could not update MAC address information"); + return -EINVAL; + } + + wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR, + MAC2STR(addr)); + + return 0; +} + + /** * wpas_p2p_init - Initialize P2P module for %wpa_supplicant * @global: Pointer to global data from wpa_supplicant_init() @@ -4325,6 +4441,12 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) if (global->p2p) return 0; + if (wpas_p2p_mac_setup(wpa_s) < 0) { + wpa_msg(wpa_s, MSG_ERROR, + "Failed to initialize P2P random MAC address."); + return -1; + } + os_memset(&p2p, 0, sizeof(p2p)); p2p.cb_ctx = wpa_s; p2p.debug_print = wpas_p2p_debug_print; @@ -4389,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; @@ -4414,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: " @@ -4810,6 +4939,7 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht, wpa_s->p2p_go_max_oper_chwidth, + wpa_s->p2p_go_he, NULL, 0); return; } @@ -5107,17 +5237,18 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq, os_memcpy(group->p2p_pin, wpa_s->p2p_pin, sizeof(group->p2p_pin)); group->p2p_wps_method = wpa_s->p2p_wps_method; - } else { - /* - * Need to mark the current interface for p2p_group_formation - * when a separate group interface is not used. This is needed - * to allow p2p_cancel stop a pending p2p_connect-join. - * wpas_p2p_init_group_interface() addresses this for the case - * where a separate group interface is used. - */ - wpa_s->global->p2p_group_formation = wpa_s; } + /* + * Need to mark the current interface for p2p_group_formation + * when a separate group interface is not used. This is needed + * to allow p2p_cancel stop a pending p2p_connect-join. + * wpas_p2p_init_group_interface() addresses this for the case + * where a separate group interface is used. + */ + if (group == wpa_s->parent) + wpa_s->global->p2p_group_formation = group; + group->p2p_in_provisioning = 1; group->p2p_fallback_to_go_neg = wpa_s->p2p_fallback_to_go_neg; @@ -5357,7 +5488,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, int persistent_group, int auto_join, int join, int auth, int go_intent, int freq, unsigned int vht_center_freq2, int persistent_id, int pd, int ht40, int vht, - unsigned int vht_chwidth, const u8 *group_ssid, + unsigned int vht_chwidth, int he, const u8 *group_ssid, size_t group_ssid_len) { int force_freq = 0, pref_freq = 0; @@ -5402,6 +5533,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, wpa_s->p2p_go_vht = !!vht; wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2; wpa_s->p2p_go_max_oper_chwidth = vht_chwidth; + wpa_s->p2p_go_he = !!he; if (pin) os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin)); @@ -5825,7 +5957,7 @@ static int wpas_same_band(int freq1, int freq2) static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, struct p2p_go_neg_results *params, int freq, int vht_center_freq2, int ht40, - int vht, int max_oper_chwidth, + int vht, int max_oper_chwidth, int he, const struct p2p_channels *channels) { struct wpa_used_freq_data *freqs; @@ -5838,6 +5970,7 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, params->role_go = 1; params->ht40 = ht40; params->vht = vht; + params->he = he; params->max_oper_chwidth = max_oper_chwidth; params->vht_center_freq2 = vht_center_freq2; @@ -6194,7 +6327,7 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, */ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, int freq, int vht_center_freq2, int ht40, int vht, - int max_oper_chwidth) + int max_oper_chwidth, int he) { struct p2p_go_neg_results params; @@ -6215,7 +6348,7 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, } if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, vht_center_freq2, - ht40, vht, max_oper_chwidth, NULL)) + ht40, vht, max_oper_chwidth, he, NULL)) return -1; p2p_go_params(wpa_s->global->p2p, ¶ms); @@ -6294,7 +6427,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int addr_allocated, int force_freq, int neg_freq, int vht_center_freq2, int ht40, - int vht, int max_oper_chwidth, + int vht, int max_oper_chwidth, int he, const struct p2p_channels *channels, int connection_timeout, int force_scan) { @@ -6370,7 +6503,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, } if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, vht_center_freq2, - ht40, vht, max_oper_chwidth, channels)) + ht40, vht, max_oper_chwidth, he, channels)) return -1; params.role_go = 1; @@ -6922,7 +7055,7 @@ int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr) int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, int vht_center_freq2, int ht40, int vht, int max_chwidth, - int pref_freq) + int pref_freq, int he) { enum p2p_invite_role role; u8 *bssid = NULL; @@ -6940,6 +7073,7 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, wpa_s->p2p_persistent_go_freq = freq; wpa_s->p2p_go_ht40 = !!ht40; wpa_s->p2p_go_vht = !!vht; + wpa_s->p2p_go_he = !!he; wpa_s->p2p_go_max_oper_chwidth = max_chwidth; wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2; if (ssid->mode == WPAS_MODE_P2P_GO) { @@ -7086,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) { @@ -7133,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, @@ -7145,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); } @@ -7962,7 +8097,8 @@ static int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s, wpa_s->p2p_pd_before_go_neg, wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht, - wpa_s->p2p_go_max_oper_chwidth, NULL, 0); + wpa_s->p2p_go_max_oper_chwidth, + wpa_s->p2p_go_he, NULL, 0); return ret; } @@ -8498,6 +8634,7 @@ static int wpas_p2p_nfc_join_group(struct wpa_supplicant *wpa_s, WPS_NFC, 0, 0, 1, 0, wpa_s->conf->p2p_go_intent, params->go_freq, wpa_s->p2p_go_vht_center_freq2, -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth, + wpa_s->p2p_go_he, params->go_ssid_len ? params->go_ssid : NULL, params->go_ssid_len); } @@ -8577,7 +8714,7 @@ static int wpas_p2p_nfc_init_go_neg(struct wpa_supplicant *wpa_s, WPS_NFC, 0, 0, 0, 0, wpa_s->conf->p2p_go_intent, forced_freq, wpa_s->p2p_go_vht_center_freq2, -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth, - NULL, 0); + wpa_s->p2p_go_he, NULL, 0); } @@ -8593,7 +8730,7 @@ static int wpas_p2p_nfc_resp_go_neg(struct wpa_supplicant *wpa_s, WPS_NFC, 0, 0, 0, 1, wpa_s->conf->p2p_go_intent, forced_freq, wpa_s->p2p_go_vht_center_freq2, -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth, - NULL, 0); + wpa_s->p2p_go_he, NULL, 0); if (res) return res; @@ -8978,7 +9115,7 @@ static int wpas_p2p_move_go_csa(struct wpa_supplicant *wpa_s) * TODO: This function may not always work correctly. For example, * when we have a running GO and a BSS on a DFS channel. */ - if (wpas_p2p_init_go_params(wpa_s, ¶ms, 0, 0, 0, 0, 0, NULL)) { + if (wpas_p2p_init_go_params(wpa_s, ¶ms, 0, 0, 0, 0, 0, 0, NULL)) { wpa_dbg(wpa_s, MSG_DEBUG, "P2P CSA: Failed to select new frequency for GO"); return -1; @@ -9090,7 +9227,7 @@ static void wpas_p2p_move_go_no_csa(struct wpa_supplicant *wpa_s) wpa_supplicant_ap_deinit(wpa_s); /* Reselect the GO frequency */ - if (wpas_p2p_init_go_params(wpa_s, ¶ms, 0, 0, 0, 0, 0, NULL)) { + if (wpas_p2p_init_go_params(wpa_s, ¶ms, 0, 0, 0, 0, 0, 0, NULL)) { wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Failed to reselect freq"); wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_GO_LEAVE_CHANNEL); diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 63910d1c268e..24ec2cafc249 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -37,18 +37,18 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, int persistent_group, int auto_join, int join, int auth, int go_intent, int freq, unsigned int vht_center_freq2, int persistent_id, int pd, int ht40, int vht, - unsigned int vht_chwidth, const u8 *group_ssid, + unsigned int vht_chwidth, int he, const u8 *group_ssid, size_t group_ssid_len); int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq, struct wpa_ssid *ssid); int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, int freq, int vht_center_freq2, int ht40, int vht, - int max_oper_chwidth); + int max_oper_chwidth, int he); int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int addr_allocated, int force_freq, int neg_freq, int vht_center_freq2, int ht40, - int vht, int max_oper_chwidth, + int vht, int max_oper_chwidth, int he, const struct p2p_channels *channels, int connection_timeout, int force_scan); struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s, @@ -117,7 +117,7 @@ int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr); int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, int vht_center_freq2, int ht40, int vht, - int max_oper_chwidth, int pref_freq); + int max_oper_chwidth, int pref_freq, int he); int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, const u8 *peer_addr, const u8 *go_dev_addr); int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1, @@ -211,6 +211,7 @@ int wpas_p2p_lo_start(struct wpa_supplicant *wpa_s, unsigned int freq, unsigned int period, unsigned int interval, unsigned int count); int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s); +int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s); #else /* CONFIG_P2P */ diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c index f4fbfa719352..cb3c6c995dd9 100644 --- a/wpa_supplicant/rrm.c +++ b/wpa_supplicant/rrm.c @@ -392,17 +392,66 @@ static void wpas_rrm_send_msr_report_mpdu(struct wpa_supplicant *wpa_s, } +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; + + if (msr_rep->eid != WLAN_EID_MEASURE_REPORT || + msr_rep_end > end) { + /* Should not happen. This indicates a bug. */ + wpa_printf(MSG_ERROR, + "RRM: non-measurement report element in measurement report frame"); + return -1; + } + + if (msr_rep->type == MEASURE_TYPE_BEACON) + rep = (struct rrm_measurement_beacon_report *) + msr_rep->variable; + + 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; +} + + static void wpas_rrm_send_msr_report(struct wpa_supplicant *wpa_s, struct wpabuf *buf) { int len = wpabuf_len(buf); - const u8 *pos = wpabuf_head_u8(buf), *next = pos; + u8 *pos = wpabuf_mhead_u8(buf), *next = pos; #define MPDU_REPORT_LEN (int) (IEEE80211_MAX_MMPDU_SIZE - IEEE80211_HDRLEN - 3) while (len) { int send_len = (len > MPDU_REPORT_LEN) ? next - pos : len; + if (send_len == len) + wpas_rrm_beacon_rep_update_last_frame(pos, len); + if (send_len == len || (send_len + next[1] + 2) > MPDU_REPORT_LEN) { wpas_rrm_send_msr_report_mpdu(wpa_s, pos, send_len); @@ -707,15 +756,17 @@ static int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len, static int wpas_beacon_rep_add_frame_body(struct bitfield *eids, enum beacon_report_detail detail, struct wpa_bss *bss, u8 *buf, - size_t buf_len) + size_t buf_len, u8 **ies_buf, + size_t *ie_len, int add_fixed) { - u8 *ies = (u8 *) (bss + 1); - size_t ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len; + u8 *ies = *ies_buf; + size_t ies_len = *ie_len; u8 *pos = buf; int rem_len; rem_len = 255 - sizeof(struct rrm_measurement_beacon_report) - - sizeof(struct rrm_measurement_report_element) - 2; + sizeof(struct rrm_measurement_report_element) - 2 - + REPORTED_FRAME_BODY_SUBELEM_LEN; if (detail > BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS) { wpa_printf(MSG_DEBUG, @@ -731,18 +782,21 @@ static int wpas_beacon_rep_add_frame_body(struct bitfield *eids, * Minimal frame body subelement size: EID(1) + length(1) + TSF(8) + * beacon interval(2) + capabilities(2) = 14 bytes */ - if (buf_len < 14) - return 0; + if (add_fixed && buf_len < 14) + return -1; *pos++ = WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY; /* The length will be filled later */ pos++; - WPA_PUT_LE64(pos, bss->tsf); - pos += sizeof(bss->tsf); - WPA_PUT_LE16(pos, bss->beacon_int); - pos += 2; - WPA_PUT_LE16(pos, bss->caps); - pos += 2; + + if (add_fixed) { + WPA_PUT_LE64(pos, bss->tsf); + pos += sizeof(bss->tsf); + WPA_PUT_LE16(pos, bss->beacon_int); + pos += 2; + WPA_PUT_LE16(pos, bss->caps); + pos += 2; + } rem_len -= pos - buf; @@ -757,15 +811,7 @@ static int wpas_beacon_rep_add_frame_body(struct bitfield *eids, while (ies_len > 2 && 2U + ies[1] <= ies_len && rem_len > 0) { if (detail == BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS || (eids && bitfield_is_set(eids, ies[0]))) { - u8 eid = ies[0], elen = ies[1]; - - if ((eid == WLAN_EID_TIM || eid == WLAN_EID_RSN) && - elen > 4) - elen = 4; - /* - * TODO: Truncate IBSS DFS element as described in - * IEEE Std 802.11-2016, 9.4.2.22.7. - */ + u8 elen = ies[1]; if (2 + elen > buf + buf_len - pos || 2 + elen > rem_len) @@ -782,22 +828,91 @@ static int wpas_beacon_rep_add_frame_body(struct bitfield *eids, ies += 2 + ies[1]; } + *ie_len = ies_len; + *ies_buf = ies; + /* Now the length is known */ buf[1] = pos - buf - 2; return pos - buf; } +static int wpas_add_beacon_rep_elem(struct beacon_rep_data *data, + struct wpa_bss *bss, + struct wpabuf **wpa_buf, + struct rrm_measurement_beacon_report *rep, + u8 **ie, size_t *ie_len, u8 idx) +{ + int ret; + u8 *buf, *pos; + u32 subelems_len = REPORTED_FRAME_BODY_SUBELEM_LEN + + (data->last_indication ? + BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN : 0); + + /* Maximum element length: Beacon Report element + Reported Frame Body + * subelement + all IEs of the reported Beacon frame + Reported Frame + * Body Fragment ID subelement */ + buf = os_malloc(sizeof(*rep) + 14 + *ie_len + subelems_len); + if (!buf) + return -1; + + os_memcpy(buf, rep, sizeof(*rep)); + + ret = wpas_beacon_rep_add_frame_body(data->eids, data->report_detail, + bss, buf + sizeof(*rep), + 14 + *ie_len, ie, ie_len, + idx == 0); + if (ret < 0) + goto out; + + pos = buf + ret + sizeof(*rep); + pos[0] = WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY_FRAGMENT_ID; + pos[1] = 2; + + /* + * Only one Beacon Report Measurement is supported at a time, so + * the Beacon Report ID can always be set to 1. + */ + pos[2] = 1; + + /* Fragment ID Number (bits 0..6) and More Frame Body Fragments (bit 7) + */ + pos[3] = idx; + if (data->report_detail != BEACON_REPORT_DETAIL_NONE && *ie_len) + pos[3] |= REPORTED_FRAME_BODY_MORE_FRAGMENTS; + else + pos[3] &= ~REPORTED_FRAME_BODY_MORE_FRAGMENTS; + + pos += REPORTED_FRAME_BODY_SUBELEM_LEN; + + if (data->last_indication) { + pos[0] = WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION; + pos[1] = 1; + + /* This field will be updated later if this is the last frame */ + pos[2] = 0; + } + + ret = wpas_rrm_report_elem(wpa_buf, data->token, + MEASUREMENT_REPORT_MODE_ACCEPT, + MEASURE_TYPE_BEACON, buf, + ret + sizeof(*rep) + subelems_len); +out: + os_free(buf); + return ret; +} + + static int wpas_add_beacon_rep(struct wpa_supplicant *wpa_s, struct wpabuf **wpa_buf, struct wpa_bss *bss, u64 start, u64 parent_tsf) { struct beacon_rep_data *data = &wpa_s->beacon_rep_data; - u8 *ie = (u8 *) (bss + 1); - size_t ie_len = bss->ie_len + bss->beacon_ie_len; - int ret; - u8 *buf; - struct rrm_measurement_beacon_report *rep; + u8 *ies = (u8 *) (bss + 1); + u8 *pos = ies; + size_t ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len; + struct rrm_measurement_beacon_report rep; + u8 idx = 0; if (os_memcmp(data->bssid, broadcast_ether_addr, ETH_ALEN) != 0 && os_memcmp(data->bssid, bss->bssid, ETH_ALEN) != 0) @@ -808,39 +923,29 @@ static int wpas_add_beacon_rep(struct wpa_supplicant *wpa_s, os_memcmp(data->ssid, bss->ssid, bss->ssid_len) != 0)) return 0; - /* Maximum element length: beacon report element + reported frame body - * subelement + all IEs of the reported beacon */ - buf = os_malloc(sizeof(*rep) + 14 + ie_len); - if (!buf) - return -1; + if (wpas_get_op_chan_phy(bss->freq, ies, ies_len, &rep.op_class, + &rep.channel, &rep.report_info) < 0) + return 0; - rep = (struct rrm_measurement_beacon_report *) buf; - if (wpas_get_op_chan_phy(bss->freq, ie, ie_len, &rep->op_class, - &rep->channel, &rep->report_info) < 0) { - ret = 0; - goto out; - } + rep.start_time = host_to_le64(start); + rep.duration = host_to_le16(data->scan_params.duration); + rep.rcpi = rssi_to_rcpi(bss->level); + rep.rsni = 255; /* 255 indicates that RSNI is not available */ + os_memcpy(rep.bssid, bss->bssid, ETH_ALEN); + rep.antenna_id = 0; /* unknown */ + rep.parent_tsf = host_to_le32(parent_tsf); - rep->start_time = host_to_le64(start); - rep->duration = host_to_le16(data->scan_params.duration); - rep->rcpi = rssi_to_rcpi(bss->level); - rep->rsni = 255; /* 255 indicates that RSNI is not available */ - os_memcpy(rep->bssid, bss->bssid, ETH_ALEN); - rep->antenna_id = 0; /* unknown */ - rep->parent_tsf = host_to_le32(parent_tsf); + do { + int ret; - ret = wpas_beacon_rep_add_frame_body(data->eids, data->report_detail, - bss, rep->variable, 14 + ie_len); - if (ret < 0) - goto out; + ret = wpas_add_beacon_rep_elem(data, bss, wpa_buf, &rep, + &pos, &ies_len, idx++); + if (ret) + return ret; + } while (data->report_detail != BEACON_REPORT_DETAIL_NONE && + ies_len >= 2); - ret = wpas_rrm_report_elem(wpa_buf, wpa_s->beacon_rep_data.token, - MEASUREMENT_REPORT_MODE_ACCEPT, - MEASURE_TYPE_BEACON, buf, - ret + sizeof(*rep)); -out: - os_free(buf); - return ret; + return 0; } @@ -1006,6 +1111,16 @@ static int wpas_rm_handle_beacon_req_subelem(struct wpa_supplicant *wpa_s, case WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL: /* Skip - it will be processed when freqs are added */ break; + case WLAN_BEACON_REQUEST_SUBELEM_LAST_INDICATION: + if (slen != 1) { + wpa_printf(MSG_DEBUG, + "Beacon request: Invalid last indication request subelement length: %u", + slen); + return -1; + } + + data->last_indication = subelem[0]; + break; default: wpa_printf(MSG_DEBUG, "Beacon request: Unknown subelement id %u", sid); diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index ee39e0c9228d..7abb028dd344 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. @@ -581,8 +581,8 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s) #endif /* CONFIG_WPS */ #ifdef CONFIG_HS20 - if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 7) == 0) - wpas_hs20_add_indication(extra_ie, -1); + if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 9) == 0) + wpas_hs20_add_indication(extra_ie, -1, 0); #endif /* CONFIG_HS20 */ #ifdef CONFIG_FST @@ -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)) { @@ -2806,6 +2807,13 @@ int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s, { u8 *tmp = NULL; + if ((wpa_s->mac_addr_rand_supported & type) != type ) { + wpa_printf(MSG_INFO, + "scan: MAC randomization type %u != supported=%u", + type, wpa_s->mac_addr_rand_supported); + return -1; + } + wpas_mac_addr_rand_scan_clear(wpa_s, type); if (addr) { diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 39c80696a94c..17a984d1a17d 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -12,9 +12,11 @@ #include "utils/eloop.h" #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" +#include "common/ocv.h" #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" @@ -56,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; @@ -83,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; @@ -95,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; } @@ -110,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; @@ -122,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); @@ -302,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"); @@ -434,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]); @@ -459,7 +480,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, wpa_s->sme.assoc_req_ie_len += 5; } - if (wpa_s->sme.ft_used && + if (wpa_s->sme.prev_bssid_set && wpa_s->sme.ft_used && os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 && wpa_sm_has_ptk(wpa_s->wpa)) { wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying to use FT " @@ -519,7 +540,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, sme_auth_handle_rrm(wpa_s, bss); wpa_s->sme.assoc_req_ie_len += wpas_supp_op_class_ie( - wpa_s, bss->freq, + wpa_s, ssid, bss->freq, wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len, sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len); @@ -550,7 +571,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid); size_t len; - wpas_hs20_add_indication(hs20, pps_mo_id); + wpas_hs20_add_indication(hs20, pps_mo_id, + get_hs20_version(bss)); wpas_hs20_add_roam_cons_sel(hs20, ssid); len = sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len; @@ -618,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); @@ -629,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) { @@ -912,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; @@ -939,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); } @@ -952,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) @@ -1035,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; @@ -1063,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, @@ -1386,7 +1411,6 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) } -#ifdef CONFIG_FILS #ifdef CONFIG_IEEE80211R static void remove_ie(u8 *buf, size_t *len, u8 eid) { @@ -1401,7 +1425,6 @@ static void remove_ie(u8 *buf, size_t *len, u8 eid) } } #endif /* CONFIG_IEEE80211R */ -#endif /* CONFIG_FILS */ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, @@ -1554,6 +1577,52 @@ 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; + + multi_ap_ie_len = add_multi_ap_ie( + wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len, + sizeof(wpa_s->sme.assoc_req_ie) - + wpa_s->sme.assoc_req_ie_len, + MULTI_AP_BACKHAUL_STA); + if (multi_ap_ie_len == 0) { + wpa_printf(MSG_ERROR, + "Multi-AP: Failed to build Multi-AP IE"); + return; + } + wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len; + } + params.bssid = bssid; params.ssid = wpa_s->sme.ssid; params.ssid_len = wpa_s->sme.ssid_len; @@ -1916,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); @@ -2220,6 +2286,7 @@ void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable) static const unsigned int sa_query_max_timeout = 1000; static const unsigned int sa_query_retry_timeout = 201; +static const unsigned int sa_query_ch_switch_max_delay = 5000; /* in usec */ static int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s) { @@ -2243,7 +2310,9 @@ static int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s) static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s, const u8 *trans_id) { - u8 req[2 + WLAN_SA_QUERY_TR_ID_LEN]; + u8 req[2 + WLAN_SA_QUERY_TR_ID_LEN + OCV_OCI_EXTENDED_LEN]; + u8 req_len = 2 + WLAN_SA_QUERY_TR_ID_LEN; + wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Request to " MACSTR, MAC2STR(wpa_s->bssid)); wpa_hexdump(MSG_DEBUG, "SME: SA Query Transaction ID", @@ -2251,9 +2320,27 @@ static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s, req[0] = WLAN_ACTION_SA_QUERY; req[1] = WLAN_SA_QUERY_REQUEST; os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN); + +#ifdef CONFIG_OCV + if (wpa_sm_ocv_enabled(wpa_s->wpa)) { + struct wpa_channel_info ci; + + if (wpa_drv_channel_info(wpa_s, &ci) != 0) { + wpa_printf(MSG_WARNING, + "Failed to get channel info for OCI element in SA Query Request frame"); + return; + } + + if (ocv_insert_extended_oci(&ci, req + req_len) < 0) + return; + + req_len += OCV_OCI_EXTENDED_LEN; + } +#endif /* CONFIG_OCV */ + if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, wpa_s->own_addr, wpa_s->bssid, - req, sizeof(req), 0) < 0) + req, req_len, 0) < 0) wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query " "Request"); } @@ -2310,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; @@ -2348,15 +2437,74 @@ void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa, } -void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa, - const u8 *data, size_t len) +void sme_event_ch_switch(struct wpa_supplicant *wpa_s) +{ + unsigned int usec; + u32 _rand; + + if (wpa_s->wpa_state != WPA_COMPLETED || + !wpa_sm_ocv_enabled(wpa_s->wpa)) + return; + + wpa_dbg(wpa_s, MSG_DEBUG, + "SME: Channel switch completed - trigger new SA Query to verify new operating channel"); + sme_stop_sa_query(wpa_s); + + if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) + _rand = os_random(); + usec = _rand % (sa_query_ch_switch_max_delay + 1); + eloop_register_timeout(0, usec, sme_sa_query_timer, wpa_s, NULL); +} + + +static void sme_process_sa_query_request(struct wpa_supplicant *wpa_s, + const u8 *sa, const u8 *data, + size_t len) +{ + u8 resp[2 + WLAN_SA_QUERY_TR_ID_LEN + OCV_OCI_EXTENDED_LEN]; + u8 resp_len = 2 + WLAN_SA_QUERY_TR_ID_LEN; + + wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Response to " + MACSTR, MAC2STR(wpa_s->bssid)); + + resp[0] = WLAN_ACTION_SA_QUERY; + resp[1] = WLAN_SA_QUERY_RESPONSE; + os_memcpy(resp + 2, data + 1, WLAN_SA_QUERY_TR_ID_LEN); + +#ifdef CONFIG_OCV + if (wpa_sm_ocv_enabled(wpa_s->wpa)) { + struct wpa_channel_info ci; + + if (wpa_drv_channel_info(wpa_s, &ci) != 0) { + wpa_printf(MSG_WARNING, + "Failed to get channel info for OCI element in SA Query Response frame"); + return; + } + + if (ocv_insert_extended_oci(&ci, resp + resp_len) < 0) + return; + + resp_len += OCV_OCI_EXTENDED_LEN; + } +#endif /* CONFIG_OCV */ + + if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, + wpa_s->own_addr, wpa_s->bssid, + resp, resp_len, 0) < 0) + wpa_msg(wpa_s, MSG_INFO, + "SME: Failed to send SA Query Response"); +} + + +static void sme_process_sa_query_response(struct wpa_supplicant *wpa_s, + const u8 *sa, const u8 *data, + size_t len) { int i; - if (wpa_s->sme.sa_query_trans_id == NULL || - len < 1 + WLAN_SA_QUERY_TR_ID_LEN || - data[0] != WLAN_SA_QUERY_RESPONSE) + if (!wpa_s->sme.sa_query_trans_id) return; + wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query response from " MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]); @@ -2381,4 +2529,48 @@ void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa, sme_stop_sa_query(wpa_s); } + +void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa, + const u8 *data, size_t len) +{ + if (len < 1 + WLAN_SA_QUERY_TR_ID_LEN) + return; + + wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query frame from " + MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]); + +#ifdef CONFIG_OCV + if (wpa_sm_ocv_enabled(wpa_s->wpa)) { + struct ieee802_11_elems elems; + struct wpa_channel_info ci; + + if (ieee802_11_parse_elems(data + 1 + WLAN_SA_QUERY_TR_ID_LEN, + len - 1 - WLAN_SA_QUERY_TR_ID_LEN, + &elems, 1) == ParseFailed) { + wpa_printf(MSG_DEBUG, + "SA Query: Failed to parse elements"); + return; + } + + if (wpa_drv_channel_info(wpa_s, &ci) != 0) { + wpa_printf(MSG_WARNING, + "Failed to get channel info to validate received OCI in SA Query Action frame"); + return; + } + + if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, + channel_width_to_int(ci.chanwidth), + ci.seg1_idx) != 0) { + wpa_printf(MSG_WARNING, "%s", ocv_errorstr); + return; + } + } +#endif /* CONFIG_OCV */ + + if (data[0] == WLAN_SA_QUERY_REQUEST) + sme_process_sa_query_request(wpa_s, sa, data, len); + else if (data[0] == WLAN_SA_QUERY_RESPONSE) + sme_process_sa_query_response(wpa_s, sa, data, len); +} + #endif /* CONFIG_IEEE80211W */ diff --git a/wpa_supplicant/sme.h b/wpa_supplicant/sme.h index f3c822025574..1a7f9e8320c7 100644 --- a/wpa_supplicant/sme.h +++ b/wpa_supplicant/sme.h @@ -28,6 +28,7 @@ void sme_event_disassoc(struct wpa_supplicant *wpa_s, struct disassoc_info *info); void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *da, u16 reason_code); +void sme_event_ch_switch(struct wpa_supplicant *wpa_s); void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *data, size_t len); void sme_state_changed(struct wpa_supplicant *wpa_s); @@ -89,6 +90,10 @@ static inline void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, { } +static inline void sme_event_ch_switch(struct wpa_supplicant *wpa_s) +{ +} + static inline void sme_state_changed(struct wpa_supplicant *wpa_s) { } diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in index bc5d49af8655..75a37a8cdbd3 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/utils/log2pcap.py b/wpa_supplicant/utils/log2pcap.py index 65e2fa109cbb..141aecbe5178 100755 --- a/wpa_supplicant/utils/log2pcap.py +++ b/wpa_supplicant/utils/log2pcap.py @@ -28,7 +28,7 @@ if __name__ == "__main__": input = sys.argv[1] pcap = sys.argv[2] except IndexError: - print "Usage: %s <log file> <pcap file>" % sys.argv[0] + print("Usage: %s <log file> <pcap file>" % sys.argv[0]) sys.exit(2) input_file = open(input, 'r') diff --git a/wpa_supplicant/wmm_ac.c b/wpa_supplicant/wmm_ac.c index a88cc46f3956..38800cc77fb7 100644 --- a/wpa_supplicant/wmm_ac.c +++ b/wpa_supplicant/wmm_ac.c @@ -471,13 +471,8 @@ static int wmm_ac_init(struct wpa_supplicant *wpa_s, const u8 *ies, return -1; } - if (!ies) { - wpa_printf(MSG_ERROR, "WMM AC: Missing IEs"); - return -1; - } - - if (!(wmm_params->info_bitmap & WMM_PARAMS_UAPSD_QUEUES_INFO)) { - wpa_printf(MSG_DEBUG, "WMM AC: Missing U-APSD configuration"); + if (!ies || !(wmm_params->info_bitmap & WMM_PARAMS_UAPSD_QUEUES_INFO)) { + /* WMM AC not in use for this connection */ return -1; } @@ -522,7 +517,7 @@ static void wmm_ac_deinit(struct wpa_supplicant *wpa_s) for (i = 0; i < WMM_AC_NUM; i++) wmm_ac_del_ts(wpa_s, i, TS_DIR_IDX_ALL); - /* delete pending add_ts requset */ + /* delete pending add_ts request */ wmm_ac_del_req(wpa_s, 1); os_free(wpa_s->wmm_ac_assoc_info); diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index 6b68fc9e3772..22a21361ad8a 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -12,6 +12,7 @@ #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" #include "common/wpa_ctrl.h" +#include "common/ocv.h" #include "rsn_supp/wpa.h" #include "config.h" #include "wpa_supplicant_i.h" @@ -20,6 +21,7 @@ #include "ctrl_iface.h" #include "bss.h" #include "wnm_sta.h" +#include "notify.h" #include "hs20_supplicant.h" #define MAX_TFS_IE_LEN 1024 @@ -58,8 +60,8 @@ int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s, int res; size_t len; struct wnm_sleep_element *wnmsleep_ie; - u8 *wnmtfs_ie; - u8 wnmsleep_ie_len; + u8 *wnmtfs_ie, *oci_ie; + u8 wnmsleep_ie_len, oci_ie_len; u16 wnmtfs_ie_len; /* possibly multiple IE(s) */ enum wnm_oper tfs_oper = action == 0 ? WNM_SLEEP_TFS_REQ_IE_ADD : WNM_SLEEP_TFS_REQ_IE_NONE; @@ -106,7 +108,41 @@ int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s, wpa_hexdump(MSG_DEBUG, "WNM: TFS Request element", (u8 *) wnmtfs_ie, wnmtfs_ie_len); - mgmt = os_zalloc(sizeof(*mgmt) + wnmsleep_ie_len + wnmtfs_ie_len); + oci_ie = NULL; + oci_ie_len = 0; +#ifdef CONFIG_OCV + if (action == WNM_SLEEP_MODE_EXIT && wpa_sm_ocv_enabled(wpa_s->wpa)) { + struct wpa_channel_info ci; + + if (wpa_drv_channel_info(wpa_s, &ci) != 0) { + wpa_printf(MSG_WARNING, + "Failed to get channel info for OCI element in WNM-Sleep Mode frame"); + os_free(wnmsleep_ie); + os_free(wnmtfs_ie); + return -1; + } + + oci_ie_len = OCV_OCI_EXTENDED_LEN; + oci_ie = os_zalloc(oci_ie_len); + if (!oci_ie) { + wpa_printf(MSG_WARNING, + "Failed to allocate buffer for for OCI element in WNM-Sleep Mode frame"); + os_free(wnmsleep_ie); + os_free(wnmtfs_ie); + return -1; + } + + if (ocv_insert_extended_oci(&ci, oci_ie) < 0) { + os_free(wnmsleep_ie); + os_free(wnmtfs_ie); + os_free(oci_ie); + return -1; + } + } +#endif /* CONFIG_OCV */ + + mgmt = os_zalloc(sizeof(*mgmt) + wnmsleep_ie_len + wnmtfs_ie_len + + oci_ie_len); if (mgmt == NULL) { wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for " "WNM-Sleep Request action frame"); @@ -131,8 +167,16 @@ int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s, wnmsleep_ie_len, wnmtfs_ie, wnmtfs_ie_len); } +#ifdef CONFIG_OCV + /* copy OCV OCI here */ + if (oci_ie_len > 0) { + os_memcpy(mgmt->u.action.u.wnm_sleep_req.variable + + wnmsleep_ie_len + wnmtfs_ie_len, oci_ie, oci_ie_len); + } +#endif /* CONFIG_OCV */ + len = 1 + sizeof(mgmt->u.action.u.wnm_sleep_req) + wnmsleep_ie_len + - wnmtfs_ie_len; + wnmtfs_ie_len + oci_ie_len; res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, wpa_s->own_addr, wpa_s->bssid, @@ -145,6 +189,7 @@ int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s, os_free(wnmsleep_ie); os_free(wnmtfs_ie); + os_free(oci_ie); os_free(mgmt); return res; @@ -256,6 +301,10 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, /* multiple TFS Resp IE (assuming consecutive) */ const u8 *tfsresp_ie_start = NULL; const u8 *tfsresp_ie_end = NULL; +#ifdef CONFIG_OCV + const u8 *oci_ie = NULL; + u8 oci_ie_len = 0; +#endif /* CONFIG_OCV */ size_t left; if (!wpa_s->wnmsleep_used) { @@ -289,6 +338,12 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, if (!tfsresp_ie_start) tfsresp_ie_start = pos; tfsresp_ie_end = pos; +#ifdef CONFIG_OCV + } else if (*pos == WLAN_EID_EXTENSION && ie_len >= 1 && + pos[2] == WLAN_EID_EXT_OCV_OCI) { + oci_ie = pos + 3; + oci_ie_len = ie_len - 1; +#endif /* CONFIG_OCV */ } else wpa_printf(MSG_DEBUG, "EID %d not recognized", *pos); pos += ie_len + 2; @@ -299,6 +354,26 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, return; } +#ifdef CONFIG_OCV + if (wnmsleep_ie->action_type == WNM_SLEEP_MODE_EXIT && + wpa_sm_ocv_enabled(wpa_s->wpa)) { + struct wpa_channel_info ci; + + if (wpa_drv_channel_info(wpa_s, &ci) != 0) { + wpa_msg(wpa_s, MSG_WARNING, + "Failed to get channel info to validate received OCI in WNM-Sleep Mode frame"); + return; + } + + if (ocv_verify_tx_params(oci_ie, oci_ie_len, &ci, + channel_width_to_int(ci.chanwidth), + ci.seg1_idx) != 0) { + wpa_msg(wpa_s, MSG_WARNING, "WNM: %s", ocv_errorstr); + return; + } + } +#endif /* CONFIG_OCV */ + wpa_s->wnmsleep_used = 0; if (wnmsleep_ie->status == WNM_STATUS_SLEEP_ACCEPT || @@ -696,7 +771,7 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs, continue; } - if (wpa_is_bss_tmp_disallowed(wpa_s, target->bssid)) { + if (wpa_is_bss_tmp_disallowed(wpa_s, target)) { wpa_printf(MSG_DEBUG, "MBO: Candidate BSS " MACSTR " retry delay is not over yet", @@ -941,6 +1016,9 @@ static void wnm_send_bss_transition_mgmt_resp( return; } + wpa_s->bss_tm_status = status; + wpas_notify_bss_tm_status(wpa_s); + wpabuf_put_u8(buf, WLAN_ACTION_WNM); wpabuf_put_u8(buf, WNM_BSS_TRANS_MGMT_RESP); wpabuf_put_u8(buf, dialog_token); diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 779355440a01..695fcbe04995 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - command line interface for wpa_supplicant daemon - * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi> + * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -29,7 +29,7 @@ static const char *const wpa_cli_version = "wpa_cli v" VERSION_STR "\n" -"Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi> and contributors"; +"Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> and contributors"; #define VENDOR_ELEM_FRAME_ID \ " 0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \ @@ -49,6 +49,7 @@ static int wpa_cli_last_id = 0; static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR; static const char *client_socket_dir = NULL; static char *ctrl_ifname = NULL; +static const char *global = NULL; static const char *pid_file = NULL; static const char *action_file = NULL; static int ping_interval = 5; @@ -74,6 +75,7 @@ static char ** wpa_list_cmd_list(void); static void update_creds(struct wpa_ctrl *ctrl); static void update_networks(struct wpa_ctrl *ctrl); static void update_stations(struct wpa_ctrl *ctrl); +static void update_ifnames(struct wpa_ctrl *ctrl); static void usage(void) @@ -1203,6 +1205,39 @@ static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +static int wpa_cli_cmd_psk_passphrase(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char cmd[256], *pos, *end; + int i, ret; + + if (argc < 2) { + printf("Invalid PSK_PASSPHRASE command: needs two arguments (network id and PSK/passphrase)\n"); + return -1; + } + + end = cmd + sizeof(cmd); + pos = cmd; + ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PSK_PASSPHRASE-%s:%s", + argv[0], argv[1]); + if (os_snprintf_error(end - pos, ret)) { + printf("Too long PSK_PASSPHRASE command.\n"); + return -1; + } + pos += ret; + for (i = 2; i < argc; i++) { + ret = os_snprintf(pos, end - pos, " %s", argv[i]); + if (os_snprintf_error(end - pos, ret)) { + printf("Too long PSK_PASSPHRASE command.\n"); + return -1; + } + pos += ret; + } + + return wpa_ctrl_command(ctrl, cmd); +} + + static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -1376,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", @@ -1412,7 +1449,7 @@ static const char *network_fields[] = { #ifdef CONFIG_HT_OVERRIDES "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc", "ht40_intolerant", "disable_max_amsdu", "ampdu_factor", - "ampdu_density", "ht_mcs", + "ampdu_density", "ht_mcs", "rx_stbc", "tx_stbc", #endif /* CONFIG_HT_OVERRIDES */ #ifdef CONFIG_VHT_OVERRIDES "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1", @@ -1426,6 +1463,8 @@ static const char *network_fields[] = { #ifdef CONFIG_MACSEC "macsec_policy", "macsec_integ_only", + "macsec_replay_protect", + "macsec_replay_window", "macsec_port", "mka_priority", #endif /* CONFIG_MACSEC */ @@ -2955,6 +2994,13 @@ static int wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, int argc, } +static int wpa_cli_cmd_dpp_configurator_sign(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_SIGN", 1, argc, argv); +} + + static int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -3084,6 +3130,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { cli_cmd_flag_sensitive, "<network id> <password> = configure one-time-password for an SSID" }, + { "psk_passphrase", wpa_cli_cmd_psk_passphrase, + wpa_cli_complete_network_id, cli_cmd_flag_sensitive, + "<network id> <PSK/passphrase> = configure PSK/passphrase for an SSID" }, { "passphrase", wpa_cli_cmd_passphrase, wpa_cli_complete_network_id, cli_cmd_flag_sensitive, "<network id> <passphrase> = configure private key passphrase\n" @@ -3614,6 +3663,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "dpp_configurator_get_key", wpa_cli_cmd_dpp_configurator_get_key, NULL, cli_cmd_flag_none, "<id> = Get DPP configurator's private key" }, + { "dpp_configurator_sign", wpa_cli_cmd_dpp_configurator_sign, NULL, + cli_cmd_flag_none, + "conf=<role> configurator=<id> = generate self DPP configuration" }, { "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL, cli_cmd_flag_sensitive, "add PKEX code" }, @@ -3972,10 +4024,46 @@ static void wpa_cli_action_cb(char *msg, size_t len) #endif /* CONFIG_ANSI_C_EXTRA */ +static int wpa_cli_open_global_ctrl(void) +{ +#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE + ctrl_conn = wpa_ctrl_open(NULL); +#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ + ctrl_conn = wpa_ctrl_open(global); +#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ + if (!ctrl_conn) { + fprintf(stderr, + "Failed to connect to wpa_supplicant global interface: %s error: %s\n", + global, strerror(errno)); + return -1; + } + + if (interactive) { + update_ifnames(ctrl_conn); + mon_conn = wpa_ctrl_open(global); + if (mon_conn) { + if (wpa_ctrl_attach(mon_conn) == 0) { + wpa_cli_attached = 1; + eloop_register_read_sock( + wpa_ctrl_get_fd(mon_conn), + wpa_cli_mon_receive, + NULL, NULL); + } else { + printf("Failed to open monitor connection through global control interface\n"); + } + } + update_stations(ctrl_conn); + } + + return 0; +} + + static void wpa_cli_reconnect(void) { wpa_cli_close_connection(); - if (wpa_cli_open_connection(ctrl_ifname, 1) < 0) + if ((global && wpa_cli_open_global_ctrl() < 0) || + (!global && wpa_cli_open_connection(ctrl_ifname, 1) < 0)) return; if (interactive) { @@ -4534,7 +4622,6 @@ int main(int argc, char *argv[]) int c; int daemonize = 0; int ret = 0; - const char *global = NULL; if (os_program_init()) return -1; @@ -4589,38 +4676,8 @@ int main(int argc, char *argv[]) if (eloop_init()) return -1; - if (global) { -#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE - ctrl_conn = wpa_ctrl_open(NULL); -#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ - ctrl_conn = wpa_ctrl_open(global); -#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ - if (ctrl_conn == NULL) { - fprintf(stderr, "Failed to connect to wpa_supplicant " - "global interface: %s error: %s\n", - global, strerror(errno)); - return -1; - } - - if (interactive) { - update_ifnames(ctrl_conn); - mon_conn = wpa_ctrl_open(global); - if (mon_conn) { - if (wpa_ctrl_attach(mon_conn) == 0) { - wpa_cli_attached = 1; - eloop_register_read_sock( - wpa_ctrl_get_fd(mon_conn), - wpa_cli_mon_receive, - NULL, NULL); - } else { - printf("Failed to open monitor " - "connection through global " - "control interface\n"); - } - } - update_stations(ctrl_conn); - } - } + if (global && wpa_cli_open_global_ctrl() < 0) + return -1; eloop_register_signal_terminate(wpa_cli_terminate, NULL); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index e587d7e3cd69..96a3691cf3cf 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - * Copyright (c) 2003-2018, 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. @@ -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" @@ -68,7 +69,7 @@ const char *const wpa_supplicant_version = "wpa_supplicant v" VERSION_STR "\n" -"Copyright (c) 2003-2018, Jouni Malinen <j@w1.fi> and contributors"; +"Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors"; const char *const wpa_supplicant_license = "This software may be distributed under the terms of the BSD license.\n" @@ -444,7 +445,7 @@ void free_hw_features(struct wpa_supplicant *wpa_s) } -static void free_bss_tmp_disallowed(struct wpa_supplicant *wpa_s) +void free_bss_tmp_disallowed(struct wpa_supplicant *wpa_s) { struct wpa_bss_tmp_disallowed *bss, *prev; @@ -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 */ } @@ -846,6 +849,23 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_supplicant_state_txt(wpa_s->wpa_state), wpa_supplicant_state_txt(state)); + if (state == WPA_COMPLETED && + os_reltime_initialized(&wpa_s->roam_start)) { + os_reltime_age(&wpa_s->roam_start, &wpa_s->roam_time); + wpa_s->roam_start.sec = 0; + wpa_s->roam_start.usec = 0; + wpas_notify_auth_changed(wpa_s); + wpas_notify_roam_time(wpa_s); + wpas_notify_roam_complete(wpa_s); + } else if (state == WPA_DISCONNECTED && + os_reltime_initialized(&wpa_s->roam_start)) { + wpa_s->roam_start.sec = 0; + wpa_s->roam_start.usec = 0; + wpa_s->roam_time.sec = 0; + wpa_s->roam_time.usec = 0; + wpas_notify_roam_complete(wpa_s); + } + if (state == WPA_INTERFACE_DISABLED) { /* Assure normal scan when interface is restored */ wpa_s->normal_scans = 0; @@ -941,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) @@ -1172,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 @@ -1203,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; @@ -1344,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 " @@ -1354,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 " @@ -1365,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; @@ -1399,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"); @@ -1422,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; @@ -1463,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"); @@ -1486,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 " @@ -1511,13 +1558,22 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, wpas_get_ssid_pmf(wpa_s, ssid)); #endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_OCV + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv); +#endif /* CONFIG_OCV */ if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) { wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE"); 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; @@ -1901,6 +1957,8 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, if (wpa_s->current_bss && wpa_s->current_bss == bss) { wmm_ac_save_tspecs(wpa_s); wpa_s->reassoc_same_bss = 1; + } else if (wpa_s->current_bss && wpa_s->current_bss != bss) { + os_get_reltime(&wpa_s->roam_start); } } @@ -2169,9 +2227,14 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) return; + freq->channel = pri_chan->chan; + #ifdef CONFIG_HT_OVERRIDES - if (ssid->disable_ht40) - return; + if (ssid->disable_ht40) { + if (ssid->disable_vht) + return; + goto skip_ht40; + } #endif /* CONFIG_HT_OVERRIDES */ /* Check/setup HT40+/HT40- */ @@ -2196,8 +2259,6 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) return; - freq->channel = pri_chan->chan; - if (ht40 == -1) { if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS)) return; @@ -2241,6 +2302,9 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, wpa_scan_results_free(scan_res); } +#ifdef CONFIG_HT_OVERRIDES +skip_ht40: +#endif /* CONFIG_HT_OVERRIDES */ wpa_printf(MSG_DEBUG, "IBSS/mesh: setup freq channel %d, sec_channel_offset %d", freq->channel, freq->sec_channel_offset); @@ -2330,6 +2394,13 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; seg0 = 114; } + } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_USE_HT) { + chwidth = VHT_CHANWIDTH_USE_HT; + seg0 = vht80[j] + 2; +#ifdef CONFIG_HT_OVERRIDES + if (ssid->disable_ht40) + seg0 = 0; +#endif /* CONFIG_HT_OVERRIDES */ } if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq, @@ -2450,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; @@ -2487,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)) { @@ -2601,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; @@ -2633,7 +2719,7 @@ static u8 * wpas_populate_assoc_ies( #endif /* CONFIG_P2P */ if (bss) { - wpa_ie_len += wpas_supp_op_class_ie(wpa_s, bss->freq, + wpa_ie_len += wpas_supp_op_class_ie(wpa_s, ssid, bss->freq, wpa_ie + wpa_ie_len, max_wpa_ie_len - wpa_ie_len); @@ -2678,7 +2764,8 @@ static u8 * wpas_populate_assoc_ies( int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid); size_t len; - wpas_hs20_add_indication(hs20, pps_mo_id); + wpas_hs20_add_indication(hs20, pps_mo_id, + get_hs20_version(bss)); wpas_hs20_add_roam_cons_sel(hs20, ssid); len = max_wpa_ie_len - wpa_ie_len; if (wpabuf_len(hs20) <= len) { @@ -2774,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, @@ -2812,6 +2921,21 @@ static u8 * wpas_populate_assoc_ies( } #endif /* CONFIG_IEEE80211R */ + if (ssid->multi_ap_backhaul_sta) { + size_t multi_ap_ie_len; + + multi_ap_ie_len = add_multi_ap_ie(wpa_ie + wpa_ie_len, + max_wpa_ie_len - wpa_ie_len, + MULTI_AP_BACKHAUL_STA); + if (multi_ap_ie_len == 0) { + wpa_printf(MSG_ERROR, + "Multi-AP: Failed to build Multi-AP IE"); + os_free(wpa_ie); + return NULL; + } + wpa_ie_len += multi_ap_ie_len; + } + params->wpa_ie = wpa_ie; params->wpa_ie_len = wpa_ie_len; params->auth_alg = algs; @@ -2850,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; @@ -3055,7 +3207,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) } params.wep_tx_keyidx = ssid->wep_tx_keyidx; - if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) && + if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) && (params.key_mgmt_suite == WPA_KEY_MGMT_PSK || params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) { params.passphrase = ssid->passphrase; @@ -3063,6 +3215,13 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) params.psk = ssid->psk; } + if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) && + (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X || + params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 || + params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B || + params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)) + params.req_key_mgmt_offload = 1; + if (wpa_s->conf->key_mgmt_offload) { if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X || params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 || @@ -3290,6 +3449,9 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, zero_addr = 1; } + if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0) + wpa_s->enabled_4addr_mode = 0; + #ifdef CONFIG_TDLS wpa_tdls_teardown_peers(wpa_s->wpa); #endif /* CONFIG_TDLS */ @@ -3881,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; @@ -4059,7 +4223,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, } if (wpa_s->eapol_received == 0 && - (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) || + (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) || !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || wpa_s->wpa_state != WPA_COMPLETED) && (wpa_s->current_ssid == NULL || @@ -4125,7 +4289,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0) return; wpa_drv_poll(wpa_s); - if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) + if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK)) wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len); else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { /* @@ -4367,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) @@ -4388,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); @@ -4412,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.", @@ -4437,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); @@ -4455,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; @@ -4476,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; @@ -4489,6 +4656,58 @@ static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s, } +static int wpa_set_tx_stbc(struct wpa_supplicant *wpa_s, + struct ieee80211_ht_capabilities *htcaps, + struct ieee80211_ht_capabilities *htcaps_mask, + int tx_stbc) +{ + le16 msk = host_to_le16(HT_CAP_INFO_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); + return -EINVAL; + } + + htcaps_mask->ht_capabilities_info |= msk; + htcaps->ht_capabilities_info &= ~msk; + htcaps->ht_capabilities_info |= (tx_stbc << 7) & msk; + + return 0; +} + + +static int wpa_set_rx_stbc(struct wpa_supplicant *wpa_s, + struct ieee80211_ht_capabilities *htcaps, + struct ieee80211_ht_capabilities *htcaps_mask, + int rx_stbc) +{ + le16 msk = host_to_le16(HT_CAP_INFO_RX_STBC_MASK); + + 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); + return -EINVAL; + } + + htcaps_mask->ht_capabilities_info |= msk; + htcaps->ht_capabilities_info &= ~msk; + htcaps->ht_capabilities_info |= (rx_stbc << 8) & msk; + + return 0; +} + + void wpa_supplicant_apply_ht_overrides( struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_driver_associate_params *params) @@ -4513,6 +4732,8 @@ void wpa_supplicant_apply_ht_overrides( wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40); wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi); wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc); + wpa_set_rx_stbc(wpa_s, htcaps, htcaps_mask, ssid->rx_stbc); + wpa_set_tx_stbc(wpa_s, htcaps, htcaps_mask, ssid->tx_stbc); if (ssid->ht40_intolerant) { le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT); @@ -4547,6 +4768,16 @@ void wpa_supplicant_apply_vht_overrides( vhtcaps_mask->vht_capabilities_info = host_to_le32(ssid->vht_capa_mask); #ifdef CONFIG_HT_OVERRIDES + if (ssid->disable_sgi) { + vhtcaps_mask->vht_capabilities_info |= (VHT_CAP_SHORT_GI_80 | + VHT_CAP_SHORT_GI_160); + vhtcaps->vht_capabilities_info &= ~(VHT_CAP_SHORT_GI_80 | + VHT_CAP_SHORT_GI_160); + wpa_msg(wpa_s, MSG_DEBUG, + "disable-sgi override specified, vht-caps: 0x%x", + vhtcaps->vht_capabilities_info); + } + /* if max ampdu is <= 3, we have to make the HT cap the same */ if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) { int max_ampdu; @@ -5560,6 +5791,12 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, capa.mac_addr_rand_sched_scan_supported) wpa_s->mac_addr_rand_supported |= (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO); + + wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION); + if (wpa_s->extended_capa && + wpa_s->extended_capa_len >= 3 && + wpa_s->extended_capa[2] & 0x40) + wpa_s->multi_bss_support = 1; } if (wpa_s->max_remain_on_chan == 0) wpa_s->max_remain_on_chan = 1000; @@ -6543,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)); } @@ -6928,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); } @@ -7182,16 +7424,14 @@ static void wpa_bss_tmp_disallow_timeout(void *eloop_ctx, void *timeout_ctx) void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid, - unsigned int sec) + unsigned int sec, int rssi_threshold) { struct wpa_bss_tmp_disallowed *bss; bss = wpas_get_disallowed_bss(wpa_s, bssid); if (bss) { eloop_cancel_timeout(wpa_bss_tmp_disallow_timeout, wpa_s, bss); - eloop_register_timeout(sec, 0, wpa_bss_tmp_disallow_timeout, - wpa_s, bss); - return; + goto finish; } bss = os_malloc(sizeof(*bss)); @@ -7204,23 +7444,31 @@ void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid, os_memcpy(bss->bssid, bssid, ETH_ALEN); dl_list_add(&wpa_s->bss_tmp_disallowed, &bss->list); wpa_set_driver_tmp_disallow_list(wpa_s); + +finish: + bss->rssi_threshold = rssi_threshold; eloop_register_timeout(sec, 0, wpa_bss_tmp_disallow_timeout, wpa_s, bss); } -int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s, const u8 *bssid) +int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s, + struct wpa_bss *bss) { - struct wpa_bss_tmp_disallowed *bss = NULL, *tmp, *prev; + struct wpa_bss_tmp_disallowed *disallowed = NULL, *tmp, *prev; dl_list_for_each_safe(tmp, prev, &wpa_s->bss_tmp_disallowed, struct wpa_bss_tmp_disallowed, list) { - if (os_memcmp(bssid, tmp->bssid, ETH_ALEN) == 0) { - bss = tmp; + if (os_memcmp(bss->bssid, tmp->bssid, ETH_ALEN) == 0) { + disallowed = tmp; break; } } - if (!bss) + if (!disallowed) + return 0; + + if (disallowed->rssi_threshold != 0 && + bss->level > disallowed->rssi_threshold) return 0; return 1; diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 4f5916025aab..a9205f0b8a2c 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 @@ -907,6 +929,13 @@ fast_reauth=1 # PMF required: ieee80211w=2 and key_mgmt=WPA-EAP-SHA256 # (and similarly for WPA-PSK and WPA-WPSK-SHA256 if WPA2-Personal is used) # +# ocv: whether operating channel validation is enabled +# This is a countermeasure against multi-channel man-in-the-middle attacks. +# Enabling this automatically also enables ieee80211w, if not yet enabled. +# 0 = disabled (default) +# 1 = enabled +#ocv=1 +# # auth_alg: list of allowed IEEE 802.11 authentication algorithms # OPEN = Open System authentication (required for WPA/WPA2) # SHARED = Shared Key authentication (requires static WEP keys) @@ -987,6 +1016,22 @@ fast_reauth=1 # 0: Encrypt traffic (default) # 1: Integrity only # +# macsec_replay_protect: IEEE 802.1X/MACsec replay protection +# This setting applies only when MACsec is in use, i.e., +# - macsec_policy is enabled +# - the key server has decided to enable MACsec +# 0: Replay protection disabled (default) +# 1: Replay protection enabled +# +# macsec_replay_window: IEEE 802.1X/MACsec replay protection window +# This determines a window in which replay is tolerated, to allow receipt +# of frames that have been misordered by the network. +# This setting applies only when MACsec replay protection active, i.e., +# - macsec_replay_protect is enabled +# - the key server has decided to enable MACsec +# 0: No replay window, strict check (default) +# 1..2^32-1: number of packets that could be misordered +# # macsec_port: IEEE 802.1X/MACsec port # Port component of the SCI # Range: 1-65534 (default: 1) @@ -995,9 +1040,10 @@ fast_reauth=1 # This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair. # In this mode, instances of wpa_supplicant can act as MACsec peers. The peer # with lower priority will become the key server and start distributing SAKs. -# mka_cak (CAK = Secure Connectivity Association Key) takes a 16-bytes (128 bit) -# hex-string (32 hex-digits) -# mka_ckn (CKN = CAK Name) takes a 32-bytes (256 bit) hex-string (64 hex-digits) +# mka_cak (CAK = Secure Connectivity Association Key) takes a 16-byte (128-bit) +# hex-string (32 hex-digits) or a 32-byte (256-bit) hex-string (64 hex-digits) +# mka_ckn (CKN = CAK Name) takes a 1..32-bytes (8..256 bit) hex-string +# (2..64 hex-digits) # mka_priority (Priority of MKA Actor) is in 0..255 range with 255 being # default priority # @@ -1143,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 @@ -1155,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") @@ -1216,12 +1274,19 @@ fast_reauth=1 # For EAP-FAST, this must be set to 0 (or left unconfigured for the # default value to be used automatically). # tls_disable_tlsv1_0=1 - disable use of TLSv1.0 +# tls_disable_tlsv1_0=0 - explicitly enable use of TLSv1.0 (this allows +# systemwide TLS policies to be overridden) # tls_disable_tlsv1_1=1 - disable use of TLSv1.1 (a workaround for AAA servers # that have issues interoperating with updated TLS version) +# tls_disable_tlsv1_1=0 - explicitly enable use of TLSv1.1 (this allows +# systemwide TLS policies to be overridden) # tls_disable_tlsv1_2=1 - disable use of TLSv1.2 (a workaround for AAA servers # that have issues interoperating with updated TLS version) +# tls_disable_tlsv1_2=0 - explicitly enable use of TLSv1.2 (this allows +# systemwide TLS policies to be overridden) # tls_disable_tlsv1_3=1 - disable use of TLSv1.3 (a workaround for AAA servers # that have issues interoperating with updated TLS version) +# tls_disable_tlsv1_3=0 - enable TLSv1.3 (experimental - disabled by default) # tls_ext_cert_check=0 - No external server certificate validation (default) # tls_ext_cert_check=1 - External server certificate validation enabled; this # requires an external program doing validation of server certificate @@ -1381,6 +1446,20 @@ fast_reauth=1 # Treated as hint by the kernel. # -1 = Do not make any changes. # 0-3 = Set AMPDU density (aka factor) to specified value. +# +# tx_stbc: Allow overriding STBC support for TX streams +# Value: 0-1, see IEEE Std 802.11-2016, 9.4.2.56.2. +# -1 = Do not make any changes (default) +# 0 = Set if not supported +# 1 = Set if supported +# +# rx_stbc: Allow overriding STBC support for RX streams +# Value: 0-3, see IEEE Std 802.11-2016, 9.4.2.56.2. +# -1 = Do not make any changes (default) +# 0 = Set if not supported +# 1 = Set for support of one spatial stream +# 2 = Set for support of one and two spatial streams +# 3 = Set for support of one, two and three spatial streams # disable_vht: Whether VHT should be disabled. # 0 = VHT enabled (if AP supports it) @@ -1396,6 +1475,13 @@ fast_reauth=1 # 2: MCS 0-9 # 3: not supported +# multi_ap_backhaul_sta: Multi-AP backhaul STA functionality +# 0 = normal STA (default) +# 1 = backhaul STA +# A backhaul STA sends the Multi-AP IE, fails to associate if the AP does not +# support Multi-AP, and sets 4-address mode if it does. Thus, the netdev can be +# added to a bridge to allow forwarding frames over this backhaul link. + ##### Fast Session Transfer (FST) support ##################################### # # The options in this section are only available when the build configuration diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 8b749f44e235..16e4db62aeef 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -451,10 +451,12 @@ struct icon_entry { struct wpa_bss_tmp_disallowed { struct dl_list list; u8 bssid[ETH_ALEN]; + int rssi_threshold; }; struct beacon_rep_data { u8 token; + u8 last_indication; struct wpa_driver_scan_params scan_params; u8 ssid[SSID_MAX_LEN]; size_t ssid_len; @@ -492,15 +494,16 @@ struct wpa_supplicant { struct wpa_supplicant *next; struct l2_packet_data *l2; struct l2_packet_data *l2_br; + struct os_reltime roam_start; + struct os_reltime roam_time; + struct os_reltime session_start; + struct os_reltime session_length; unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; #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; @@ -745,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; @@ -814,6 +821,7 @@ struct wpa_supplicant { unsigned int mesh_if_created:1; unsigned int mesh_ht_enabled:1; unsigned int mesh_vht_enabled:1; + struct wpa_driver_mesh_join_params *mesh_params; #ifdef CONFIG_PMKSA_CACHE_EXTERNAL /* struct external_pmksa_cache::list */ struct dl_list mesh_external_pmksa_cache; @@ -911,6 +919,7 @@ struct wpa_supplicant { unsigned int p2p_pd_before_go_neg:1; unsigned int p2p_go_ht40:1; unsigned int p2p_go_vht:1; + unsigned int p2p_go_he:1; unsigned int user_initiated_pd:1; unsigned int p2p_go_group_formation_completed:1; unsigned int group_formation_reported:1; @@ -1018,6 +1027,10 @@ struct wpa_supplicant { /* WLAN_REASON_* reason codes. Negative if locally generated. */ int disconnect_reason; + /* WLAN_STATUS_* status codes from last received Authentication frame + * from the AP. */ + u16 auth_status_code; + /* WLAN_STATUS_* status codes from (Re)Association Response frame. */ u16 assoc_status_code; @@ -1059,6 +1072,7 @@ struct wpa_supplicant { struct neighbor_report *wnm_neighbor_report_elements; struct os_reltime wnm_cand_valid_until; u8 wnm_cand_from_bss[ETH_ALEN]; + enum bss_trans_mgmt_status_code bss_tm_status; struct wpabuf *coloc_intf_elems; u8 coloc_intf_dialog_token; u8 coloc_intf_auto_report; @@ -1193,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; @@ -1222,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; @@ -1234,6 +1249,8 @@ struct wpa_supplicant { unsigned int disable_fils:1; #endif /* CONFIG_FILS */ unsigned int ieee80211ac:1; + unsigned int enabled_4addr_mode:1; + unsigned int multi_bss_support:1; }; @@ -1369,6 +1386,8 @@ int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len, int add_oce_capa); const u8 * mbo_attr_from_mbo_ie(const u8 *mbo_ie, enum mbo_attr_id attr); const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr); +const u8 * mbo_get_attr_from_ies(const u8 *ies, size_t ies_len, + enum mbo_attr_id attr); int wpas_mbo_update_non_pref_chan(struct wpa_supplicant *wpa_s, const char *non_pref_chan); void wpas_mbo_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ie); @@ -1383,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 { @@ -1391,8 +1411,9 @@ enum chan_allowed { enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 channel, u8 bw); -size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s, int freq, u8 *pos, - size_t len); +size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, + int freq, u8 *pos, size_t len); /** * wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response @@ -1425,6 +1446,8 @@ int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s); struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s, struct wpa_ssid **selected_ssid); int wpas_temp_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); +void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s, + struct channel_list_changed *info); /* eap_register.c */ int eap_register_methods(void); @@ -1477,8 +1500,10 @@ struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, u16 num_modes, enum hostapd_hw_mode mode); void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid, - unsigned int sec); -int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s, const u8 *bssid); + unsigned int sec, int rssi_threshold); +int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s, + struct wpa_bss *bss); +void free_bss_tmp_disallowed(struct wpa_supplicant *wpa_s); struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, int i, struct wpa_bss *bss, diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 4634ed7fc368..449e04acded8 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -296,7 +296,7 @@ static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, } if (result != EAPOL_SUPP_RESULT_SUCCESS || - !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) + !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X)) return; if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) @@ -1183,6 +1183,15 @@ static void wpa_supplicant_fils_hlp_rx(void *ctx, const u8 *dst, const u8 *src, os_free(hex); } + +static int wpa_supplicant_channel_info(void *_wpa_s, + struct wpa_channel_info *ci) +{ + struct wpa_supplicant *wpa_s = _wpa_s; + + return wpa_drv_channel_info(wpa_s, ci); +} + #endif /* CONFIG_NO_WPA */ @@ -1233,6 +1242,7 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) ctx->set_rekey_offload = wpa_supplicant_set_rekey_offload; ctx->key_mgmt_set_pmk = wpa_supplicant_key_mgmt_set_pmk; ctx->fils_hlp_rx = wpa_supplicant_fils_hlp_rx; + ctx->channel_info = wpa_supplicant_channel_info; wpa_s->wpa = wpa_sm_init(ctx); if (wpa_s->wpa == NULL) { diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c index d3d06b8ae231..41477d514d3f 100644 --- a/wpa_supplicant/wpas_kay.c +++ b/wpa_supplicant/wpas_kay.c @@ -92,6 +92,12 @@ static int wpas_set_transmit_next_pn(void *wpa_s, struct transmit_sa *sa) } +static int wpas_set_receive_lowest_pn(void *wpa_s, struct receive_sa *sa) +{ + return wpa_drv_set_receive_lowest_pn(wpa_s, sa); +} + + static unsigned int conf_offset_val(enum confidentiality_offset co) { switch (co) { @@ -219,6 +225,7 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) kay_ctx->get_receive_lowest_pn = wpas_get_receive_lowest_pn; kay_ctx->get_transmit_next_pn = wpas_get_transmit_next_pn; kay_ctx->set_transmit_next_pn = wpas_set_transmit_next_pn; + kay_ctx->set_receive_lowest_pn = wpas_set_receive_lowest_pn; kay_ctx->create_receive_sc = wpas_create_receive_sc; kay_ctx->delete_receive_sc = wpas_delete_receive_sc; kay_ctx->create_receive_sa = wpas_create_receive_sa; @@ -232,7 +239,8 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) kay_ctx->enable_transmit_sa = wpas_enable_transmit_sa; kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa; - res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_port, + res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_replay_protect, + ssid->macsec_replay_window, ssid->macsec_port, ssid->mka_priority, wpa_s->ifname, wpa_s->own_addr); /* ieee802_1x_kay_init() frees kay_ctx on failure */ @@ -349,8 +357,8 @@ void * ieee802_1x_notify_create_actor(struct wpa_supplicant *wpa_s, /* Derive CAK from MSK */ cak->len = DEFAULT_KEY_LEN; - if (ieee802_1x_cak_128bits_aes_cmac(msk->key, wpa_s->own_addr, - peer_addr, cak->key)) { + if (ieee802_1x_cak_aes_cmac(msk->key, msk->len, wpa_s->own_addr, + peer_addr, cak->key, cak->len)) { wpa_printf(MSG_ERROR, "IEEE 802.1X: Deriving CAK failed"); goto fail; @@ -359,9 +367,8 @@ void * ieee802_1x_notify_create_actor(struct wpa_supplicant *wpa_s, /* Derive CKN from MSK */ ckn->len = DEFAULT_CKN_LEN; - if (ieee802_1x_ckn_128bits_aes_cmac(msk->key, wpa_s->own_addr, - peer_addr, sid, sid_len, - ckn->name)) { + if (ieee802_1x_ckn_aes_cmac(msk->key, msk->len, wpa_s->own_addr, + peer_addr, sid, sid_len, ckn->name)) { wpa_printf(MSG_ERROR, "IEEE 802.1X: Deriving CKN failed"); goto fail; @@ -411,10 +418,10 @@ void * ieee802_1x_create_preshared_mka(struct wpa_supplicant *wpa_s, if (wpa_s->kay->policy == DO_NOT_SECURE) goto dealloc; - cak->len = MACSEC_CAK_LEN; + cak->len = ssid->mka_cak_len; os_memcpy(cak->key, ssid->mka_cak, cak->len); - ckn->len = MACSEC_CKN_LEN; + ckn->len = ssid->mka_ckn_len; os_memcpy(ckn->name, ssid->mka_ckn, ckn->len); res = ieee802_1x_kay_create_mka(wpa_s->kay, ckn, cak, 0, PSK, FALSE); diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 1a2677b8eea4..057927410256 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 c8fe47e37279..0fbc85174f94 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); |