diff options
author | rpaulo <rpaulo@FreeBSD.org> | 2010-11-03 10:43:38 +0000 |
---|---|---|
committer | rpaulo <rpaulo@FreeBSD.org> | 2010-11-03 10:43:38 +0000 |
commit | e0d70c33109c041ff2046fe529eb8e3c0f2acec1 (patch) | |
tree | bf6082c2ad69b06fcb45c37be7157b66ffbd4fc7 /contrib/wpa/wpa_supplicant | |
parent | 6ddde2168bc79a10ab0937ba69afe0a74559eea0 (diff) | |
parent | 14ab4e9475c66439a7a011706ada056765de1555 (diff) | |
download | FreeBSD-src-e0d70c33109c041ff2046fe529eb8e3c0f2acec1.zip FreeBSD-src-e0d70c33109c041ff2046fe529eb8e3c0f2acec1.tar.gz |
Merge wpa_supplicant and hostapd 0.7.3.
Diffstat (limited to 'contrib/wpa/wpa_supplicant')
109 files changed, 17435 insertions, 7411 deletions
diff --git a/contrib/wpa/wpa_supplicant/.gitignore b/contrib/wpa/wpa_supplicant/.gitignore new file mode 100644 index 0000000..e7e034c --- /dev/null +++ b/contrib/wpa/wpa_supplicant/.gitignore @@ -0,0 +1,8 @@ +*.d +.config +eapol_test +preauth_test +wpa_cli +wpa_passphrase +wpa_supplicant +wpa_priv diff --git a/contrib/wpa/wpa_supplicant/ChangeLog b/contrib/wpa/wpa_supplicant/ChangeLog index ab99514..56046c3 100644 --- a/contrib/wpa/wpa_supplicant/ChangeLog +++ b/contrib/wpa/wpa_supplicant/ChangeLog @@ -1,33 +1,151 @@ ChangeLog for wpa_supplicant -2010-01-12 - v0.6.10 - * fixed SHA-256 based key derivation function to match with the - standard when using CCMP (for IEEE 802.11r and IEEE 802.11w) - (note: this breaks interoperability with previous version) [Bug 307] - * changed driver_wext to disconnect at init/deinit to clear state - * added explicit disconnect on 4-way handshake failures - * added WPS workarounds for known interoperability issues with broken, - deployed implementation - * update IEEE 802.11w implementation to match with the published - standard - * do not send WPS M8 message when learning current AP configuration as - an external Registrar - * added a workaround for race condition between receive EAPOL frames - and association events - * fixed compilation with newer GnuTLS versions - * fixed PKCS#12 use with OpenSSL 1.0.0 +2010-09-07 - v0.7.3 + * fixed fallback from failed PMKSA caching into full EAP authentication + [Bug 355] + * fixed issue with early D-Bus signals during initialization + * fixed X.509 name handling in internal TLS + * fixed WPS ER to use corrent Enrollee MAC Address in Credential + * fixed scanning routines ot improve AP selection for WPS + * added WPS workaround for open networks + * fixed WPS Diffie-Hellman derivation to use correct public key length + * fixed wpa_supplicant AP mode operations to ignore Supplicant and + scan result events + * improved SME operations with nl80211 + * fixed WPS ER event_id handling in some cases + * fixed some issues with bgscan simple to avoid unnecessary scans + * fixed issue with l2_packet_ndis overlapped writes corrupting stack + [Bug 328] + * updated WinPcap to the latest stable version 4.1.2 in Windows + installer -2009-03-23 - v0.6.9 - * driver_ndis: add PAE group address to the multicast address list to - fix wired IEEE 802.1X authentication - * fixed IEEE 802.11r key derivation function to match with the standard - (note: this breaks interoperability with previous version) [Bug 303] +2010-04-18 - v0.7.2 + * nl80211: fixed number of issues with roaming + * avoid unnecessary roaming if multiple APs with similar signal + strength are present in scan results + * add TLS client events and server probing to ease design of + automatic detection of EAP parameters + * add option for server certificate matching (SHA256 hash of the + certificate) instead of trusted CA certificate configuration + * bsd: Cleaned up driver wrapper and added various low-level + configuration options + * wpa_gui-qt4: do not show too frequent WPS AP available events as + tray messages + * TNC: fixed issues with fragmentation + * EAP-TNC: add Flags field into fragment acknowledgement (needed to + interoperate with other implementations; may potentially breaks + compatibility with older wpa_supplicant/hostapd versions) + * wpa_cli: added option for using a separate process to receive event + messages to reduce latency in showing these + (CFLAGS += -DCONFIG_WPA_CLI_FORK=y in .config to enable this) + * maximum BSS table size can now be configured (bss_max_count) + * BSSes to be included in the BSS table can be filtered based on + configured SSIDs to save memory (filter_ssids) + * fix number of issues with IEEE 802.11r/FT; this version is not + backwards compatible with old versions + * nl80211: add support for IEEE 802.11r/FT protocol (both over-the-air + and over-the-DS) + * add freq_list network configuration parameter to allow the AP + selection to filter out entries based on the operating channel + * add signal strength change events for bgscan; this allows more + dynamic changes to background scanning interval based on changes in + the signal strength with the current AP; this improves roaming within + ESS quite a bit, e.g., with bgscan="simple:30:-45:300" in the network + configuration block to request background scans less frequently when + signal strength remains good and to automatically trigger background + scans whenever signal strength drops noticeably + (this is currently only available with nl80211) + * add BSSID and reason code (if available) to disconnect event messages + * wpa_gui-qt4: more complete support for translating the GUI with + linguist and add German translation + * fix DH padding with internal crypto code (mainly, for WPS) + * do not trigger initial scan automatically anymore if there are no + enabled networks -2009-02-15 - v0.6.8 +2010-01-16 - v0.7.1 + * cleaned up driver wrapper API (struct wpa_driver_ops); the new API + is not fully backwards compatible, so out-of-tree driver wrappers + will need modifications + * cleaned up various module interfaces + * merge hostapd and wpa_supplicant developers' documentation into a + single document + * nl80211: use explicit deauthentication to clear cfg80211 state to + avoid issues when roaming between APs + * dbus: major design changes in the new D-Bus API + (fi.w1.wpa_supplicant1) + * nl80211: added support for IBSS networks + * added internal debugging mechanism with backtrace support and memory + allocation/freeing validation, etc. tests (CONFIG_WPA_TRACE=y) + * added WPS ER unsubscription command to more cleanly unregister from + receiving UPnP events when ER is terminated + * cleaned up AP mode operations to avoid need for virtual driver_ops + wrapper + * added BSS table to maintain more complete scan result information + over multiple scans (that may include only partial results) + * wpa_gui-qt4: update Peers dialog information more dynamically while + the dialog is kept open + * fixed PKCS#12 use with OpenSSL 1.0.0 + * driver_wext: Added cfg80211-specific optimization to avoid some + unnecessary scans and to speed up association + +2009-11-21 - v0.7.0 * increased wpa_cli ping interval to 5 seconds and made this configurable with a new command line options (-G<seconds>) * fixed scan buffer processing with WEXT to handle up to 65535 byte result buffer (previously, limited to 32768 bytes) + * allow multiple driver wrappers to be specified on command line + (e.g., -Dnl80211,wext); the first one that is able to initialize the + interface will be used + * added support for multiple SSIDs per scan request to optimize + scan_ssid=1 operations in ap_scan=1 mode (i.e., search for hidden + SSIDs); this requires driver support and can currently be used only + with nl80211 + * added support for WPS USBA out-of-band mechanism with USB Flash + Drives (UFD) (CONFIG_WPS_UFD=y) + * driver_ndis: add PAE group address to the multicast address list to + fix wired IEEE 802.1X authentication + * fixed IEEE 802.11r key derivation function to match with the standard + (note: this breaks interoperability with previous version) [Bug 303] + * added better support for drivers that allow separate authentication + and association commands (e.g., mac80211-based Linux drivers with + nl80211; SME in wpa_supplicant); this allows over-the-air FT protocol + to be used (IEEE 802.11r) + * fixed SHA-256 based key derivation function to match with the + standard when using CCMP (for IEEE 802.11r and IEEE 802.11w) + (note: this breaks interoperability with previous version) [Bug 307] + * use shared driver wrapper files with hostapd + * added AP mode functionality (CONFIG_AP=y) with mode=2 in the network + block; this can be used for open and WPA2-Personal networks + (optionally, with WPS); this links in parts of hostapd functionality + into wpa_supplicant + * wpa_gui-qt4: added new Peers dialog to show information about peers + (other devices, including APs and stations, etc. in the neighborhood) + * added support for WPS External Registrar functionality (configure APs + and enroll new devices); can be used with wpa_gui-qt4 Peers dialog + and wpa_cli commands wps_er_start, wps_er_stop, wps_er_pin, + wps_er_pbc, wps_er_learn + (this can also be used with a new 'none' driver wrapper if no + wireless device or IEEE 802.1X on wired is needed) + * driver_nl80211: multiple updates to provide support for new Linux + nl80211/mac80211 functionality + * updated management frame protection to use IEEE Std 802.11w-2009 + * fixed number of small WPS issues and added workarounds to + interoperate with common deployed broken implementations + * added support for NFC out-of-band mechanism with WPS + * driver_ndis: fixed wired IEEE 802.1X authentication with PAE group + address frames + * added preliminary support for IEEE 802.11r RIC processing + * added support for specifying subset of enabled frequencies to scan + (scan_freq option in the network configuration block); this can speed + up scanning process considerably if it is known that only a small + subset of channels is actually used in the network (this is currently + supported only with -Dnl80211) + * added a workaround for race condition between receiving the + association event and the following EAPOL-Key + * added background scan and roaming infrastructure to allow + network-specific optimizations to be used to improve roaming within + an ESS (same SSID) + * added new DBus interface (fi.w1.wpa_supplicant1) 2009-01-06 - v0.6.7 * added support for Wi-Fi Protected Setup (WPS) diff --git a/contrib/wpa/wpa_supplicant/Makefile b/contrib/wpa/wpa_supplicant/Makefile index 5a88fb3..1d25623 100644 --- a/contrib/wpa/wpa_supplicant/Makefile +++ b/contrib/wpa/wpa_supplicant/Makefile @@ -10,10 +10,7 @@ export LIBDIR ?= /usr/local/lib/ export BINDIR ?= /usr/local/sbin/ CFLAGS += -I../src -CFLAGS += -I../src/crypto CFLAGS += -I../src/utils -CFLAGS += -I../src/common -CFLAGS += -I../src/rsn_supp ALL=wpa_supplicant wpa_passphrase wpa_cli @@ -29,7 +26,7 @@ verify_config: fi mkconfig: - @if [ -e .config ]; then \ + @if [ -f .config ]; then \ echo '.config exists - did not replace it'; \ exit 1; \ fi @@ -42,21 +39,16 @@ install: all $(MAKE) -C ../src install OBJS = config.o +OBJS += notify.o +OBJS += bss.o +OBJS += eap_register.o OBJS += ../src/utils/common.o OBJS += ../src/utils/wpa_debug.o OBJS += ../src/utils/wpabuf.o -OBJS += ../src/crypto/md5.o -OBJS += ../src/crypto/rc4.o -OBJS += ../src/crypto/md4.o -OBJS += ../src/crypto/sha1.o -OBJS += ../src/crypto/des.o OBJS_p = wpa_passphrase.o OBJS_p += ../src/utils/common.o OBJS_p += ../src/utils/wpa_debug.o -OBJS_p += ../src/crypto/md5.o -OBJS_p += ../src/crypto/md4.o -OBJS_p += ../src/crypto/sha1.o -OBJS_p += ../src/crypto/des.o +OBJS_p += ../src/utils/wpabuf.o OBJS_c = wpa_cli.o ../src/common/wpa_ctrl.o -include .config @@ -77,6 +69,22 @@ OBJS += ../src/utils/os_$(CONFIG_OS).o OBJS_p += ../src/utils/os_$(CONFIG_OS).o OBJS_c += ../src/utils/os_$(CONFIG_OS).o +ifdef CONFIG_WPA_TRACE +CFLAGS += -DWPA_TRACE +OBJS += ../src/utils/trace.o +OBJS_p += ../src/utils/trace.o +OBJS_c += ../src/utils/trace.o +OBJS_c += ../src/utils/wpa_debug.o +LDFLAGS += -rdynamic +CFLAGS += -funwind-tables +ifdef CONFIG_WPA_TRACE_BFD +CFLAGS += -DWPA_TRACE_BFD +LIBS += -lbfd +LIBS_p += -lbfd +LIBS_c += -lbfd +endif +endif + ifndef CONFIG_ELOOP CONFIG_ELOOP=eloop endif @@ -119,128 +127,61 @@ ifdef CONFIG_NO_SCAN_PROCESSING CFLAGS += -DCONFIG_NO_SCAN_PROCESSING endif -ifdef CONFIG_DRIVER_HOSTAP -CFLAGS += -DCONFIG_DRIVER_HOSTAP -OBJS_d += ../src/drivers/driver_hostap.o -CONFIG_WIRELESS_EXTENSION=y -endif - -ifdef CONFIG_DRIVER_WEXT -CFLAGS += -DCONFIG_DRIVER_WEXT -CONFIG_WIRELESS_EXTENSION=y -endif - -ifdef CONFIG_DRIVER_NL80211 -CFLAGS += -DCONFIG_DRIVER_NL80211 -OBJS_d += ../src/drivers/driver_nl80211.o -LIBS += -lnl -ifdef CONFIG_CLIENT_MLME -OBJS_d += ../src/drivers/radiotap.o -endif -endif - -ifdef CONFIG_DRIVER_PRISM54 -CFLAGS += -DCONFIG_DRIVER_PRISM54 -OBJS_d += ../src/drivers/driver_prism54.o -CONFIG_WIRELESS_EXTENSION=y -endif - -ifdef CONFIG_DRIVER_HERMES -CFLAGS += -DCONFIG_DRIVER_HERMES -OBJS_d += ../src/drivers/driver_hermes.o -CONFIG_WIRELESS_EXTENSION=y -endif - -ifdef CONFIG_DRIVER_MADWIFI -CFLAGS += -DCONFIG_DRIVER_MADWIFI -OBJS_d += ../src/drivers/driver_madwifi.o -CONFIG_WIRELESS_EXTENSION=y -endif - -ifdef CONFIG_DRIVER_ATMEL -CFLAGS += -DCONFIG_DRIVER_ATMEL -OBJS_d += ../src/drivers/driver_atmel.o -CONFIG_WIRELESS_EXTENSION=y -endif - -ifdef CONFIG_DRIVER_NDISWRAPPER -CFLAGS += -DCONFIG_DRIVER_NDISWRAPPER -OBJS_d += ../src/drivers/driver_ndiswrapper.o -CONFIG_WIRELESS_EXTENSION=y -endif - -ifdef CONFIG_DRIVER_RALINK -CFLAGS += -DCONFIG_DRIVER_RALINK -OBJS_d += ../src/drivers/driver_ralink.o -endif - -ifdef CONFIG_DRIVER_BROADCOM -CFLAGS += -DCONFIG_DRIVER_BROADCOM -OBJS_d += ../src/drivers/driver_broadcom.o -endif - -ifdef CONFIG_DRIVER_IPW -CFLAGS += -DCONFIG_DRIVER_IPW -OBJS_d += ../src/drivers/driver_ipw.o -CONFIG_WIRELESS_EXTENSION=y -endif - -ifdef CONFIG_DRIVER_BSD -CFLAGS += -DCONFIG_DRIVER_BSD -OBJS_d += ../src/drivers/driver_bsd.o -ifndef CONFIG_L2_PACKET -CONFIG_L2_PACKET=freebsd -endif -endif - -ifdef CONFIG_DRIVER_NDIS -CFLAGS += -DCONFIG_DRIVER_NDIS -OBJS_d += ../src/drivers/driver_ndis.o -ifdef CONFIG_NDIS_EVENTS_INTEGRATED -OBJS_d += ../src/drivers/driver_ndis_.o -endif -ifndef CONFIG_L2_PACKET -CONFIG_L2_PACKET=pcap -endif -CONFIG_WINPCAP=y -ifdef CONFIG_USE_NDISUIO -CFLAGS += -DCONFIG_USE_NDISUIO -endif +ifdef CONFIG_IEEE80211W +CFLAGS += -DCONFIG_IEEE80211W +NEED_SHA256=y +NEED_AES_OMAC1=y endif -ifdef CONFIG_DRIVER_WIRED -CFLAGS += -DCONFIG_DRIVER_WIRED -OBJS_d += ../src/drivers/driver_wired.o +ifdef CONFIG_IEEE80211R +CFLAGS += -DCONFIG_IEEE80211R +OBJS += ../src/rsn_supp/wpa_ft.o +NEED_80211_COMMON=y +NEED_SHA256=y +NEED_AES_OMAC1=y endif -ifdef CONFIG_DRIVER_TEST -CFLAGS += -DCONFIG_DRIVER_TEST -OBJS_d += ../src/drivers/driver_test.o +ifdef CONFIG_PEERKEY +CFLAGS += -DCONFIG_PEERKEY endif -ifdef CONFIG_DRIVER_OSX -CFLAGS += -DCONFIG_DRIVER_OSX -OBJS_d += ../src/drivers/driver_osx.o -LDFLAGS += -framework CoreFoundation -LDFLAGS += -F/System/Library/PrivateFrameworks -framework Apple80211 +ifndef CONFIG_NO_WPA +OBJS += ../src/rsn_supp/wpa.o +OBJS += ../src/rsn_supp/preauth.o +OBJS += ../src/rsn_supp/pmksa_cache.o +OBJS += ../src/rsn_supp/peerkey.o +OBJS += ../src/rsn_supp/wpa_ie.o +OBJS += ../src/common/wpa_common.o +NEED_AES=y +NEED_SHA1=y +NEED_MD5=y +NEED_RC4=y +else +CFLAGS += -DCONFIG_NO_WPA -DCONFIG_NO_WPA2 endif -ifdef CONFIG_DRIVER_PS3 -CFLAGS += -DCONFIG_DRIVER_PS3 -m64 -OBJS_d += ../src/drivers/driver_ps3.o -LDFLAGS += -m64 +ifdef CONFIG_IBSS_RSN +NEED_RSN_AUTHENTICATOR=y +CFLAGS += -DCONFIG_IBSS_RSN +OBJS += ibss_rsn.o endif -ifdef CONFIG_DRIVER_IPHONE -CFLAGS += -DCONFIG_DRIVER_IPHONE -OBJS_d += ../src/drivers/driver_iphone.o -OBJS_d += ../src/drivers/MobileApple80211.o -LIBS += -framework CoreFoundation +ifdef CONFIG_NO_WPA2 +CFLAGS += -DCONFIG_NO_WPA2 endif -ifdef CONFIG_DRIVER_ROBOSWITCH -CFLAGS += -DCONFIG_DRIVER_ROBOSWITCH -OBJS_d += ../src/drivers/driver_roboswitch.o +include ../src/drivers/drivers.mak +ifdef CONFIG_AP +OBJS_d += $(DRV_BOTH_OBJS) +CFLAGS += $(DRV_BOTH_CFLAGS) +LDFLAGS += $(DRV_BOTH_LDFLAGS) +LIBS += $(DRV_BOTH_LIBS) +else +NEED_AP_MLME= +OBJS_d += $(DRV_WPA_OBJS) +CFLAGS += $(DRV_WPA_CFLAGS) +LDFLAGS += $(DRV_WPA_LDFLAGS) +LIBS += $(DRV_WPA_LIBS) endif ifndef CONFIG_L2_PACKET @@ -276,7 +217,7 @@ EAPDYN += ../src/eap_peer/eap_tls.so else CFLAGS += -DEAP_TLS OBJS += ../src/eap_peer/eap_tls.o -OBJS_h += ../src/eap_server/eap_tls.o +OBJS_h += ../src/eap_server/eap_server_tls.o endif TLS_FUNCS=y CONFIG_IEEE8021X_EAPOL=y @@ -291,7 +232,7 @@ else CFLAGS += -DEAP_PEAP OBJS += ../src/eap_peer/eap_peap.o OBJS += ../src/eap_common/eap_peap_common.o -OBJS_h += ../src/eap_server/eap_peap.o +OBJS_h += ../src/eap_server/eap_server_peap.o endif TLS_FUNCS=y CONFIG_IEEE8021X_EAPOL=y @@ -305,7 +246,7 @@ EAPDYN += ../src/eap_peer/eap_ttls.so else CFLAGS += -DEAP_TTLS OBJS += ../src/eap_peer/eap_ttls.o -OBJS_h += ../src/eap_server/eap_ttls.o +OBJS_h += ../src/eap_server/eap_server_ttls.o endif MS_FUNCS=y TLS_FUNCS=y @@ -321,7 +262,7 @@ EAPDYN += ../src/eap_peer/eap_md5.so else CFLAGS += -DEAP_MD5 OBJS += ../src/eap_peer/eap_md5.o -OBJS_h += ../src/eap_server/eap_md5.o +OBJS_h += ../src/eap_server/eap_server_md5.o endif CHAP=y CONFIG_IEEE8021X_EAPOL=y @@ -344,7 +285,7 @@ else CFLAGS += -DEAP_MSCHAPv2 OBJS += ../src/eap_peer/eap_mschapv2.o OBJS += ../src/eap_peer/mschapv2.o -OBJS_h += ../src/eap_server/eap_mschapv2.o +OBJS_h += ../src/eap_server/eap_server_mschapv2.o endif MS_FUNCS=y CONFIG_IEEE8021X_EAPOL=y @@ -358,7 +299,7 @@ EAPDYN += ../src/eap_peer/eap_gtc.so else CFLAGS += -DEAP_GTC OBJS += ../src/eap_peer/eap_gtc.o -OBJS_h += ../src/eap_server/eap_gtc.o +OBJS_h += ../src/eap_server/eap_server_gtc.o endif CONFIG_IEEE8021X_EAPOL=y endif @@ -383,10 +324,11 @@ EAPDYN += ../src/eap_peer/eap_sim.so else CFLAGS += -DEAP_SIM OBJS += ../src/eap_peer/eap_sim.o -OBJS_h += ../src/eap_server/eap_sim.o +OBJS_h += ../src/eap_server/eap_server_sim.o endif CONFIG_IEEE8021X_EAPOL=y CONFIG_EAP_SIM_COMMON=y +NEED_AES_CBC=y endif ifdef CONFIG_EAP_LEAP @@ -410,10 +352,13 @@ EAPDYN += ../src/eap_peer/eap_psk.so else CFLAGS += -DEAP_PSK OBJS += ../src/eap_peer/eap_psk.o ../src/eap_common/eap_psk_common.o -OBJS_h += ../src/eap_server/eap_psk.o +OBJS_h += ../src/eap_server/eap_server_psk.o endif CONFIG_IEEE8021X_EAPOL=y NEED_AES=y +NEED_AES_OMAC1=y +NEED_AES_ENCBLOCK=y +NEED_AES_EAX=y endif ifdef CONFIG_EAP_AKA @@ -424,10 +369,11 @@ EAPDYN += ../src/eap_peer/eap_aka.so else CFLAGS += -DEAP_AKA OBJS += ../src/eap_peer/eap_aka.o -OBJS_h += ../src/eap_server/eap_aka.o +OBJS_h += ../src/eap_server/eap_server_aka.o endif CONFIG_IEEE8021X_EAPOL=y CONFIG_EAP_SIM_COMMON=y +NEED_AES_CBC=y endif ifdef CONFIG_EAP_AKA_PRIME @@ -457,7 +403,7 @@ else CFLAGS += -DEAP_FAST OBJS += ../src/eap_peer/eap_fast.o ../src/eap_peer/eap_fast_pac.o OBJS += ../src/eap_common/eap_fast_common.o -OBJS_h += ../src/eap_server/eap_fast.o +OBJS_h += ../src/eap_server/eap_server_fast.o endif TLS_FUNCS=y CONFIG_IEEE8021X_EAPOL=y @@ -472,7 +418,7 @@ EAPDYN += ../src/eap_peer/eap_pax.so else CFLAGS += -DEAP_PAX OBJS += ../src/eap_peer/eap_pax.o ../src/eap_common/eap_pax_common.o -OBJS_h += ../src/eap_server/eap_pax.o +OBJS_h += ../src/eap_server/eap_server_pax.o endif CONFIG_IEEE8021X_EAPOL=y endif @@ -485,7 +431,7 @@ EAPDYN += ../src/eap_peer/eap_sake.so else CFLAGS += -DEAP_SAKE OBJS += ../src/eap_peer/eap_sake.o ../src/eap_common/eap_sake_common.o -OBJS_h += ../src/eap_server/eap_sake.o +OBJS_h += ../src/eap_server/eap_server_sake.o endif CONFIG_IEEE8021X_EAPOL=y endif @@ -498,13 +444,14 @@ EAPDYN += ../src/eap_peer/eap_gpsk.so else CFLAGS += -DEAP_GPSK OBJS += ../src/eap_peer/eap_gpsk.o ../src/eap_common/eap_gpsk_common.o -OBJS_h += ../src/eap_server/eap_gpsk.o +OBJS_h += ../src/eap_server/eap_server_gpsk.o endif CONFIG_IEEE8021X_EAPOL=y ifdef CONFIG_EAP_GPSK_SHA256 CFLAGS += -DEAP_GPSK_SHA256 endif NEED_SHA256=y +NEED_AES_OMAC1=y endif ifdef CONFIG_WPS @@ -521,13 +468,46 @@ OBJS += ../src/wps/wps_attr_process.o OBJS += ../src/wps/wps_dev_attr.o OBJS += ../src/wps/wps_enrollee.o OBJS += ../src/wps/wps_registrar.o -OBJS_h += ../src/eap_server/eap_wsc.o +OBJS_h += ../src/eap_server/eap_server_wsc.o CONFIG_IEEE8021X_EAPOL=y NEED_DH_GROUPS=y NEED_SHA256=y NEED_BASE64=y -NEED_CRYPTO=y NEED_80211_COMMON=y +NEED_AES_CBC=y +NEED_MODEXP=y + +ifdef CONFIG_WPS_UFD +CFLAGS += -DCONFIG_WPS_UFD +OBJS += ../src/wps/wps_ufd.o +NEED_WPS_OOB=y +endif + +ifdef CONFIG_WPS_NFC +CFLAGS += -DCONFIG_WPS_NFC +OBJS += ../src/wps/ndef.o +OBJS += ../src/wps/wps_nfc.o +NEED_WPS_OOB=y +ifdef CONFIG_WPS_NFC_PN531 +PN531_PATH ?= /usr/local/src/nfc +CFLAGS += -DCONFIG_WPS_NFC_PN531 +CFLAGS += -I${PN531_PATH}/inc +OBJS += ../src/wps/wps_nfc_pn531.o +LIBS += ${PN531_PATH}/lib/wpsnfc.dll +LIBS += ${PN531_PATH}/lib/libnfc_mapping_pn53x.dll +endif +endif + +ifdef NEED_WPS_OOB +CFLAGS += -DCONFIG_WPS_OOB +endif + +ifdef CONFIG_WPS_ER +CONFIG_WPS_UPNP=y +CFLAGS += -DCONFIG_WPS_ER +OBJS += ../src/wps/wps_er.o +OBJS += ../src/wps/wps_er_ssdp.o +endif ifdef CONFIG_WPS_UPNP CFLAGS += -DCONFIG_WPS_UPNP @@ -535,7 +515,11 @@ OBJS += ../src/wps/wps_upnp.o OBJS += ../src/wps/wps_upnp_ssdp.o OBJS += ../src/wps/wps_upnp_web.o OBJS += ../src/wps/wps_upnp_event.o +OBJS += ../src/wps/wps_upnp_ap.o +OBJS += ../src/wps/upnp_xml.o OBJS += ../src/wps/httpread.o +OBJS += ../src/wps/http_client.o +OBJS += ../src/wps/http_server.o endif endif @@ -550,12 +534,14 @@ else CFLAGS += -DEAP_IKEV2 OBJS += ../src/eap_peer/eap_ikev2.o ../src/eap_peer/ikev2.o OBJS += ../src/eap_common/eap_ikev2_common.o ../src/eap_common/ikev2_common.o -OBJS_h += ../src/eap_server/eap_ikev2.o +OBJS_h += ../src/eap_server/eap_server_ikev2.o OBJS_h += ../src/eap_server/ikev2.o endif CONFIG_IEEE8021X_EAPOL=y NEED_DH_GROUPS=y NEED_DH_GROUPS_ALL=y +NEED_MODEXP=y +NEED_CIPHER=y endif ifdef CONFIG_EAP_VENDOR_TEST @@ -565,7 +551,7 @@ EAPDYN += ../src/eap_peer/eap_vendor_test.so else CFLAGS += -DEAP_VENDOR_TEST OBJS += ../src/eap_peer/eap_vendor_test.o -OBJS_h += ../src/eap_server/eap_vendor_test.o +OBJS_h += ../src/eap_server/eap_server_vendor_test.o endif CONFIG_IEEE8021X_EAPOL=y endif @@ -575,6 +561,8 @@ ifdef CONFIG_EAP_TNC CFLAGS += -DEAP_TNC OBJS += ../src/eap_peer/eap_tnc.o OBJS += ../src/eap_peer/tncc.o +OBJS_h += ../src/eap_server/eap_server_tnc.o +OBJS_h += ../src/eap_server/tncs.o NEED_BASE64=y ifndef CONFIG_NATIVE_WINDOWS ifndef CONFIG_DRIVER_BSD @@ -586,18 +574,88 @@ endif ifdef CONFIG_IEEE8021X_EAPOL # IEEE 802.1X/EAPOL state machines (e.g., for RADIUS authentication) CFLAGS += -DIEEE8021X_EAPOL -OBJS += ../src/eapol_supp/eapol_supp_sm.o ../src/eap_peer/eap.o ../src/eap_common/eap_common.o ../src/eap_peer/eap_methods.o +OBJS += ../src/eapol_supp/eapol_supp_sm.o +OBJS += ../src/eap_peer/eap.o ../src/eap_peer/eap_methods.o +NEED_EAP_COMMON=y ifdef CONFIG_DYNAMIC_EAP_METHODS CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS LIBS += -ldl -rdynamic endif endif +ifdef CONFIG_AP +NEED_80211_COMMON=y +NEED_EAP_COMMON=y +NEED_RSN_AUTHENTICATOR=y +CFLAGS += -DCONFIG_AP +OBJS += ap.o +CFLAGS += -DCONFIG_NO_RADIUS +CFLAGS += -DCONFIG_NO_ACCOUNTING +CFLAGS += -DCONFIG_NO_VLAN +OBJS += ../src/ap/hostapd.o +OBJS += ../src/ap/wpa_auth_glue.o +OBJS += ../src/ap/utils.o +OBJS += ../src/ap/authsrv.o +OBJS += ../src/ap/ap_config.o +OBJS += ../src/utils/ip_addr.o +OBJS += ../src/ap/sta_info.o +OBJS += ../src/ap/tkip_countermeasures.o +OBJS += ../src/ap/ap_mlme.o +OBJS += ../src/ap/ieee802_1x.o +OBJS += ../src/eapol_auth/eapol_auth_sm.o +OBJS += ../src/ap/ieee802_11_auth.o +OBJS += ../src/ap/drv_callbacks.o +OBJS += ../src/ap/ap_drv_ops.o +ifdef CONFIG_CTRL_IFACE +OBJS += ../src/ap/ctrl_iface_ap.o +endif + +CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY +OBJS += ../src/eap_server/eap_server.o +OBJS += ../src/eap_server/eap_server_identity.o +OBJS += ../src/eap_server/eap_server_methods.o + +ifdef CONFIG_IEEE80211N +CFLAGS += -DCONFIG_IEEE80211N +endif + +ifdef NEED_AP_MLME +OBJS += ../src/ap/beacon.o +OBJS += ../src/ap/wmm.o +OBJS += ../src/ap/ap_list.o +OBJS += ../src/ap/ieee802_11.o +OBJS += ../src/ap/hw_features.o +ifdef CONFIG_IEEE80211N +OBJS += ../src/ap/ieee802_11_ht.o +endif +CFLAGS += -DNEED_AP_MLME +endif +ifdef CONFIG_WPS +CFLAGS += -DEAP_SERVER_WSC +OBJS += ../src/ap/wps_hostapd.o +OBJS += ../src/eap_server/eap_server_wsc.o +endif +endif + +ifdef NEED_RSN_AUTHENTICATOR +CFLAGS += -DCONFIG_NO_RADIUS +NEED_AES_WRAP=y +OBJS += ../src/ap/wpa_auth.o +OBJS += ../src/ap/wpa_auth_ie.o +OBJS += ../src/ap/pmksa_cache_auth.o +ifdef CONFIG_IEEE80211R +OBJS += ../src/ap/wpa_auth_ft.o +endif +ifdef CONFIG_PEERKEY +OBJS += ../src/ap/peerkey_auth.o +endif +endif + ifdef CONFIG_EAP_SERVER CFLAGS += -DEAP_SERVER -OBJS_h += ../src/eap_server/eap.o -OBJS_h += ../src/eap_server/eap_identity.o -OBJS_h += ../src/eap_server/eap_methods.o +OBJS_h += ../src/eap_server/eap_server.o +OBJS_h += ../src/eap_server/eap_server_identity.o +OBJS_h += ../src/eap_server/eap_server_methods.o endif ifdef CONFIG_RADIUS_CLIENT @@ -607,18 +665,19 @@ OBJS_h += ../src/radius/radius_client.o endif ifdef CONFIG_AUTHENTICATOR -OBJS_h += ../hostapd/eapol_sm.o -OBJS_h += ../hostapd/ieee802_1x.o +OBJS_h += ../src/eapol_auth/eapol_auth_sm.o +OBJS_h += ../src/ap/ieee802_1x.o endif ifdef CONFIG_WPA_AUTHENTICATOR -OBJS_h += ../hostapd/wpa.o -OBJS_h += ../hostapd/wpa_auth_ie.o +OBJS_h += ../src/ap/wpa_auth.o +OBJS_h += ../src/ap/wpa_auth_ie.o +OBJS_h += ../src/ap/pmksa_cache_auth.o ifdef CONFIG_IEEE80211R -OBJS_h += ../hostapd/wpa_ft.o +OBJS_h += ../src/ap/wpa_auth_ft.o endif ifdef CONFIG_PEERKEY -OBJS_h += ../hostapd/peerkey.o +OBJS_h += ../src/ap/peerkey_auth.o endif endif @@ -647,149 +706,152 @@ NEED_MILENAGE=y endif ifdef NEED_MILENAGE -OBJS += ../src/hlr_auc_gw/milenage.o +OBJS += ../src/crypto/milenage.o endif -ifndef CONFIG_TLS -CONFIG_TLS=openssl +ifdef CONFIG_PKCS12 +CFLAGS += -DPKCS12_FUNCS endif -ifeq ($(CONFIG_TLS), internal) -ifndef CONFIG_CRYPTO -CONFIG_CRYPTO=internal -endif -endif -ifeq ($(CONFIG_CRYPTO), libtomcrypt) -CFLAGS += -DCONFIG_INTERNAL_X509 +ifdef CONFIG_SMARTCARD +CFLAGS += -DCONFIG_SMARTCARD endif -ifeq ($(CONFIG_CRYPTO), internal) -CFLAGS += -DCONFIG_INTERNAL_X509 + +ifdef MS_FUNCS +OBJS += ../src/crypto/ms_funcs.o +NEED_DES=y +NEED_MD4=y endif +ifdef CHAP +OBJS += ../src/eap_common/chap.o +endif ifdef TLS_FUNCS +NEED_DES=y # Shared TLS functions (needed for EAP_TLS, EAP_PEAP, EAP_TTLS, and EAP_FAST) -CFLAGS += -DEAP_TLS_FUNCS OBJS += ../src/eap_peer/eap_tls_common.o -OBJS_h += ../src/eap_server/eap_tls_common.o +OBJS_h += ../src/eap_server/eap_server_tls_common.o NEED_TLS_PRF=y +endif + +ifndef CONFIG_TLS +CONFIG_TLS=openssl +endif + ifeq ($(CONFIG_TLS), openssl) +ifdef TLS_FUNCS CFLAGS += -DEAP_TLS_OPENSSL OBJS += ../src/crypto/tls_openssl.o -LIBS += -lssl -lcrypto +LIBS += -lssl +endif +OBJS += ../src/crypto/crypto_openssl.o +OBJS_p += ../src/crypto/crypto_openssl.o +ifdef NEED_FIPS186_2_PRF +OBJS += ../src/crypto/fips_prf_openssl.o +endif +LIBS += -lcrypto LIBS_p += -lcrypto endif + ifeq ($(CONFIG_TLS), gnutls) +ifdef TLS_FUNCS OBJS += ../src/crypto/tls_gnutls.o -LIBS += -lgnutls -lgcrypt -lgpg-error -LIBS_p += -lgcrypt +LIBS += -lgnutls -lgpg-error ifdef CONFIG_GNUTLS_EXTRA CFLAGS += -DCONFIG_GNUTLS_EXTRA LIBS += -lgnutls-extra endif endif -ifeq ($(CONFIG_TLS), schannel) -OBJS += ../src/crypto/tls_schannel.o -endif -ifeq ($(CONFIG_TLS), internal) -OBJS += ../src/crypto/tls_internal.o -OBJS += ../src/tls/tlsv1_common.o ../src/tls/tlsv1_record.o -OBJS += ../src/tls/tlsv1_cred.o ../src/tls/tlsv1_client.o -OBJS += ../src/tls/tlsv1_client_write.o ../src/tls/tlsv1_client_read.o -OBJS += ../src/tls/asn1.o ../src/tls/rsa.o ../src/tls/x509v3.o -OBJS_p += ../src/tls/asn1.o ../src/tls/rsa.o -OBJS_p += ../src/crypto/rc4.o ../src/crypto/aes_wrap.o ../src/crypto/aes.o -NEED_BASE64=y -NEED_TLS_PRF=y -CFLAGS += -DCONFIG_TLS_INTERNAL -CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT -ifeq ($(CONFIG_CRYPTO), internal) -endif -ifeq ($(CONFIG_CRYPTO), libtomcrypt) -LIBS += -ltomcrypt -ltfm -LIBS_p += -ltomcrypt -ltfm -endif +OBJS += ../src/crypto/crypto_gnutls.o +OBJS_p += ../src/crypto/crypto_gnutls.o +ifdef NEED_FIPS186_2_PRF +OBJS += ../src/crypto/fips_prf_gnutls.o endif -ifeq ($(CONFIG_TLS), none) -OBJS += ../src/crypto/tls_none.o -CFLAGS += -DEAP_TLS_NONE -CONFIG_INTERNAL_AES=y -CONFIG_INTERNAL_SHA1=y -CONFIG_INTERNAL_MD5=y +LIBS += -lgcrypt +LIBS_p += -lgcrypt CONFIG_INTERNAL_SHA256=y -endif -ifdef CONFIG_SMARTCARD -ifndef CONFIG_NATIVE_WINDOWS -ifneq ($(CONFIG_L2_PACKET), freebsd) -LIBS += -ldl -endif -endif -endif -NEED_CRYPTO=y -else -OBJS += ../src/crypto/tls_none.o +CONFIG_INTERNAL_RC4=y +CONFIG_INTERNAL_DH_GROUP5=y endif -ifdef CONFIG_PKCS12 -CFLAGS += -DPKCS12_FUNCS -endif - -ifdef CONFIG_SMARTCARD -CFLAGS += -DCONFIG_SMARTCARD +ifeq ($(CONFIG_TLS), schannel) +ifdef TLS_FUNCS +OBJS += ../src/crypto/tls_schannel.o endif - -ifdef MS_FUNCS -OBJS += ../src/crypto/ms_funcs.o -NEED_CRYPTO=y +OBJS += ../src/crypto/crypto_cryptoapi.o +OBJS_p += ../src/crypto/crypto_cryptoapi.o +ifdef NEED_FIPS186_2_PRF +OBJS += ../src/crypto/fips_prf_cryptoapi.o endif - -ifdef CHAP -OBJS += ../src/eap_common/chap.o +CONFIG_INTERNAL_SHA256=y +CONFIG_INTERNAL_RC4=y +CONFIG_INTERNAL_DH_GROUP5=y endif -ifdef NEED_CRYPTO -ifndef TLS_FUNCS -ifeq ($(CONFIG_TLS), openssl) -LIBS += -lcrypto -LIBS_p += -lcrypto +ifeq ($(CONFIG_TLS), nss) +ifdef TLS_FUNCS +OBJS += ../src/crypto/tls_nss.o +LIBS += -lssl3 endif -ifeq ($(CONFIG_TLS), gnutls) -LIBS += -lgcrypt -LIBS_p += -lgcrypt +OBJS += ../src/crypto/crypto_nss.o +OBJS_p += ../src/crypto/crypto_nss.o +ifdef NEED_FIPS186_2_PRF +OBJS += ../src/crypto/fips_prf_nss.o endif -ifeq ($(CONFIG_TLS), schannel) +LIBS += -lnss3 +LIBS_p += -lnss3 +CONFIG_INTERNAL_MD4=y +CONFIG_INTERNAL_DH_GROUP5=y endif + ifeq ($(CONFIG_TLS), internal) -ifeq ($(CONFIG_CRYPTO), libtomcrypt) -LIBS += -ltomcrypt -ltfm -LIBS_p += -ltomcrypt -ltfm -endif -endif +ifndef CONFIG_CRYPTO +CONFIG_CRYPTO=internal endif -ifeq ($(CONFIG_TLS), openssl) -OBJS += ../src/crypto/crypto_openssl.o -OBJS_p += ../src/crypto/crypto_openssl.o -CONFIG_INTERNAL_SHA256=y +ifdef TLS_FUNCS +OBJS += ../src/crypto/crypto_internal-rsa.o +OBJS += ../src/crypto/tls_internal.o +OBJS += ../src/tls/tlsv1_common.o +OBJS += ../src/tls/tlsv1_record.o +OBJS += ../src/tls/tlsv1_cred.o +OBJS += ../src/tls/tlsv1_client.o +OBJS += ../src/tls/tlsv1_client_write.o +OBJS += ../src/tls/tlsv1_client_read.o +OBJS += ../src/tls/asn1.o +OBJS += ../src/tls/rsa.o +OBJS += ../src/tls/x509v3.o +OBJS += ../src/tls/pkcs1.o +OBJS += ../src/tls/pkcs5.o +OBJS += ../src/tls/pkcs8.o +NEED_SHA256=y +NEED_BASE64=y +NEED_TLS_PRF=y +NEED_MODEXP=y +NEED_CIPHER=y +CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT endif -ifeq ($(CONFIG_TLS), gnutls) -OBJS += ../src/crypto/crypto_gnutls.o -OBJS_p += ../src/crypto/crypto_gnutls.o -CONFIG_INTERNAL_SHA256=y +ifdef NEED_CIPHER +NEED_DES=y +OBJS += ../src/crypto/crypto_internal-cipher.o endif -ifeq ($(CONFIG_TLS), schannel) -OBJS += ../src/crypto/crypto_cryptoapi.o -OBJS_p += ../src/crypto/crypto_cryptoapi.o -CONFIG_INTERNAL_SHA256=y +ifdef NEED_MODEXP +OBJS += ../src/crypto/crypto_internal-modexp.o +OBJS += ../src/tls/bignum.o endif -ifeq ($(CONFIG_TLS), internal) ifeq ($(CONFIG_CRYPTO), libtomcrypt) OBJS += ../src/crypto/crypto_libtomcrypt.o OBJS_p += ../src/crypto/crypto_libtomcrypt.o +LIBS += -ltomcrypt -ltfm +LIBS_p += -ltomcrypt -ltfm CONFIG_INTERNAL_SHA256=y +CONFIG_INTERNAL_RC4=y +CONFIG_INTERNAL_DH_GROUP5=y endif ifeq ($(CONFIG_CRYPTO), internal) -OBJS += ../src/crypto/crypto_internal.o ../src/tls/bignum.o -OBJS_p += ../src/crypto/crypto_internal.o ../src/tls/bignum.o +OBJS += ../src/crypto/crypto_internal.o +OBJS_p += ../src/crypto/crypto_internal.o +NEED_AES_ENC=y CFLAGS += -DCONFIG_CRYPTO_INTERNAL ifdef CONFIG_INTERNAL_LIBTOMMATH CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH @@ -806,60 +868,159 @@ CONFIG_INTERNAL_SHA1=y CONFIG_INTERNAL_MD4=y CONFIG_INTERNAL_MD5=y CONFIG_INTERNAL_SHA256=y +CONFIG_INTERNAL_RC4=y +CONFIG_INTERNAL_DH_GROUP5=y endif ifeq ($(CONFIG_CRYPTO), cryptoapi) OBJS += ../src/crypto/crypto_cryptoapi.o OBJS_p += ../src/crypto/crypto_cryptoapi.o CFLAGS += -DCONFIG_CRYPTO_CRYPTOAPI CONFIG_INTERNAL_SHA256=y +CONFIG_INTERNAL_RC4=y endif endif + ifeq ($(CONFIG_TLS), none) +ifdef TLS_FUNCS +OBJS += ../src/crypto/tls_none.o +CFLAGS += -DEAP_TLS_NONE +CONFIG_INTERNAL_AES=y +CONFIG_INTERNAL_SHA1=y +CONFIG_INTERNAL_MD5=y +endif OBJS += ../src/crypto/crypto_none.o OBJS_p += ../src/crypto/crypto_none.o CONFIG_INTERNAL_SHA256=y +CONFIG_INTERNAL_RC4=y endif -else + +ifdef TLS_FUNCS +ifdef CONFIG_SMARTCARD +ifndef CONFIG_NATIVE_WINDOWS +ifneq ($(CONFIG_L2_PACKET), freebsd) +LIBS += -ldl +endif +endif +endif +endif + +ifndef TLS_FUNCS +OBJS += ../src/crypto/tls_none.o +ifeq ($(CONFIG_TLS), internal) CONFIG_INTERNAL_AES=y CONFIG_INTERNAL_SHA1=y CONFIG_INTERNAL_MD5=y +CONFIG_INTERNAL_RC4=y +endif endif +AESOBJS = # none so far (see below) ifdef CONFIG_INTERNAL_AES -CFLAGS += -DINTERNAL_AES +AESOBJS += ../src/crypto/aes-internal.o ../src/crypto/aes-internal-dec.o +endif + +AESOBJS += ../src/crypto/aes-unwrap.o +ifdef NEED_AES_EAX +AESOBJS += ../src/crypto/aes-eax.o +NEED_AES_CTR=y +endif +ifdef NEED_AES_CTR +AESOBJS += ../src/crypto/aes-ctr.o +endif +ifdef NEED_AES_ENCBLOCK +AESOBJS += ../src/crypto/aes-encblock.o +endif +ifdef NEED_AES_OMAC1 +NEED_AES_ENC=y +AESOBJS += ../src/crypto/aes-omac1.o endif +ifdef NEED_AES_WRAP +NEED_AES_ENC=y +AESOBJS += ../src/crypto/aes-wrap.o +endif +ifdef NEED_AES_CBC +NEED_AES_ENC=y +AESOBJS += ../src/crypto/aes-cbc.o +endif +ifdef NEED_AES_ENC +ifdef CONFIG_INTERNAL_AES +AESOBJS += ../src/crypto/aes-internal-enc.o +endif +endif +ifdef NEED_AES +OBJS += $(AESOBJS) +endif + +ifdef NEED_SHA1 +SHA1OBJS += ../src/crypto/sha1.o ifdef CONFIG_INTERNAL_SHA1 -CFLAGS += -DINTERNAL_SHA1 +SHA1OBJS += ../src/crypto/sha1-internal.o +ifdef NEED_FIPS186_2_PRF +SHA1OBJS += ../src/crypto/fips_prf_internal.o endif -ifdef CONFIG_INTERNAL_SHA256 -CFLAGS += -DINTERNAL_SHA256 endif +ifndef CONFIG_NO_WPA_PASSPHRASE +SHA1OBJS += ../src/crypto/sha1-pbkdf2.o +endif +ifdef NEED_T_PRF +SHA1OBJS += ../src/crypto/sha1-tprf.o +endif +ifdef NEED_TLS_PRF +SHA1OBJS += ../src/crypto/sha1-tlsprf.o +endif +endif + +MD5OBJS = ../src/crypto/md5.o +ifdef NEED_MD5 ifdef CONFIG_INTERNAL_MD5 -CFLAGS += -DINTERNAL_MD5 +MD5OBJS += ../src/crypto/md5-internal.o endif +ifdef CONFIG_FIPS +MD5OBJS += ../src/crypto/md5-non-fips.o +endif +OBJS += $(MD5OBJS) +OBJS_p += $(MD5OBJS) +endif + +ifdef NEED_MD4 ifdef CONFIG_INTERNAL_MD4 -CFLAGS += -DINTERNAL_MD4 +OBJS += ../src/crypto/md4-internal.o endif -ifdef CONFIG_INTERNAL_DES -CFLAGS += -DINTERNAL_DES endif -ifdef CONFIG_IEEE80211R -NEED_SHA256=y +DESOBJS = # none needed when not internal +ifdef NEED_DES +ifdef CONFIG_INTERNAL_DES +DESOBJS += ../src/crypto/des-internal.o +endif endif -ifdef CONFIG_IEEE80211W -CFLAGS += -DCONFIG_IEEE80211W -NEED_SHA256=y +ifdef NEED_RC4 +ifdef CONFIG_INTERNAL_RC4 +OBJS += ../src/crypto/rc4.o +endif endif +SHA256OBJS = # none by default ifdef NEED_SHA256 -OBJS += ../src/crypto/sha256.o -CFLAGS += -DNEED_SHA256 +CFLAGS += -DCONFIG_SHA256 +SHA256OBJS += ../src/crypto/sha256.o +ifdef CONFIG_INTERNAL_SHA256 +SHA256OBJS += ../src/crypto/sha256-internal.o +endif +OBJS += $(SHA256OBJS) endif -ifdef CONFIG_WIRELESS_EXTENSION -OBJS_d += ../src/drivers/driver_wext.o +ifdef NEED_DH_GROUPS +OBJS += ../src/crypto/dh_groups.o +endif +ifdef NEED_DH_GROUPS_ALL +CFLAGS += -DALL_DH_GROUPS +endif +ifdef CONFIG_INTERNAL_DH_GROUP5 +ifdef NEED_DH_GROUPS +OBJS += ../src/crypto/dh_group5.o +endif endif ifdef CONFIG_CTRL_IFACE @@ -884,12 +1045,16 @@ OBJS += ctrl_iface.o ctrl_iface_$(CONFIG_CTRL_IFACE).o endif ifdef CONFIG_CTRL_IFACE_DBUS -CFLAGS += -DCONFIG_CTRL_IFACE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE -OBJS += ctrl_iface_dbus.o ctrl_iface_dbus_handlers.o dbus_dict_helpers.o +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 -LIBS += $(DBUS_LIBS) ifndef DBUS_INCLUDE DBUS_INCLUDE := $(shell pkg-config --cflags dbus-1) endif @@ -904,9 +1069,40 @@ DBUS_VERSION_MINOR=0 endif DBUS_INCLUDE += -DDBUS_VERSION_MAJOR=$(DBUS_VERSION_MAJOR) DBUS_INCLUDE += -DDBUS_VERSION_MINOR=$(DBUS_VERSION_MINOR) -CFLAGS += $(DBUS_INCLUDE) +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.o +DBUS_OBJS += dbus/dbus_new_helpers.o +DBUS_OBJS += dbus/dbus_new.o dbus/dbus_new_handlers.o +ifdef CONFIG_WPS +DBUS_OBJS += dbus/dbus_new_handlers_wps.o +endif +ifndef DBUS_LIBS +DBUS_LIBS := $(shell pkg-config --libs dbus-1) +endif +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) +endif + +ifdef DBUS +DBUS_CFLAGS += -DCONFIG_DBUS +DBUS_OBJS += dbus/dbus_common.o +endif + +OBJS += $(DBUS_OBJS) +CFLAGS += $(DBUS_CFLAGS) +LIBS += $(DBUS_LIBS) + ifdef CONFIG_READLINE CFLAGS += -DCONFIG_READLINE LIBS_c += -lncurses -lreadline @@ -934,73 +1130,28 @@ ifdef CONFIG_IPV6 CFLAGS += -DCONFIG_IPV6 endif -ifdef CONFIG_PEERKEY -CFLAGS += -DCONFIG_PEERKEY -endif - -ifdef CONFIG_IEEE80211R -CFLAGS += -DCONFIG_IEEE80211R -OBJS += ../src/rsn_supp/wpa_ft.o -endif - -ifndef CONFIG_NO_WPA -OBJS += ../src/rsn_supp/wpa.o -OBJS += ../src/rsn_supp/preauth.o -OBJS += ../src/rsn_supp/pmksa_cache.o -OBJS += ../src/rsn_supp/peerkey.o -OBJS += ../src/rsn_supp/wpa_ie.o -OBJS += ../src/common/wpa_common.o -NEED_AES=y -else -CFLAGS += -DCONFIG_NO_WPA -DCONFIG_NO_WPA2 -endif - -ifdef CONFIG_NO_WPA2 -CFLAGS += -DCONFIG_NO_WPA2 -endif - -ifdef CONFIG_NO_WPA_PASSPHRASE -CFLAGS += -DCONFIG_NO_PBKDF2 -endif - -ifdef CONFIG_NO_AES_EXTRAS -CFLAGS += -DCONFIG_NO_AES_WRAP -CFLAGS += -DCONFIG_NO_AES_CTR -DCONFIG_NO_AES_OMAC1 -CFLAGS += -DCONFIG_NO_AES_EAX -DCONFIG_NO_AES_CBC -CFLAGS += -DCONFIG_NO_AES_ENCRYPT -CFLAGS += -DCONFIG_NO_AES_ENCRYPT_BLOCK -endif - -ifdef NEED_AES -OBJS += ../src/crypto/aes_wrap.o ../src/crypto/aes.o -endif - -ifdef NEED_DH_GROUPS -OBJS += ../src/crypto/dh_groups.o -ifdef NEED_DH_GROUPS_ALL -CFLAGS += -DALL_DH_GROUPS -endif -endif - -ifndef NEED_FIPS186_2_PRF -CFLAGS += -DCONFIG_NO_FIPS186_2_PRF +ifdef NEED_BASE64 +OBJS += ../src/utils/base64.o endif -ifndef NEED_T_PRF -CFLAGS += -DCONFIG_NO_T_PRF +ifdef NEED_SME +NEED_80211_COMMON=y +OBJS += sme.o +CFLAGS += -DCONFIG_SME endif -ifndef NEED_TLS_PRF -CFLAGS += -DCONFIG_NO_TLS_PRF +ifdef CONFIG_CLIENT_MLME +OBJS += mlme.o +CFLAGS += -DCONFIG_CLIENT_MLME +NEED_80211_COMMON=y endif -ifdef NEED_BASE64 -OBJS += ../src/utils/base64.o +ifdef NEED_80211_COMMON +OBJS += ../src/common/ieee802_11_common.o endif -ifdef CONFIG_CLIENT_MLME -OBJS += mlme.o ../src/common/ieee802_11_common.o -CFLAGS += -DCONFIG_CLIENT_MLME +ifdef NEED_EAP_COMMON +OBJS += ../src/eap_common/eap_common.o endif ifndef CONFIG_MAIN @@ -1019,7 +1170,24 @@ ifdef CONFIG_DELAYED_MIC_ERROR_REPORT CFLAGS += -DCONFIG_DELAYED_MIC_ERROR_REPORT endif -OBJS += ../src/drivers/scan_helpers.o +ifdef CONFIG_FIPS +CFLAGS += -DCONFIG_FIPS +endif + +OBJS += $(SHA1OBJS) $(DESOBJS) + +OBJS_p += $(SHA1OBJS) + +ifdef CONFIG_BGSCAN_SIMPLE +CFLAGS += -DCONFIG_BGSCAN_SIMPLE +OBJS += bgscan_simple.o +NEED_BGSCAN=y +endif + +ifdef NEED_BGSCAN +CFLAGS += -DCONFIG_BGSCAN +OBJS += bgscan.o +endif OBJS_wpa_rm := ctrl_iface.o mlme.o ctrl_iface_unix.o OBJS_wpa := $(filter-out $(OBJS_wpa_rm),$(OBJS)) $(OBJS_h) tests/test_wpa.o @@ -1028,13 +1196,17 @@ OBJS_wpa += tests/link_test.o endif OBJS_wpa += $(OBJS_l2) OBJS += wpa_supplicant.o events.o blacklist.o wpas_glue.o scan.o -OBJS_t := $(OBJS) $(OBJS_l2) eapol_test.o ../src/radius/radius.o ../src/radius/radius_client.o +OBJS_t := $(OBJS) $(OBJS_l2) eapol_test.o +OBJS_t += ../src/radius/radius_client.o +OBJS_t += ../src/radius/radius.o +ifndef CONFIG_AP OBJS_t += ../src/utils/ip_addr.o +endif OBJS_t2 := $(OBJS) $(OBJS_l2) preauth_test.o OBJS += $(CONFIG_MAIN).o ifdef CONFIG_PRIVSEP -OBJS_priv += $(OBJS_d) ../src/drivers/drivers.o ../src/drivers/scan_helpers.o +OBJS_priv += $(OBJS_d) ../src/drivers/drivers.o OBJS_priv += $(OBJS_l2) OBJS_priv += ../src/utils/os_$(CONFIG_OS).o OBJS_priv += ../src/utils/$(CONFIG_ELOOP).o @@ -1043,14 +1215,17 @@ OBJS_priv += ../src/utils/wpa_debug.o OBJS_priv += ../src/utils/wpabuf.o OBJS_priv += wpa_priv.o ifdef CONFIG_DRIVER_TEST -OBJS_priv += ../src/crypto/sha1.o -OBJS_priv += ../src/crypto/md5.o +OBJS_priv += $(SHA1OBJS) +OBJS_priv += $(MD5OBJS) ifeq ($(CONFIG_TLS), openssl) OBJS_priv += ../src/crypto/crypto_openssl.o endif ifeq ($(CONFIG_TLS), gnutls) OBJS_priv += ../src/crypto/crypto_gnutls.o endif +ifeq ($(CONFIG_TLS), nss) +OBJS_priv += ../src/crypto/crypto_nss.o +endif ifeq ($(CONFIG_TLS), internal) ifeq ($(CONFIG_CRYPTO), libtomcrypt) OBJS_priv += ../src/crypto/crypto_libtomcrypt.o @@ -1084,10 +1259,18 @@ endif dynamic_eap_methods: $(EAPDYN) -wpa_priv: $(OBJS_priv) +../src/drivers/build.wpa_supplicant: + @if [ -f ../src/drivers/build.hostapd ]; then \ + $(MAKE) -C ../src/drivers clean; \ + fi + @touch ../src/drivers/build.wpa_supplicant + +BCHECK=../src/drivers/build.wpa_supplicant + +wpa_priv: $(BCHECK) $(OBJS_priv) $(LDO) $(LDFLAGS) -o wpa_priv $(OBJS_priv) $(LIBS) -wpa_supplicant: .config $(OBJS) $(EXTRA_progs) +wpa_supplicant: .config $(BCHECK) $(OBJS) $(EXTRA_progs) $(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) eapol_test: .config $(OBJS_t) @@ -1108,48 +1291,31 @@ link_test: $(OBJS) $(OBJS_h) tests/link_test.o test_wpa: $(OBJS_wpa) $(OBJS_h) $(LDO) $(LDFLAGS) -o test_wpa $(OBJS_wpa) $(LIBS) -OBJSa=../src/tls/asn1_test.o ../src/tls/asn1.o ../src/tls/x509v3.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_unix.o \ - ../src/crypto/crypto_$(CONFIG_CRYPTO).o ../src/crypto/md5.o ../src/crypto/sha1.o \ - ../src/crypto/rc4.o ../src/crypto/des.o ../src/crypto/aes_wrap.o \ - ../src/crypto/aes.o ../src/tls/bignum.o ../src/tls/rsa.o -asn1_test: $(OBJSa) - $(LDO) $(LDFLAGS) -o asn1_test $(OBJSa) - -OBJSx=tests/test_x509v3.o ../src/tls/asn1.o ../src/tls/x509v3.o \ - ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_unix.o \ - ../src/crypto/crypto_$(CONFIG_CRYPTO).o \ - ../src/crypto/md5.o ../src/crypto/sha1.o ../src/crypto/aes.o \ - ../src/crypto/rc4.o ../src/crypto/des.o ../src/crypto/aes_wrap.o \ - ../src/crypto/sha256.o \ - ../src/tls/bignum.o ../src/tls/rsa.o -test_x509v3: $(OBJSx) - $(LDO) $(LDFLAGS) -o test_x509v3 $(OBJSx) - win_if_list: win_if_list.c $(LDO) $(LDFLAGS) -o $@ win_if_list.c $(CFLAGS) $(LIBS_w) eap_psk.so: ../src/eap_peer/eap_psk.c ../src/eap_common/eap_psk_common.c - $(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ + $(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ -Deap_peer_psk_register=eap_peer_method_dynamic_init eap_pax.so: ../src/eap_peer/eap_pax.c ../src/eap_common/eap_pax_common.c - $(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ + $(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ -Deap_peer_pax_register=eap_peer_method_dynamic_init eap_sake.so: ../src/eap_peer/eap_sake.c ../src/eap_common/eap_sake_common.c - $(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ + $(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ -Deap_peer_sake_register=eap_peer_method_dynamic_init eap_wsc.so: ../src/eap_peer/eap_wsc.c ../src/eap_common/eap_wsc_common.c ../src/wps/wps.c - $(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ + $(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ -Deap_peer_wsc_register=eap_peer_method_dynamic_init eap_ikev2.so: ../src/eap_peer/eap_ikev2.c ../src/eap_peer/ikev2.c ../src/eap_common/eap_ikev2_common.o ../src/eap_common/ikev2_common.c - $(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ + $(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \ -Deap_peer_ikev2_register=eap_peer_method_dynamic_init %.so: %.c - $(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $< \ + $(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $< \ -D$(*F:eap_%=eap_peer_%)_register=eap_peer_method_dynamic_init Q=@ @@ -1188,81 +1354,27 @@ wpa_gui: wpa_gui/Makefile wpa_gui-qt4/Makefile: qmake -o wpa_gui-qt4/Makefile wpa_gui-qt4/wpa_gui.pro -wpa_gui-qt4: wpa_gui-qt4/Makefile +wpa_gui-qt4/lang/wpa_gui_de.qm: wpa_gui-qt4/lang/wpa_gui_de.ts + lrelease wpa_gui-qt4/wpa_gui.pro + +wpa_gui-qt4: wpa_gui-qt4/Makefile wpa_gui-qt4/lang/wpa_gui_de.qm $(MAKE) -C wpa_gui-qt4 -TEST_MS_FUNCS_OBJS = ../src/crypto/crypto_openssl.o ../src/crypto/sha1.o ../src/crypto/md5.o \ - ../src/utils/os_unix.o ../src/crypto/rc4.o tests/test_ms_funcs.o -test-ms_funcs: $(TEST_MS_FUNCS_OBJS) - $(LDO) $(LDFLAGS) -o $@ $(TEST_MS_FUNCS_OBJS) $(LIBS) -lcrypto - ./test-ms_funcs - rm test-ms_funcs - -TEST_SHA1_OBJS = ../src/crypto/sha1.o ../src/crypto/md5.o tests/test_sha1.o #../src/crypto/crypto_openssl.o -test-sha1: $(TEST_SHA1_OBJS) - $(LDO) $(LDFLAGS) -o $@ $(TEST_SHA1_OBJS) $(LIBS) - ./test-sha1 - rm test-sha1 - -TEST_SHA256_OBJS = ../src/crypto/sha256.o ../src/crypto/md5.o tests/test_sha256.o ../src/utils/os_unix.o ../src/crypto/crypto_openssl.o -test-sha256: $(TEST_SHA256_OBJS) - $(LDO) $(LDFLAGS) -o $@ $(TEST_SHA256_OBJS) $(LIBS) - ./test-sha256 - rm test-sha256 - -TEST_AES_OBJS = ../src/crypto/aes_wrap.o ../src/crypto/aes.o tests/test_aes.o -test-aes: $(TEST_AES_OBJS) - $(LDO) $(LDFLAGS) -o $@ $(TEST_AES_OBJS) $(LIBS) - ./test-aes - rm test-aes - -TEST_EAP_SIM_COMMON_OBJS = ../src/crypto/sha1.o ../src/crypto/md5.o \ - ../src/crypto/aes_wrap.o ../src/utils/common.o ../src/utils/os_unix.o \ - ../src/utils/wpa_debug.o ../src/crypto/aes.o \ +TEST_EAP_SIM_COMMON_OBJS = $(SHA1OBJS) $(MD5OBJS) \ + ../src/utils/common.o ../src/utils/os_unix.o \ + ../src/utils/wpa_debug.o $(AESOBJS) \ tests/test_eap_sim_common.o test-eap_sim_common: $(TEST_EAP_SIM_COMMON_OBJS) - $(LDO) $(LDFLAGS) -o $@ $(TEST_AES_OBJS) $(LIBS) + $(LDO) $(LDFLAGS) -o $@ $(TEST_EAP_SIM_COMMON_OBJS) $(LIBS) ./test-eap_sim_common rm test-eap_sim_common -TEST_MD4_OBJS = ../src/crypto/md4.o tests/test_md4.o #../src/crypto/crypto_openssl.o -test-md4: $(TEST_MD4_OBJS) - $(LDO) $(LDFLAGS) -o $@ $(TEST_MD4_OBJS) $(LIBS) - ./test-md4 - rm test-md4 - -TEST_MD5_OBJS = ../src/crypto/md5.o tests/test_md5.o #../src/crypto/crypto_openssl.o -test-md5: $(TEST_MD5_OBJS) - $(LDO) $(LDFLAGS) -o $@ $(TEST_MD5_OBJS) $(LIBS) - ./test-md5 - rm test-md5 - -tests: test-ms_funcs test-sha1 test-aes test-eap_sim_common test-md4 test-md5 +tests: test-eap_sim_common clean: $(MAKE) -C ../src clean + $(MAKE) -C dbus clean rm -f core *~ *.o *.d eap_*.so $(ALL) $(WINALL) eapol_test preauth_test rm -f wpa_priv -%.eps: %.fig - fig2dev -L eps $*.fig $*.eps - -%.png: %.fig - fig2dev -L png -m 3 $*.fig | pngtopnm | pnmscale 0.4 | pnmtopng \ - > $*.png - -docs-pics: doc/wpa_supplicant.png doc/wpa_supplicant.eps - -docs: docs-pics - (cd ..; doxygen wpa_supplicant/doc/doxygen.full; cd wpa_supplicant) - $(MAKE) -C doc/latex - cp doc/latex/refman.pdf wpa_supplicant-devel.pdf - -docs-fast: docs-pics - (cd ..; doxygen wpa_supplicant/doc/doxygen.fast; cd wpa_supplicant) - -clean-docs: - rm -rf doc/latex doc/html - rm -f doc/wpa_supplicant.{eps,png} wpa_supplicant-devel.pdf - -include $(OBJS:%.o=%.d) diff --git a/contrib/wpa/wpa_supplicant/README b/contrib/wpa/wpa_supplicant/README index b282150..45c8bae 100644 --- a/contrib/wpa/wpa_supplicant/README +++ b/contrib/wpa/wpa_supplicant/README @@ -1,7 +1,7 @@ WPA Supplicant ============== -Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> and contributors +Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> and contributors All Rights Reserved. This program is dual-licensed under both the GPL version 2 and BSD @@ -497,7 +497,7 @@ options: -C = ctrl_interface parameter (only used if -c is not) -i = interface name -d = increase debugging verbosity (-dd even more) - -D = driver name + -D = driver name (can be multiple drivers: nl80211,wext) -f = Log output to default log location (normally /tmp) -g = global ctrl_interface -K = include keys (passwords, etc.) in debug output @@ -541,6 +541,13 @@ enabled: wpa_supplicant -c/etc/wpa_supplicant.conf -iwlan0 -d +If the specific driver wrapper is not known beforehand, it is possible +to specify multiple comma separated driver wrappers on the command +line. wpa_supplicant will use the first driver wrapper that is able to +initialize the interface. + +wpa_supplicant -Dnl80211,wext -c/etc/wpa_supplicant.conf -iwlan0 + wpa_supplicant can control multiple interfaces (radios) either by running one process for each interface separately or by running just diff --git a/contrib/wpa/wpa_supplicant/README-WPS b/contrib/wpa/wpa_supplicant/README-WPS index 6b826a7..8f0d0d6 100644 --- a/contrib/wpa/wpa_supplicant/README-WPS +++ b/contrib/wpa/wpa_supplicant/README-WPS @@ -61,7 +61,6 @@ configuration that includes WPS support and Linux wireless extensions -based driver interface: CONFIG_DRIVER_WEXT=y -CONFIG_EAP=y CONFIG_WPS=y @@ -131,17 +130,29 @@ negotiation which will generate a new WPA PSK in the same way as the PIN method described above. -If the client wants to operate in the Registrar role to configure an -AP, wpa_supplicant is notified over the control interface, e.g., with +If the client wants to operate in the Registrar role to learn the +current AP configuration and optionally, to configure an AP, +wpa_supplicant is notified over the control interface, e.g., with wpa_cli: wpa_cli wps_reg <AP BSSID> <AP PIN> (example: wpa_cli wps_reg 02:34:56:78:9a:bc 12345670) -This is currently only used to fetch the current AP settings instead -of actually changing them. The main difference with the wps_pin -command is that wps_reg uses the AP PIN (e.g., from a label on the AP) -instead of a PIN generated at the client. +This is used to fetch the current AP settings instead of actually +changing them. The main difference with the wps_pin command is that +wps_reg uses the AP PIN (e.g., from a label on the AP) instead of a +PIN generated at the client. + +In order to change the AP configuration, the new configuration +parameters are given to the wps_reg command: + +wpa_cli wps_reg <AP BSSID> <AP PIN> <new SSID> <auth> <encr> <new key> +examples: + wpa_cli wps_reg 02:34:56:78:9a:bc 12345670 testing WPA2PSK CCMP 12345678 + wpa_cli wps_reg 02:34:56:78:9a:bc 12345670 clear OPEN NONE "" + +<auth> must be one of the following: OPEN WPAPSK WPA2PSK +<encr> must be one of the following: NONE WEP TKIP CCMP Scanning diff --git a/contrib/wpa/wpa_supplicant/ap.c b/contrib/wpa/wpa_supplicant/ap.c new file mode 100644 index 0000000..2b93984 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/ap.c @@ -0,0 +1,481 @@ +/* + * WPA Supplicant - Basic AP mode support routines + * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> + * Copyright (c) 2009, Atheros Communications + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "utils/includes.h" + +#include "utils/common.h" +#include "common/ieee802_11_defs.h" +#include "ap/hostapd.h" +#include "ap/ap_config.h" +#ifdef NEED_AP_MLME +#include "ap/ieee802_11.h" +#endif /* NEED_AP_MLME */ +#include "ap/ieee802_1x.h" +#include "ap/wps_hostapd.h" +#include "ap/ctrl_iface_ap.h" +#include "eap_common/eap_defs.h" +#include "eap_server/eap_methods.h" +#include "eap_common/eap_wsc_common.h" +#include "wps/wps.h" +#include "config_ssid.h" +#include "config.h" +#include "wpa_supplicant_i.h" +#include "driver_i.h" +#include "ap.h" + + +static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, + struct hostapd_config *conf) +{ + struct hostapd_bss_config *bss = &conf->bss[0]; + int pairwise; + + conf->driver = wpa_s->driver; + + os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface)); + + if (ssid->frequency == 0) { + /* default channel 11 */ + conf->hw_mode = HOSTAPD_MODE_IEEE80211G; + conf->channel = 11; + } else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) { + conf->hw_mode = HOSTAPD_MODE_IEEE80211G; + conf->channel = (ssid->frequency - 2407) / 5; + } else if ((ssid->frequency >= 5180 && ssid->frequency <= 5240) || + (ssid->frequency >= 5745 && ssid->frequency <= 5825)) { + conf->hw_mode = HOSTAPD_MODE_IEEE80211A; + conf->channel = (ssid->frequency - 5000) / 5; + } else { + wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz", + ssid->frequency); + return -1; + } + + /* TODO: enable HT if driver supports it; + * drop to 11b if driver does not support 11g */ + + if (ssid->ssid_len == 0) { + wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); + return -1; + } + os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len); + bss->ssid.ssid[ssid->ssid_len] = '\0'; + bss->ssid.ssid_len = ssid->ssid_len; + bss->ssid.ssid_set = 1; + + if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) + bss->wpa = ssid->proto; + bss->wpa_key_mgmt = ssid->key_mgmt; + bss->wpa_pairwise = ssid->pairwise_cipher; + if (ssid->passphrase) { + bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase); + } else if (ssid->psk_set) { + os_free(bss->ssid.wpa_psk); + bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk)); + if (bss->ssid.wpa_psk == NULL) + return -1; + os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN); + bss->ssid.wpa_psk->group = 1; + } + + /* Select group cipher based on the enabled pairwise cipher suites */ + pairwise = 0; + if (bss->wpa & 1) + pairwise |= bss->wpa_pairwise; + if (bss->wpa & 2) { + if (bss->rsn_pairwise == 0) + bss->rsn_pairwise = bss->wpa_pairwise; + pairwise |= bss->rsn_pairwise; + } + if (pairwise & WPA_CIPHER_TKIP) + bss->wpa_group = WPA_CIPHER_TKIP; + else + bss->wpa_group = WPA_CIPHER_CCMP; + + if (bss->wpa && bss->ieee802_1x) + bss->ssid.security_policy = SECURITY_WPA; + else if (bss->wpa) + bss->ssid.security_policy = SECURITY_WPA_PSK; + else if (bss->ieee802_1x) { + bss->ssid.security_policy = SECURITY_IEEE_802_1X; + bss->ssid.wep.default_len = bss->default_wep_key_len; + } else if (bss->ssid.wep.keys_set) + bss->ssid.security_policy = SECURITY_STATIC_WEP; + else + bss->ssid.security_policy = SECURITY_PLAINTEXT; + +#ifdef CONFIG_WPS + /* + * Enable WPS by default, but require user interaction to actually use + * it. Only the internal Registrar is supported. + */ + bss->eap_server = 1; + bss->wps_state = 2; + bss->ap_setup_locked = 1; + if (wpa_s->conf->config_methods) + bss->config_methods = os_strdup(wpa_s->conf->config_methods); + if (wpa_s->conf->device_type) + bss->device_type = os_strdup(wpa_s->conf->device_type); +#endif /* CONFIG_WPS */ + + return 0; +} + + +static void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq) +{ +} + + +static int ap_probe_req_rx(void *ctx, const u8 *addr, const u8 *ie, + size_t ie_len) +{ + return 0; +} + + +static void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr, + const u8 *uuid_e) +{ +} + + +int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + struct wpa_driver_associate_params params; + struct hostapd_iface *hapd_iface; + struct hostapd_config *conf; + size_t i; + + if (ssid->ssid == NULL || ssid->ssid_len == 0) { + wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); + return -1; + } + + wpa_supplicant_ap_deinit(wpa_s); + + wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')", + wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); + + os_memset(¶ms, 0, sizeof(params)); + params.ssid = ssid->ssid; + params.ssid_len = ssid->ssid_len; + switch (ssid->mode) { + case WPAS_MODE_INFRA: + params.mode = IEEE80211_MODE_INFRA; + break; + case WPAS_MODE_IBSS: + params.mode = IEEE80211_MODE_IBSS; + break; + case WPAS_MODE_AP: + params.mode = IEEE80211_MODE_AP; + break; + } + params.freq = ssid->frequency; + + if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) + wpa_s->key_mgmt = WPA_KEY_MGMT_PSK; + else + wpa_s->key_mgmt = WPA_KEY_MGMT_NONE; + params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt); + + if (ssid->pairwise_cipher & WPA_CIPHER_CCMP) + wpa_s->pairwise_cipher = WPA_CIPHER_CCMP; + else if (ssid->pairwise_cipher & WPA_CIPHER_TKIP) + wpa_s->pairwise_cipher = WPA_CIPHER_TKIP; + else if (ssid->pairwise_cipher & WPA_CIPHER_NONE) + wpa_s->pairwise_cipher = WPA_CIPHER_NONE; + else { + wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise " + "cipher."); + return -1; + } + params.pairwise_suite = cipher_suite2driver(wpa_s->pairwise_cipher); + params.group_suite = params.pairwise_suite; + + if (wpa_drv_associate(wpa_s, ¶ms) < 0) { + wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality"); + return -1; + } + + wpa_s->ap_iface = hapd_iface = os_zalloc(sizeof(*wpa_s->ap_iface)); + if (hapd_iface == NULL) + return -1; + hapd_iface->owner = wpa_s; + + wpa_s->ap_iface->conf = conf = hostapd_config_defaults(); + if (conf == NULL) { + wpa_supplicant_ap_deinit(wpa_s); + return -1; + } + + if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) { + wpa_printf(MSG_ERROR, "Failed to create AP configuration"); + wpa_supplicant_ap_deinit(wpa_s); + return -1; + } + + hapd_iface->num_bss = conf->num_bss; + hapd_iface->bss = os_zalloc(conf->num_bss * + sizeof(struct hostapd_data *)); + if (hapd_iface->bss == NULL) { + wpa_supplicant_ap_deinit(wpa_s); + return -1; + } + + for (i = 0; i < conf->num_bss; i++) { + hapd_iface->bss[i] = + hostapd_alloc_bss_data(hapd_iface, conf, + &conf->bss[i]); + if (hapd_iface->bss[i] == NULL) { + wpa_supplicant_ap_deinit(wpa_s); + return -1; + } + + hapd_iface->bss[i]->msg_ctx = wpa_s; + hapd_iface->bss[i]->public_action_cb = ap_public_action_rx; + hapd_iface->bss[i]->public_action_cb_ctx = wpa_s; + hostapd_register_probereq_cb(hapd_iface->bss[i], + ap_probe_req_rx, wpa_s); + hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb; + hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s; + } + + os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN); + hapd_iface->bss[0]->driver = wpa_s->driver; + hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv; + + if (hostapd_setup_interface(wpa_s->ap_iface)) { + wpa_printf(MSG_ERROR, "Failed to initialize AP interface"); + wpa_supplicant_ap_deinit(wpa_s); + return -1; + } + + wpa_s->current_ssid = ssid; + os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN); + wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); + + if (wpa_s->ap_configured_cb) + wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx, + wpa_s->ap_configured_cb_data); + + return 0; +} + + +void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->ap_iface == NULL) + return; + + wpa_s->current_ssid = NULL; + hostapd_interface_deinit(wpa_s->ap_iface); + hostapd_interface_free(wpa_s->ap_iface); + wpa_s->ap_iface = NULL; + wpa_drv_deinit_ap(wpa_s); +} + + +void ap_tx_status(void *ctx, const u8 *addr, + const u8 *buf, size_t len, int ack) +{ +#ifdef NEED_AP_MLME + struct wpa_supplicant *wpa_s = ctx; + hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack); +#endif /* NEED_AP_MLME */ +} + + +void ap_rx_from_unknown_sta(void *ctx, const u8 *frame, size_t len) +{ +#ifdef NEED_AP_MLME + struct wpa_supplicant *wpa_s = ctx; + const struct ieee80211_hdr *hdr = + (const struct ieee80211_hdr *) frame; + u16 fc = le_to_host16(hdr->frame_control); + ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], hdr->addr2, + (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == + (WLAN_FC_TODS | WLAN_FC_FROMDS)); +#endif /* NEED_AP_MLME */ +} + + +void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt) +{ +#ifdef NEED_AP_MLME + struct wpa_supplicant *wpa_s = ctx; + struct hostapd_frame_info fi; + os_memset(&fi, 0, sizeof(fi)); + fi.datarate = rx_mgmt->datarate; + fi.ssi_signal = rx_mgmt->ssi_signal; + ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame, + rx_mgmt->frame_len, &fi); +#endif /* NEED_AP_MLME */ +} + + +void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok) +{ +#ifdef NEED_AP_MLME + struct wpa_supplicant *wpa_s = ctx; + ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok); +#endif /* NEED_AP_MLME */ +} + + +void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s, + const u8 *src_addr, const u8 *buf, size_t len) +{ + ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len); +} + + +#ifdef CONFIG_WPS + +int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid) +{ + if (!wpa_s->ap_iface) + return -1; + return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0]); +} + + +int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, + const char *pin, char *buf, size_t buflen) +{ + int ret, ret_len = 0; + + if (!wpa_s->ap_iface) + return -1; + + if (pin == NULL) { + unsigned int rpin = wps_generate_pin(); + ret_len = os_snprintf(buf, buflen, "%d", rpin); + pin = buf; + } + + ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], "any", pin, 0); + if (ret) + return -1; + return ret_len; +} + +#endif /* CONFIG_WPS */ + + +#ifdef CONFIG_CTRL_IFACE + +int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s, + char *buf, size_t buflen) +{ + if (wpa_s->ap_iface == NULL) + return -1; + return hostapd_ctrl_iface_sta_first(wpa_s->ap_iface->bss[0], + buf, buflen); +} + + +int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr, + char *buf, size_t buflen) +{ + if (wpa_s->ap_iface == NULL) + return -1; + return hostapd_ctrl_iface_sta(wpa_s->ap_iface->bss[0], txtaddr, + buf, buflen); +} + + +int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr, + char *buf, size_t buflen) +{ + if (wpa_s->ap_iface == NULL) + return -1; + return hostapd_ctrl_iface_sta_next(wpa_s->ap_iface->bss[0], txtaddr, + buf, buflen); +} + + +int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf, + size_t buflen, int verbose) +{ + char *pos = buf, *end = buf + buflen; + int ret; + struct hostapd_bss_config *conf; + + if (wpa_s->ap_iface == NULL) + return -1; + + conf = wpa_s->ap_iface->bss[0]->conf; + if (conf->wpa == 0) + return 0; + + ret = os_snprintf(pos, end - pos, + "pairwise_cipher=%s\n" + "group_cipher=%s\n" + "key_mgmt=%s\n", + wpa_cipher_txt(conf->rsn_pairwise), + wpa_cipher_txt(conf->wpa_group), + wpa_key_mgmt_txt(conf->wpa_key_mgmt, + conf->wpa)); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + return pos - buf; +} + +#endif /* CONFIG_CTRL_IFACE */ + + +int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s, + const u8 *addr) +{ + struct hostapd_data *hapd; + struct hostapd_bss_config *conf; + + if (!wpa_s->ap_iface) + return -1; + + if (addr) + wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR, + MAC2STR(addr)); + else + wpa_printf(MSG_DEBUG, "AP: Clear MAC address filter"); + + hapd = wpa_s->ap_iface->bss[0]; + conf = hapd->conf; + + os_free(conf->accept_mac); + conf->accept_mac = NULL; + conf->num_accept_mac = 0; + os_free(conf->deny_mac); + conf->deny_mac = NULL; + conf->num_deny_mac = 0; + + if (addr == NULL) { + conf->macaddr_acl = ACCEPT_UNLESS_DENIED; + return 0; + } + + conf->macaddr_acl = DENY_UNLESS_ACCEPTED; + conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry)); + if (conf->accept_mac == NULL) + return -1; + os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN); + conf->num_accept_mac = 1; + + return 0; +} diff --git a/contrib/wpa/wpa_supplicant/ap.h b/contrib/wpa/wpa_supplicant/ap.h new file mode 100644 index 0000000..381a432 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/ap.h @@ -0,0 +1,43 @@ +/* + * WPA Supplicant - Basic AP mode support routines + * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> + * Copyright (c) 2009, Atheros Communications + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef AP_H +#define AP_H + +int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s); +void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s, + const u8 *src_addr, const u8 *buf, size_t len); +int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid); +int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, + const char *pin, char *buf, size_t buflen); +int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s, + char *buf, size_t buflen); +int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr, + char *buf, size_t buflen); +int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr, + char *buf, size_t buflen); +int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf, + size_t buflen, int verbose); +void ap_tx_status(void *ctx, const u8 *addr, + const u8 *buf, size_t len, int ack); +void ap_rx_from_unknown_sta(void *ctx, const u8 *frame, size_t len); +void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt); +void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok); +int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s, + const u8 *addr); + +#endif /* AP_H */ diff --git a/contrib/wpa/wpa_supplicant/bgscan.c b/contrib/wpa/wpa_supplicant/bgscan.c new file mode 100644 index 0000000..31b5d27 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/bgscan.c @@ -0,0 +1,110 @@ +/* + * WPA Supplicant - background scan and roaming interface + * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "wpa_supplicant_i.h" +#include "config_ssid.h" +#include "bgscan.h" + +#ifdef CONFIG_BGSCAN_SIMPLE +extern const struct bgscan_ops bgscan_simple_ops; +#endif /* CONFIG_BGSCAN_SIMPLE */ + +static const struct bgscan_ops * bgscan_modules[] = { +#ifdef CONFIG_BGSCAN_SIMPLE + &bgscan_simple_ops, +#endif /* CONFIG_BGSCAN_SIMPLE */ + NULL +}; + + +int bgscan_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) +{ + const char *name = ssid->bgscan; + const char *params; + size_t nlen; + int i; + const struct bgscan_ops *ops = NULL; + + bgscan_deinit(wpa_s); + if (name == NULL) + return 0; + + params = os_strchr(name, ':'); + if (params == NULL) { + params = ""; + nlen = os_strlen(name); + } else { + nlen = params - name; + params++; + } + + for (i = 0; bgscan_modules[i]; i++) { + if (os_strncmp(name, bgscan_modules[i]->name, nlen) == 0) { + ops = bgscan_modules[i]; + break; + } + } + + if (ops == NULL) { + wpa_printf(MSG_ERROR, "bgscan: Could not find module " + "matching the parameter '%s'", name); + return -1; + } + + wpa_s->bgscan_priv = ops->init(wpa_s, params, ssid); + if (wpa_s->bgscan_priv == NULL) + return -1; + wpa_s->bgscan = ops; + wpa_printf(MSG_DEBUG, "bgscan: Initialized module '%s' with " + "parameters '%s'", ops->name, params); + + return 0; +} + + +void bgscan_deinit(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->bgscan && wpa_s->bgscan_priv) { + wpa_printf(MSG_DEBUG, "bgscan: Deinitializing module '%s'", + wpa_s->bgscan->name); + wpa_s->bgscan->deinit(wpa_s->bgscan_priv); + wpa_s->bgscan = NULL; + wpa_s->bgscan_priv = NULL; + } +} + + +int bgscan_notify_scan(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->bgscan && wpa_s->bgscan_priv) + return wpa_s->bgscan->notify_scan(wpa_s->bgscan_priv); + return 0; +} + + +void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->bgscan && wpa_s->bgscan_priv) + wpa_s->bgscan->notify_beacon_loss(wpa_s->bgscan_priv); +} + + +void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above) +{ + if (wpa_s->bgscan && wpa_s->bgscan_priv) + wpa_s->bgscan->notify_signal_change(wpa_s->bgscan_priv, above); +} diff --git a/contrib/wpa/wpa_supplicant/bgscan.h b/contrib/wpa/wpa_supplicant/bgscan.h new file mode 100644 index 0000000..69e99b6 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/bgscan.h @@ -0,0 +1,69 @@ +/* + * WPA Supplicant - background scan and roaming interface + * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef BGSCAN_H +#define BGSCAN_H + +struct wpa_supplicant; +struct wpa_ssid; + +struct bgscan_ops { + const char *name; + + void * (*init)(struct wpa_supplicant *wpa_s, const char *params, + const struct wpa_ssid *ssid); + void (*deinit)(void *priv); + + int (*notify_scan)(void *priv); + void (*notify_beacon_loss)(void *priv); + void (*notify_signal_change)(void *priv, int above); +}; + +#ifdef CONFIG_BGSCAN + +int bgscan_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); +void bgscan_deinit(struct wpa_supplicant *wpa_s); +int bgscan_notify_scan(struct wpa_supplicant *wpa_s); +void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s); +void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above); + +#else /* CONFIG_BGSCAN */ + +static inline int bgscan_init(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + return 0; +} + +static inline void bgscan_deinit(struct wpa_supplicant *wpa_s) +{ +} + +static inline int bgscan_notify_scan(struct wpa_supplicant *wpa_s) +{ + return 0; +} + +static inline void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s) +{ +} + +static inline void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, + int above) +{ +} + +#endif /* CONFIG_BGSCAN */ + +#endif /* BGSCAN_H */ diff --git a/contrib/wpa/wpa_supplicant/bgscan_simple.c b/contrib/wpa/wpa_supplicant/bgscan_simple.c new file mode 100644 index 0000000..8e80b12 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/bgscan_simple.c @@ -0,0 +1,230 @@ +/* + * WPA Supplicant - background scan and roaming module: simple + * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "eloop.h" +#include "drivers/driver.h" +#include "config_ssid.h" +#include "wpa_supplicant_i.h" +#include "driver_i.h" +#include "scan.h" +#include "bgscan.h" + +struct bgscan_simple_data { + struct wpa_supplicant *wpa_s; + const struct wpa_ssid *ssid; + int scan_interval; + int signal_threshold; + int short_interval; /* use if signal < threshold */ + int long_interval; /* use if signal > threshold */ + struct os_time last_bgscan; +}; + + +static void bgscan_simple_timeout(void *eloop_ctx, void *timeout_ctx) +{ + struct bgscan_simple_data *data = eloop_ctx; + struct wpa_supplicant *wpa_s = data->wpa_s; + struct wpa_driver_scan_params params; + + os_memset(¶ms, 0, sizeof(params)); + params.num_ssids = 1; + params.ssids[0].ssid = data->ssid->ssid; + params.ssids[0].ssid_len = data->ssid->ssid_len; + params.freqs = data->ssid->scan_freq; + + /* + * A more advanced bgscan module would learn about most like channels + * over time and request scans only for some channels (probing others + * every now and then) to reduce effect on the data connection. + */ + + wpa_printf(MSG_DEBUG, "bgscan simple: Request a background scan"); + if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) { + wpa_printf(MSG_DEBUG, "bgscan simple: Failed to trigger scan"); + eloop_register_timeout(data->scan_interval, 0, + bgscan_simple_timeout, data, NULL); + } else + os_get_time(&data->last_bgscan); +} + + +static int bgscan_simple_get_params(struct bgscan_simple_data *data, + const char *params) +{ + const char *pos; + + if (params == NULL) + return 0; + + data->short_interval = atoi(params); + + pos = os_strchr(params, ':'); + if (pos == NULL) + return 0; + pos++; + data->signal_threshold = atoi(pos); + pos = os_strchr(pos, ':'); + if (pos == NULL) { + wpa_printf(MSG_ERROR, "bgscan simple: Missing scan interval " + "for high signal"); + return -1; + } + pos++; + data->long_interval = atoi(pos); + + return 0; +} + + +static void * bgscan_simple_init(struct wpa_supplicant *wpa_s, + const char *params, + const struct wpa_ssid *ssid) +{ + struct bgscan_simple_data *data; + + data = os_zalloc(sizeof(*data)); + if (data == NULL) + return NULL; + data->wpa_s = wpa_s; + data->ssid = ssid; + if (bgscan_simple_get_params(data, params) < 0) { + os_free(data); + return NULL; + } + if (data->short_interval <= 0) + data->short_interval = 30; + if (data->long_interval <= 0) + data->long_interval = 30; + + wpa_printf(MSG_DEBUG, "bgscan simple: Signal strength threshold %d " + "Short bgscan interval %d Long bgscan interval %d", + data->signal_threshold, data->short_interval, + data->long_interval); + + if (data->signal_threshold && + wpa_drv_signal_monitor(wpa_s, data->signal_threshold, 4) < 0) { + wpa_printf(MSG_ERROR, "bgscan simple: Failed to enable " + "signal strength monitoring"); + } + + data->scan_interval = data->short_interval; + eloop_register_timeout(data->scan_interval, 0, bgscan_simple_timeout, + data, NULL); + + /* + * This function is called immediately after an association, so it is + * reasonable to assume that a scan was completed recently. This makes + * us skip an immediate new scan in cases where the current signal + * level is below the bgscan threshold. + */ + os_get_time(&data->last_bgscan); + + return data; +} + + +static void bgscan_simple_deinit(void *priv) +{ + struct bgscan_simple_data *data = priv; + eloop_cancel_timeout(bgscan_simple_timeout, data, NULL); + if (data->signal_threshold) + wpa_drv_signal_monitor(data->wpa_s, 0, 0); + os_free(data); +} + + +static int bgscan_simple_notify_scan(void *priv) +{ + struct bgscan_simple_data *data = priv; + + wpa_printf(MSG_DEBUG, "bgscan simple: scan result notification"); + + eloop_cancel_timeout(bgscan_simple_timeout, data, NULL); + eloop_register_timeout(data->scan_interval, 0, bgscan_simple_timeout, + data, NULL); + + /* + * A more advanced bgscan could process scan results internally, select + * the BSS and request roam if needed. This sample uses the existing + * BSS/ESS selection routine. Change this to return 1 if selection is + * done inside the bgscan module. + */ + + return 0; +} + + +static void bgscan_simple_notify_beacon_loss(void *priv) +{ + wpa_printf(MSG_DEBUG, "bgscan simple: beacon loss"); + /* TODO: speed up background scanning */ +} + + +static void bgscan_simple_notify_signal_change(void *priv, int above) +{ + struct bgscan_simple_data *data = priv; + int scan = 0; + struct os_time now; + + if (data->short_interval == data->long_interval || + data->signal_threshold == 0) + return; + + wpa_printf(MSG_DEBUG, "bgscan simple: signal level changed " + "(above=%d)", above); + if (data->scan_interval == data->long_interval && !above) { + wpa_printf(MSG_DEBUG, "bgscan simple: Start using short " + "bgscan interval"); + data->scan_interval = data->short_interval; + os_get_time(&now); + if (now.sec > data->last_bgscan.sec + 1) + scan = 1; + } else if (data->scan_interval == data->short_interval && above) { + wpa_printf(MSG_DEBUG, "bgscan simple: Start using long bgscan " + "interval"); + data->scan_interval = data->long_interval; + eloop_cancel_timeout(bgscan_simple_timeout, data, NULL); + eloop_register_timeout(data->scan_interval, 0, + bgscan_simple_timeout, data, NULL); + } else if (!above) { + /* + * Signal dropped further 4 dB. Request a new scan if we have + * not yet scanned in a while. + */ + os_get_time(&now); + if (now.sec > data->last_bgscan.sec + 10) + scan = 1; + } + + if (scan) { + wpa_printf(MSG_DEBUG, "bgscan simple: Trigger immediate scan"); + eloop_cancel_timeout(bgscan_simple_timeout, data, NULL); + eloop_register_timeout(0, 0, bgscan_simple_timeout, data, + NULL); + } +} + + +const struct bgscan_ops bgscan_simple_ops = { + .name = "simple", + .init = bgscan_simple_init, + .deinit = bgscan_simple_deinit, + .notify_scan = bgscan_simple_notify_scan, + .notify_beacon_loss = bgscan_simple_notify_beacon_loss, + .notify_signal_change = bgscan_simple_notify_signal_change, +}; diff --git a/contrib/wpa/wpa_supplicant/bss.c b/contrib/wpa/wpa_supplicant/bss.c new file mode 100644 index 0000000..e2ac230 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/bss.c @@ -0,0 +1,606 @@ +/* + * BSS table + * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "utils/includes.h" + +#include "utils/common.h" +#include "utils/eloop.h" +#include "common/ieee802_11_defs.h" +#include "drivers/driver.h" +#include "wpa_supplicant_i.h" +#include "config.h" +#include "notify.h" +#include "scan.h" +#include "bss.h" + + +/** + * WPA_BSS_EXPIRATION_PERIOD - Period of expiration run in seconds + */ +#define WPA_BSS_EXPIRATION_PERIOD 10 + +/** + * WPA_BSS_EXPIRATION_AGE - BSS entry age after which it can be expired + * + * This value control the time in seconds after which a BSS entry gets removed + * if it has not been updated or is not in use. + */ +#define WPA_BSS_EXPIRATION_AGE 180 + +/** + * WPA_BSS_EXPIRATION_SCAN_COUNT - Expire BSS after number of scans + * + * If the BSS entry has not been seen in this many scans, it will be removed. + * Value 1 means that the entry is removed after the first scan without the + * BSSID being seen. Larger values can be used to avoid BSS entries + * disappearing if they are not visible in every scan (e.g., low signal quality + * or interference). + */ +#define WPA_BSS_EXPIRATION_SCAN_COUNT 2 + +#define WPA_BSS_FREQ_CHANGED_FLAG BIT(0) +#define WPA_BSS_SIGNAL_CHANGED_FLAG BIT(1) +#define WPA_BSS_PRIVACY_CHANGED_FLAG BIT(2) +#define WPA_BSS_MODE_CHANGED_FLAG BIT(3) +#define WPA_BSS_WPAIE_CHANGED_FLAG BIT(4) +#define WPA_BSS_RSNIE_CHANGED_FLAG BIT(5) +#define WPA_BSS_WPS_CHANGED_FLAG BIT(6) +#define WPA_BSS_RATES_CHANGED_FLAG BIT(7) +#define WPA_BSS_IES_CHANGED_FLAG BIT(8) + + +static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) +{ + dl_list_del(&bss->list); + dl_list_del(&bss->list_id); + wpa_s->num_bss--; + wpa_printf(MSG_DEBUG, "BSS: Remove id %u BSSID " MACSTR " SSID '%s'", + bss->id, MAC2STR(bss->bssid), + wpa_ssid_txt(bss->ssid, bss->ssid_len)); + wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id); + os_free(bss); +} + + +struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid, + const u8 *ssid, size_t ssid_len) +{ + struct wpa_bss *bss; + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { + if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0 && + bss->ssid_len == ssid_len && + os_memcmp(bss->ssid, ssid, ssid_len) == 0) + return bss; + } + return NULL; +} + + +static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src) +{ + os_time_t usec; + + dst->flags = src->flags; + os_memcpy(dst->bssid, src->bssid, ETH_ALEN); + dst->freq = src->freq; + dst->beacon_int = src->beacon_int; + dst->caps = src->caps; + dst->qual = src->qual; + dst->noise = src->noise; + dst->level = src->level; + dst->tsf = src->tsf; + + os_get_time(&dst->last_update); + dst->last_update.sec -= src->age / 1000; + usec = (src->age % 1000) * 1000; + if (dst->last_update.usec < usec) { + dst->last_update.sec--; + dst->last_update.usec += 1000000; + } + dst->last_update.usec -= usec; +} + + +static void wpa_bss_add(struct wpa_supplicant *wpa_s, + const u8 *ssid, size_t ssid_len, + struct wpa_scan_res *res) +{ + struct wpa_bss *bss; + + bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len); + if (bss == NULL) + return; + bss->id = wpa_s->bss_next_id++; + bss->last_update_idx = wpa_s->bss_update_idx; + wpa_bss_copy_res(bss, res); + os_memcpy(bss->ssid, ssid, ssid_len); + bss->ssid_len = ssid_len; + bss->ie_len = res->ie_len; + bss->beacon_ie_len = res->beacon_ie_len; + os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len); + + dl_list_add_tail(&wpa_s->bss, &bss->list); + dl_list_add_tail(&wpa_s->bss_id, &bss->list_id); + wpa_s->num_bss++; + wpa_printf(MSG_DEBUG, "BSS: Add new id %u BSSID " MACSTR " SSID '%s'", + bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len)); + wpas_notify_bss_added(wpa_s, bss->bssid, bss->id); + if (wpa_s->num_bss > wpa_s->conf->bss_max_count) { + /* Remove the oldest entry */ + wpa_bss_remove(wpa_s, dl_list_first(&wpa_s->bss, + struct wpa_bss, list)); + } +} + + +static int are_ies_equal(const struct wpa_bss *old, + const struct wpa_scan_res *new, u32 ie) +{ + const u8 *old_ie, *new_ie; + struct wpabuf *old_ie_buff = NULL; + struct wpabuf *new_ie_buff = NULL; + int new_ie_len, old_ie_len, ret, is_multi; + + switch (ie) { + case WPA_IE_VENDOR_TYPE: + old_ie = wpa_bss_get_vendor_ie(old, ie); + new_ie = wpa_scan_get_vendor_ie(new, ie); + is_multi = 0; + break; + case WPS_IE_VENDOR_TYPE: + old_ie_buff = wpa_bss_get_vendor_ie_multi(old, ie); + new_ie_buff = wpa_scan_get_vendor_ie_multi(new, ie); + is_multi = 1; + break; + case WLAN_EID_RSN: + case WLAN_EID_SUPP_RATES: + case WLAN_EID_EXT_SUPP_RATES: + old_ie = wpa_bss_get_ie(old, ie); + new_ie = wpa_scan_get_ie(new, ie); + is_multi = 0; + break; + default: + wpa_printf(MSG_DEBUG, "bss: %s: cannot compare IEs", __func__); + return 0; + } + + if (is_multi) { + /* in case of multiple IEs stored in buffer */ + old_ie = old_ie_buff ? wpabuf_head_u8(old_ie_buff) : NULL; + new_ie = new_ie_buff ? wpabuf_head_u8(new_ie_buff) : NULL; + old_ie_len = old_ie_buff ? wpabuf_len(old_ie_buff) : 0; + new_ie_len = new_ie_buff ? wpabuf_len(new_ie_buff) : 0; + } else { + /* in case of single IE */ + old_ie_len = old_ie ? old_ie[1] + 2 : 0; + new_ie_len = new_ie ? new_ie[1] + 2 : 0; + } + + ret = (old_ie_len == new_ie_len && + os_memcmp(old_ie, new_ie, old_ie_len) == 0); + + wpabuf_free(old_ie_buff); + wpabuf_free(new_ie_buff); + + return ret; +} + + +static u32 wpa_bss_compare_res(const struct wpa_bss *old, + const struct wpa_scan_res *new) +{ + u32 changes = 0; + int caps_diff = old->caps ^ new->caps; + + if (old->freq != new->freq) + changes |= WPA_BSS_FREQ_CHANGED_FLAG; + + if (old->level != new->level) + changes |= WPA_BSS_SIGNAL_CHANGED_FLAG; + + if (caps_diff & IEEE80211_CAP_PRIVACY) + changes |= WPA_BSS_PRIVACY_CHANGED_FLAG; + + if (caps_diff & IEEE80211_CAP_IBSS) + changes |= WPA_BSS_MODE_CHANGED_FLAG; + + if (old->ie_len == new->ie_len && + os_memcmp(old + 1, new + 1, old->ie_len) == 0) + return changes; + changes |= WPA_BSS_IES_CHANGED_FLAG; + + if (!are_ies_equal(old, new, WPA_IE_VENDOR_TYPE)) + changes |= WPA_BSS_WPAIE_CHANGED_FLAG; + + if (!are_ies_equal(old, new, WLAN_EID_RSN)) + changes |= WPA_BSS_RSNIE_CHANGED_FLAG; + + if (!are_ies_equal(old, new, WPS_IE_VENDOR_TYPE)) + changes |= WPA_BSS_WPS_CHANGED_FLAG; + + if (!are_ies_equal(old, new, WLAN_EID_SUPP_RATES) || + !are_ies_equal(old, new, WLAN_EID_EXT_SUPP_RATES)) + changes |= WPA_BSS_RATES_CHANGED_FLAG; + + return changes; +} + + +static void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes, + const struct wpa_bss *bss) +{ + if (changes & WPA_BSS_FREQ_CHANGED_FLAG) + wpas_notify_bss_freq_changed(wpa_s, bss->id); + + if (changes & WPA_BSS_SIGNAL_CHANGED_FLAG) + wpas_notify_bss_signal_changed(wpa_s, bss->id); + + if (changes & WPA_BSS_PRIVACY_CHANGED_FLAG) + wpas_notify_bss_privacy_changed(wpa_s, bss->id); + + if (changes & WPA_BSS_MODE_CHANGED_FLAG) + wpas_notify_bss_mode_changed(wpa_s, bss->id); + + if (changes & WPA_BSS_WPAIE_CHANGED_FLAG) + wpas_notify_bss_wpaie_changed(wpa_s, bss->id); + + if (changes & WPA_BSS_RSNIE_CHANGED_FLAG) + wpas_notify_bss_rsnie_changed(wpa_s, bss->id); + + if (changes & WPA_BSS_WPS_CHANGED_FLAG) + wpas_notify_bss_wps_changed(wpa_s, bss->id); + + if (changes & WPA_BSS_IES_CHANGED_FLAG) + wpas_notify_bss_ies_changed(wpa_s, bss->id); + + if (changes & WPA_BSS_RATES_CHANGED_FLAG) + wpas_notify_bss_rates_changed(wpa_s, bss->id); +} + + +static void wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, + struct wpa_scan_res *res) +{ + u32 changes; + + changes = wpa_bss_compare_res(bss, res); + bss->scan_miss_count = 0; + bss->last_update_idx = wpa_s->bss_update_idx; + wpa_bss_copy_res(bss, res); + /* Move the entry to the end of the list */ + dl_list_del(&bss->list); + if (bss->ie_len + bss->beacon_ie_len >= + res->ie_len + res->beacon_ie_len) { + os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len); + bss->ie_len = res->ie_len; + bss->beacon_ie_len = res->beacon_ie_len; + } else { + struct wpa_bss *nbss; + struct dl_list *prev = bss->list_id.prev; + dl_list_del(&bss->list_id); + nbss = os_realloc(bss, sizeof(*bss) + res->ie_len + + res->beacon_ie_len); + if (nbss) { + bss = nbss; + os_memcpy(bss + 1, res + 1, + res->ie_len + res->beacon_ie_len); + bss->ie_len = res->ie_len; + bss->beacon_ie_len = res->beacon_ie_len; + } + dl_list_add(prev, &bss->list_id); + } + dl_list_add_tail(&wpa_s->bss, &bss->list); + + notify_bss_changes(wpa_s, changes, bss); +} + + +static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) +{ + return bss == wpa_s->current_bss || + os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) == 0 || + os_memcmp(bss->bssid, wpa_s->pending_bssid, ETH_ALEN) == 0; +} + + +void wpa_bss_update_start(struct wpa_supplicant *wpa_s) +{ + wpa_s->bss_update_idx++; + wpa_printf(MSG_DEBUG, "BSS: Start scan result update %u", + wpa_s->bss_update_idx); +} + + +void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s, + struct wpa_scan_res *res) +{ + const u8 *ssid; + struct wpa_bss *bss; + + ssid = wpa_scan_get_ie(res, WLAN_EID_SSID); + if (ssid == NULL) { + wpa_printf(MSG_DEBUG, "BSS: No SSID IE included for " MACSTR, + MAC2STR(res->bssid)); + return; + } + if (ssid[1] > 32) { + wpa_printf(MSG_DEBUG, "BSS: Too long SSID IE included for " + MACSTR, MAC2STR(res->bssid)); + return; + } + + /* TODO: add option for ignoring BSSes we are not interested in + * (to save memory) */ + bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]); + if (bss == NULL) + wpa_bss_add(wpa_s, ssid + 2, ssid[1], res); + else + wpa_bss_update(wpa_s, bss, res); +} + + +static int wpa_bss_included_in_scan(const struct wpa_bss *bss, + const struct scan_info *info) +{ + int found; + size_t i; + + if (info == NULL) + return 1; + + if (info->num_freqs) { + found = 0; + for (i = 0; i < info->num_freqs; i++) { + if (bss->freq == info->freqs[i]) { + found = 1; + break; + } + } + if (!found) + return 0; + } + + if (info->num_ssids) { + found = 0; + for (i = 0; i < info->num_ssids; i++) { + const struct wpa_driver_scan_ssid *s = &info->ssids[i]; + if ((s->ssid == NULL || s->ssid_len == 0) || + (s->ssid_len == bss->ssid_len && + os_memcmp(s->ssid, bss->ssid, bss->ssid_len) == + 0)) { + found = 1; + break; + } + } + if (!found) + return 0; + } + + return 1; +} + + +void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, + int new_scan) +{ + struct wpa_bss *bss, *n; + + if (!new_scan) + return; /* do not expire entries without new scan */ + + dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) { + if (wpa_bss_in_use(wpa_s, bss)) + continue; + if (!wpa_bss_included_in_scan(bss, info)) + continue; /* expire only BSSes that were scanned */ + if (bss->last_update_idx < wpa_s->bss_update_idx) + bss->scan_miss_count++; + if (bss->scan_miss_count >= WPA_BSS_EXPIRATION_SCAN_COUNT) { + wpa_printf(MSG_DEBUG, "BSS: Expire BSS %u due to no " + "match in scan", bss->id); + wpa_bss_remove(wpa_s, bss); + } + } +} + + +static void wpa_bss_timeout(void *eloop_ctx, void *timeout_ctx) +{ + struct wpa_supplicant *wpa_s = eloop_ctx; + struct wpa_bss *bss, *n; + struct os_time t; + + if (dl_list_empty(&wpa_s->bss)) + return; + + os_get_time(&t); + t.sec -= WPA_BSS_EXPIRATION_AGE; + + dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) { + if (wpa_bss_in_use(wpa_s, bss)) + continue; + + if (os_time_before(&bss->last_update, &t)) { + wpa_printf(MSG_DEBUG, "BSS: Expire BSS %u due to age", + bss->id); + wpa_bss_remove(wpa_s, bss); + } else + break; + } + eloop_register_timeout(WPA_BSS_EXPIRATION_PERIOD, 0, + wpa_bss_timeout, wpa_s, NULL); +} + + +int wpa_bss_init(struct wpa_supplicant *wpa_s) +{ + dl_list_init(&wpa_s->bss); + dl_list_init(&wpa_s->bss_id); + eloop_register_timeout(WPA_BSS_EXPIRATION_PERIOD, 0, + wpa_bss_timeout, wpa_s, NULL); + return 0; +} + + +void wpa_bss_deinit(struct wpa_supplicant *wpa_s) +{ + struct wpa_bss *bss, *n; + eloop_cancel_timeout(wpa_bss_timeout, wpa_s, NULL); + if (wpa_s->bss.next == NULL) + return; /* BSS table not yet initialized */ + dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) + wpa_bss_remove(wpa_s, bss); +} + + +struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s, + const u8 *bssid) +{ + struct wpa_bss *bss; + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { + if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) + return bss; + } + return NULL; +} + + +struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id) +{ + struct wpa_bss *bss; + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { + if (bss->id == id) + return bss; + } + return NULL; +} + + +const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie) +{ + const u8 *end, *pos; + + pos = (const u8 *) (bss + 1); + end = pos + bss->ie_len; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + break; + if (pos[0] == ie) + return pos; + pos += 2 + pos[1]; + } + + return NULL; +} + + +const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type) +{ + const u8 *end, *pos; + + pos = (const u8 *) (bss + 1); + end = pos + bss->ie_len; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + break; + if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && + vendor_type == WPA_GET_BE32(&pos[2])) + return pos; + pos += 2 + pos[1]; + } + + return NULL; +} + + +struct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss, + u32 vendor_type) +{ + struct wpabuf *buf; + const u8 *end, *pos; + + buf = wpabuf_alloc(bss->ie_len); + if (buf == NULL) + return NULL; + + pos = (const u8 *) (bss + 1); + end = pos + bss->ie_len; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + break; + if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && + vendor_type == WPA_GET_BE32(&pos[2])) + wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4); + pos += 2 + pos[1]; + } + + if (wpabuf_len(buf) == 0) { + wpabuf_free(buf); + buf = NULL; + } + + return buf; +} + + +int wpa_bss_get_max_rate(const struct wpa_bss *bss) +{ + int rate = 0; + const u8 *ie; + int i; + + ie = wpa_bss_get_ie(bss, WLAN_EID_SUPP_RATES); + for (i = 0; ie && i < ie[1]; i++) { + if ((ie[i + 2] & 0x7f) > rate) + rate = ie[i + 2] & 0x7f; + } + + ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES); + for (i = 0; ie && i < ie[1]; i++) { + if ((ie[i + 2] & 0x7f) > rate) + rate = ie[i + 2] & 0x7f; + } + + return rate; +} + + +int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates) +{ + const u8 *ie, *ie2; + int i, j; + unsigned int len; + u8 *r; + + ie = wpa_bss_get_ie(bss, WLAN_EID_SUPP_RATES); + ie2 = wpa_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES); + + len = (ie ? ie[1] : 0) + (ie2 ? ie2[1] : 0); + + r = os_malloc(len); + if (!r) + return -1; + + for (i = 0; ie && i < ie[1]; i++) + r[i] = ie[i + 2] & 0x7f; + + for (j = 0; ie2 && j < ie2[1]; j++) + r[i + j] = ie2[j + 2] & 0x7f; + + *rates = r; + return len; +} diff --git a/contrib/wpa/wpa_supplicant/bss.h b/contrib/wpa/wpa_supplicant/bss.h new file mode 100644 index 0000000..1de4722 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/bss.h @@ -0,0 +1,93 @@ +/* + * BSS table + * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef BSS_H +#define BSS_H + +struct wpa_scan_res; + +#define WPA_BSS_QUAL_INVALID BIT(0) +#define WPA_BSS_NOISE_INVALID BIT(1) +#define WPA_BSS_LEVEL_INVALID BIT(2) +#define WPA_BSS_LEVEL_DBM BIT(3) +#define WPA_BSS_AUTHENTICATED BIT(4) +#define WPA_BSS_ASSOCIATED BIT(5) + +/** + * struct wpa_bss - BSS table + * @list: List entry for struct wpa_supplicant::bss + * @list_id: List entry for struct wpa_supplicant::bss_id + * @id: Unique identifier for this BSS entry + * @scan_miss_count: Number of counts without seeing this BSS + * @flags: information flags about the BSS/IBSS (WPA_BSS_*) + * @last_update_idx: Index of the last scan update + * @bssid: BSSID + * @freq: frequency of the channel in MHz (e.g., 2412 = channel 1) + * @beacon_int: beacon interval in TUs (host byte order) + * @caps: capability information field in host byte order + * @qual: signal quality + * @noise: noise level + * @level: signal level + * @tsf: Timestamp of last Beacon/Probe Response frame + * @last_update: Time of the last update (i.e., Beacon or Probe Response RX) + * @ie_len: length of the following IE field in octets (from Probe Response) + * @beacon_ie_len: length of the following Beacon IE field in octets + * + * This structure is used to store information about neighboring BSSes in + * generic format. It is mainly updated based on scan results from the driver. + */ +struct wpa_bss { + struct dl_list list; + struct dl_list list_id; + unsigned int id; + unsigned int scan_miss_count; + unsigned int last_update_idx; + unsigned int flags; + u8 bssid[ETH_ALEN]; + u8 ssid[32]; + size_t ssid_len; + int freq; + u16 beacon_int; + u16 caps; + int qual; + int noise; + int level; + u64 tsf; + struct os_time last_update; + size_t ie_len; + size_t beacon_ie_len; + /* followed by ie_len octets of IEs */ + /* followed by beacon_ie_len octets of IEs */ +}; + +void wpa_bss_update_start(struct wpa_supplicant *wpa_s); +void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s, + struct wpa_scan_res *res); +void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, + int new_scan); +int wpa_bss_init(struct wpa_supplicant *wpa_s); +void wpa_bss_deinit(struct wpa_supplicant *wpa_s); +struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid, + const u8 *ssid, size_t ssid_len); +struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s, + const u8 *bssid); +struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id); +const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie); +const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type); +struct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss, + u32 vendor_type); +int wpa_bss_get_max_rate(const struct wpa_bss *bss); +int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates); + +#endif /* BSS_H */ diff --git a/contrib/wpa/wpa_supplicant/config.c b/contrib/wpa/wpa_supplicant/config.c index 9a79374..7e2a5b4 100644 --- a/contrib/wpa/wpa_supplicant/config.c +++ b/contrib/wpa/wpa_supplicant/config.c @@ -15,8 +15,8 @@ #include "includes.h" #include "common.h" -#include "wpa.h" -#include "sha1.h" +#include "crypto/sha1.h" +#include "rsn_supp/wpa.h" #include "eap_peer/eap.h" #include "config.h" @@ -917,6 +917,130 @@ static char * wpa_config_write_auth_alg(const struct parse_data *data, #endif /* NO_CONFIG_WRITE */ +static int * wpa_config_parse_freqs(const struct parse_data *data, + struct wpa_ssid *ssid, int line, + const char *value) +{ + int *freqs; + size_t used, len; + const char *pos; + + used = 0; + len = 10; + freqs = os_zalloc((len + 1) * sizeof(int)); + if (freqs == NULL) + return NULL; + + pos = value; + while (pos) { + while (*pos == ' ') + pos++; + if (used == len) { + int *n; + size_t i; + n = os_realloc(freqs, (len * 2 + 1) * sizeof(int)); + if (n == NULL) { + os_free(freqs); + return NULL; + } + for (i = len; i <= len * 2; i++) + n[i] = 0; + freqs = n; + len *= 2; + } + + freqs[used] = atoi(pos); + if (freqs[used] == 0) + break; + used++; + pos = os_strchr(pos + 1, ' '); + } + + return freqs; +} + + +static int wpa_config_parse_scan_freq(const struct parse_data *data, + struct wpa_ssid *ssid, int line, + const char *value) +{ + int *freqs; + + freqs = wpa_config_parse_freqs(data, ssid, line, value); + if (freqs == NULL) + return -1; + os_free(ssid->scan_freq); + ssid->scan_freq = freqs; + + return 0; +} + + +static int wpa_config_parse_freq_list(const struct parse_data *data, + struct wpa_ssid *ssid, int line, + const char *value) +{ + int *freqs; + + freqs = wpa_config_parse_freqs(data, ssid, line, value); + if (freqs == NULL) + return -1; + os_free(ssid->freq_list); + ssid->freq_list = freqs; + + return 0; +} + + +#ifndef NO_CONFIG_WRITE +static char * wpa_config_write_freqs(const struct parse_data *data, + const int *freqs) +{ + char *buf, *pos, *end; + int i, ret; + size_t count; + + if (freqs == NULL) + return NULL; + + count = 0; + for (i = 0; freqs[i]; i++) + count++; + + pos = buf = os_zalloc(10 * count + 1); + if (buf == NULL) + return NULL; + end = buf + 10 * count + 1; + + for (i = 0; freqs[i]; i++) { + ret = os_snprintf(pos, end - pos, "%s%u", + i == 0 ? "" : " ", freqs[i]); + if (ret < 0 || ret >= end - pos) { + end[-1] = '\0'; + return buf; + } + pos += ret; + } + + return buf; +} + + +static char * wpa_config_write_scan_freq(const struct parse_data *data, + struct wpa_ssid *ssid) +{ + return wpa_config_write_freqs(data, ssid->scan_freq); +} + + +static char * wpa_config_write_freq_list(const struct parse_data *data, + struct wpa_ssid *ssid) +{ + return wpa_config_write_freqs(data, ssid->freq_list); +} +#endif /* NO_CONFIG_WRITE */ + + #ifdef IEEE8021X_EAPOL static int wpa_config_parse_eap(const struct parse_data *data, struct wpa_ssid *ssid, int line, @@ -1317,6 +1441,8 @@ static const struct parse_data ssid_fields[] = { { FUNC(pairwise) }, { FUNC(group) }, { FUNC(auth_alg) }, + { FUNC(scan_freq) }, + { FUNC(freq_list) }, #ifdef IEEE8021X_EAPOL { FUNC(eap) }, { STR_LENe(identity) }, @@ -1366,7 +1492,7 @@ static const struct parse_data ssid_fields[] = { { STRe(pac_file) }, { INTe(fragment_size) }, #endif /* IEEE8021X_EAPOL */ - { INT_RANGE(mode, 0, 1) }, + { INT_RANGE(mode, 0, 2) }, { INT_RANGE(proactive_key_caching, 0, 1) }, { INT_RANGE(disabled, 0, 1) }, { STR(id_str) }, @@ -1376,7 +1502,8 @@ static const struct parse_data ssid_fields[] = { { INT_RANGE(peerkey, 0, 1) }, { INT_RANGE(mixed_cell, 0, 1) }, { INT_RANGE(frequency, 0, 10000) }, - { INT(wpa_ptk_rekey) } + { INT(wpa_ptk_rekey) }, + { STR(bgscan) }, }; #undef OFFSET @@ -1460,7 +1587,7 @@ int wpa_config_add_prio_network(struct wpa_config *config, * configuration when a network is being added or removed. This is also called * if a priority for a network is changed. */ -static int wpa_config_update_prio_list(struct wpa_config *config) +int wpa_config_update_prio_list(struct wpa_config *config) { struct wpa_ssid *ssid; int ret = 0; @@ -1540,6 +1667,9 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid) eap_peer_config_free(&ssid->eap); #endif /* IEEE8021X_EAPOL */ os_free(ssid->id_str); + os_free(ssid->scan_freq); + os_free(ssid->freq_list); + os_free(ssid->bgscan); os_free(ssid); } @@ -1576,11 +1706,9 @@ void wpa_config_free(struct wpa_config *config) os_free(config->ctrl_interface); os_free(config->ctrl_interface_group); -#ifdef EAP_TLS_OPENSSL os_free(config->opensc_engine_path); os_free(config->pkcs11_engine_path); os_free(config->pkcs11_module_path); -#endif /* EAP_TLS_OPENSSL */ os_free(config->driver_param); os_free(config->device_name); os_free(config->manufacturer); @@ -1588,6 +1716,7 @@ void wpa_config_free(struct wpa_config *config) os_free(config->model_number); os_free(config->serial_number); os_free(config->device_type); + os_free(config->config_methods); os_free(config->pssid); os_free(config); } @@ -1747,6 +1876,65 @@ int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value, } +/** + * wpa_config_get_all - Get all options from network configuration + * @ssid: Pointer to network configuration data + * @get_keys: Determines if keys/passwords will be included in returned list + * Returns: %NULL terminated list of all set keys and their values in the form + * of [key1, val1, key2, val2, ... , NULL] + * + * This function can be used to get list of all configured network properties. + * The caller is responsible for freeing the returned list and all its + * elements. + */ +char ** wpa_config_get_all(struct wpa_ssid *ssid, int get_keys) +{ + const struct parse_data *field; + char *key, *value; + size_t i; + char **props; + int fields_num; + + props = os_zalloc(sizeof(char *) * ((2 * NUM_SSID_FIELDS) + 1)); + if (!props) + return NULL; + + fields_num = 0; + for (i = 0; i < NUM_SSID_FIELDS; i++) { + field = &ssid_fields[i]; + if (field->key_data && !get_keys) + continue; + value = field->writer(field, ssid); + if (value == NULL) + continue; + if (os_strlen(value) == 0) { + os_free(value); + continue; + } + + key = os_strdup(field->name); + if (key == NULL) { + os_free(value); + goto err; + } + + props[fields_num * 2] = key; + props[fields_num * 2 + 1] = value; + + fields_num++; + } + + return props; + +err: + value = *props; + while (value) + os_free(value++); + os_free(props); + return NULL; +} + + #ifndef NO_CONFIG_WRITE /** * wpa_config_get - Get a variable in network configuration @@ -1943,6 +2131,7 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface, config->eapol_version = DEFAULT_EAPOL_VERSION; config->ap_scan = DEFAULT_AP_SCAN; config->fast_reauth = DEFAULT_FAST_REAUTH; + config->bss_max_count = DEFAULT_BSS_MAX_COUNT; if (ctrl_interface) config->ctrl_interface = os_strdup(ctrl_interface); diff --git a/contrib/wpa/wpa_supplicant/config.h b/contrib/wpa/wpa_supplicant/config.h index 4484e91..754e4be 100644 --- a/contrib/wpa/wpa_supplicant/config.h +++ b/contrib/wpa/wpa_supplicant/config.h @@ -22,6 +22,7 @@ #define DEFAULT_AP_SCAN 1 #endif /* CONFIG_NO_SCAN_PROCESSING */ #define DEFAULT_FAST_REAUTH 1 +#define DEFAULT_BSS_MAX_COUNT 200 #include "config_ssid.h" @@ -169,7 +170,6 @@ struct wpa_config { */ int fast_reauth; -#ifdef EAP_TLS_OPENSSL /** * opensc_engine_path - Path to the OpenSSL engine for opensc * @@ -194,7 +194,6 @@ struct wpa_config { * module is not loaded. */ char *pkcs11_module_path; -#endif /* EAP_TLS_OPENSSL */ /** * driver_param - Driver interface parameters @@ -300,6 +299,16 @@ struct wpa_config { char *device_type; /** + * config_methods - Config Methods + * + * This is a space-separated list of supported WPS configuration + * methods. For example, "label display push_button keypad". + * Available methods: usba ethernet label display ext_nfc_token + * int_nfc_token nfc_interface push_button keypad. + */ + char *config_methods; + + /** * os_version - OS Version (WPS) * 4-octet operating system version number */ @@ -323,6 +332,19 @@ struct wpa_config { * ctrl_iface to external program(s) */ int wps_cred_processing; + + /** + * bss_max_count - Maximum number of BSS entries to keep in memory + */ + unsigned int bss_max_count; + + /** + * filter_ssids - SSID-based scan result filtering + * + * 0 = do not filter scan results + * 1 = only include configured SSIDs in scan results/BSS table + */ + int filter_ssids; }; @@ -336,11 +358,13 @@ int wpa_config_remove_network(struct wpa_config *config, int id); void wpa_config_set_network_defaults(struct wpa_ssid *ssid); int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value, int line); +char ** wpa_config_get_all(struct wpa_ssid *ssid, int get_keys); char * wpa_config_get(struct wpa_ssid *ssid, const char *var); char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var); void wpa_config_update_psk(struct wpa_ssid *ssid); int wpa_config_add_prio_network(struct wpa_config *config, struct wpa_ssid *ssid); +int wpa_config_update_prio_list(struct wpa_config *config); const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config, const char *name); void wpa_config_set_blob(struct wpa_config *config, diff --git a/contrib/wpa/wpa_supplicant/config_file.c b/contrib/wpa/wpa_supplicant/config_file.c index 29e494c..5f07045 100644 --- a/contrib/wpa/wpa_supplicant/config_file.c +++ b/contrib/wpa/wpa_supplicant/config_file.c @@ -434,11 +434,9 @@ static const struct global_parse_data global_fields[] = { { INT_RANGE(eapol_version, 1, 2) }, { INT(ap_scan) }, { INT(fast_reauth) }, -#ifdef EAP_TLS_OPENSSL { STR(opensc_engine_path) }, { STR(pkcs11_engine_path) }, { STR(pkcs11_module_path) }, -#endif /* EAP_TLS_OPENSSL */ { STR(driver_param) }, { INT(dot11RSNAConfigPMKLifetime) }, { INT(dot11RSNAConfigPMKReauthThreshold) }, @@ -456,9 +454,12 @@ static const struct global_parse_data global_fields[] = { { STR_RANGE(serial_number, 0, 32) }, { STR(device_type) }, { FUNC(os_version) }, + { STR(config_methods) }, { INT_RANGE(wps_cred_processing, 0, 2) }, #endif /* CONFIG_WPS */ - { FUNC(country) } + { FUNC(country) }, + { INT(bss_max_count) }, + { INT_RANGE(filter_ssids, 0, 1) } }; #undef FUNC @@ -837,7 +838,6 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) fprintf(f, "ap_scan=%d\n", config->ap_scan); if (config->fast_reauth != DEFAULT_FAST_REAUTH) fprintf(f, "fast_reauth=%d\n", config->fast_reauth); -#ifdef EAP_TLS_OPENSSL if (config->opensc_engine_path) fprintf(f, "opensc_engine_path=%s\n", config->opensc_engine_path); @@ -847,7 +847,6 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->pkcs11_module_path) fprintf(f, "pkcs11_module_path=%s\n", config->pkcs11_module_path); -#endif /* EAP_TLS_OPENSSL */ if (config->driver_param) fprintf(f, "driver_param=%s\n", config->driver_param); if (config->dot11RSNAConfigPMKLifetime) @@ -882,6 +881,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (WPA_GET_BE32(config->os_version)) fprintf(f, "os_version=%08x\n", WPA_GET_BE32(config->os_version)); + if (config->config_methods) + fprintf(f, "config_methods=%s\n", config->config_methods); if (config->wps_cred_processing) fprintf(f, "wps_cred_processing=%d\n", config->wps_cred_processing); @@ -890,6 +891,10 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) fprintf(f, "country=%c%c\n", config->country[0], config->country[1]); } + if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT) + fprintf(f, "bss_max_count=%u\n", config->bss_max_count); + if (config->filter_ssids) + fprintf(f, "filter_ssids=%d\n", config->filter_ssids); } #endif /* CONFIG_NO_CONFIG_WRITE */ diff --git a/contrib/wpa/wpa_supplicant/config_ssid.h b/contrib/wpa/wpa_supplicant/config_ssid.h index 5510639..25e87aa 100644 --- a/contrib/wpa/wpa_supplicant/config_ssid.h +++ b/contrib/wpa/wpa_supplicant/config_ssid.h @@ -15,7 +15,7 @@ #ifndef CONFIG_SSID_H #define CONFIG_SSID_H -#include "defs.h" +#include "common/defs.h" #include "eap_peer/eap_config.h" #define MAX_SSID_LEN 32 @@ -271,6 +271,8 @@ struct wpa_ssid { * * 1 = IBSS (ad-hoc, peer-to-peer) * + * 2 = AP (access point) + * * Note: IBSS can only be used with key_mgmt NONE (plaintext and * static WEP) and key_mgmt=WPA-NONE (fixed group key TKIP/CCMP). In * addition, ap_scan has to be set to 2 for IBSS. WPA-None requires @@ -278,7 +280,11 @@ struct wpa_ssid { * pairwise=NONE, group=TKIP (or CCMP, but not both), and psk must also * be set (either directly or using ASCII passphrase). */ - int mode; + enum wpas_mode { + WPAS_MODE_INFRA = 0, + WPAS_MODE_IBSS = 1, + WPAS_MODE_AP = 2, + } mode; /** * disabled - Whether this network is currently disabled @@ -316,11 +322,7 @@ struct wpa_ssid { * This value is used to configure policy for management frame * protection (IEEE 802.11w). 0 = disabled, 1 = optional, 2 = required. */ - enum { - NO_IEEE80211W = 0, - IEEE80211W_OPTIONAL = 1, - IEEE80211W_REQUIRED = 2 - } ieee80211w; + enum mfp_options ieee80211w; #endif /* CONFIG_IEEE80211W */ /** @@ -342,6 +344,35 @@ struct wpa_ssid { * attacks against TKIP deficiencies. */ int wpa_ptk_rekey; + + /** + * scan_freq - Array of frequencies to scan or %NULL for all + * + * This is an optional zero-terminated array of frequencies in + * megahertz (MHz) to include in scan requests when searching for this + * network. This can be used to speed up scanning when the network is + * known to not use all possible channels. + */ + int *scan_freq; + + /** + * bgscan - Background scan and roaming parameters or %NULL if none + * + * This is an optional set of parameters for background scanning and + * roaming within a network (ESS) in following format: + * <bgscan module name>:<module parameters> + */ + char *bgscan; + + /** + * freq_list - Array of allowed frequencies or %NULL for all + * + * This is an optional zero-terminated array of frequencies in + * megahertz (MHz) to allow for selecting the BSS. If set, scan results + * that do not match any of the specified frequencies are not + * considered when selecting a BSS. + */ + int *freq_list; }; #endif /* CONFIG_SSID_H */ diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface.c b/contrib/wpa/wpa_supplicant/ctrl_iface.c index 2b737bc..19fea29 100644 --- a/contrib/wpa/wpa_supplicant/ctrl_iface.c +++ b/contrib/wpa/wpa_supplicant/ctrl_iface.c @@ -1,6 +1,6 @@ /* * WPA Supplicant / Control interface (shared code for all backends) - * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> + * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -12,23 +12,31 @@ * See README and COPYING for more details. */ -#include "includes.h" +#include "utils/includes.h" -#include "common.h" -#include "eloop.h" -#include "wpa.h" -#include "config.h" +#include "utils/common.h" +#include "utils/eloop.h" +#include "common/ieee802_11_defs.h" +#include "common/wpa_ctrl.h" +#include "eap_peer/eap.h" #include "eapol_supp/eapol_supp_sm.h" -#include "wpa_supplicant_i.h" -#include "ctrl_iface.h" +#include "rsn_supp/wpa.h" +#include "rsn_supp/preauth.h" +#include "rsn_supp/pmksa_cache.h" #include "l2_packet/l2_packet.h" -#include "preauth.h" -#include "pmksa_cache.h" -#include "wpa_ctrl.h" -#include "eap_peer/eap.h" -#include "ieee802_11_defs.h" -#include "wps_supplicant.h" #include "wps/wps.h" +#include "config.h" +#include "wpa_supplicant_i.h" +#include "driver_i.h" +#include "wps_supplicant.h" +#include "ibss_rsn.h" +#include "ap.h" +#include "notify.h" +#include "bss.h" +#include "scan.h" +#include "ctrl_iface.h" + +extern struct wpa_driver_ops *wpa_drivers[]; static int wpa_supplicant_global_iface_list(struct wpa_global *global, char *buf, int len); @@ -111,7 +119,7 @@ static int wpa_supplicant_ctrl_iface_stkstart( if (hwaddr_aton(addr, peer)) { wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid " - "address '%s'", peer); + "address '%s'", addr); return -1; } @@ -128,16 +136,24 @@ static int wpa_supplicant_ctrl_iface_ft_ds( struct wpa_supplicant *wpa_s, char *addr) { u8 target_ap[ETH_ALEN]; + struct wpa_bss *bss; + const u8 *mdie; if (hwaddr_aton(addr, target_ap)) { wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid " - "address '%s'", target_ap); + "address '%s'", addr); return -1; } wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap)); - return wpa_ft_start_over_ds(wpa_s->wpa, target_ap); + bss = wpa_bss_get_bssid(wpa_s, target_ap); + if (bss) + mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); + else + mdie = NULL; + + return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie); } #endif /* CONFIG_IEEE80211R */ @@ -146,18 +162,22 @@ static int wpa_supplicant_ctrl_iface_ft_ds( static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s, char *cmd) { - u8 bssid[ETH_ALEN]; + u8 bssid[ETH_ALEN], *_bssid = bssid; if (cmd == NULL || os_strcmp(cmd, "any") == 0) - return wpas_wps_start_pbc(wpa_s, NULL); - - if (hwaddr_aton(cmd, bssid)) { + _bssid = NULL; + else if (hwaddr_aton(cmd, bssid)) { wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'", cmd); return -1; } - return wpas_wps_start_pbc(wpa_s, bssid); +#ifdef CONFIG_AP + if (wpa_s->ap_iface) + return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid); +#endif /* CONFIG_AP */ + + return wpas_wps_start_pbc(wpa_s, _bssid); } @@ -181,6 +201,12 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, return -1; } +#ifdef CONFIG_AP + if (wpa_s->ap_iface) + return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin, + buf, buflen); +#endif /* CONFIG_AP */ + if (pin) { ret = wpas_wps_start_pin(wpa_s, _bssid, pin); if (ret < 0) @@ -203,11 +229,41 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, } +#ifdef CONFIG_WPS_OOB +static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s, + char *cmd) +{ + char *path, *method, *name; + + path = os_strchr(cmd, ' '); + if (path == NULL) + return -1; + *path++ = '\0'; + + method = os_strchr(path, ' '); + if (method == NULL) + return -1; + *method++ = '\0'; + + name = os_strchr(method, ' '); + if (name != NULL) + *name++ = '\0'; + + return wpas_wps_start_oob(wpa_s, cmd, path, method, name); +} +#endif /* CONFIG_WPS_OOB */ + + static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s, char *cmd) { u8 bssid[ETH_ALEN], *_bssid = bssid; char *pin; + char *new_ssid; + char *new_auth; + char *new_encr; + char *new_key; + struct wps_new_ap_settings ap; pin = os_strchr(cmd, ' '); if (pin == NULL) @@ -222,11 +278,83 @@ static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s, return -1; } - return wpas_wps_start_reg(wpa_s, _bssid, pin); + new_ssid = os_strchr(pin, ' '); + if (new_ssid == NULL) + return wpas_wps_start_reg(wpa_s, _bssid, pin, NULL); + *new_ssid++ = '\0'; + + new_auth = os_strchr(new_ssid, ' '); + if (new_auth == NULL) + return -1; + *new_auth++ = '\0'; + + new_encr = os_strchr(new_auth, ' '); + if (new_encr == NULL) + return -1; + *new_encr++ = '\0'; + + new_key = os_strchr(new_encr, ' '); + if (new_key == NULL) + return -1; + *new_key++ = '\0'; + + os_memset(&ap, 0, sizeof(ap)); + ap.ssid_hex = new_ssid; + ap.auth = new_auth; + ap.encr = new_encr; + ap.key_hex = new_key; + return wpas_wps_start_reg(wpa_s, _bssid, pin, &ap); +} + + +#ifdef CONFIG_WPS_ER +static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s, + char *cmd) +{ + char *uuid = cmd, *pin; + pin = os_strchr(uuid, ' '); + if (pin == NULL) + return -1; + *pin++ = '\0'; + return wpas_wps_er_add_pin(wpa_s, uuid, pin); } + + +static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s, + char *cmd) +{ + char *uuid = cmd, *pin; + pin = os_strchr(uuid, ' '); + if (pin == NULL) + return -1; + *pin++ = '\0'; + return wpas_wps_er_learn(wpa_s, uuid, pin); +} +#endif /* CONFIG_WPS_ER */ + #endif /* CONFIG_WPS */ +#ifdef CONFIG_IBSS_RSN +static int wpa_supplicant_ctrl_iface_ibss_rsn( + struct wpa_supplicant *wpa_s, char *addr) +{ + u8 peer[ETH_ALEN]; + + if (hwaddr_aton(addr, peer)) { + wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid " + "address '%s'", addr); + return -1; + } + + wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR, + MAC2STR(peer)); + + return ibss_rsn_start(wpa_s->ibss_rsn, peer); +} +#endif /* CONFIG_IBSS_RSN */ + + static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s, char *rsp) { @@ -355,8 +483,36 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, return pos - buf; pos += ret; } + + switch (ssid->mode) { + case WPAS_MODE_INFRA: + ret = os_snprintf(pos, end - pos, + "mode=station\n"); + break; + case WPAS_MODE_IBSS: + ret = os_snprintf(pos, end - pos, + "mode=IBSS\n"); + break; + case WPAS_MODE_AP: + ret = os_snprintf(pos, end - pos, + "mode=AP\n"); + break; + default: + ret = 0; + break; + } + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; } +#ifdef CONFIG_AP + if (wpa_s->ap_iface) { + pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, + end - pos, + verbose); + } else +#endif /* CONFIG_AP */ pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose); } ret = os_snprintf(pos, end - pos, "wpa_state=%s\n", @@ -616,18 +772,16 @@ static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto, return pos; } -static char * wpa_supplicant_wps_ie_txt(char *pos, char *end, - const struct wpa_scan_res *res) -{ + #ifdef CONFIG_WPS - struct wpabuf *wps_ie; +static char * wpa_supplicant_wps_ie_txt_buf(char *pos, char *end, + struct wpabuf *wps_ie) +{ int ret; const char *txt; - wps_ie = wpa_scan_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE); if (wps_ie == NULL) return pos; - if (wps_is_selected_pbc_registrar(wps_ie)) txt = "[WPS-PBC]"; else if (wps_is_selected_pin_registrar(wps_ie)) @@ -639,15 +793,27 @@ static char * wpa_supplicant_wps_ie_txt(char *pos, char *end, if (ret >= 0 && ret < end - pos) pos += ret; wpabuf_free(wps_ie); + return pos; +} #endif /* CONFIG_WPS */ + +static char * wpa_supplicant_wps_ie_txt(char *pos, char *end, + const struct wpa_bss *bss) +{ +#ifdef CONFIG_WPS + struct wpabuf *wps_ie; + wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); + return wpa_supplicant_wps_ie_txt_buf(pos, end, wps_ie); +#else /* CONFIG_WPS */ return pos; +#endif /* CONFIG_WPS */ } /* Format one result on one text line into a buffer. */ static int wpa_supplicant_ctrl_iface_scan_result( - const struct wpa_scan_res *res, char *buf, size_t buflen) + const struct wpa_bss *bss, char *buf, size_t buflen) { char *pos, *end; int ret; @@ -657,33 +823,38 @@ static int wpa_supplicant_ctrl_iface_scan_result( end = buf + buflen; ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t", - MAC2STR(res->bssid), res->freq, res->level); + MAC2STR(bss->bssid), bss->freq, bss->level); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; - ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); if (ie) pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); - ie2 = wpa_scan_get_ie(res, WLAN_EID_RSN); + ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); if (ie2) pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); - pos = wpa_supplicant_wps_ie_txt(pos, end, res); - if (!ie && !ie2 && res->caps & IEEE80211_CAP_PRIVACY) { + pos = wpa_supplicant_wps_ie_txt(pos, end, bss); + if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { ret = os_snprintf(pos, end - pos, "[WEP]"); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; } - if (res->caps & IEEE80211_CAP_IBSS) { + if (bss->caps & IEEE80211_CAP_IBSS) { ret = os_snprintf(pos, end - pos, "[IBSS]"); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; } + if (bss->caps & IEEE80211_CAP_ESS) { + ret = os_snprintf(pos, end - pos, "[ESS]"); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + } - ie = wpa_scan_get_ie(res, WLAN_EID_SSID); ret = os_snprintf(pos, end - pos, "\t%s", - ie ? wpa_ssid_txt(ie + 2, ie[1]) : ""); + wpa_ssid_txt(bss->ssid, bss->ssid_len)); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; @@ -701,13 +872,8 @@ static int wpa_supplicant_ctrl_iface_scan_results( struct wpa_supplicant *wpa_s, char *buf, size_t buflen) { char *pos, *end; - struct wpa_scan_res *res; + struct wpa_bss *bss; int ret; - size_t i; - - if (wpa_s->scan_res == NULL && - wpa_supplicant_get_scan_results(wpa_s) < 0) - return 0; pos = buf; end = buf + buflen; @@ -717,9 +883,8 @@ static int wpa_supplicant_ctrl_iface_scan_results( return pos - buf; pos += ret; - for (i = 0; i < wpa_s->scan_res->num; i++) { - res = wpa_s->scan_res->res[i]; - ret = wpa_supplicant_ctrl_iface_scan_result(res, pos, + dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { + ret = wpa_supplicant_ctrl_iface_scan_result(bss, pos, end - pos); if (ret < 0 || ret >= end - pos) return pos - buf; @@ -739,37 +904,20 @@ static int wpa_supplicant_ctrl_iface_select_network( /* cmd: "<network id>" or "any" */ if (os_strcmp(cmd, "any") == 0) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any"); - ssid = wpa_s->conf->ssid; - while (ssid) { - ssid->disabled = 0; - ssid = ssid->next; - } - wpa_s->reassociate = 1; - wpa_supplicant_req_scan(wpa_s, 0, 0); - return 0; - } - - id = atoi(cmd); - wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id); + ssid = NULL; + } else { + id = atoi(cmd); + wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id); - ssid = wpa_config_get_network(wpa_s->conf, id); - if (ssid == NULL) { - wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " - "id=%d", id); - return -1; + ssid = wpa_config_get_network(wpa_s->conf, id); + if (ssid == NULL) { + wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " + "network id=%d", id); + return -1; + } } - if (ssid != wpa_s->current_ssid && wpa_s->current_ssid) - wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); - - /* Mark all other networks disabled and trigger reassociation */ - ssid = wpa_s->conf->ssid; - while (ssid) { - ssid->disabled = id != ssid->id; - ssid = ssid->next; - } - wpa_s->reassociate = 1; - wpa_supplicant_req_scan(wpa_s, 0, 0); + wpa_supplicant_select_network(wpa_s, ssid); return 0; } @@ -784,36 +932,19 @@ static int wpa_supplicant_ctrl_iface_enable_network( /* cmd: "<network id>" or "all" */ if (os_strcmp(cmd, "all") == 0) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all"); - ssid = wpa_s->conf->ssid; - while (ssid) { - if (ssid == wpa_s->current_ssid && ssid->disabled) - wpa_s->reassociate = 1; - ssid->disabled = 0; - ssid = ssid->next; - } - if (wpa_s->reassociate) - wpa_supplicant_req_scan(wpa_s, 0, 0); - return 0; - } - - id = atoi(cmd); - wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); - - ssid = wpa_config_get_network(wpa_s->conf, id); - if (ssid == NULL) { - wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " - "id=%d", id); - return -1; - } + ssid = NULL; + } else { + id = atoi(cmd); + wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); - if (wpa_s->current_ssid == NULL && ssid->disabled) { - /* - * Try to reassociate since there is no current configuration - * and a new network was made available. */ - wpa_s->reassociate = 1; - wpa_supplicant_req_scan(wpa_s, 0, 0); + ssid = wpa_config_get_network(wpa_s->conf, id); + if (ssid == NULL) { + wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " + "network id=%d", id); + return -1; + } } - ssid->disabled = 0; + wpa_supplicant_enable_network(wpa_s, ssid); return 0; } @@ -828,30 +959,19 @@ static int wpa_supplicant_ctrl_iface_disable_network( /* cmd: "<network id>" or "all" */ if (os_strcmp(cmd, "all") == 0) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all"); - ssid = wpa_s->conf->ssid; - while (ssid) { - ssid->disabled = 1; - ssid = ssid->next; - } - if (wpa_s->current_ssid) - wpa_supplicant_disassociate(wpa_s, - WLAN_REASON_DEAUTH_LEAVING); - return 0; - } - - id = atoi(cmd); - wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id); + ssid = NULL; + } else { + id = atoi(cmd); + wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id); - ssid = wpa_config_get_network(wpa_s->conf, id); - if (ssid == NULL) { - wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " - "id=%d", id); - return -1; + ssid = wpa_config_get_network(wpa_s->conf, id); + if (ssid == NULL) { + wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " + "network id=%d", id); + return -1; + } } - - if (ssid == wpa_s->current_ssid) - wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); - ssid->disabled = 1; + wpa_supplicant_disable_network(wpa_s, ssid); return 0; } @@ -868,6 +988,9 @@ static int wpa_supplicant_ctrl_iface_add_network( ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) return -1; + + wpas_notify_network_added(wpa_s, ssid); + ssid->disabled = 1; wpa_config_set_network_defaults(ssid); @@ -889,8 +1012,10 @@ static int wpa_supplicant_ctrl_iface_remove_network( wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all"); ssid = wpa_s->conf->ssid; while (ssid) { + struct wpa_ssid *remove_ssid = ssid; id = ssid->id; ssid = ssid->next; + wpas_notify_network_removed(wpa_s, remove_ssid); wpa_config_remove_network(wpa_s->conf, id); } if (wpa_s->current_ssid) { @@ -975,6 +1100,8 @@ static int wpa_supplicant_ctrl_iface_set_network( value[0] == '"' && ssid->ssid_len) || (os_strcmp(name, "ssid") == 0 && ssid->passphrase)) wpa_config_update_psk(ssid); + else if (os_strcmp(name, "priority") == 0) + wpa_config_update_prio_list(wpa_s->conf); return 0; } @@ -1361,36 +1488,49 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, { u8 bssid[ETH_ALEN]; size_t i; - struct wpa_scan_results *results; - struct wpa_scan_res *bss; + struct wpa_bss *bss; int ret; char *pos, *end; const u8 *ie, *ie2; - if (wpa_s->scan_res == NULL && - wpa_supplicant_get_scan_results(wpa_s) < 0) - return 0; - - results = wpa_s->scan_res; - if (results == NULL) - return 0; - - if (hwaddr_aton(cmd, bssid) == 0) { - for (i = 0; i < results->num; i++) { - if (os_memcmp(bssid, results->res[i]->bssid, ETH_ALEN) - == 0) - break; + if (os_strcmp(cmd, "FIRST") == 0) + bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list); + else if (os_strncmp(cmd, "ID-", 3) == 0) { + i = atoi(cmd + 3); + bss = wpa_bss_get_id(wpa_s, i); + } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { + i = atoi(cmd + 5); + bss = wpa_bss_get_id(wpa_s, i); + if (bss) { + struct dl_list *next = bss->list_id.next; + if (next == &wpa_s->bss_id) + bss = NULL; + else + bss = dl_list_entry(next, struct wpa_bss, + list_id); } - } else + } else if (hwaddr_aton(cmd, bssid) == 0) + bss = wpa_bss_get_bssid(wpa_s, bssid); + else { + struct wpa_bss *tmp; i = atoi(cmd); + bss = NULL; + dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id) + { + if (i-- == 0) { + bss = tmp; + break; + } + } + } - if (i >= results->num || results->res[i] == NULL) - return 0; /* no match found */ + if (bss == NULL) + return 0; - bss = results->res[i]; pos = buf; end = buf + buflen; ret = os_snprintf(pos, end - pos, + "id=%u\n" "bssid=" MACSTR "\n" "freq=%d\n" "beacon_int=%d\n" @@ -1400,6 +1540,7 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, "level=%d\n" "tsf=%016llu\n" "ie=", + bss->id, MAC2STR(bss->bssid), bss->freq, bss->beacon_int, bss->caps, bss->qual, bss->noise, bss->level, (unsigned long long) bss->tsf); @@ -1425,10 +1566,10 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, return pos - buf; pos += ret; - ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); if (ie) pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); - ie2 = wpa_scan_get_ie(bss, WLAN_EID_RSN); + ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); if (ie2) pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); pos = wpa_supplicant_wps_ie_txt(pos, end, bss); @@ -1444,19 +1585,32 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, return pos - buf; pos += ret; } + if (bss->caps & IEEE80211_CAP_ESS) { + ret = os_snprintf(pos, end - pos, "[ESS]"); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + } ret = os_snprintf(pos, end - pos, "\n"); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; - ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); ret = os_snprintf(pos, end - pos, "ssid=%s\n", - ie ? wpa_ssid_txt(ie + 2, ie[1]) : ""); + wpa_ssid_txt(bss->ssid, bss->ssid_len)); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; +#ifdef CONFIG_WPS + ie = (const u8 *) (bss + 1); + ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; +#endif /* CONFIG_WPS */ + return pos - buf; } @@ -1465,10 +1619,71 @@ static int wpa_supplicant_ctrl_iface_ap_scan( struct wpa_supplicant *wpa_s, char *cmd) { int ap_scan = atoi(cmd); + return wpa_supplicant_set_ap_scan(wpa_s, ap_scan); +} + + +static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s) +{ + u8 *bcast = (u8 *) "\xff\xff\xff\xff\xff\xff"; + + wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication"); + /* MLME-DELETEKEYS.request */ + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 0, 0, NULL, 0, NULL, 0); + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 1, 0, NULL, 0, NULL, 0); + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 2, 0, NULL, 0, NULL, 0); + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 3, 0, NULL, 0, NULL, 0); +#ifdef CONFIG_IEEE80211W + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 4, 0, NULL, 0, NULL, 0); + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 5, 0, NULL, 0, NULL, 0); +#endif /* CONFIG_IEEE80211W */ + + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL, + 0); + /* MLME-SETPROTECTION.request(None) */ + wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid, + MLME_SETPROTECTION_PROTECT_TYPE_NONE, + MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); + wpa_sm_drop_sa(wpa_s->wpa); +} + - if (ap_scan < 0 || ap_scan > 2) +static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s, + char *addr) +{ + u8 bssid[ETH_ALEN]; + struct wpa_bss *bss; + struct wpa_ssid *ssid = wpa_s->current_ssid; + + if (hwaddr_aton(addr, bssid)) { + wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid " + "address '%s'", addr); + return -1; + } + + wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid)); + + bss = wpa_bss_get_bssid(wpa_s, bssid); + if (!bss) { + wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found " + "from BSS table"); + return -1; + } + + /* + * TODO: Find best network configuration block from configuration to + * allow roaming to other networks + */ + + if (!ssid) { + wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network " + "configuration known for the target AP"); return -1; - wpa_s->conf->ap_scan = ap_scan; + } + + wpa_s->reassociate = 1; + wpa_supplicant_connect(wpa_s, bss, ssid); + return 0; } @@ -1517,7 +1732,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, reply_len = wpa_supplicant_ctrl_iface_status( wpa_s, buf + 6, reply, reply_size); } else if (os_strcmp(buf, "PMKSA") == 0) { - reply_len = pmksa_cache_list(wpa_s->wpa, reply, reply_size); + reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply, + reply_size); } else if (os_strncmp(buf, "SET ", 4) == 0) { if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) reply_len = -1; @@ -1561,10 +1777,37 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8, reply, reply_size); +#ifdef CONFIG_WPS_OOB + } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) { + if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8)) + reply_len = -1; +#endif /* CONFIG_WPS_OOB */ } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) { if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8)) reply_len = -1; +#ifdef CONFIG_WPS_ER + } else if (os_strcmp(buf, "WPS_ER_START") == 0) { + if (wpas_wps_er_start(wpa_s)) + reply_len = -1; + } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) { + if (wpas_wps_er_stop(wpa_s)) + reply_len = -1; + } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) { + if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11)) + reply_len = -1; + } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) { + if (wpas_wps_er_pbc(wpa_s, buf + 11)) + reply_len = -1; + } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) { + if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13)) + reply_len = -1; +#endif /* CONFIG_WPS_ER */ #endif /* CONFIG_WPS */ +#ifdef CONFIG_IBSS_RSN + } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) { + if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9)) + reply_len = -1; +#endif /* CONFIG_IBSS_RSN */ } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) { if (wpa_supplicant_ctrl_iface_ctrl_rsp( @@ -1576,7 +1819,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, if (wpa_supplicant_reload_configuration(wpa_s)) reply_len = -1; } else if (os_strcmp(buf, "TERMINATE") == 0) { - eloop_terminate(); + wpa_supplicant_terminate_proc(wpa_s->global); } else if (os_strncmp(buf, "BSSID ", 6) == 0) { if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) reply_len = -1; @@ -1586,7 +1829,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strcmp(buf, "DISCONNECT") == 0) { wpa_s->reassociate = 0; wpa_s->disconnected = 1; - wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); + wpa_supplicant_deauthenticate(wpa_s, + WLAN_REASON_DEAUTH_LEAVING); } else if (os_strcmp(buf, "SCAN") == 0) { wpa_s->scan_req = 2; wpa_supplicant_req_scan(wpa_s, 0, 0); @@ -1634,6 +1878,25 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "BSS ", 4) == 0) { reply_len = wpa_supplicant_ctrl_iface_bss( wpa_s, buf + 4, reply, reply_size); +#ifdef CONFIG_AP + } else if (os_strcmp(buf, "STA-FIRST") == 0) { + reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); + } else if (os_strncmp(buf, "STA ", 4) == 0) { + reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply, + reply_size); + } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { + reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, + reply_size); +#endif /* CONFIG_AP */ + } else if (os_strcmp(buf, "SUSPEND") == 0) { + wpas_notify_suspend(wpa_s->global); + } else if (os_strcmp(buf, "RESUME") == 0) { + wpas_notify_resume(wpa_s->global); + } else if (os_strcmp(buf, "DROP_SA") == 0) { + wpa_supplicant_ctrl_iface_drop_sa(wpa_s); + } else if (os_strncmp(buf, "ROAM ", 5) == 0) { + if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5)) + reply_len = -1; } else { os_memcpy(reply, "UNKNOWN COMMAND\n", 16); reply_len = 16; @@ -1765,11 +2028,11 @@ static int wpa_supplicant_global_iface_list(struct wpa_global *global, struct wpa_interface_info *iface = NULL, *last = NULL, *tmp; char *pos, *end; - for (i = 0; wpa_supplicant_drivers[i]; i++) { - struct wpa_driver_ops *drv = wpa_supplicant_drivers[i]; + for (i = 0; wpa_drivers[i]; i++) { + struct wpa_driver_ops *drv = wpa_drivers[i]; if (drv->get_interfaces == NULL) continue; - tmp = drv->get_interfaces(global->drv_priv); + tmp = drv->get_interfaces(global->drv_priv[i]); if (tmp == NULL) continue; @@ -1859,7 +2122,11 @@ char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global, reply_len = wpa_supplicant_global_iface_interfaces( global, reply, reply_size); } else if (os_strcmp(buf, "TERMINATE") == 0) { - eloop_terminate(); + wpa_supplicant_terminate_proc(global); + } else if (os_strcmp(buf, "SUSPEND") == 0) { + wpas_notify_suspend(global); + } else if (os_strcmp(buf, "RESUME") == 0) { + wpas_notify_resume(global); } else { os_memcpy(reply, "UNKNOWN COMMAND\n", 16); reply_len = 16; diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface_named_pipe.c b/contrib/wpa/wpa_supplicant/ctrl_iface_named_pipe.c index e8b53b1..5f7e24d 100644 --- a/contrib/wpa/wpa_supplicant/ctrl_iface_named_pipe.c +++ b/contrib/wpa/wpa_supplicant/ctrl_iface_named_pipe.c @@ -20,7 +20,7 @@ #include "eapol_supp/eapol_supp_sm.h" #include "wpa_supplicant_i.h" #include "ctrl_iface.h" -#include "wpa_ctrl.h" +#include "common/wpa_ctrl.h" #ifdef __MINGW32_VERSION /* mingw-w32api v3.1 does not yet include sddl.h, so define needed parts here diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface_udp.c b/contrib/wpa/wpa_supplicant/ctrl_iface_udp.c index 18e4040..110ca4f 100644 --- a/contrib/wpa/wpa_supplicant/ctrl_iface_udp.c +++ b/contrib/wpa/wpa_supplicant/ctrl_iface_udp.c @@ -20,7 +20,7 @@ #include "eapol_supp/eapol_supp_sm.h" #include "wpa_supplicant_i.h" #include "ctrl_iface.h" -#include "wpa_ctrl.h" +#include "common/wpa_ctrl.h" #define COOKIE_LEN 8 diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface_unix.c b/contrib/wpa/wpa_supplicant/ctrl_iface_unix.c index 2a62713..84ac760 100644 --- a/contrib/wpa/wpa_supplicant/ctrl_iface_unix.c +++ b/contrib/wpa/wpa_supplicant/ctrl_iface_unix.c @@ -1,6 +1,6 @@ /* * WPA Supplicant / UNIX domain socket -based control interface - * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi> + * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -18,10 +18,11 @@ #include <grp.h> #include <stddef.h> -#include "common.h" -#include "eloop.h" -#include "config.h" +#include "utils/common.h" +#include "utils/eloop.h" +#include "utils/list.h" #include "eapol_supp/eapol_supp_sm.h" +#include "config.h" #include "wpa_supplicant_i.h" #include "ctrl_iface.h" @@ -35,7 +36,7 @@ * ctrl_iface_unix.c and should not be touched directly from other files. */ struct wpa_ctrl_dst { - struct wpa_ctrl_dst *next; + struct dl_list list; struct sockaddr_un addr; socklen_t addrlen; int debug_level; @@ -46,7 +47,7 @@ struct wpa_ctrl_dst { struct ctrl_iface_priv { struct wpa_supplicant *wpa_s; int sock; - struct wpa_ctrl_dst *ctrl_dst; + struct dl_list ctrl_dst; }; @@ -67,8 +68,7 @@ static int wpa_supplicant_ctrl_iface_attach(struct ctrl_iface_priv *priv, os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un)); dst->addrlen = fromlen; dst->debug_level = MSG_INFO; - dst->next = priv->ctrl_dst; - priv->ctrl_dst = dst; + dl_list_add(&priv->ctrl_dst, &dst->list); wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached", (u8 *) from->sun_path, fromlen - offsetof(struct sockaddr_un, sun_path)); @@ -80,18 +80,14 @@ static int wpa_supplicant_ctrl_iface_detach(struct ctrl_iface_priv *priv, struct sockaddr_un *from, socklen_t fromlen) { - struct wpa_ctrl_dst *dst, *prev = NULL; + struct wpa_ctrl_dst *dst; - dst = priv->ctrl_dst; - while (dst) { + dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) { if (fromlen == dst->addrlen && os_memcmp(from->sun_path, dst->addr.sun_path, fromlen - offsetof(struct sockaddr_un, sun_path)) == 0) { - if (prev == NULL) - priv->ctrl_dst = dst->next; - else - prev->next = dst->next; + dl_list_del(&dst->list); os_free(dst); wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached", (u8 *) from->sun_path, @@ -99,8 +95,6 @@ static int wpa_supplicant_ctrl_iface_detach(struct ctrl_iface_priv *priv, offsetof(struct sockaddr_un, sun_path)); return 0; } - prev = dst; - dst = dst->next; } return -1; } @@ -115,8 +109,7 @@ static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv, wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level); - dst = priv->ctrl_dst; - while (dst) { + dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) { if (fromlen == dst->addrlen && os_memcmp(from->sun_path, dst->addr.sun_path, fromlen - offsetof(struct sockaddr_un, sun_path)) @@ -128,7 +121,6 @@ static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv, dst->debug_level = atoi(level); return 0; } - dst = dst->next; } return -1; @@ -274,6 +266,7 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) priv = os_zalloc(sizeof(*priv)); if (priv == NULL) return NULL; + dl_list_init(&priv->ctrl_dst); priv->wpa_s = wpa_s; priv->sock = -1; @@ -353,7 +346,7 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) } os_memset(&addr, 0, sizeof(addr)); -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) addr.sun_len = sizeof(addr); #endif /* __FreeBSD__ */ addr.sun_family = AF_UNIX; @@ -433,7 +426,7 @@ void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) char *fname; char *buf, *dir = NULL, *gid_str = NULL; eloop_unregister_read_sock(priv->sock); - if (priv->ctrl_dst) { + if (!dl_list_empty(&priv->ctrl_dst)) { /* * Wait a second before closing the control socket if * there are any attached monitors in order to allow @@ -477,12 +470,9 @@ void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) } free_dst: - dst = priv->ctrl_dst; - while (dst) { - prev = dst; - dst = dst->next; - os_free(prev); - } + dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst, + list) + os_free(dst); os_free(priv); } @@ -506,8 +496,7 @@ static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, struct msghdr msg; struct iovec io[2]; - dst = priv->ctrl_dst; - if (priv->sock < 0 || dst == NULL) + if (priv->sock < 0 || dl_list_empty(&priv->ctrl_dst)) return; res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); @@ -522,8 +511,8 @@ static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, msg.msg_iovlen = 2; idx = 0; - while (dst) { - next = dst->next; + dl_list_for_each_safe(dst, next, &priv->ctrl_dst, struct wpa_ctrl_dst, + list) { if (level >= dst->debug_level) { wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send", (u8 *) dst->addr.sun_path, dst->addrlen - @@ -536,7 +525,9 @@ static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, "%d - %s", idx, errno, strerror(errno)); dst->errors++; - if (dst->errors > 10 || _errno == ENOENT) { + if (dst->errors > 1000 || + (_errno != ENOBUFS && dst->errors > 10) || + _errno == ENOENT) { wpa_supplicant_ctrl_iface_detach( priv, &dst->addr, dst->addrlen); @@ -545,7 +536,6 @@ static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, dst->errors = 0; } idx++; - dst = next; } } @@ -657,7 +647,7 @@ wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global) } os_memset(&addr, 0, sizeof(addr)); -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) addr.sun_len = sizeof(addr); #endif /* __FreeBSD__ */ addr.sun_family = AF_UNIX; diff --git a/contrib/wpa/wpa_supplicant/dbus/.gitignore b/contrib/wpa/wpa_supplicant/dbus/.gitignore new file mode 100644 index 0000000..6db2468 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/.gitignore @@ -0,0 +1 @@ +libwpadbus.a diff --git a/contrib/wpa/wpa_supplicant/dbus/Makefile b/contrib/wpa/wpa_supplicant/dbus/Makefile new file mode 100644 index 0000000..cfaf58d --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/Makefile @@ -0,0 +1,84 @@ +all: libwpadbus.a + +clean: + rm -f *~ *.o *.d + rm -f libwpadbus.a + +install: + @echo Nothing to be made. + +ifndef CC +CC=gcc +endif + +ifndef CFLAGS +CFLAGS = -MMD -O2 -Wall -g +endif + +CFLAGS += -I../../src -I../../src/utils + + +Q=@ +E=echo +ifeq ($(V), 1) +Q= +E=true +endif + +%.o: %.c + $(Q)$(CC) -c -o $@ $(CFLAGS) $< + @$(E) " CC " $< + + +ifdef CONFIG_WPS +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) +endif +ifndef DBUS_INCLUDE +DBUS_INCLUDE := $(shell pkg-config --cflags dbus-1) +endif +ifdef CONFIG_CTRL_IFACE_DBUS_INTRO +CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO +DBUS_INCLUDE += $(shell xml2-config --cflags) +DBUS_LIBS += $(shell xml2-config --libs) +endif + +dbus_version=$(subst ., ,$(shell pkg-config --modversion dbus-1)) +DBUS_VERSION_MAJOR=$(word 1,$(dbus_version)) +DBUS_VERSION_MINOR=$(word 2,$(dbus_version)) +ifeq ($(DBUS_VERSION_MAJOR),) +DBUS_VERSION_MAJOR=0 +endif +ifeq ($(DBUS_VERSION_MINOR),) +DBUS_VERSION_MINOR=0 +endif +DBUS_INCLUDE += -DDBUS_VERSION_MAJOR=$(DBUS_VERSION_MAJOR) +DBUS_INCLUDE += -DDBUS_VERSION_MINOR=$(DBUS_VERSION_MINOR) + +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 \ + dbus_new_introspect.o \ + dbus_dict_helpers.o + +ifdef CONFIG_WPS +LIB_OBJS += dbus_old_handlers_wps.o +LIB_OBJS += dbus_new_handlers_wps.o +endif + +libwpadbus.a: $(LIB_OBJS) + $(AR) crT $@ $? + +-include $(OBJS:%.o=%.d) diff --git a/contrib/wpa/wpa_supplicant/dbus-wpa_supplicant.conf b/contrib/wpa/wpa_supplicant/dbus/dbus-wpa_supplicant.conf index 51a29e3..c091234 100644 --- a/contrib/wpa/wpa_supplicant/dbus-wpa_supplicant.conf +++ b/contrib/wpa/wpa_supplicant/dbus/dbus-wpa_supplicant.conf @@ -7,10 +7,21 @@ <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"/> + <allow send_interface="fi.w1.wpa_supplicant1"/> + <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 send_interface="fi.epitest.hostap.WPASupplicant"/> + + <deny own="fi.w1.wpa_supplicant1"/> + <deny send_destination="fi.w1.wpa_supplicant1"/> + <deny send_interface="fi.w1.wpa_supplicant1"/> + <deny receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/> </policy> </busconfig> diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_common.c b/contrib/wpa/wpa_supplicant/dbus/dbus_common.c new file mode 100644 index 0000000..5850636 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_common.c @@ -0,0 +1,371 @@ +/* + * wpa_supplicant D-Bus control interface - common functionality + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> + * Copyright (c) 2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "utils/includes.h" +#include <dbus/dbus.h> + +#include "utils/common.h" +#include "utils/eloop.h" +#include "dbus_common.h" +#include "dbus_common_i.h" +#include "dbus_new.h" +#include "dbus_old.h" + + +#ifndef SIGPOLL +#ifdef SIGIO +/* + * If we do not have SIGPOLL, try to use SIGIO instead. This is needed for + * FreeBSD. + */ +#define SIGPOLL SIGIO +#endif +#endif + + +static void dispatch_data(DBusConnection *con) +{ + while (dbus_connection_get_dispatch_status(con) == + DBUS_DISPATCH_DATA_REMAINS) + dbus_connection_dispatch(con); +} + + +/** + * dispatch_initial_dbus_messages - Dispatch initial dbus messages after + * claiming bus name + * @eloop_ctx: the DBusConnection to dispatch on + * @timeout_ctx: unused + * + * If clients are quick to notice that service claimed its bus name, + * there may have been messages that came in before initialization was + * all finished. Dispatch those here. + */ +static void dispatch_initial_dbus_messages(void *eloop_ctx, void *timeout_ctx) +{ + DBusConnection *con = eloop_ctx; + dispatch_data(con); +} + + +static void process_watch(struct wpas_dbus_priv *priv, + DBusWatch *watch, eloop_event_type type) +{ + dbus_connection_ref(priv->con); + + priv->should_dispatch = 0; + + if (type == EVENT_TYPE_READ) + dbus_watch_handle(watch, DBUS_WATCH_READABLE); + else if (type == EVENT_TYPE_WRITE) + dbus_watch_handle(watch, DBUS_WATCH_WRITABLE); + else if (type == EVENT_TYPE_EXCEPTION) + dbus_watch_handle(watch, DBUS_WATCH_ERROR); + + if (priv->should_dispatch) { + dispatch_data(priv->con); + priv->should_dispatch = 0; + } + + dbus_connection_unref(priv->con); +} + + +static void process_watch_exception(int sock, void *eloop_ctx, void *sock_ctx) +{ + process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_EXCEPTION); +} + + +static void process_watch_read(int sock, void *eloop_ctx, void *sock_ctx) +{ + process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_READ); +} + + +static void process_watch_write(int sock, void *eloop_ctx, void *sock_ctx) +{ + process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_WRITE); +} + + +static dbus_bool_t add_watch(DBusWatch *watch, void *data) +{ + struct wpas_dbus_priv *priv = data; + unsigned int flags; + int fd; + + if (!dbus_watch_get_enabled(watch)) + return TRUE; + + flags = dbus_watch_get_flags(watch); + fd = dbus_watch_get_unix_fd(watch); + + eloop_register_sock(fd, EVENT_TYPE_EXCEPTION, process_watch_exception, + priv, watch); + + if (flags & DBUS_WATCH_READABLE) { + eloop_register_sock(fd, EVENT_TYPE_READ, process_watch_read, + priv, watch); + } + if (flags & DBUS_WATCH_WRITABLE) { + eloop_register_sock(fd, EVENT_TYPE_WRITE, process_watch_write, + priv, watch); + } + + dbus_watch_set_data(watch, priv, NULL); + + return TRUE; +} + + +static void remove_watch(DBusWatch *watch, void *data) +{ + unsigned int flags; + int fd; + + flags = dbus_watch_get_flags(watch); + fd = dbus_watch_get_unix_fd(watch); + + eloop_unregister_sock(fd, EVENT_TYPE_EXCEPTION); + + if (flags & DBUS_WATCH_READABLE) + eloop_unregister_sock(fd, EVENT_TYPE_READ); + if (flags & DBUS_WATCH_WRITABLE) + eloop_unregister_sock(fd, EVENT_TYPE_WRITE); + + dbus_watch_set_data(watch, NULL, NULL); +} + + +static void watch_toggled(DBusWatch *watch, void *data) +{ + if (dbus_watch_get_enabled(watch)) + add_watch(watch, data); + else + remove_watch(watch, data); +} + + +static void process_timeout(void *eloop_ctx, void *sock_ctx) +{ + DBusTimeout *timeout = sock_ctx; + dbus_timeout_handle(timeout); +} + + +static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) +{ + struct wpas_dbus_priv *priv = data; + if (!dbus_timeout_get_enabled(timeout)) + return TRUE; + + eloop_register_timeout(0, dbus_timeout_get_interval(timeout) * 1000, + process_timeout, priv, timeout); + + dbus_timeout_set_data(timeout, priv, NULL); + + return TRUE; +} + + +static void remove_timeout(DBusTimeout *timeout, void *data) +{ + struct wpas_dbus_priv *priv = data; + eloop_cancel_timeout(process_timeout, priv, timeout); + dbus_timeout_set_data(timeout, NULL, NULL); +} + + +static void timeout_toggled(DBusTimeout *timeout, void *data) +{ + if (dbus_timeout_get_enabled(timeout)) + add_timeout(timeout, data); + else + remove_timeout(timeout, data); +} + + +static void process_wakeup_main(int sig, void *signal_ctx) +{ + struct wpas_dbus_priv *priv = signal_ctx; + + if (sig != SIGPOLL || !priv->con) + return; + + if (dbus_connection_get_dispatch_status(priv->con) != + DBUS_DISPATCH_DATA_REMAINS) + return; + + /* Only dispatch once - we do not want to starve other events */ + dbus_connection_ref(priv->con); + dbus_connection_dispatch(priv->con); + dbus_connection_unref(priv->con); +} + + +/** + * wakeup_main - Attempt to wake our mainloop up + * @data: dbus control interface private data + * + * Try to wake up the main eloop so it will process + * dbus events that may have happened. + */ +static void wakeup_main(void *data) +{ + struct wpas_dbus_priv *priv = data; + + /* Use SIGPOLL to break out of the eloop select() */ + raise(SIGPOLL); + priv->should_dispatch = 1; +} + + +/** + * integrate_with_eloop - Register our mainloop integration with dbus + * @connection: connection to the system message bus + * @priv: a dbus control interface data structure + * Returns: 0 on success, -1 on failure + */ +static int integrate_with_eloop(struct wpas_dbus_priv *priv) +{ + if (!dbus_connection_set_watch_functions(priv->con, add_watch, + remove_watch, watch_toggled, + priv, NULL) || + !dbus_connection_set_timeout_functions(priv->con, add_timeout, + remove_timeout, + timeout_toggled, priv, + NULL)) { + wpa_printf(MSG_ERROR, "dbus: Failed to set callback " + "functions"); + return -1; + } + + if (eloop_register_signal(SIGPOLL, process_wakeup_main, priv)) + return -1; + dbus_connection_set_wakeup_main_function(priv->con, wakeup_main, + priv, NULL); + + return 0; +} + + +static int wpas_dbus_init_common(struct wpas_dbus_priv *priv) +{ + DBusError error; + int ret = 0; + + /* Get a reference to the system bus */ + dbus_error_init(&error); + priv->con = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (!priv->con) { + wpa_printf(MSG_ERROR, "dbus: Could not acquire the system " + "bus: %s - %s", error.name, error.message); + ret = -1; + } + dbus_error_free(&error); + + return ret; +} + + +static int wpas_dbus_init_common_finish(struct wpas_dbus_priv *priv) +{ + /* Tell dbus about our mainloop integration functions */ + integrate_with_eloop(priv); + + /* + * Dispatch initial DBus messages that may have come in since the bus + * name was claimed above. Happens when clients are quick to notice the + * service. + * + * FIXME: is there a better solution to this problem? + */ + eloop_register_timeout(0, 50, dispatch_initial_dbus_messages, + priv->con, NULL); + + return 0; +} + + +static void wpas_dbus_deinit_common(struct wpas_dbus_priv *priv) +{ + if (priv->con) { + eloop_cancel_timeout(dispatch_initial_dbus_messages, + priv->con, NULL); + dbus_connection_set_watch_functions(priv->con, NULL, NULL, + NULL, NULL, NULL); + dbus_connection_set_timeout_functions(priv->con, NULL, NULL, + NULL, NULL, NULL); + dbus_connection_unref(priv->con); + } + + os_free(priv); +} + + +struct wpas_dbus_priv * wpas_dbus_init(struct wpa_global *global) +{ + struct wpas_dbus_priv *priv; + + priv = os_zalloc(sizeof(*priv)); + if (priv == NULL) + return NULL; + priv->global = global; + + if (wpas_dbus_init_common(priv) < 0) { + wpas_dbus_deinit(priv); + return NULL; + } + +#ifdef CONFIG_CTRL_IFACE_DBUS_NEW + if (wpas_dbus_ctrl_iface_init(priv) < 0) { + wpas_dbus_deinit(priv); + return NULL; + } +#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ + +#ifdef CONFIG_CTRL_IFACE_DBUS + if (wpa_supplicant_dbus_ctrl_iface_init(priv) < 0) { + wpas_dbus_deinit(priv); + return NULL; + } +#endif /* CONFIG_CTRL_IFACE_DBUS */ + + if (wpas_dbus_init_common_finish(priv) < 0) { + wpas_dbus_deinit(priv); + return NULL; + } + + return priv; +} + + +void wpas_dbus_deinit(struct wpas_dbus_priv *priv) +{ + if (priv == NULL) + return; + +#ifdef CONFIG_CTRL_IFACE_DBUS_NEW + 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/contrib/wpa/wpa_supplicant/dbus/dbus_common.h b/contrib/wpa/wpa_supplicant/dbus/dbus_common.h new file mode 100644 index 0000000..50da09b --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_common.h @@ -0,0 +1,26 @@ +/* + * wpa_supplicant D-Bus control interface - common definitions + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> + * Copyright (c) 2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef DBUS_COMMON_H +#define DBUS_COMMON_H + +struct wpas_dbus_priv; +struct wpa_global; + +struct wpas_dbus_priv * wpas_dbus_init(struct wpa_global *global); +void wpas_dbus_deinit(struct wpas_dbus_priv *priv); + +#endif /* DBUS_COMMON_H */ diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_common_i.h b/contrib/wpa/wpa_supplicant/dbus/dbus_common_i.h new file mode 100644 index 0000000..9dab1ee --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_common_i.h @@ -0,0 +1,30 @@ +/* + * wpa_supplicant D-Bus control interface - internal definitions + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> + * Copyright (c) 2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef DBUS_COMMON_I_H +#define DBUS_COMMON_I_H + +#include <dbus/dbus.h> + +struct wpas_dbus_priv { + DBusConnection *con; + int should_dispatch; + struct wpa_global *global; + u32 next_objid; + int dbus_new_initialized; +}; + +#endif /* DBUS_COMMON_I_H */ diff --git a/contrib/wpa/wpa_supplicant/dbus_dict_helpers.c b/contrib/wpa/wpa_supplicant/dbus/dbus_dict_helpers.c index f93fc9d..b3aff40 100644 --- a/contrib/wpa/wpa_supplicant/dbus_dict_helpers.c +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_dict_helpers.c @@ -69,7 +69,7 @@ dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter, } -static const char * _wpa_get_type_as_string_from_type(const int type) +const char * wpa_dbus_type_as_string(const int type) { switch(type) { case DBUS_TYPE_BYTE: @@ -140,7 +140,10 @@ static dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict, DBusMessageIter iter_dict_entry, iter_dict_val; const char *type_as_string = NULL; - type_as_string = _wpa_get_type_as_string_from_type(value_type); + if (key == NULL) + return FALSE; + + type_as_string = wpa_dbus_type_as_string(value_type); if (!type_as_string) return FALSE; @@ -218,7 +221,7 @@ static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array( dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict, const char *key, const char *value) { - if (!key || !value) + if (!value) return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING, &value); @@ -238,8 +241,6 @@ dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict, dbus_bool_t wpa_dbus_dict_append_byte(DBusMessageIter *iter_dict, const char *key, const char value) { - if (!key) - return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_BYTE, &value); } @@ -258,8 +259,6 @@ dbus_bool_t wpa_dbus_dict_append_byte(DBusMessageIter *iter_dict, dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict, const char *key, const dbus_bool_t value) { - if (!key) - return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_BOOLEAN, &value); } @@ -279,8 +278,6 @@ dbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict, const char *key, const dbus_int16_t value) { - if (!key) - return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16, &value); } @@ -300,8 +297,6 @@ dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict, const char *key, const dbus_uint16_t value) { - if (!key) - return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16, &value); } @@ -321,8 +316,6 @@ dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict, const char *key, const dbus_int32_t value) { - if (!key) - return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32, &value); } @@ -342,8 +335,6 @@ dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict, const char *key, const dbus_uint32_t value) { - if (!key) - return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32, &value); } @@ -363,8 +354,6 @@ dbus_bool_t wpa_dbus_dict_append_int64(DBusMessageIter *iter_dict, const char *key, const dbus_int64_t value) { - if (!key) - return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT64, &value); } @@ -384,8 +373,6 @@ dbus_bool_t wpa_dbus_dict_append_uint64(DBusMessageIter *iter_dict, const char *key, const dbus_uint64_t value) { - if (!key) - return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT64, &value); } @@ -402,11 +389,8 @@ dbus_bool_t wpa_dbus_dict_append_uint64(DBusMessageIter *iter_dict, * */ dbus_bool_t wpa_dbus_dict_append_double(DBusMessageIter *iter_dict, - const char * key, - const double value) + const char *key, const double value) { - if (!key) - return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_DOUBLE, &value); } @@ -426,7 +410,7 @@ dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict, const char *key, const char *value) { - if (!key || !value) + if (!value) return FALSE; return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_OBJECT_PATH, &value); @@ -636,17 +620,14 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array( { dbus_uint32_t count = 0; dbus_bool_t success = FALSE; - char *buffer; + char *buffer, *nbuffer;; entry->bytearray_value = NULL; entry->array_type = DBUS_TYPE_BYTE; buffer = os_zalloc(BYTE_ARRAY_ITEM_SIZE * BYTE_ARRAY_CHUNK_SIZE); - if (!buffer) { - perror("_wpa_dbus_dict_entry_get_byte_array[dbus]: out of " - "memory"); - goto done; - } + if (!buffer) + return FALSE; entry->bytearray_value = buffer; entry->array_len = 0; @@ -654,14 +635,17 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array( char byte; if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) { - buffer = realloc(buffer, BYTE_ARRAY_ITEM_SIZE * - (count + BYTE_ARRAY_CHUNK_SIZE)); - if (buffer == NULL) { - perror("_wpa_dbus_dict_entry_get_byte_array[" - "dbus] out of memory trying to " - "retrieve the string array"); + nbuffer = os_realloc(buffer, BYTE_ARRAY_ITEM_SIZE * + (count + BYTE_ARRAY_CHUNK_SIZE)); + if (nbuffer == NULL) { + os_free(buffer); + wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_" + "entry_get_byte_array out of " + "memory trying to retrieve the " + "string array"); goto done; } + buffer = nbuffer; } entry->bytearray_value = buffer; @@ -673,7 +657,7 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array( /* Zero-length arrays are valid. */ if (entry->array_len == 0) { - free(entry->bytearray_value); + os_free(entry->bytearray_value); entry->bytearray_value = NULL; } @@ -693,17 +677,14 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array( { dbus_uint32_t count = 0; dbus_bool_t success = FALSE; - char **buffer; + char **buffer, **nbuffer; entry->strarray_value = NULL; entry->array_type = DBUS_TYPE_STRING; buffer = os_zalloc(STR_ARRAY_ITEM_SIZE * STR_ARRAY_CHUNK_SIZE); - if (buffer == NULL) { - perror("_wpa_dbus_dict_entry_get_string_array[dbus] out of " - "memory trying to retrieve a string array"); - goto done; - } + if (buffer == NULL) + return FALSE; entry->strarray_value = buffer; entry->array_len = 0; @@ -712,23 +693,26 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array( char *str; if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) { - buffer = realloc(buffer, STR_ARRAY_ITEM_SIZE * - (count + STR_ARRAY_CHUNK_SIZE)); - if (buffer == NULL) { - perror("_wpa_dbus_dict_entry_get_string_array[" - "dbus] out of memory trying to " - "retrieve the string array"); + nbuffer = os_realloc(buffer, STR_ARRAY_ITEM_SIZE * + (count + STR_ARRAY_CHUNK_SIZE)); + if (nbuffer == NULL) { + os_free(buffer); + wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_" + "entry_get_string_array out of " + "memory trying to retrieve the " + "string array"); goto done; } + buffer = nbuffer; } entry->strarray_value = buffer; dbus_message_iter_get_basic(iter, &value); - str = strdup(value); + str = os_strdup(value); if (str == NULL) { - perror("_wpa_dbus_dict_entry_get_string_array[dbus] " - "out of memory trying to duplicate the string " - "array"); + wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_entry_get_" + "string_array out of memory trying to " + "duplicate the string array"); goto done; } entry->strarray_value[count] = str; @@ -738,7 +722,7 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array( /* Zero-length arrays are valid. */ if (entry->array_len == 0) { - free(entry->strarray_value); + os_free(entry->strarray_value); entry->strarray_value = NULL; } @@ -781,87 +765,52 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_array( static dbus_bool_t _wpa_dbus_dict_fill_value_from_variant( - struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter_dict_val) + struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter) { - dbus_bool_t success = TRUE; + const char *v; switch (entry->type) { - case DBUS_TYPE_STRING: { - const char *v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->str_value = strdup(v); - break; - } - case DBUS_TYPE_BOOLEAN: { - dbus_bool_t v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->bool_value = v; - break; - } - case DBUS_TYPE_BYTE: { - char v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->byte_value = v; + case DBUS_TYPE_OBJECT_PATH: + case DBUS_TYPE_STRING: + dbus_message_iter_get_basic(iter, &v); + entry->str_value = os_strdup(v); + if (entry->str_value == NULL) + return FALSE; break; - } - case DBUS_TYPE_INT16: { - dbus_int16_t v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->int16_value = v; + case DBUS_TYPE_BOOLEAN: + dbus_message_iter_get_basic(iter, &entry->bool_value); break; - } - case DBUS_TYPE_UINT16: { - dbus_uint16_t v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->uint16_value = v; + case DBUS_TYPE_BYTE: + dbus_message_iter_get_basic(iter, &entry->byte_value); break; - } - case DBUS_TYPE_INT32: { - dbus_int32_t v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->int32_value = v; + case DBUS_TYPE_INT16: + dbus_message_iter_get_basic(iter, &entry->int16_value); break; - } - case DBUS_TYPE_UINT32: { - dbus_uint32_t v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->uint32_value = v; + case DBUS_TYPE_UINT16: + dbus_message_iter_get_basic(iter, &entry->uint16_value); break; - } - case DBUS_TYPE_INT64: { - dbus_int64_t v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->int64_value = v; + case DBUS_TYPE_INT32: + dbus_message_iter_get_basic(iter, &entry->int32_value); break; - } - case DBUS_TYPE_UINT64: { - dbus_uint64_t v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->uint64_value = v; + case DBUS_TYPE_UINT32: + dbus_message_iter_get_basic(iter, &entry->uint32_value); break; - } - case DBUS_TYPE_DOUBLE: { - double v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->double_value = v; + case DBUS_TYPE_INT64: + dbus_message_iter_get_basic(iter, &entry->int64_value); break; - } - case DBUS_TYPE_OBJECT_PATH: { - char *v; - dbus_message_iter_get_basic(iter_dict_val, &v); - entry->str_value = strdup(v); + case DBUS_TYPE_UINT64: + dbus_message_iter_get_basic(iter, &entry->uint64_value); break; - } - case DBUS_TYPE_ARRAY: { - success = _wpa_dbus_dict_entry_get_array(iter_dict_val, entry); + case DBUS_TYPE_DOUBLE: + dbus_message_iter_get_basic(iter, &entry->double_value); break; - } + case DBUS_TYPE_ARRAY: + return _wpa_dbus_dict_entry_get_array(iter, entry); default: - success = FALSE; - break; + return FALSE; } - return success; + return TRUE; } @@ -933,10 +882,8 @@ error: */ dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict) { - if (!iter_dict) { - perror("wpa_dbus_dict_has_dict_entry[dbus]: out of memory"); + if (!iter_dict) return FALSE; - } return dbus_message_iter_get_arg_type(iter_dict) == DBUS_TYPE_DICT_ENTRY; } @@ -956,17 +903,17 @@ void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry) switch (entry->type) { case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_STRING: - free(entry->str_value); + os_free(entry->str_value); break; case DBUS_TYPE_ARRAY: switch (entry->array_type) { case DBUS_TYPE_BYTE: - free(entry->bytearray_value); + os_free(entry->bytearray_value); break; case DBUS_TYPE_STRING: for (i = 0; i < entry->array_len; i++) - free(entry->strarray_value[i]); - free(entry->strarray_value); + os_free(entry->strarray_value[i]); + os_free(entry->strarray_value); break; } break; diff --git a/contrib/wpa/wpa_supplicant/dbus_dict_helpers.h b/contrib/wpa/wpa_supplicant/dbus/dbus_dict_helpers.h index f873efc..eb31575 100644 --- a/contrib/wpa/wpa_supplicant/dbus_dict_helpers.h +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_dict_helpers.h @@ -25,6 +25,8 @@ dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter, dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter, DBusMessageIter *iter_dict); +const char * wpa_dbus_type_as_string(const int type); + dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict, const char *key, const char *value); diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new.c b/contrib/wpa/wpa_supplicant/dbus/dbus_new.c new file mode 100644 index 0000000..bdfbbac --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new.c @@ -0,0 +1,1562 @@ +/* + * WPA Supplicant / dbus-based control interface + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com> + * Copyright (c) 2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "wps/wps.h" +#include "../config.h" +#include "../wpa_supplicant_i.h" +#include "../bss.h" +#include "dbus_new_helpers.h" +#include "dbus_dict_helpers.h" +#include "dbus_new.h" +#include "dbus_new_handlers.h" +#include "dbus_common.h" +#include "dbus_common_i.h" + + +/** + * wpas_dbus_signal_interface - Send a interface related event signal + * @wpa_s: %wpa_supplicant network interface data + * @sig_name: signal name - InterfaceAdded or InterfaceRemoved + * @properties: Whether to add second argument with object properties + * + * Notify listeners about event related with interface + */ +static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s, + const char *sig_name, int properties) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter, iter_dict; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH, + WPAS_DBUS_NEW_INTERFACE, sig_name); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &iter); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, + &wpa_s->dbus_new_path)) + goto err; + + if (properties) { + if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) + goto err; + + wpa_dbus_get_object_properties(iface, wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + &iter_dict); + + if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) + goto err; + } + + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); + return; + +err: + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_interface_added - Send a interface created signal + * @wpa_s: %wpa_supplicant network interface data + * + * Notify listeners about creating new interface + */ +static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s) +{ + wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE); +} + + +/** + * wpas_dbus_signal_interface_removed - Send a interface removed signal + * @wpa_s: %wpa_supplicant network interface data + * + * Notify listeners about removing interface + */ +static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s) +{ + wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE); + +} + + +/** + * wpas_dbus_signal_scan_done - send scan done signal + * @wpa_s: %wpa_supplicant network interface data + * @success: indicates if scanning succeed or failed + * + * Notify listeners about finishing a scan + */ +void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + dbus_bool_t succ; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + "ScanDone"); + if (msg == NULL) + return; + + succ = success ? TRUE : FALSE; + if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ, + DBUS_TYPE_INVALID)) + dbus_connection_send(iface->con, msg, NULL); + else + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_blob - Send a BSS related event signal + * @wpa_s: %wpa_supplicant network interface data + * @bss_obj_path: BSS object path + * @sig_name: signal name - BSSAdded or BSSRemoved + * @properties: Whether to add second argument with object properties + * + * Notify listeners about event related with BSS + */ +static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s, + const char *bss_obj_path, + const char *sig_name, int properties) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter, iter_dict; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + sig_name); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &iter); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, + &bss_obj_path)) + goto err; + + if (properties) { + if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) + goto err; + + wpa_dbus_get_object_properties(iface, bss_obj_path, + WPAS_DBUS_NEW_IFACE_BSS, + &iter_dict); + + if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) + goto err; + } + + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); + return; + +err: + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_bss_added - Send a BSS added signal + * @wpa_s: %wpa_supplicant network interface data + * @bss_obj_path: new BSS object path + * + * Notify listeners about adding new BSS + */ +static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s, + const char *bss_obj_path) +{ + wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE); +} + + +/** + * wpas_dbus_signal_bss_removed - Send a BSS removed signal + * @wpa_s: %wpa_supplicant network interface data + * @bss_obj_path: BSS object path + * + * Notify listeners about removing BSS + */ +static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s, + const char *bss_obj_path) +{ + wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE); +} + + +/** + * wpas_dbus_signal_blob - Send a blob related event signal + * @wpa_s: %wpa_supplicant network interface data + * @name: blob name + * @sig_name: signal name - BlobAdded or BlobRemoved + * + * Notify listeners about event related with blob + */ +static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s, + const char *name, const char *sig_name) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + sig_name); + if (msg == NULL) + return; + + if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + dbus_connection_send(iface->con, msg, NULL); + else + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_blob_added - Send a blob added signal + * @wpa_s: %wpa_supplicant network interface data + * @name: blob name + * + * Notify listeners about adding a new blob + */ +void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s, + const char *name) +{ + wpas_dbus_signal_blob(wpa_s, name, "BlobAdded"); +} + + +/** + * wpas_dbus_signal_blob_removed - Send a blob removed signal + * @wpa_s: %wpa_supplicant network interface data + * @name: blob name + * + * Notify listeners about removing blob + */ +void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s, + const char *name) +{ + wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved"); +} + + +/** + * wpas_dbus_signal_network - Send a network related event signal + * @wpa_s: %wpa_supplicant network interface data + * @id: new network id + * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected + * @properties: determines if add second argument with object properties + * + * Notify listeners about event related with configured network + */ +static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s, + int id, const char *sig_name, + int properties) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter, iter_dict; + char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", + wpa_s->dbus_new_path, id); + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + sig_name); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &iter); + path = net_obj_path; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, + &path)) + goto err; + + if (properties) { + if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) + goto err; + + wpa_dbus_get_object_properties(iface, net_obj_path, + WPAS_DBUS_NEW_IFACE_NETWORK, + &iter_dict); + + if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) + goto err; + } + + dbus_connection_send(iface->con, msg, NULL); + + dbus_message_unref(msg); + return; + +err: + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_network_added - Send a network added signal + * @wpa_s: %wpa_supplicant network interface data + * @id: new network id + * + * Notify listeners about adding new network + */ +static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s, + int id) +{ + wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE); +} + + +/** + * wpas_dbus_signal_network_removed - Send a network removed signal + * @wpa_s: %wpa_supplicant network interface data + * @id: network id + * + * Notify listeners about removing a network + */ +static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s, + int id) +{ + wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE); +} + + +/** + * wpas_dbus_signal_network_selected - Send a network selected signal + * @wpa_s: %wpa_supplicant network interface data + * @id: network id + * + * Notify listeners about selecting a network + */ +void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id) +{ + wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE); +} + + +/** + * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes + * @wpa_s: %wpa_supplicant network interface data + * @ssid: configured network which Enabled property has changed + * + * Sends PropertyChanged signals containing new value of Enabled property + * for specified network + */ +void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + + char path[WPAS_DBUS_OBJECT_PATH_MAX]; + os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d", + wpa_s->dbus_new_path, ssid->id); + + wpa_dbus_mark_property_changed(wpa_s->global->dbus, path, + WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled"); +} + + +#ifdef CONFIG_WPS + +/** + * wpas_dbus_signal_wps_event_success - Signals Success WPS event + * @wpa_s: %wpa_supplicant network interface data + * + * Sends Event dbus signal with name "success" and empty dict as arguments + */ +void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s) +{ + + DBusMessage *msg; + DBusMessageIter iter, dict_iter; + struct wpas_dbus_priv *iface; + char *key = "success"; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_WPS, "Event"); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) || + !wpa_dbus_dict_open_write(&iter, &dict_iter) || + !wpa_dbus_dict_close_write(&iter, &dict_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_wps_event_fail - Signals Fail WPS event + * @wpa_s: %wpa_supplicant network interface data + * + * Sends Event dbus signal with name "fail" and dictionary containing + * "msg field with fail message number (int32) as arguments + */ +void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s, + struct wps_event_fail *fail) +{ + + DBusMessage *msg; + DBusMessageIter iter, dict_iter; + struct wpas_dbus_priv *iface; + char *key = "fail"; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_WPS, "Event"); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) || + !wpa_dbus_dict_open_write(&iter, &dict_iter) || + !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) || + !wpa_dbus_dict_close_write(&iter, &dict_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_wps_event_m2d - Signals M2D WPS event + * @wpa_s: %wpa_supplicant network interface data + * + * Sends Event dbus signal with name "m2d" and dictionary containing + * fields of wps_event_m2d structure. + */ +void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s, + struct wps_event_m2d *m2d) +{ + + DBusMessage *msg; + DBusMessageIter iter, dict_iter; + struct wpas_dbus_priv *iface; + char *key = "m2d"; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_WPS, "Event"); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) || + !wpa_dbus_dict_open_write(&iter, &dict_iter) || + !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods", + m2d->config_methods) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer", + (const char *) m2d->manufacturer, + m2d->manufacturer_len) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name", + (const char *) m2d->model_name, + m2d->model_name_len) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number", + (const char *) m2d->model_number, + m2d->model_number_len) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number", + (const char *) + m2d->serial_number, + m2d->serial_number_len) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name", + (const char *) m2d->dev_name, + m2d->dev_name_len) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type", + (const char *) + m2d->primary_dev_type, 8) || + !wpa_dbus_dict_append_uint16(&dict_iter, "config_error", + m2d->config_error) || + !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id", + m2d->dev_password_id) || + !wpa_dbus_dict_close_write(&iter, &dict_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_wps_cred - Signals new credentials + * @wpa_s: %wpa_supplicant network interface data + * + * Sends signal with credentials in directory argument + */ +void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s, + const struct wps_credential *cred) +{ + DBusMessage *msg; + DBusMessageIter iter, dict_iter; + struct wpas_dbus_priv *iface; + char *auth_type[6]; /* we have six possible authorization types */ + int at_num = 0; + char *encr_type[4]; /* we have four possible encryption types */ + int et_num = 0; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_WPS, + "Credentials"); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &iter); + if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) + goto nomem; + + if (cred->auth_type & WPS_AUTH_OPEN) + auth_type[at_num++] = "open"; + if (cred->auth_type & WPS_AUTH_WPAPSK) + auth_type[at_num++] = "wpa-psk"; + if (cred->auth_type & WPS_AUTH_SHARED) + auth_type[at_num++] = "shared"; + if (cred->auth_type & WPS_AUTH_WPA) + auth_type[at_num++] = "wpa-eap"; + if (cred->auth_type & WPS_AUTH_WPA2) + auth_type[at_num++] = "wpa2-eap"; + if (cred->auth_type & WPS_AUTH_WPA2PSK) + auth_type[at_num++] = + "wpa2-psk"; + + if (cred->encr_type & WPS_ENCR_NONE) + encr_type[et_num++] = "none"; + if (cred->encr_type & WPS_ENCR_WEP) + encr_type[et_num++] = "wep"; + if (cred->encr_type & WPS_ENCR_TKIP) + encr_type[et_num++] = "tkip"; + if (cred->encr_type & WPS_ENCR_AES) + encr_type[et_num++] = "aes"; + + if (wpa_s->current_ssid) { + if (!wpa_dbus_dict_append_byte_array( + &dict_iter, "BSSID", + (const char *) wpa_s->current_ssid->bssid, + ETH_ALEN)) + goto nomem; + } + + if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID", + (const char *) cred->ssid, + cred->ssid_len) || + !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType", + (const char **) auth_type, + at_num) || + !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType", + (const char **) encr_type, + et_num) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "Key", + (const char *) cred->key, + cred->key_len) || + !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex", + cred->key_idx) || + !wpa_dbus_dict_close_write(&iter, &dict_iter)) + goto nomem; + + dbus_connection_send(iface->con, msg, NULL); + +nomem: + dbus_message_unref(msg); +} + +#endif /* CONFIG_WPS */ + + +/** + * wpas_dbus_signal_prop_changed - Signals change of property + * @wpa_s: %wpa_supplicant network interface data + * @property: indicates which property has changed + * + * Sends ProertyChanged signals with path, interface and arguments + * depending on which property has changed. + */ +void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s, + enum wpas_dbus_prop property) +{ + WPADBusPropertyAccessor getter; + char *prop; + + if (wpa_s->dbus_new_path == NULL) + return; /* Skip signal since D-Bus setup is not yet ready */ + + switch (property) { + case WPAS_DBUS_PROP_AP_SCAN: + getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan; + prop = "ApScan"; + break; + case WPAS_DBUS_PROP_SCANNING: + getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning; + prop = "Scanning"; + break; + case WPAS_DBUS_PROP_STATE: + getter = (WPADBusPropertyAccessor) wpas_dbus_getter_state; + prop = "State"; + break; + case WPAS_DBUS_PROP_CURRENT_BSS: + getter = (WPADBusPropertyAccessor) + wpas_dbus_getter_current_bss; + prop = "CurrentBSS"; + break; + case WPAS_DBUS_PROP_CURRENT_NETWORK: + getter = (WPADBusPropertyAccessor) + wpas_dbus_getter_current_network; + prop = "CurrentNetwork"; + break; + default: + wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d", + __func__, property); + return; + } + + wpa_dbus_mark_property_changed(wpa_s->global->dbus, + wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, prop); +} + + +/** + * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property + * @wpa_s: %wpa_supplicant network interface data + * @property: indicates which property has changed + * @id: unique BSS identifier + * + * Sends PropertyChanged signals with path, interface, and arguments depending + * on which property has changed. + */ +void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s, + enum wpas_dbus_bss_prop property, + unsigned int id) +{ + char path[WPAS_DBUS_OBJECT_PATH_MAX]; + char *prop; + + switch (property) { + case WPAS_DBUS_BSS_PROP_SIGNAL: + prop = "Signal"; + break; + case WPAS_DBUS_BSS_PROP_FREQ: + prop = "Frequency"; + break; + case WPAS_DBUS_BSS_PROP_MODE: + prop = "Mode"; + break; + case WPAS_DBUS_BSS_PROP_PRIVACY: + prop = "Privacy"; + break; + case WPAS_DBUS_BSS_PROP_RATES: + prop = "Rates"; + break; + case WPAS_DBUS_BSS_PROP_WPA: + prop = "WPA"; + break; + case WPAS_DBUS_BSS_PROP_RSN: + prop = "RSN"; + break; + case WPAS_DBUS_BSS_PROP_IES: + prop = "IEs"; + 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_BSSIDS_PART "/%u", + wpa_s->dbus_new_path, id); + + wpa_dbus_mark_property_changed(wpa_s->global->dbus, path, + WPAS_DBUS_NEW_IFACE_BSS, prop); +} + + +/** + * wpas_dbus_signal_debug_level_changed - Signals change of debug param + * @global: wpa_global structure + * + * Sends ProertyChanged signals informing that debug level has changed. + */ +void wpas_dbus_signal_debug_level_changed(struct wpa_global *global) +{ + wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH, + WPAS_DBUS_NEW_INTERFACE, + "DebugLevel"); +} + + +/** + * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param + * @global: wpa_global structure + * + * Sends ProertyChanged signals informing that debug timestamp has changed. + */ +void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global) +{ + wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH, + WPAS_DBUS_NEW_INTERFACE, + "DebugTimestamp"); +} + + +/** + * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param + * @global: wpa_global structure + * + * Sends ProertyChanged signals informing that debug show_keys has changed. + */ +void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global) +{ + wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH, + WPAS_DBUS_NEW_INTERFACE, + "DebugShowKeys"); +} + + +static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc, + void *priv, + WPADBusArgumentFreeFunction priv_free, + const struct wpa_dbus_method_desc *methods, + const struct wpa_dbus_property_desc *properties, + const struct wpa_dbus_signal_desc *signals) +{ + int n; + + obj_desc->user_data = priv; + obj_desc->user_data_free_func = priv_free; + obj_desc->methods = methods; + obj_desc->properties = properties; + obj_desc->signals = signals; + + for (n = 0; properties && properties->dbus_property; properties++) + n++; + + obj_desc->prop_changed_flags = os_zalloc(n); + if (!obj_desc->prop_changed_flags) + wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers", + __func__); +} + + +static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = { + { "CreateInterface", WPAS_DBUS_NEW_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_create_interface, + { + { "args", "a{sv}", ARG_IN }, + { "path", "o", ARG_OUT }, + END_ARGS + } + }, + { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface, + { + { "path", "o", ARG_IN }, + END_ARGS + } + }, + { "GetInterface", WPAS_DBUS_NEW_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_get_interface, + { + { "ifname", "s", ARG_IN }, + { "path", "o", ARG_OUT }, + END_ARGS + } + }, + { NULL, NULL, NULL, { END_ARGS } } +}; + +static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = { + { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s", + (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level, + (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level, + RW + }, + { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b", + (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp, + (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp, + RW + }, + { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b", + (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys, + (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys, + RW + }, + { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao", + (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces, + NULL, + R + }, + { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as", + (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods, + NULL, + R + }, + { NULL, NULL, NULL, NULL, NULL, 0 } +}; + +static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = { + { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE, + { + { "path", "o", ARG_OUT }, + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE, + { + { "path", "o", ARG_OUT }, + END_ARGS + } + }, + { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE, + { + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { NULL, NULL, { END_ARGS } } +}; + + +/** + * wpas_dbus_ctrl_iface_init - Initialize dbus control interface + * @global: Pointer to global data from wpa_supplicant_init() + * Returns: 0 on success or -1 on failure + * + * Initialize the dbus control interface for wpa_supplicantand and start + * receiving commands from external programs over the bus. + */ +int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv) +{ + struct wpa_dbus_object_desc *obj_desc; + int ret; + + obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); + if (!obj_desc) { + wpa_printf(MSG_ERROR, "Not enough memory " + "to create object description"); + return -1; + } + + wpas_dbus_register(obj_desc, priv->global, NULL, + wpas_dbus_global_methods, + wpas_dbus_global_properties, + wpas_dbus_global_signals); + + wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'", + WPAS_DBUS_NEW_PATH); + ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH, + WPAS_DBUS_NEW_SERVICE, + obj_desc); + if (ret < 0) + free_dbus_object_desc(obj_desc); + else + priv->dbus_new_initialized = 1; + + return ret; +} + + +/** + * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for + * wpa_supplicant + * @iface: Pointer to dbus private data from wpas_dbus_init() + * + * Deinitialize the dbus control interface that was initialized with + * wpas_dbus_ctrl_iface_init(). + */ +void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface) +{ + if (!iface->dbus_new_initialized) + return; + wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'", + WPAS_DBUS_NEW_PATH); + dbus_connection_unregister_object_path(iface->con, + WPAS_DBUS_NEW_PATH); +} + + +static void wpa_dbus_free(void *ptr) +{ + os_free(ptr); +} + + +static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = { + { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}", + (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties, + (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties, + RW + }, + { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b", + (WPADBusPropertyAccessor) wpas_dbus_getter_enabled, + (WPADBusPropertyAccessor) wpas_dbus_setter_enabled, + RW + }, + { NULL, NULL, NULL, NULL, NULL, 0 } +}; + + +static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = { + { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK, + { + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { NULL, NULL, { END_ARGS } } +}; + + +/** + * wpas_dbus_register_network - Register a configured network with dbus + * @wpa_s: wpa_supplicant interface structure + * @ssid: network configuration data + * Returns: 0 on success, -1 on failure + * + * Registers network representing object with dbus + */ +int wpas_dbus_register_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + struct wpas_dbus_priv *ctrl_iface; + struct wpa_dbus_object_desc *obj_desc; + struct network_handler_args *arg; + char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + + /* 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) + return 0; + + os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", + wpa_s->dbus_new_path, ssid->id); + + wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'", + net_obj_path); + 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; + } + + /* allocate memory for handlers arguments */ + arg = os_zalloc(sizeof(struct network_handler_args)); + if (!arg) { + wpa_printf(MSG_ERROR, "Not enough memory " + "to create arguments for method"); + goto err; + } + + arg->wpa_s = wpa_s; + arg->ssid = ssid; + + wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL, + wpas_dbus_network_properties, + wpas_dbus_network_signals); + + if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path, + wpa_s->ifname, obj_desc)) + goto err; + + wpas_dbus_signal_network_added(wpa_s, ssid->id); + + return 0; + +err: + free_dbus_object_desc(obj_desc); + return -1; +} + + +/** + * wpas_dbus_unregister_network - Unregister a configured network from dbus + * @wpa_s: wpa_supplicant interface structure + * @nid: network id + * Returns: 0 on success, -1 on failure + * + * Unregisters network representing object from dbus + */ +int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid) +{ + struct wpas_dbus_priv *ctrl_iface; + char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + int ret; + + /* Do nothing if the control interface is not turned on */ + if (wpa_s == NULL || wpa_s->global == NULL || + wpa_s->dbus_new_path == NULL) + return 0; + ctrl_iface = wpa_s->global->dbus; + if (ctrl_iface == NULL) + return 0; + + os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", + wpa_s->dbus_new_path, nid); + + wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'", + net_obj_path); + ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path); + + if (!ret) + wpas_dbus_signal_network_removed(wpa_s, nid); + + return ret; +} + + +static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = { + { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid, + NULL, + R + }, + { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid, + NULL, + R + }, + { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy, + NULL, + R + }, + { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode, + NULL, + R + }, + { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal, + NULL, + R + }, + { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency, + NULL, + R + }, + { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rates, + NULL, + R + }, + { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpa, + NULL, + R + }, + { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsn, + NULL, + R + }, + { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay", + (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ies, + NULL, + R + }, + { NULL, NULL, NULL, NULL, NULL, 0 } +}; + + +static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = { + { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS, + { + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { NULL, NULL, { END_ARGS } } +}; + + +/** + * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus + * @wpa_s: wpa_supplicant interface structure + * @bssid: scanned network bssid + * @id: unique BSS identifier + * Returns: 0 on success, -1 on failure + * + * Unregisters BSS representing object from dbus + */ +int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s, + u8 bssid[ETH_ALEN], unsigned int id) +{ + struct wpas_dbus_priv *ctrl_iface; + char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + + /* 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) + return 0; + + os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", + wpa_s->dbus_new_path, id); + + wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'", + bss_obj_path); + if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) { + wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s", + bss_obj_path); + return -1; + } + + wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path); + + return 0; +} + + +/** + * wpas_dbus_register_bss - Register a scanned BSS with dbus + * @wpa_s: wpa_supplicant interface structure + * @bssid: scanned network bssid + * @id: unique BSS identifier + * Returns: 0 on success, -1 on failure + * + * Registers BSS representing object with dbus + */ +int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, + u8 bssid[ETH_ALEN], unsigned int id) +{ + struct wpas_dbus_priv *ctrl_iface; + struct wpa_dbus_object_desc *obj_desc; + char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + struct bss_handler_args *arg; + + /* 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) + return 0; + + os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", + wpa_s->dbus_new_path, id); + + 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 bss_handler_args)); + if (!arg) { + wpa_printf(MSG_ERROR, "Not enough memory " + "to create arguments for handler"); + goto err; + } + arg->wpa_s = wpa_s; + arg->id = id; + + wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL, + wpas_dbus_bss_properties, + wpas_dbus_bss_signals); + + wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'", + bss_obj_path); + if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path, + wpa_s->ifname, obj_desc)) { + wpa_printf(MSG_ERROR, + "Cannot register BSSID dbus object %s.", + bss_obj_path); + goto err; + } + + wpas_dbus_signal_bss_added(wpa_s, bss_obj_path); + + 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, + { + { "args", "a{sv}", ARG_IN }, + END_ARGS + } + }, + { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_disconnect, + { + END_ARGS + } + }, + { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_add_network, + { + { "args", "a{sv}", ARG_IN }, + { "path", "o", ARG_OUT }, + END_ARGS + } + }, + { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_remove_network, + { + { "path", "o", ARG_IN }, + END_ARGS + } + }, + { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_select_network, + { + { "path", "o", ARG_IN }, + END_ARGS + } + }, + { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_add_blob, + { + { "name", "s", ARG_IN }, + { "data", "ay", ARG_IN }, + END_ARGS + } + }, + { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_get_blob, + { + { "name", "s", ARG_IN }, + { "data", "ay", ARG_OUT }, + END_ARGS + } + }, + { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob, + { + { "name", "s", ARG_IN }, + END_ARGS + } + }, +#ifdef CONFIG_WPS + { "Start", WPAS_DBUS_NEW_IFACE_WPS, + (WPADBusMethodHandler) &wpas_dbus_handler_wps_start, + { + { "args", "a{sv}", ARG_IN }, + { "output", "a{sv}", ARG_OUT }, + END_ARGS + } + }, +#endif /* CONFIG_WPS */ + { NULL, NULL, NULL, { END_ARGS } } +}; + +static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { + { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}", + (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities, + NULL, R + }, + { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", + (WPADBusPropertyAccessor) wpas_dbus_getter_state, + NULL, R + }, + { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b", + (WPADBusPropertyAccessor) wpas_dbus_getter_scanning, + NULL, R + }, + { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", + (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan, + (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan, + RW + }, + { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", + (WPADBusPropertyAccessor) wpas_dbus_getter_ifname, + NULL, R + }, + { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", + (WPADBusPropertyAccessor) wpas_dbus_getter_driver, + NULL, R + }, + { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", + (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname, + NULL, R + }, + { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", + (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss, + NULL, R + }, + { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", + (WPADBusPropertyAccessor) wpas_dbus_getter_current_network, + NULL, R + }, + { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}", + (WPADBusPropertyAccessor) wpas_dbus_getter_blobs, + NULL, R + }, + { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", + (WPADBusPropertyAccessor) wpas_dbus_getter_bsss, + NULL, R + }, + { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", + (WPADBusPropertyAccessor) wpas_dbus_getter_networks, + NULL, R + }, +#ifdef CONFIG_WPS + { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b", + (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials, + (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials, + RW + }, +#endif /* CONFIG_WPS */ + { NULL, NULL, NULL, NULL, NULL, 0 } +}; + +static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { + { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "success", "b", ARG_OUT }, + END_ARGS + } + }, + { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + END_ARGS + } + }, + { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "name", "s", ARG_OUT }, + END_ARGS + } + }, + { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "name", "s", ARG_OUT }, + END_ARGS + } + }, + { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + END_ARGS + } + }, + { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + END_ARGS + } + }, + { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, +#ifdef CONFIG_WPS + { "Event", WPAS_DBUS_NEW_IFACE_WPS, + { + { "name", "s", ARG_OUT }, + { "args", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "Credentials", WPAS_DBUS_NEW_IFACE_WPS, + { + { "credentials", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS, + { + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, +#endif /* CONFIG_WPS */ + { NULL, NULL, { END_ARGS } } +}; + + +int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s) +{ + + struct wpa_dbus_object_desc *obj_desc = NULL; + struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus; + int next; + + /* Do nothing if the control interface is not turned on */ + if (ctrl_iface == NULL) + return 0; + + /* Create and set the interface's object path */ + wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); + if (wpa_s->dbus_new_path == NULL) + return -1; + next = ctrl_iface->next_objid++; + os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX, + WPAS_DBUS_NEW_PATH_INTERFACES "/%u", + next); + + 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; + } + + wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods, + wpas_dbus_interface_properties, + wpas_dbus_interface_signals); + + wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'", + wpa_s->dbus_new_path); + if (wpa_dbus_register_object_per_iface(ctrl_iface, + wpa_s->dbus_new_path, + wpa_s->ifname, obj_desc)) + goto err; + + wpas_dbus_signal_interface_added(wpa_s); + + return 0; + +err: + os_free(wpa_s->dbus_new_path); + wpa_s->dbus_new_path = NULL; + free_dbus_object_desc(obj_desc); + return -1; +} + + +int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s) +{ + struct wpas_dbus_priv *ctrl_iface; + + /* 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) + return 0; + + wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'", + wpa_s->dbus_new_path); + if (wpa_dbus_unregister_object_per_iface(ctrl_iface, + wpa_s->dbus_new_path)) + return -1; + + wpas_dbus_signal_interface_removed(wpa_s); + + os_free(wpa_s->dbus_new_path); + wpa_s->dbus_new_path = NULL; + + return 0; +} diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new.h b/contrib/wpa/wpa_supplicant/dbus/dbus_new.h new file mode 100644 index 0000000..80ea98c --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new.h @@ -0,0 +1,234 @@ +/* + * WPA Supplicant / dbus-based control interface + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef CTRL_IFACE_DBUS_NEW_H +#define CTRL_IFACE_DBUS_NEW_H + +struct wpa_global; +struct wpa_supplicant; +struct wpa_ssid; +struct wps_event_m2d; +struct wps_event_fail; +struct wps_credential; +enum wpa_states; + +enum wpas_dbus_prop { + WPAS_DBUS_PROP_AP_SCAN, + WPAS_DBUS_PROP_SCANNING, + WPAS_DBUS_PROP_STATE, + WPAS_DBUS_PROP_CURRENT_BSS, + WPAS_DBUS_PROP_CURRENT_NETWORK, +}; + +enum wpas_dbus_bss_prop { + WPAS_DBUS_BSS_PROP_SIGNAL, + WPAS_DBUS_BSS_PROP_FREQ, + WPAS_DBUS_BSS_PROP_MODE, + WPAS_DBUS_BSS_PROP_PRIVACY, + WPAS_DBUS_BSS_PROP_RATES, + WPAS_DBUS_BSS_PROP_WPA, + WPAS_DBUS_BSS_PROP_RSN, + WPAS_DBUS_BSS_PROP_IES, +}; + +#define WPAS_DBUS_OBJECT_PATH_MAX 150 + +#define WPAS_DBUS_NEW_SERVICE "fi.w1.wpa_supplicant1" +#define WPAS_DBUS_NEW_PATH "/fi/w1/wpa_supplicant1" +#define WPAS_DBUS_NEW_INTERFACE "fi.w1.wpa_supplicant1" + +#define WPAS_DBUS_NEW_PATH_INTERFACES WPAS_DBUS_NEW_PATH "/Interfaces" +#define WPAS_DBUS_NEW_IFACE_INTERFACE WPAS_DBUS_NEW_INTERFACE ".Interface" +#define WPAS_DBUS_NEW_IFACE_WPS WPAS_DBUS_NEW_IFACE_INTERFACE ".WPS" + +#define WPAS_DBUS_NEW_NETWORKS_PART "Networks" +#define WPAS_DBUS_NEW_IFACE_NETWORK WPAS_DBUS_NEW_INTERFACE ".Network" + +#define WPAS_DBUS_NEW_BSSIDS_PART "BSSs" +#define WPAS_DBUS_NEW_IFACE_BSS WPAS_DBUS_NEW_INTERFACE ".BSS" + + +/* Errors */ +#define WPAS_DBUS_ERROR_UNKNOWN_ERROR \ + WPAS_DBUS_NEW_INTERFACE ".UnknownError" +#define WPAS_DBUS_ERROR_INVALID_ARGS \ + WPAS_DBUS_NEW_INTERFACE ".InvalidArgs" + +#define WPAS_DBUS_ERROR_IFACE_EXISTS \ + WPAS_DBUS_NEW_INTERFACE ".InterfaceExists" +#define WPAS_DBUS_ERROR_IFACE_UNKNOWN \ + WPAS_DBUS_NEW_INTERFACE ".InterfaceUnknown" + +#define WPAS_DBUS_ERROR_NOT_CONNECTED \ + WPAS_DBUS_NEW_INTERFACE ".NotConnected" +#define WPAS_DBUS_ERROR_NETWORK_UNKNOWN \ + WPAS_DBUS_NEW_INTERFACE ".NetworkUnknown" + +#define WPAS_DBUS_ERROR_BLOB_EXISTS \ + WPAS_DBUS_NEW_INTERFACE ".BlobExists" +#define WPAS_DBUS_ERROR_BLOB_UNKNOWN \ + WPAS_DBUS_NEW_INTERFACE ".BlobUnknown" + + +#ifdef CONFIG_CTRL_IFACE_DBUS_NEW + +int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv); +void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface); + +int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s); +int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s); +void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s, + enum wpas_dbus_prop property); +void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s, + enum wpas_dbus_bss_prop property, + unsigned int id); +void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id); +void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success); +void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s, + const struct wps_credential *cred); +void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s, + struct wps_event_m2d *m2d); +void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s, + struct wps_event_fail *fail); +void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s); +int wpas_dbus_register_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid); +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); +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, + const char *name); +void wpas_dbus_signal_debug_level_changed(struct wpa_global *global); +void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global); +void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global); + +#else /* CONFIG_CTRL_IFACE_DBUS_NEW */ + +static inline int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s) +{ + return 0; +} + +static inline int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s) +{ + return 0; +} + +#define wpas_dbus_signal_state_changed(w, n, o) do { } while (0) + +static inline void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s, + enum wpas_dbus_prop property) +{ +} + +static inline void wpas_dbus_bss_signal_prop_changed( + struct wpa_supplicant *wpa_s, enum wpas_dbus_bss_prop property, + unsigned int id) +{ +} + +static inline void wpas_dbus_signal_network_enabled_changed( + struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) +{ +} + +static inline void wpas_dbus_signal_network_selected( + struct wpa_supplicant *wpa_s, int id) +{ +} + +static inline void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, + int success) +{ +} + +static inline void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s, + const struct wps_credential *cred) +{ +} + +static inline void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s, + struct wps_event_m2d *m2d) +{ +} + +static inline void wpas_dbus_signal_wps_event_fail( + struct wpa_supplicant *wpa_s, struct wps_event_fail *fail) +{ +} + +static inline void wpas_dbus_signal_wps_event_success( + struct wpa_supplicant *wpa_s) +{ +} + +static inline int wpas_dbus_register_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + return 0; +} + +static inline int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, + int nid) +{ + return 0; +} + +static inline int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s, + u8 bssid[ETH_ALEN], unsigned int id) +{ + return 0; +} + +static inline int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, + u8 bssid[ETH_ALEN], unsigned int id) +{ + return 0; +} + +static inline void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s, + const char *name) +{ +} + +static inline void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s, + const char *name) +{ +} + +static inline void wpas_dbus_signal_debug_level_changed( + struct wpa_global *global) +{ +} + +static inline void wpas_dbus_signal_debug_timestamp_changed( + struct wpa_global *global) +{ +} + +static inline void wpas_dbus_signal_debug_show_keys_changed( + struct wpa_global *global) +{ +} + +#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ + +#endif /* CTRL_IFACE_DBUS_H_NEW */ diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.c b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.c new file mode 100644 index 0000000..e2b5e50 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.c @@ -0,0 +1,2957 @@ +/* + * WPA Supplicant / dbus-based control interface + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com> + * Copyright (c) 2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "common/ieee802_11_defs.h" +#include "eap_peer/eap_methods.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_new_helpers.h" +#include "dbus_new.h" +#include "dbus_new_handlers.h" +#include "dbus_dict_helpers.h" + +extern int wpa_debug_level; +extern int wpa_debug_show_keys; +extern int wpa_debug_timestamp; + +static const char *debug_strings[] = { + "msgdump", "debug", "info", "warning", "error", NULL +}; + + +/** + * wpas_dbus_new_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. + */ +static char * wpas_dbus_new_decompose_object_path(const char *path, + char **network, + char **bssid) +{ + const unsigned int dev_path_prefix_len = + strlen(WPAS_DBUS_NEW_PATH_INTERFACES "/"); + char *obj_path_only; + char *next_sep; + + /* Be a bit paranoid about path */ + if (!path || os_strncmp(path, WPAS_DBUS_NEW_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 = os_strchr(obj_path_only + dev_path_prefix_len, '/'); + if (next_sep != NULL) { + const char *net_part = os_strstr( + next_sep, WPAS_DBUS_NEW_NETWORKS_PART "/"); + const char *bssid_part = os_strstr( + next_sep, WPAS_DBUS_NEW_BSSIDS_PART "/"); + + if (network && net_part) { + /* Deal with a request for a configured network */ + const char *net_name = net_part + + os_strlen(WPAS_DBUS_NEW_NETWORKS_PART "/"); + *network = NULL; + if (os_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 + + os_strlen(WPAS_DBUS_NEW_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_error_unknown_error - Return a new InvalidArgs error message + * @message: Pointer to incoming dbus message this error refers to + * @arg: Optional string appended to error message + * Returns: a dbus error message + * + * Convenience function to create and return an UnknownError + */ +DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message, + const char *arg) +{ + return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR, + arg); +} + + +/** + * wpas_dbus_error_iface_unknown - 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 + */ +static DBusMessage * wpas_dbus_error_iface_unknown(DBusMessage *message) +{ + return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_UNKNOWN, + "wpa_supplicant knows nothing about " + "this interface."); +} + + +/** + * wpas_dbus_error_network_unknown - Return a new NetworkUnknown 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 + */ +static DBusMessage * wpas_dbus_error_network_unknown(DBusMessage *message) +{ + return dbus_message_new_error(message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN, + "There is no such a network in this " + "interface."); +} + + +/** + * wpas_dbus_error_invalid_args - Return a new InvalidArgs 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_error_invalid_args(DBusMessage *message, + const char *arg) +{ + DBusMessage *reply; + + reply = dbus_message_new_error(message, WPAS_DBUS_ERROR_INVALID_ARGS, + "Did not receive correct message " + "arguments."); + if (arg != NULL) + dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg, + DBUS_TYPE_INVALID); + + return reply; +} + + +static const char *dont_quote[] = { + "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap", + "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path", + "bssid", 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; +} + +/** + * 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 + */ +static struct 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 (os_strcmp(wpa_s->dbus_new_path, path) == 0) + return wpa_s; + } + return NULL; +} + + +/** + * set_network_properties - Set properties of 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 + * @iter: DBus message iterator containing dictionary of network + * properties to set. + * Returns: NULL when succeed or DBus error on failure + * + * Sets network configuration with parameters given id DBus dictionary + */ +static DBusMessage * set_network_properties(DBusMessage *message, + struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, + DBusMessageIter *iter) +{ + + struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; + DBusMessage *reply = NULL; + DBusMessageIter iter_dict; + + if (!wpa_dbus_dict_open_read(iter, &iter_dict)) + return wpas_dbus_error_invalid_args(message, NULL); + + 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_error_invalid_args(message, NULL); + break; + } + 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); + if (size <= 0) + goto error; + + size += 3; + value = os_zalloc(size); + if (value == NULL) + goto error; + + ret = os_snprintf(value, size, "\"%s\"", + entry.str_value); + if (ret < 0 || (size_t) ret != (size - 1)) + 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 (ret <= 0) + 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 (ret <= 0) + 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) || + (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_error_invalid_args(message, entry.key); + wpa_dbus_dict_entry_clear(&entry); + break; + } + + return reply; +} + + +/** + * wpas_dbus_simple_property_getter - Get basic type property + * @message: Pointer to incoming dbus message + * @type: DBus type of property (must be basic type) + * @val: pointer to place holding property value + * Returns: The DBus message containing response for Properties.Get call + * or DBus error message if error occurred. + * + * Generic getter for basic type properties. Type is required to be basic. + */ +DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message, + const int type, const void *val) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter, variant_iter; + + if (!dbus_type_is_basic(type)) { + wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:" + " given type is not basic"); + return wpas_dbus_error_unknown_error(message, NULL); + } + + if (message == NULL) + reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); + else + reply = dbus_message_new_method_return(message); + + if (reply != NULL) { + dbus_message_iter_init_append(reply, &iter); + if (!dbus_message_iter_open_container( + &iter, DBUS_TYPE_VARIANT, + wpa_dbus_type_as_string(type), &variant_iter) || + !dbus_message_iter_append_basic(&variant_iter, type, + val) || + !dbus_message_iter_close_container(&iter, &variant_iter)) { + wpa_printf(MSG_ERROR, "dbus: " + "wpas_dbus_simple_property_getter: out of " + "memory to put property value into " + "message"); + dbus_message_unref(reply); + reply = dbus_message_new_error(message, + DBUS_ERROR_NO_MEMORY, + NULL); + } + } else { + wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:" + " out of memory to return property value"); + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + return reply; +} + + +/** + * wpas_dbus_simple_property_setter - Set basic type property + * @message: Pointer to incoming dbus message + * @type: DBus type of property (must be basic type) + * @val: pointer to place where value being set will be stored + * Returns: NULL or DBus error message if error occurred. + * + * Generic setter for basic type properties. Type is required to be basic. + */ +DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message, + const int type, void *val) +{ + DBusMessageIter iter, variant_iter; + + if (!dbus_type_is_basic(type)) { + wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:" + " given type is not basic"); + return wpas_dbus_error_unknown_error(message, NULL); + } + + if (!dbus_message_iter_init(message, &iter)) { + wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:" + " out of memory to return scanning state"); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + /* omit first and second argument and get value from third */ + dbus_message_iter_next(&iter); + dbus_message_iter_next(&iter); + dbus_message_iter_recurse(&iter, &variant_iter); + + if (dbus_message_iter_get_arg_type(&variant_iter) != type) { + wpa_printf(MSG_DEBUG, "dbus: wpas_dbus_simple_property_setter:" + " wrong property type"); + return wpas_dbus_error_invalid_args(message, + "wrong property type"); + } + dbus_message_iter_get_basic(&variant_iter, val); + + return NULL; +} + + +/** + * wpas_dbus_simple_array_property_getter - Get array type property + * @message: Pointer to incoming dbus message + * @type: DBus type of property array elements (must be basic type) + * @array: pointer to array of elements to put into response message + * @array_len: length of above array + * Returns: The DBus message containing response for Properties.Get call + * or DBus error message if error occurred. + * + * Generic getter for array type properties. Array elements type is + * required to be basic. + */ +DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message, + const int type, + const void *array, + size_t array_len) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter, variant_iter, array_iter; + char type_str[] = "a?"; /* ? will be replaced with subtype letter; */ + const char *sub_type_str; + size_t element_size, i; + + if (!dbus_type_is_basic(type)) { + wpa_printf(MSG_ERROR, "dbus: " + "wpas_dbus_simple_array_property_getter: given " + "type is not basic"); + return wpas_dbus_error_unknown_error(message, NULL); + } + + sub_type_str = wpa_dbus_type_as_string(type); + type_str[1] = sub_type_str[0]; + + if (message == NULL) + reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); + else + reply = dbus_message_new_method_return(message); + if (reply == NULL) { + wpa_printf(MSG_ERROR, "dbus: " + "wpas_dbus_simple_array_property_getter: out of " + "memory to create return message"); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + type_str, &variant_iter) || + !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, + sub_type_str, &array_iter)) { + wpa_printf(MSG_ERROR, "dbus: " + "wpas_dbus_simple_array_property_getter: out of " + "memory to open container"); + dbus_message_unref(reply); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + switch(type) { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + element_size = 1; + break; + case DBUS_TYPE_INT16: + case DBUS_TYPE_UINT16: + element_size = sizeof(uint16_t); + break; + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + element_size = sizeof(uint32_t); + break; + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: + element_size = sizeof(uint64_t); + break; + case DBUS_TYPE_DOUBLE: + element_size = sizeof(double); + break; + case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: + element_size = sizeof(char *); + break; + default: + wpa_printf(MSG_ERROR, "dbus: " + "wpas_dbus_simple_array_property_getter: " + "fatal: unknown element type"); + element_size = 1; + break; + } + + for (i = 0; i < array_len; i++) { + dbus_message_iter_append_basic(&array_iter, type, + array + i * element_size); + } + + if (!dbus_message_iter_close_container(&variant_iter, &array_iter) || + !dbus_message_iter_close_container(&iter, &variant_iter)) { + wpa_printf(MSG_ERROR, "dbus: " + "wpas_dbus_simple_array_property_getter: out of " + "memory to close container"); + dbus_message_unref(reply); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + return reply; +} + + +/** + * wpas_dbus_handler_create_interface - Request registration of a network iface + * @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 "CreateInterface" method call. Handles requests + * by dbus clients to register a network interface that wpa_supplicant + * will manage. + */ +DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, + struct wpa_global *global) +{ + DBusMessageIter iter_dict; + DBusMessage *reply = NULL; + DBusMessageIter iter; + struct wpa_dbus_dict_entry entry; + char *driver = NULL; + char *ifname = NULL; + char *bridge_ifname = NULL; + + dbus_message_iter_init(message, &iter); + + if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + 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)) { + driver = os_strdup(entry.str_value); + wpa_dbus_dict_entry_clear(&entry); + if (driver == NULL) + goto error; + } else if (!strcmp(entry.key, "Ifname") && + (entry.type == DBUS_TYPE_STRING)) { + ifname = os_strdup(entry.str_value); + wpa_dbus_dict_entry_clear(&entry); + if (ifname == NULL) + goto error; + } else if (!strcmp(entry.key, "BridgeIfname") && + (entry.type == DBUS_TYPE_STRING)) { + 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; + } + } + + if (ifname == NULL) + goto error; /* Required Ifname argument missing */ + + /* + * 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_DBUS_ERROR_IFACE_EXISTS, + "wpa_supplicant already " + "controls this interface."); + } else { + struct wpa_supplicant *wpa_s; + struct wpa_interface iface; + os_memset(&iface, 0, sizeof(iface)); + iface.driver = driver; + iface.ifname = ifname; + iface.bridge_ifname = bridge_ifname; + /* Otherwise, have wpa_supplicant attach to it. */ + if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) { + const char *path = wpa_s->dbus_new_path; + reply = dbus_message_new_method_return(message); + dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, + &path, DBUS_TYPE_INVALID); + } else { + reply = wpas_dbus_error_unknown_error( + message, "wpa_supplicant couldn't grab this " + "interface."); + } + } + +out: + os_free(driver); + os_free(ifname); + os_free(bridge_ifname); + return reply; + +error: + reply = wpas_dbus_error_invalid_args(message, NULL); + goto out; +} + + +/** + * wpas_dbus_handler_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_handler_remove_interface(DBusMessage *message, + struct wpa_global *global) +{ + struct wpa_supplicant *wpa_s; + char *path; + DBusMessage *reply = NULL; + + dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID); + + wpa_s = get_iface_by_dbus_path(global, path); + if (wpa_s == NULL) + reply = wpas_dbus_error_iface_unknown(message); + else if (wpa_supplicant_remove_iface(global, wpa_s)) { + reply = wpas_dbus_error_unknown_error( + message, "wpa_supplicant couldn't remove this " + "interface."); + } + + return reply; +} + + +/** + * wpas_dbus_handler_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. + */ +DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message, + struct wpa_global *global) +{ + DBusMessage *reply = NULL; + const char *ifname; + const char *path; + struct wpa_supplicant *wpa_s; + + dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname, + DBUS_TYPE_INVALID); + + wpa_s = wpa_supplicant_get_iface(global, ifname); + if (wpa_s == NULL) + return wpas_dbus_error_iface_unknown(message); + + path = wpa_s->dbus_new_path; + reply = dbus_message_new_method_return(message); + if (reply == NULL) + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + dbus_message_unref(reply); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + return reply; +} + + +/** + * wpas_dbus_getter_debug_level - Get debug level + * @message: Pointer to incoming dbus message + * @global: %wpa_supplicant global data structure + * Returns: DBus message with value of debug level + * + * Getter for "DebugLevel" property. + */ +DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message, + struct wpa_global *global) +{ + const char *str; + int idx = wpa_debug_level; + if (idx < 0) + idx = 0; + if (idx > 4) + idx = 4; + str = debug_strings[idx]; + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, + &str); +} + + +/** + * wpas_dbus_getter_debug_timestamp - Get debug timestamp + * @message: Pointer to incoming dbus message + * @global: %wpa_supplicant global data structure + * Returns: DBus message with value of debug timestamp + * + * Getter for "DebugTimestamp" property. + */ +DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message, + struct wpa_global *global) +{ + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, + &wpa_debug_timestamp); + +} + + +/** + * wpas_dbus_getter_debug_show_keys - Get debug show keys + * @message: Pointer to incoming dbus message + * @global: %wpa_supplicant global data structure + * Returns: DBus message with value of debug show_keys + * + * Getter for "DebugShowKeys" property. + */ +DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message, + struct wpa_global *global) +{ + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, + &wpa_debug_show_keys); + +} + +/** + * wpas_dbus_setter_debug_level - Set debug level + * @message: Pointer to incoming dbus message + * @global: %wpa_supplicant global data structure + * Returns: %NULL or DBus error message + * + * Setter for "DebugLevel" property. + */ +DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message, + struct wpa_global *global) +{ + DBusMessage *reply; + const char *str = NULL; + int i, val = -1; + + reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_STRING, + &str); + if (reply) + return reply; + + for (i = 0; debug_strings[i]; i++) + if (os_strcmp(debug_strings[i], str) == 0) { + val = i; + break; + } + + if (val < 0 || + wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp, + wpa_debug_show_keys)) { + dbus_message_unref(reply); + return wpas_dbus_error_invalid_args( + message, "Wrong debug level value"); + } + + return NULL; +} + + +/** + * wpas_dbus_setter_debug_timestamp - Set debug timestamp + * @message: Pointer to incoming dbus message + * @global: %wpa_supplicant global data structure + * Returns: %NULL or DBus error message + * + * Setter for "DebugTimestamp" property. + */ +DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message, + struct wpa_global *global) +{ + DBusMessage *reply; + dbus_bool_t val; + + reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, + &val); + if (reply) + return reply; + + wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0, + wpa_debug_show_keys); + + return NULL; +} + + +/** + * wpas_dbus_setter_debug_show_keys - Set debug show keys + * @message: Pointer to incoming dbus message + * @global: %wpa_supplicant global data structure + * Returns: %NULL or DBus error message + * + * Setter for "DebugShowKeys" property. + */ +DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message, + struct wpa_global *global) +{ + DBusMessage *reply; + dbus_bool_t val; + + reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, + &val); + if (reply) + return reply; + + wpa_supplicant_set_debug_params(global, wpa_debug_level, + wpa_debug_timestamp, + val ? 1 : 0); + + return NULL; +} + + +/** + * wpas_dbus_getter_interfaces - Request registered interfaces list + * @message: Pointer to incoming dbus message + * @global: %wpa_supplicant global data structure + * Returns: The object paths array containing registered interfaces + * objects paths or DBus error on failure + * + * Getter for "Interfaces" property. Handles requests + * by dbus clients to return list of registered interfaces objects + * paths + */ +DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message, + struct wpa_global *global) +{ + DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s; + const char **paths; + unsigned int i = 0, num = 0; + + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) + num++; + + paths = os_zalloc(num * sizeof(char*)); + if (!paths) { + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) + paths[i] = wpa_s->dbus_new_path; + + reply = wpas_dbus_simple_array_property_getter(message, + DBUS_TYPE_OBJECT_PATH, + paths, num); + + os_free(paths); + return reply; +} + + +/** + * wpas_dbus_getter_eap_methods - Request supported EAP methods list + * @message: Pointer to incoming dbus message + * @nothing: not used argument. may be NULL or anything else + * Returns: The object paths array containing supported EAP methods + * represented by strings or DBus error on failure + * + * Getter for "EapMethods" property. Handles requests + * by dbus clients to return list of strings with supported EAP methods + */ +DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing) +{ + DBusMessage *reply = NULL; + char **eap_methods; + size_t num_items = 0; + + eap_methods = eap_get_names_as_string_array(&num_items); + if (!eap_methods) { + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + reply = wpas_dbus_simple_array_property_getter(message, + DBUS_TYPE_STRING, + eap_methods, num_items); + + while (num_items) + os_free(eap_methods[--num_items]); + os_free(eap_methods); + return reply; +} + + +static int wpas_dbus_get_scan_type(DBusMessage *message, DBusMessageIter *var, + char **type, DBusMessage **reply) +{ + if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_STRING) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "Type must be a string"); + *reply = wpas_dbus_error_invalid_args( + message, "Wrong Type value type. String required"); + return -1; + } + dbus_message_iter_get_basic(var, type); + return 0; +} + + +static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var, + struct wpa_driver_scan_params *params, + DBusMessage **reply) +{ + struct wpa_driver_scan_ssid *ssids = params->ssids; + size_t ssids_num = 0; + u8 *ssid; + DBusMessageIter array_iter, sub_array_iter; + char *val; + int len; + + if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids " + "must be an array of arrays of bytes"); + *reply = wpas_dbus_error_invalid_args( + message, "Wrong SSIDs value type. Array of arrays of " + "bytes required"); + return -1; + } + + dbus_message_iter_recurse(var, &array_iter); + + if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE) + { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids " + "must be an array of arrays of bytes"); + *reply = wpas_dbus_error_invalid_args( + message, "Wrong SSIDs value type. Array of arrays of " + "bytes required"); + return -1; + } + + while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY) + { + if (ssids_num >= WPAS_MAX_SCAN_SSIDS) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "Too many ssids specified on scan dbus " + "call"); + *reply = wpas_dbus_error_invalid_args( + message, "Too many ssids specified. Specify " + "at most four"); + return -1; + } + + dbus_message_iter_recurse(&array_iter, &sub_array_iter); + + dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len); + if (len == 0) { + dbus_message_iter_next(&array_iter); + continue; + } + + ssid = os_malloc(len); + if (ssid == NULL) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "out of memory. Cannot allocate memory for " + "SSID"); + *reply = dbus_message_new_error( + message, DBUS_ERROR_NO_MEMORY, NULL); + return -1; + } + os_memcpy(ssid, val, len); + ssids[ssids_num].ssid = ssid; + ssids[ssids_num].ssid_len = len; + + dbus_message_iter_next(&array_iter); + ssids_num++; + } + + params->num_ssids = ssids_num; + return 0; +} + + +static int wpas_dbus_get_scan_ies(DBusMessage *message, DBusMessageIter *var, + struct wpa_driver_scan_params *params, + DBusMessage **reply) +{ + u8 *ies = NULL, *nies; + int ies_len = 0; + DBusMessageIter array_iter, sub_array_iter; + char *val; + int len; + + if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must " + "be an array of arrays of bytes"); + *reply = wpas_dbus_error_invalid_args( + message, "Wrong IEs value type. Array of arrays of " + "bytes required"); + return -1; + } + + dbus_message_iter_recurse(var, &array_iter); + + if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE) + { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must " + "be an array of arrays of bytes"); + *reply = wpas_dbus_error_invalid_args( + message, "Wrong IEs value type. Array required"); + return -1; + } + + while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY) + { + dbus_message_iter_recurse(&array_iter, &sub_array_iter); + + dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len); + if (len == 0) { + dbus_message_iter_next(&array_iter); + continue; + } + + nies = os_realloc(ies, ies_len + len); + if (nies == NULL) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "out of memory. Cannot allocate memory for " + "IE"); + os_free(ies); + *reply = dbus_message_new_error( + message, DBUS_ERROR_NO_MEMORY, NULL); + return -1; + } + ies = nies; + os_memcpy(ies + ies_len, val, len); + ies_len += len; + + dbus_message_iter_next(&array_iter); + } + + params->extra_ies = ies; + params->extra_ies_len = ies_len; + return 0; +} + + +static int wpas_dbus_get_scan_channels(DBusMessage *message, + DBusMessageIter *var, + struct wpa_driver_scan_params *params, + DBusMessage **reply) +{ + DBusMessageIter array_iter, sub_array_iter; + int *freqs = NULL, *nfreqs; + int freqs_num = 0; + + if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "Channels must be an array of structs"); + *reply = wpas_dbus_error_invalid_args( + message, "Wrong Channels value type. Array of structs " + "required"); + return -1; + } + + dbus_message_iter_recurse(var, &array_iter); + + if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) { + wpa_printf(MSG_DEBUG, + "wpas_dbus_handler_scan[dbus]: Channels must be an " + "array of structs"); + *reply = wpas_dbus_error_invalid_args( + message, "Wrong Channels value type. Array of structs " + "required"); + return -1; + } + + while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_STRUCT) + { + int freq, width; + + dbus_message_iter_recurse(&array_iter, &sub_array_iter); + + if (dbus_message_iter_get_arg_type(&sub_array_iter) != + DBUS_TYPE_UINT32) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "Channel must by specified by struct of " + "two UINT32s %c", + dbus_message_iter_get_arg_type( + &sub_array_iter)); + *reply = wpas_dbus_error_invalid_args( + message, "Wrong Channel struct. Two UINT32s " + "required"); + os_free(freqs); + return -1; + } + dbus_message_iter_get_basic(&sub_array_iter, &freq); + + if (!dbus_message_iter_next(&sub_array_iter) || + dbus_message_iter_get_arg_type(&sub_array_iter) != + DBUS_TYPE_UINT32) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "Channel must by specified by struct of " + "two UINT32s"); + *reply = wpas_dbus_error_invalid_args( + message, + "Wrong Channel struct. Two UINT32s required"); + os_free(freqs); + return -1; + } + + dbus_message_iter_get_basic(&sub_array_iter, &width); + +#define FREQS_ALLOC_CHUNK 32 + if (freqs_num % FREQS_ALLOC_CHUNK == 0) { + nfreqs = os_realloc(freqs, sizeof(int) * + (freqs_num + FREQS_ALLOC_CHUNK)); + if (nfreqs == NULL) + os_free(freqs); + freqs = nfreqs; + } + if (freqs == NULL) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "out of memory. can't allocate memory for " + "freqs"); + *reply = dbus_message_new_error( + message, DBUS_ERROR_NO_MEMORY, NULL); + return -1; + } + + freqs[freqs_num] = freq; + + freqs_num++; + dbus_message_iter_next(&array_iter); + } + + nfreqs = os_realloc(freqs, + sizeof(int) * (freqs_num + 1)); + if (nfreqs == NULL) + os_free(freqs); + freqs = nfreqs; + if (freqs == NULL) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "out of memory. Can't allocate memory for freqs"); + *reply = dbus_message_new_error( + message, DBUS_ERROR_NO_MEMORY, NULL); + return -1; + } + freqs[freqs_num] = 0; + + params->freqs = freqs; + return 0; +} + + +/** + * wpas_dbus_handler_scan - Request a wireless scan on an interface + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NULL indicating success or DBus error message on failure + * + * 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_handler_scan(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter, dict_iter, entry_iter, variant_iter; + char *key = NULL, *type = NULL; + struct wpa_driver_scan_params params; + size_t i; + + os_memset(¶ms, 0, sizeof(params)); + + dbus_message_iter_init(message, &iter); + + dbus_message_iter_recurse(&iter, &dict_iter); + + while (dbus_message_iter_get_arg_type(&dict_iter) == + DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&dict_iter, &entry_iter); + dbus_message_iter_get_basic(&entry_iter, &key); + dbus_message_iter_next(&entry_iter); + dbus_message_iter_recurse(&entry_iter, &variant_iter); + + if (os_strcmp(key, "Type") == 0) { + if (wpas_dbus_get_scan_type(message, &variant_iter, + &type, &reply) < 0) + goto out; + } else if (os_strcmp(key, "SSIDs") == 0) { + if (wpas_dbus_get_scan_ssids(message, &variant_iter, + ¶ms, &reply) < 0) + goto out; + } else if (os_strcmp(key, "IEs") == 0) { + if (wpas_dbus_get_scan_ies(message, &variant_iter, + ¶ms, &reply) < 0) + goto out; + } else if (os_strcmp(key, "Channels") == 0) { + if (wpas_dbus_get_scan_channels(message, &variant_iter, + ¶ms, &reply) < 0) + goto out; + } else { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "Unknown argument %s", key); + reply = wpas_dbus_error_invalid_args(message, key); + goto out; + } + + dbus_message_iter_next(&dict_iter); + } + + if (!type) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "Scan type not specified"); + reply = wpas_dbus_error_invalid_args(message, key); + goto out; + } + + if (!os_strcmp(type, "passive")) { + if (params.num_ssids || params.extra_ies_len) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "SSIDs or IEs specified for passive scan."); + reply = wpas_dbus_error_invalid_args( + message, "You can specify only Channels in " + "passive scan"); + goto out; + } else if (params.freqs && params.freqs[0]) { + /* wildcard ssid */ + params.num_ssids++; + wpa_supplicant_trigger_scan(wpa_s, ¶ms); + } else { + wpa_s->scan_req = 2; + wpa_supplicant_req_scan(wpa_s, 0, 0); + } + } else if (!os_strcmp(type, "active")) { + wpa_supplicant_trigger_scan(wpa_s, ¶ms); + } else { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: " + "Unknown scan type: %s", type); + reply = wpas_dbus_error_invalid_args(message, + "Wrong scan type"); + goto out; + } + +out: + for (i = 0; i < WPAS_MAX_SCAN_SSIDS; i++) + os_free((u8 *) params.ssids[i].ssid); + os_free((u8 *) params.extra_ies); + os_free(params.freqs); + return reply; +} + + +/* + * wpas_dbus_handler_disconnect - Terminate the current connection + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NotConnected DBus error message if already not connected + * or NULL otherwise. + * + * Handler function for "Disconnect" method call of network interface. + */ +DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + if (wpa_s->current_ssid != NULL) { + wpa_s->disconnected = 1; + wpa_supplicant_deauthenticate(wpa_s, + WLAN_REASON_DEAUTH_LEAVING); + + return NULL; + } + + return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED, + "This interface is not connected"); +} + + +/** + * wpas_dbus_new_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_handler_add_network(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + struct wpa_ssid *ssid = NULL; + char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf; + + dbus_message_iter_init(message, &iter); + + ssid = wpa_config_add_network(wpa_s->conf); + if (ssid == NULL) { + wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: " + "can't add new interface."); + reply = wpas_dbus_error_unknown_error( + message, + "wpa_supplicant could not add " + "a network on this interface."); + goto err; + } + wpas_notify_network_added(wpa_s, ssid); + ssid->disabled = 1; + wpa_config_set_network_defaults(ssid); + + reply = set_network_properties(message, wpa_s, ssid, &iter); + if (reply) { + wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:" + "control interface couldn't set network " + "properties"); + goto err; + } + + /* Construct the object path for this network. */ + os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d", + wpa_s->dbus_new_path, ssid->id); + + reply = dbus_message_new_method_return(message); + if (reply == NULL) { + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto err; + } + if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + dbus_message_unref(reply); + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto err; + } + + return reply; + +err: + if (ssid) { + wpas_notify_network_removed(wpa_s, ssid); + wpa_config_remove_network(wpa_s->conf, ssid->id); + } + return reply; +} + + +/** + * wpas_dbus_handler_remove_network - Remove a configured network + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NULL on success or dbus error on failure + * + * Handler function for "RemoveNetwork" method call of a network interface. + */ +DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + const char *op; + char *iface = NULL, *net_id = NULL; + int id; + struct wpa_ssid *ssid; + + dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op, + DBUS_TYPE_INVALID); + + /* Extract the network ID and ensure the network */ + /* is actually a child of this interface */ + iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL); + if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { + reply = wpas_dbus_error_invalid_args(message, op); + goto out; + } + + id = strtoul(net_id, NULL, 10); + if (errno == EINVAL) { + reply = wpas_dbus_error_invalid_args(message, op); + goto out; + } + + ssid = wpa_config_get_network(wpa_s->conf, id); + if (ssid == NULL) { + reply = wpas_dbus_error_network_unknown(message); + goto out; + } + + wpas_notify_network_removed(wpa_s, ssid); + + if (wpa_config_remove_network(wpa_s->conf, id) < 0) { + wpa_printf(MSG_ERROR, + "wpas_dbus_handler_remove_network[dbus]: " + "error occurred when removing network %d", id); + reply = wpas_dbus_error_unknown_error( + message, "error removing the specified network on " + "this interface."); + goto out; + } + + if (ssid == wpa_s->current_ssid) + wpa_supplicant_deauthenticate(wpa_s, + WLAN_REASON_DEAUTH_LEAVING); + +out: + os_free(iface); + os_free(net_id); + return reply; +} + + +/** + * wpas_dbus_handler_select_network - Attempt association with a network + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NULL on success or dbus error on failure + * + * Handler function for "SelectNetwork" method call of network interface. + */ +DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + const char *op; + char *iface = NULL, *net_id = NULL; + int id; + struct wpa_ssid *ssid; + + dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op, + DBUS_TYPE_INVALID); + + /* Extract the network ID and ensure the network */ + /* is actually a child of this interface */ + iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL); + if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { + reply = wpas_dbus_error_invalid_args(message, op); + goto out; + } + + id = strtoul(net_id, NULL, 10); + if (errno == EINVAL) { + reply = wpas_dbus_error_invalid_args(message, op); + goto out; + } + + ssid = wpa_config_get_network(wpa_s->conf, id); + if (ssid == NULL) { + reply = wpas_dbus_error_network_unknown(message); + goto out; + } + + /* Finally, associate with the network */ + wpa_supplicant_select_network(wpa_s, ssid); + +out: + os_free(iface); + os_free(net_id); + return reply; +} + + +/** + * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates) + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: A dbus message containing an error on failure or NULL on success + * + * Asks wpa_supplicant to internally store a binary blobs. + */ +DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter, array_iter; + + char *blob_name; + u8 *blob_data; + int blob_len; + struct wpa_config_blob *blob = NULL; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &blob_name); + + if (wpa_config_get_blob(wpa_s->conf, blob_name)) { + return dbus_message_new_error(message, + WPAS_DBUS_ERROR_BLOB_EXISTS, + NULL); + } + + dbus_message_iter_next(&iter); + dbus_message_iter_recurse(&iter, &array_iter); + + dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len); + + blob = os_zalloc(sizeof(*blob)); + if (!blob) { + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto err; + } + + blob->data = os_malloc(blob_len); + if (!blob->data) { + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto err; + } + os_memcpy(blob->data, blob_data, blob_len); + + blob->len = blob_len; + blob->name = os_strdup(blob_name); + if (!blob->name) { + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto err; + } + + wpa_config_set_blob(wpa_s->conf, blob); + wpas_notify_blob_added(wpa_s, blob->name); + + return reply; + +err: + if (blob) { + os_free(blob->name); + os_free(blob->data); + os_free(blob); + } + return reply; +} + + +/** + * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates) + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: A dbus message containing array of bytes (blob) + * + * Gets one wpa_supplicant's binary blobs. + */ +DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter, array_iter; + + char *blob_name; + const struct wpa_config_blob *blob; + + dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name, + DBUS_TYPE_INVALID); + + blob = wpa_config_get_blob(wpa_s->conf, blob_name); + if (!blob) { + return dbus_message_new_error(message, + WPAS_DBUS_ERROR_BLOB_UNKNOWN, + "Blob id not set"); + } + + reply = dbus_message_new_method_return(message); + if (!reply) { + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_BYTE_AS_STRING, + &array_iter)) { + dbus_message_unref(reply); + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + + if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE, + &(blob->data), blob->len)) { + dbus_message_unref(reply); + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + + if (!dbus_message_iter_close_container(&iter, &array_iter)) { + dbus_message_unref(reply); + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + +out: + return reply; +} + + +/** + * wpas_remove_handler_remove_blob - Remove named binary blob + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: NULL on success or dbus error + * + * Asks wpa_supplicant to internally remove a binary blobs. + */ +DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + char *blob_name; + + dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name, + DBUS_TYPE_INVALID); + + if (wpa_config_remove_blob(wpa_s->conf, blob_name)) { + return dbus_message_new_error(message, + WPAS_DBUS_ERROR_BLOB_UNKNOWN, + "Blob id not set"); + } + wpas_notify_blob_removed(wpa_s, blob_name); + + return reply; + +} + + +/** + * wpas_dbus_getter_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 + * + * Getter for "Capabilities" property of an interface. + */ +DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + struct wpa_driver_capa capa; + int res; + DBusMessageIter iter, iter_dict; + DBusMessageIter iter_dict_entry, iter_dict_val, iter_array, + variant_iter; + const char *scans[] = { "active", "passive", "ssid" }; + const char *modes[] = { "infrastructure", "ad-hoc", "ap" }; + int n = sizeof(modes) / sizeof(char *); + + if (message == NULL) + reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); + else + reply = dbus_message_new_method_return(message); + if (!reply) + goto nomem; + + dbus_message_iter_init_append(reply, &iter); + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + "a{sv}", &variant_iter)) + goto nomem; + + if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict)) + goto nomem; + + res = wpa_drv_get_capa(wpa_s, &capa); + + /***** pairwise cipher */ + if (res < 0) { + const char *args[] = {"ccmp", "tkip", "none"}; + if (!wpa_dbus_dict_append_string_array( + &iter_dict, "Pairwise", args, + sizeof(args) / sizeof(char*))) + goto nomem; + } else { + if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise", + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + + if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "ccmp")) + goto nomem; + } + + if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "tkip")) + goto nomem; + } + + if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "none")) + goto nomem; + } + + if (!wpa_dbus_dict_end_string_array(&iter_dict, + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + } + + /***** group cipher */ + if (res < 0) { + const char *args[] = { + "ccmp", "tkip", "wep104", "wep40" + }; + if (!wpa_dbus_dict_append_string_array( + &iter_dict, "Group", args, + sizeof(args) / sizeof(char*))) + goto nomem; + } else { + if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group", + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + + if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "ccmp")) + goto nomem; + } + + if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "tkip")) + goto nomem; + } + + if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wep104")) + goto nomem; + } + + if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wep40")) + goto nomem; + } + + if (!wpa_dbus_dict_end_string_array(&iter_dict, + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + } + + /***** key management */ + if (res < 0) { + const char *args[] = { + "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none", +#ifdef CONFIG_WPS + "wps", +#endif /* CONFIG_WPS */ + "none" + }; + if (!wpa_dbus_dict_append_string_array( + &iter_dict, "KeyMgmt", args, + sizeof(args) / sizeof(char*))) + goto nomem; + } else { + if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt", + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + + if (!wpa_dbus_dict_string_array_add_element(&iter_array, + "none")) + goto nomem; + + if (!wpa_dbus_dict_string_array_add_element(&iter_array, + "ieee8021x")) + goto nomem; + + if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | + WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wpa-eap")) + goto nomem; + + if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT) + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wpa-ft-eap")) + goto nomem; + +/* TODO: Ensure that driver actually supports sha256 encryption. */ +#ifdef CONFIG_IEEE80211W + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wpa-eap-sha256")) + goto nomem; +#endif /* CONFIG_IEEE80211W */ + } + + if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | + WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wpa-psk")) + goto nomem; + + if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK) + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wpa-ft-psk")) + goto nomem; + +/* TODO: Ensure that driver actually supports sha256 encryption. */ +#ifdef CONFIG_IEEE80211W + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wpa-psk-sha256")) + goto nomem; +#endif /* CONFIG_IEEE80211W */ + } + + if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wpa-none")) + goto nomem; + } + + +#ifdef CONFIG_WPS + if (!wpa_dbus_dict_string_array_add_element(&iter_array, + "wps")) + goto nomem; +#endif /* CONFIG_WPS */ + + if (!wpa_dbus_dict_end_string_array(&iter_dict, + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + } + + /***** WPA protocol */ + if (res < 0) { + const char *args[] = { "rsn", "wpa" }; + if (!wpa_dbus_dict_append_string_array( + &iter_dict, "Protocol", args, + sizeof(args) / sizeof(char*))) + goto nomem; + } else { + if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol", + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + + if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | + WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "rsn")) + goto nomem; + } + + if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | + WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "wpa")) + goto nomem; + } + + if (!wpa_dbus_dict_end_string_array(&iter_dict, + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + } + + /***** auth alg */ + if (res < 0) { + const char *args[] = { "open", "shared", "leap" }; + if (!wpa_dbus_dict_append_string_array( + &iter_dict, "AuthAlg", args, + sizeof(args) / sizeof(char*))) + goto nomem; + } else { + if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg", + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + + if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "open")) + goto nomem; + } + + if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "shared")) + goto nomem; + } + + if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) { + if (!wpa_dbus_dict_string_array_add_element( + &iter_array, "leap")) + goto nomem; + } + + if (!wpa_dbus_dict_end_string_array(&iter_dict, + &iter_dict_entry, + &iter_dict_val, + &iter_array)) + goto nomem; + } + + /***** Scan */ + if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans, + sizeof(scans) / sizeof(char *))) + goto nomem; + + /***** Modes */ + if (res < 0 || !(capa.flags & WPA_DRIVER_FLAGS_AP)) + n--; /* exclude ap mode if it is not supported by the driver */ + if (!wpa_dbus_dict_append_string_array(&iter_dict, "Modes", modes, n)) + goto nomem; + + if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict)) + goto nomem; + if (!dbus_message_iter_close_container(&iter, &variant_iter)) + goto nomem; + + return reply; + +nomem: + if (reply) + dbus_message_unref(reply); + + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); +} + + +/** + * wpas_dbus_getter_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 + * + * Getter for "State" property. + */ +DBusMessage * wpas_dbus_getter_state(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + const char *str_state; + char *state_ls, *tmp; + + str_state = wpa_supplicant_state_txt(wpa_s->wpa_state); + + /* make state string lowercase to fit new DBus API convention + */ + state_ls = tmp = os_strdup(str_state); + if (!tmp) { + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + while (*tmp) { + *tmp = tolower(*tmp); + tmp++; + } + + reply = wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, + &state_ls); + + os_free(state_ls); + + return reply; +} + + +/** + * wpas_dbus_new_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 + * + * Getter for "scanning" property. + */ +DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE; + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, + &scanning); +} + + +/** + * wpas_dbus_getter_ap_scan - Control roaming mode + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: A message containong value of ap_scan variable + * + * Getter function for "ApScan" property. + */ +DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + dbus_uint32_t ap_scan = wpa_s->conf->ap_scan; + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32, + &ap_scan); +} + + +/** + * wpas_dbus_setter_ap_scan - Control roaming mode + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NULL + * + * Setter function for "ApScan" property. + */ +DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + dbus_uint32_t ap_scan; + + reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32, + &ap_scan); + if (reply) + return reply; + + if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) { + return wpas_dbus_error_invalid_args( + message, "ap_scan must equal 0, 1 or 2"); + } + return NULL; +} + + +/** + * wpas_dbus_getter_ifname - Get interface name + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: A dbus message containing a name of network interface + * associated with with wpa_s + * + * Getter for "Ifname" property. + */ +DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + const char *ifname = wpa_s->ifname; + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, + &ifname); +} + + +/** + * wpas_dbus_getter_driver - Get interface name + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: A dbus message containing a name of network interface + * driver associated with with wpa_s + * + * Getter for "Driver" property. + */ +DBusMessage * wpas_dbus_getter_driver(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + const char *driver; + + if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) { + wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: " + "wpa_s has no driver set"); + return wpas_dbus_error_unknown_error(message, NULL); + } + + driver = wpa_s->driver->name; + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, + &driver); +} + + +/** + * wpas_dbus_getter_current_bss - Get current bss object path + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: A dbus message containing a DBus object path to + * current BSS + * + * Getter for "CurrentBSS" property. + */ +DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply; + char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf; + + if (wpa_s->current_bss) + os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", + wpa_s->dbus_new_path, wpa_s->current_bss->id); + else + os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/"); + + reply = wpas_dbus_simple_property_getter(message, + DBUS_TYPE_OBJECT_PATH, + &bss_obj_path); + + return reply; +} + + +/** + * wpas_dbus_getter_current_network - Get current network object path + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: A dbus message containing a DBus object path to + * current network + * + * Getter for "CurrentNetwork" property. + */ +DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply; + char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf; + + if (wpa_s->current_ssid) + os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", + wpa_s->dbus_new_path, wpa_s->current_ssid->id); + else + os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/"); + + reply = wpas_dbus_simple_property_getter(message, + DBUS_TYPE_OBJECT_PATH, + &net_obj_path); + + return reply; +} + + +/** + * wpas_dbus_getter_bridge_ifname - Get interface name + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: A dbus message containing a name of bridge network + * interface associated with with wpa_s + * + * Getter for "BridgeIfname" property. + */ +DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + const char *bridge_ifname = NULL; + + bridge_ifname = wpa_s->bridge_ifname; + if (bridge_ifname == NULL) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: " + "wpa_s has no bridge interface name set"); + return wpas_dbus_error_unknown_error(message, NULL); + } + + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, + &bridge_ifname); +} + + +/** + * wpas_dbus_getter_bsss - Get array of BSSs objects + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: a dbus message containing an array of all known BSS objects + * dbus paths + * + * Getter for "BSSs" property. + */ +DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + struct wpa_bss *bss; + char **paths; + unsigned int i = 0; + + paths = os_zalloc(wpa_s->num_bss * sizeof(char *)); + if (!paths) { + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + /* 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) { + paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); + if (paths[i] == NULL) { + reply = dbus_message_new_error(message, + DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + /* Construct the object path for this BSS. */ + os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", + wpa_s->dbus_new_path, bss->id); + } + + reply = wpas_dbus_simple_array_property_getter(message, + DBUS_TYPE_OBJECT_PATH, + paths, wpa_s->num_bss); + +out: + while (i) + os_free(paths[--i]); + os_free(paths); + return reply; +} + + +/** + * wpas_dbus_getter_networks - Get array of networks objects + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: a dbus message containing an array of all configured + * networks dbus object paths. + * + * Getter for "Networks" property. + */ +DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + struct wpa_ssid *ssid; + char **paths; + unsigned int i = 0, num = 0; + + if (wpa_s->conf == NULL) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: " + "An error occurred getting networks list."); + return wpas_dbus_error_unknown_error(message, NULL); + } + + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) + num++; + + paths = os_zalloc(num * sizeof(char *)); + if (!paths) { + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + /* Loop through configured networks and append object path of each */ + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { + paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); + if (paths[i] == NULL) { + reply = dbus_message_new_error(message, + DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + + /* Construct the object path for this network. */ + os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d", + wpa_s->dbus_new_path, ssid->id); + } + + reply = wpas_dbus_simple_array_property_getter(message, + DBUS_TYPE_OBJECT_PATH, + paths, num); + +out: + while (i) + os_free(paths[--i]); + os_free(paths); + return reply; +} + + +/** + * wpas_dbus_getter_blobs - Get all blobs defined for this interface + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: a dbus message containing a dictionary of pairs (blob_name, blob) + * + * Getter for "Blobs" property. + */ +DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter; + struct wpa_config_blob *blob; + + if (message == NULL) + reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); + else + reply = dbus_message_new_method_return(message); + if (!reply) + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + "a{say}", &variant_iter) || + !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, + "{say}", &dict_iter)) { + dbus_message_unref(reply); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + blob = wpa_s->conf->blobs; + while (blob) { + if (!dbus_message_iter_open_container(&dict_iter, + DBUS_TYPE_DICT_ENTRY, + NULL, &entry_iter) || + !dbus_message_iter_append_basic(&entry_iter, + DBUS_TYPE_STRING, + &(blob->name)) || + !dbus_message_iter_open_container(&entry_iter, + DBUS_TYPE_ARRAY, + DBUS_TYPE_BYTE_AS_STRING, + &array_iter) || + !dbus_message_iter_append_fixed_array(&array_iter, + DBUS_TYPE_BYTE, + &(blob->data), + blob->len) || + !dbus_message_iter_close_container(&entry_iter, + &array_iter) || + !dbus_message_iter_close_container(&dict_iter, + &entry_iter)) { + dbus_message_unref(reply); + return dbus_message_new_error(message, + DBUS_ERROR_NO_MEMORY, + NULL); + } + + blob = blob->next; + } + + if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) || + !dbus_message_iter_close_container(&iter, &variant_iter)) { + dbus_message_unref(reply); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + return reply; +} + + +/** + * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing the bssid for the requested bss + * + * Getter for "BSSID" property. + */ +DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message, + struct bss_handler_args *bss) +{ + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_bssid[dbus]: no " + "bss with id %d found", bss->id); + return NULL; + } + + return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE, + res->bssid, ETH_ALEN); +} + + +/** + * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing the ssid for the requested bss + * + * Getter for "SSID" property. + */ +DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message, + struct bss_handler_args *bss) +{ + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ssid[dbus]: no " + "bss with id %d found", bss->id); + return NULL; + } + + return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE, + res->ssid, + res->ssid_len); +} + + +/** + * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing the privacy flag value of requested bss + * + * Getter for "Privacy" property. + */ +DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message, + struct bss_handler_args *bss) +{ + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + dbus_bool_t privacy; + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_privacy[dbus]: no " + "bss with id %d found", bss->id); + return NULL; + } + + privacy = (res->caps & IEEE80211_CAP_PRIVACY) ? TRUE : FALSE; + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, + &privacy); +} + + +/** + * wpas_dbus_getter_bss_mode - Return the mode of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing the mode of requested bss + * + * Getter for "Mode" property. + */ +DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message, + struct bss_handler_args *bss) +{ + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + const char *mode; + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_mode[dbus]: no " + "bss with id %d found", bss->id); + return NULL; + } + + if (res->caps & IEEE80211_CAP_IBSS) + mode = "ad-hoc"; + else + mode = "infrastructure"; + + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, + &mode); +} + + +/** + * wpas_dbus_getter_bss_level - Return the signal strength of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing the signal strength of requested bss + * + * Getter for "Level" property. + */ +DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message, + struct bss_handler_args *bss) +{ + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_signal[dbus]: no " + "bss with id %d found", bss->id); + return NULL; + } + + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT16, + &res->level); +} + + +/** + * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing the frequency of requested bss + * + * Getter for "Frequency" property. + */ +DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message, + struct bss_handler_args *bss) +{ + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_frequency[dbus]: " + "no bss with id %d found", bss->id); + return NULL; + } + + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16, + &res->freq); +} + + +static int cmp_u8s_desc(const void *a, const void *b) +{ + return (*(u8 *) b - *(u8 *) a); +} + + +/** + * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing sorted array of bit rates + * + * Getter for "Rates" property. + */ +DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message, + struct bss_handler_args *bss) +{ + DBusMessage *reply; + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + u8 *ie_rates = NULL; + u32 *real_rates; + int rates_num, i; + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rates[dbus]: " + "no bss with id %d found", bss->id); + return NULL; + } + + rates_num = wpa_bss_get_bit_rates(res, &ie_rates); + if (rates_num < 0) + return NULL; + + qsort(ie_rates, rates_num, 1, cmp_u8s_desc); + + real_rates = os_malloc(sizeof(u32) * rates_num); + if (!real_rates) { + os_free(ie_rates); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + for (i = 0; i < rates_num; i++) + real_rates[i] = ie_rates[i] * 500000; + + reply = wpas_dbus_simple_array_property_getter(message, + DBUS_TYPE_UINT32, + real_rates, rates_num); + + os_free(ie_rates); + os_free(real_rates); + return reply; +} + + +static DBusMessage * wpas_dbus_get_bss_security_prop( + DBusMessage *message, struct wpa_ie_data *ie_data) +{ + DBusMessage *reply; + DBusMessageIter iter, iter_dict, variant_iter; + const char *group; + const char *pairwise[2]; /* max 2 pairwise ciphers is supported */ + const char *key_mgmt[7]; /* max 7 key managements may be supported */ + int n; + + if (message == NULL) + reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); + else + reply = dbus_message_new_method_return(message); + if (!reply) + goto nomem; + + dbus_message_iter_init_append(reply, &iter); + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + "a{sv}", &variant_iter)) + goto nomem; + + if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict)) + goto nomem; + + /* KeyMgmt */ + n = 0; + if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK) + key_mgmt[n++] = "wpa-psk"; + if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_PSK) + key_mgmt[n++] = "wpa-ft-psk"; + if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK_SHA256) + key_mgmt[n++] = "wpa-psk-sha256"; + if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X) + key_mgmt[n++] = "wpa-eap"; + if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) + key_mgmt[n++] = "wpa-ft-eap"; + if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) + key_mgmt[n++] = "wpa-eap-sha256"; + if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE) + key_mgmt[n++] = "wpa-none"; + + if (!wpa_dbus_dict_append_string_array(&iter_dict, "KeyMgmt", + key_mgmt, n)) + goto nomem; + + /* Group */ + switch (ie_data->group_cipher) { + case WPA_CIPHER_WEP40: + group = "wep40"; + break; + case WPA_CIPHER_TKIP: + group = "tkip"; + break; + case WPA_CIPHER_CCMP: + group = "ccmp"; + break; + case WPA_CIPHER_WEP104: + group = "wep104"; + break; + default: + group = ""; + break; + } + + if (!wpa_dbus_dict_append_string(&iter_dict, "Group", group)) + goto nomem; + + /* Pairwise */ + n = 0; + if (ie_data->pairwise_cipher & WPA_CIPHER_TKIP) + pairwise[n++] = "tkip"; + if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP) + pairwise[n++] = "ccmp"; + + if (!wpa_dbus_dict_append_string_array(&iter_dict, "Pairwise", + pairwise, n)) + goto nomem; + + /* Management group (RSN only) */ + if (ie_data->proto == WPA_PROTO_RSN) { + switch (ie_data->mgmt_group_cipher) { +#ifdef CONFIG_IEEE80211W + case WPA_CIPHER_AES_128_CMAC: + group = "aes128cmac"; + break; +#endif /* CONFIG_IEEE80211W */ + default: + group = ""; + break; + } + + if (!wpa_dbus_dict_append_string(&iter_dict, "MgmtGroup", + group)) + goto nomem; + } + + if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict)) + goto nomem; + if (!dbus_message_iter_close_container(&iter, &variant_iter)) + goto nomem; + + return reply; + +nomem: + if (reply) + dbus_message_unref(reply); + + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); +} + + +/** + * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing the WPA options of requested bss + * + * Getter for "WPA" property. + */ +DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message, + struct bss_handler_args *bss) +{ + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct wpa_ie_data wpa_data; + const u8 *ie; + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpa[dbus]: no " + "bss with id %d found", bss->id); + return NULL; + } + + os_memset(&wpa_data, 0, sizeof(wpa_data)); + ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE); + if (ie) { + if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) + return wpas_dbus_error_unknown_error(message, + "invalid WPA IE"); + } + + return wpas_dbus_get_bss_security_prop(message, &wpa_data); +} + + +/** + * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing the RSN options of requested bss + * + * Getter for "RSN" property. + */ +DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message, + struct bss_handler_args *bss) +{ + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct wpa_ie_data wpa_data; + const u8 *ie; + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsn[dbus]: no " + "bss with id %d found", bss->id); + return NULL; + } + + os_memset(&wpa_data, 0, sizeof(wpa_data)); + ie = wpa_bss_get_ie(res, WLAN_EID_RSN); + if (ie) { + if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) + return wpas_dbus_error_unknown_error(message, + "invalid RSN IE"); + } + + return wpas_dbus_get_bss_security_prop(message, &wpa_data); +} + + +/** + * wpas_dbus_getter_bss_ies - Return all IEs of a BSS + * @message: Pointer to incoming dbus message + * @bss: a pair of interface describing structure and bss's id + * Returns: a dbus message containing IEs byte array + * + * Getter for "IEs" property. + */ +DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message, + struct bss_handler_args *bss) +{ + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + + if (!res) { + wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ies[dbus]: no " + "bss with id %d found", bss->id); + return NULL; + } + + return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE, + res + 1, res->ie_len); +} + + +/** + * wpas_dbus_getter_enabled - Check whether network is enabled or disabled + * @message: Pointer to incoming dbus message + * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface + * and wpa_ssid structure for a configured network + * Returns: DBus message with boolean indicating state of configured network + * or DBus error on failure + * + * Getter for "enabled" property of a configured network. + */ +DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message, + struct network_handler_args *net) +{ + dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE; + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, + &enabled); +} + + +/** + * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled + * @message: Pointer to incoming dbus message + * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface + * and wpa_ssid structure for a configured network + * Returns: NULL indicating success or DBus error on failure + * + * Setter for "Enabled" property of a configured network. + */ +DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message, + struct network_handler_args *net) +{ + DBusMessage *reply = NULL; + + struct wpa_supplicant *wpa_s; + struct wpa_ssid *ssid; + + dbus_bool_t enable; + + reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, + &enable); + + if (reply) + return reply; + + wpa_s = net->wpa_s; + ssid = net->ssid; + + if (enable) + wpa_supplicant_enable_network(wpa_s, ssid); + else + wpa_supplicant_disable_network(wpa_s, ssid); + + return NULL; +} + + +/** + * wpas_dbus_getter_network_properties - Get options for a configured network + * @message: Pointer to incoming dbus message + * @net: wpa_supplicant structure for a network interface and + * wpa_ssid structure for a configured network + * Returns: DBus message with network properties or DBus error on failure + * + * Getter for "Properties" property of a configured network. + */ +DBusMessage * wpas_dbus_getter_network_properties( + DBusMessage *message, struct network_handler_args *net) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter, variant_iter, dict_iter; + char **iterator; + char **props = wpa_config_get_all(net->ssid, 0); + if (!props) + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + + if (message == NULL) + reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); + else + reply = dbus_message_new_method_return(message); + if (!reply) { + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + "a{sv}", &variant_iter) || + !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) { + dbus_message_unref(reply); + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + + iterator = props; + while (*iterator) { + if (!wpa_dbus_dict_append_string(&dict_iter, *iterator, + *(iterator + 1))) { + dbus_message_unref(reply); + reply = dbus_message_new_error(message, + DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + iterator += 2; + } + + + if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || + !dbus_message_iter_close_container(&iter, &variant_iter)) { + dbus_message_unref(reply); + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + +out: + iterator = props; + while (*iterator) { + os_free(*iterator); + iterator++; + } + os_free(props); + return reply; +} + + +/** + * wpas_dbus_setter_network_properties - Set options for a configured network + * @message: Pointer to incoming dbus message + * @net: wpa_supplicant structure for a network interface and + * wpa_ssid structure for a configured network + * Returns: NULL indicating success or DBus error on failure + * + * Setter for "Properties" property of a configured network. + */ +DBusMessage * wpas_dbus_setter_network_properties( + DBusMessage *message, struct network_handler_args *net) +{ + struct wpa_ssid *ssid = net->ssid; + + DBusMessage *reply = NULL; + DBusMessageIter iter, variant_iter; + + dbus_message_iter_init(message, &iter); + + dbus_message_iter_next(&iter); + dbus_message_iter_next(&iter); + + dbus_message_iter_recurse(&iter, &variant_iter); + + reply = set_network_properties(message, net->wpa_s, ssid, + &variant_iter); + if (reply) + wpa_printf(MSG_DEBUG, "dbus control interface couldn't set " + "network properties"); + + return reply; +} diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.h b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.h new file mode 100644 index 0000000..3cdf9cb --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.h @@ -0,0 +1,196 @@ +/* + * WPA Supplicant / dbus-based control interface + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef CTRL_IFACE_DBUS_NEW_HANDLERS_H +#define CTRL_IFACE_DBUS_NEW_HANDLERS_H + +struct network_handler_args { + struct wpa_supplicant *wpa_s; + struct wpa_ssid *ssid; +}; + +struct bss_handler_args { + struct wpa_supplicant *wpa_s; + unsigned int id; +}; + +DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message, + const int type, + const void *val); + +DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message, + const int type, void *val); + +DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message, + const int type, + const void *array, + size_t array_len); + +DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message, + struct wpa_global *global); + +DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, + void *nothing); + +DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_state(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_driver(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message, + struct wpa_supplicant *bss); + +DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message, + struct bss_handler_args *bss); + +DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message, + struct network_handler_args *net); + +DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message, + struct network_handler_args *net); + +DBusMessage * wpas_dbus_getter_network_properties( + DBusMessage *message, struct network_handler_args *net); + +DBusMessage * wpas_dbus_setter_network_properties( + DBusMessage *message, struct network_handler_args *net); + +DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_process_credentials( + DBusMessage *message, struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_setter_process_credentials( + DBusMessage *message, struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_getter_credentials(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message, + const char *arg); +DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message, + const char *arg); + +#endif /* CTRL_IFACE_DBUS_HANDLERS_NEW_H */ diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers_wps.c new file mode 100644 index 0000000..dc44a59 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers_wps.c @@ -0,0 +1,331 @@ +/* + * WPA Supplicant / dbus-based control interface (WPS) + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "../config.h" +#include "../wpa_supplicant_i.h" +#include "../wps_supplicant.h" +#include "dbus_new_helpers.h" +#include "dbus_new.h" +#include "dbus_new_handlers.h" +#include "dbus_dict_helpers.h" + + +struct wps_start_params { + int role; /* 0 - not set, 1 - enrollee, 2 - registrar */ + int type; /* 0 - not set, 1 - pin, 2 - pbc */ + u8 *bssid; + char *pin; +}; + + +static int wpas_dbus_handler_wps_role(DBusMessage *message, + DBusMessageIter *entry_iter, + struct wps_start_params *params, + DBusMessage **reply) +{ + DBusMessageIter variant_iter; + char *val; + + dbus_message_iter_recurse(entry_iter, &variant_iter); + if (dbus_message_iter_get_arg_type(&variant_iter) != + DBUS_TYPE_STRING) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Role type, " + "string required"); + *reply = wpas_dbus_error_invalid_args(message, + "Role must be a string"); + return -1; + } + dbus_message_iter_get_basic(&variant_iter, &val); + if (os_strcmp(val, "enrollee") == 0) + params->role = 1; + else if (os_strcmp(val, "registrar") == 0) + params->role = 2; + else { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Uknown role %s", val); + *reply = wpas_dbus_error_invalid_args(message, val); + return -1; + } + return 0; +} + + +static int wpas_dbus_handler_wps_type(DBusMessage *message, + DBusMessageIter *entry_iter, + struct wps_start_params *params, + DBusMessage **reply) +{ + DBusMessageIter variant_iter; + char *val; + + dbus_message_iter_recurse(entry_iter, &variant_iter); + if (dbus_message_iter_get_arg_type(&variant_iter) != + DBUS_TYPE_STRING) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Type type, " + "string required"); + *reply = wpas_dbus_error_invalid_args(message, + "Type must be a string"); + return -1; + } + dbus_message_iter_get_basic(&variant_iter, &val); + if (os_strcmp(val, "pin") == 0) + params->type = 1; + else if (os_strcmp(val, "pbc") == 0) + params->type = 2; + else { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown type %s", + val); + *reply = wpas_dbus_error_invalid_args(message, val); + return -1; + } + return 0; +} + + +static int wpas_dbus_handler_wps_bssid(DBusMessage *message, + DBusMessageIter *entry_iter, + struct wps_start_params *params, + DBusMessage **reply) +{ + DBusMessageIter variant_iter, array_iter; + int len; + + dbus_message_iter_recurse(entry_iter, &variant_iter); + if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&variant_iter) != + DBUS_TYPE_ARRAY) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Bssid type, " + "byte array required"); + *reply = wpas_dbus_error_invalid_args( + message, "Bssid must be a byte array"); + return -1; + } + dbus_message_iter_recurse(&variant_iter, &array_iter); + dbus_message_iter_get_fixed_array(&array_iter, ¶ms->bssid, &len); + if (len != ETH_ALEN) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Stsrt - Wrong Bssid length " + "%d", len); + *reply = wpas_dbus_error_invalid_args(message, + "Bssid is wrong length"); + return -1; + } + return 0; +} + + +static int wpas_dbus_handler_wps_pin(DBusMessage *message, + DBusMessageIter *entry_iter, + struct wps_start_params *params, + DBusMessage **reply) +{ + DBusMessageIter variant_iter; + + dbus_message_iter_recurse(entry_iter, &variant_iter); + if (dbus_message_iter_get_arg_type(&variant_iter) != + DBUS_TYPE_STRING) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Pin type, " + "string required"); + *reply = wpas_dbus_error_invalid_args(message, + "Pin must be a string"); + return -1; + } + dbus_message_iter_get_basic(&variant_iter, ¶ms->pin); + return 0; +} + + +static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key, + DBusMessageIter *entry_iter, + struct wps_start_params *params, + DBusMessage **reply) +{ + if (os_strcmp(key, "Role") == 0) + return wpas_dbus_handler_wps_role(message, entry_iter, + params, reply); + else if (os_strcmp(key, "Type") == 0) + return wpas_dbus_handler_wps_type(message, entry_iter, + params, reply); + else if (os_strcmp(key, "Bssid") == 0) + return wpas_dbus_handler_wps_bssid(message, entry_iter, + params, reply); + else if (os_strcmp(key, "Pin") == 0) + return wpas_dbus_handler_wps_pin(message, entry_iter, + params, reply); + + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - unknown key %s", key); + *reply = wpas_dbus_error_invalid_args(message, key); + return -1; +} + + +/** + * wpas_dbus_handler_wps_start - Start WPS configuration + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: DBus message dictionary on success or DBus error on failure + * + * Handler for "Start" method call. DBus dictionary argument contains + * information about role (enrollee or registrar), authorization method + * (pin or push button) and optionally pin and bssid. Returned message + * has a dictionary argument which may contain newly generated pin (optional). + */ +DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter, dict_iter, entry_iter; + struct wps_start_params params; + char *key; + char npin[9] = { '\0' }; + int ret; + + os_memset(¶ms, 0, sizeof(params)); + dbus_message_iter_init(message, &iter); + + dbus_message_iter_recurse(&iter, &dict_iter); + while (dbus_message_iter_get_arg_type(&dict_iter) == + DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&dict_iter, &entry_iter); + + dbus_message_iter_get_basic(&entry_iter, &key); + dbus_message_iter_next(&entry_iter); + + if (wpas_dbus_handler_wps_start_entry(message, key, + &entry_iter, + ¶ms, &reply)) + return reply; + + dbus_message_iter_next(&dict_iter); + } + + if (params.role == 0) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Role not specified"); + return wpas_dbus_error_invalid_args(message, + "Role not specified"); + } else if (params.role == 1 && params.type == 0) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Type not specified"); + return wpas_dbus_error_invalid_args(message, + "Type not specified"); + } else if (params.role == 2 && params.pin == NULL) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Pin required for " + "registrar role"); + return wpas_dbus_error_invalid_args( + message, "Pin required for registrar role."); + } + + if (params.role == 2) + ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin, + NULL); + else if (params.type == 1) { + ret = wpas_wps_start_pin(wpa_s, params.bssid, params.pin); + if (ret > 0) + os_snprintf(npin, sizeof(npin), "%08d", ret); + } else + ret = wpas_wps_start_pbc(wpa_s, params.bssid); + + if (ret < 0) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start wpas_wps_failed in " + "role %s and key %s", + (params.role == 1 ? "enrollee" : "registrar"), + (params.type == 0 ? "" : + (params.type == 1 ? "pin" : "pbc"))); + return wpas_dbus_error_unknown_error(message, + "WPS start failed"); + } + + reply = dbus_message_new_method_return(message); + if (!reply) { + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + dbus_message_iter_init_append(reply, &iter); + if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) { + dbus_message_unref(reply); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + if (os_strlen(npin) > 0) { + if (!wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) { + dbus_message_unref(reply); + return dbus_message_new_error(message, + DBUS_ERROR_NO_MEMORY, + NULL); + } + } + + if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) { + dbus_message_unref(reply); + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + return reply; +} + + +/** + * wpas_dbus_getter_process_credentials - Check if credentials are processed + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: DBus message with a boolean on success or DBus error on failure + * + * Getter for "ProcessCredentials" property. Returns returned boolean will be + * true if wps_cred_processing configuration field is not equal to 1 or false + * if otherwise. + */ +DBusMessage * wpas_dbus_getter_process_credentials( + DBusMessage *message, struct wpa_supplicant *wpa_s) +{ + dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1); + return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, + &process); +} + + +/** + * wpas_dbus_setter_process_credentials - Set credentials_processed conf param + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: NULL on success or DBus error on failure + * + * Setter for "ProcessCredentials" property. Sets credentials_processed on 2 + * if boolean argument is true or on 1 if otherwise. + */ +DBusMessage * wpas_dbus_setter_process_credentials( + DBusMessage *message, struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + dbus_bool_t process_credentials, old_pc; + + reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, + &process_credentials); + if (reply) + return reply; + + old_pc = (wpa_s->conf->wps_cred_processing != 1); + wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1); + + if ((wpa_s->conf->wps_cred_processing != 1) != old_pc) + wpa_dbus_mark_property_changed(wpa_s->global->dbus, + wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_WPS, + "ProcessCredentials"); + + return NULL; +} diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new_helpers.c b/contrib/wpa/wpa_supplicant/dbus/dbus_new_helpers.c new file mode 100644 index 0000000..06749db --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new_helpers.c @@ -0,0 +1,875 @@ +/* + * WPA Supplicant / dbus-based control interface + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "utils/includes.h" + +#include "utils/common.h" +#include "utils/eloop.h" +#include "dbus_common.h" +#include "dbus_common_i.h" +#include "dbus_new.h" +#include "dbus_new_helpers.h" + + +/** + * recursive_iter_copy - Reads arguments from one iterator and + * writes to another recursively + * @from: iterator to read from + * @to: iterator to write to + * + * Copies one iterator's elements to another. If any element in + * iterator is of container type, its content is copied recursively + */ +static void recursive_iter_copy(DBusMessageIter *from, DBusMessageIter *to) +{ + + char *subtype = NULL; + int type; + + /* iterate over iterator to copy */ + while ((type = dbus_message_iter_get_arg_type(from)) != + DBUS_TYPE_INVALID) { + + /* simply copy basic type entries */ + if (dbus_type_is_basic(type)) { + if (dbus_type_is_fixed(type)) { + /* + * According to DBus documentation all + * fixed-length types are guaranteed to fit + * 8 bytes + */ + dbus_uint64_t v; + dbus_message_iter_get_basic(from, &v); + dbus_message_iter_append_basic(to, type, &v); + } else { + char *v; + dbus_message_iter_get_basic(from, &v); + dbus_message_iter_append_basic(to, type, &v); + } + } else { + /* recursively copy container type entries */ + DBusMessageIter write_subiter, read_subiter; + + dbus_message_iter_recurse(from, &read_subiter); + + if (type == DBUS_TYPE_VARIANT || + type == DBUS_TYPE_ARRAY) { + subtype = dbus_message_iter_get_signature( + &read_subiter); + } + + dbus_message_iter_open_container(to, type, subtype, + &write_subiter); + + recursive_iter_copy(&read_subiter, &write_subiter); + + dbus_message_iter_close_container(to, &write_subiter); + if (subtype) + dbus_free(subtype); + } + + dbus_message_iter_next(from); + } +} + + +static unsigned int fill_dict_with_properties( + DBusMessageIter *dict_iter, const struct wpa_dbus_property_desc *props, + const char *interface, const void *user_data) +{ + DBusMessage *reply; + DBusMessageIter entry_iter, ret_iter; + unsigned int counter = 0; + const struct wpa_dbus_property_desc *dsc; + + for (dsc = props; dsc && dsc->dbus_property; dsc++) { + if (!os_strncmp(dsc->dbus_interface, interface, + WPAS_DBUS_INTERFACE_MAX) && + dsc->access != W && dsc->getter) { + reply = dsc->getter(NULL, user_data); + if (!reply) + continue; + + if (dbus_message_get_type(reply) == + DBUS_MESSAGE_TYPE_ERROR) { + dbus_message_unref(reply); + continue; + } + + dbus_message_iter_init(reply, &ret_iter); + + dbus_message_iter_open_container(dict_iter, + DBUS_TYPE_DICT_ENTRY, + NULL, &entry_iter); + dbus_message_iter_append_basic( + &entry_iter, DBUS_TYPE_STRING, + &dsc->dbus_property); + + recursive_iter_copy(&ret_iter, &entry_iter); + + dbus_message_iter_close_container(dict_iter, + &entry_iter); + dbus_message_unref(reply); + counter++; + } + } + + return counter; +} + + +/** + * get_all_properties - Responds for GetAll properties calls on object + * @message: Message with GetAll call + * @interface: interface name which properties will be returned + * @property_dsc: list of object's properties + * Returns: Message with dict of variants as argument with properties values + * + * Iterates over all properties registered with object and execute getters + * of those, which are readable and which interface matches interface + * specified as argument. Returned message contains one dict argument + * with properties names as keys and theirs values as values. + */ +static DBusMessage * get_all_properties( + DBusMessage *message, char *interface, + struct wpa_dbus_object_desc *obj_dsc) +{ + /* Create and initialize the return message */ + DBusMessage *reply = dbus_message_new_method_return(message); + DBusMessageIter iter, dict_iter; + int props_num; + + dbus_message_iter_init_append(reply, &iter); + + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &dict_iter); + + props_num = fill_dict_with_properties(&dict_iter, obj_dsc->properties, + interface, obj_dsc->user_data); + + dbus_message_iter_close_container(&iter, &dict_iter); + + if (props_num == 0) { + dbus_message_unref(reply); + reply = dbus_message_new_error(message, + DBUS_ERROR_INVALID_ARGS, + "No readable properties in " + "this interface"); + } + + return reply; +} + + +static int is_signature_correct(DBusMessage *message, + const struct wpa_dbus_method_desc *method_dsc) +{ + /* According to DBus documentation max length of signature is 255 */ +#define MAX_SIG_LEN 256 + char registered_sig[MAX_SIG_LEN], *pos; + const char *sig = dbus_message_get_signature(message); + int ret; + const struct wpa_dbus_argument *arg; + + pos = registered_sig; + *pos = '\0'; + + for (arg = method_dsc->args; arg && arg->name; arg++) { + if (arg->dir == ARG_IN) { + size_t blen = registered_sig + MAX_SIG_LEN - pos; + ret = os_snprintf(pos, blen, "%s", arg->type); + if (ret < 0 || (size_t) ret >= blen) + return 0; + pos += ret; + } + } + + return !os_strncmp(registered_sig, sig, MAX_SIG_LEN); +} + + +static DBusMessage * properties_get_all(DBusMessage *message, char *interface, + struct wpa_dbus_object_desc *obj_dsc) +{ + if (os_strcmp(dbus_message_get_signature(message), "s") != 0) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + + return get_all_properties(message, interface, obj_dsc); +} + + +static DBusMessage * properties_get(DBusMessage *message, + const struct wpa_dbus_property_desc *dsc, + void *user_data) +{ + if (os_strcmp(dbus_message_get_signature(message), "ss")) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + + if (dsc->access != W && dsc->getter) + return dsc->getter(message, user_data); + + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Property is write-only"); +} + + +static DBusMessage * properties_set(DBusMessage *message, + const struct wpa_dbus_property_desc *dsc, + void *user_data) +{ + if (os_strcmp(dbus_message_get_signature(message), "ssv")) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + + if (dsc->access != R && dsc->setter) + return dsc->setter(message, user_data); + + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Property is read-only"); +} + + +static DBusMessage * +properties_get_or_set(DBusMessage *message, DBusMessageIter *iter, + char *interface, + struct wpa_dbus_object_desc *obj_dsc) +{ + const struct wpa_dbus_property_desc *property_dsc; + char *property; + const char *method; + + method = dbus_message_get_member(message); + property_dsc = obj_dsc->properties; + + /* Second argument: property name (DBUS_TYPE_STRING) */ + if (!dbus_message_iter_next(iter) || + dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + } + dbus_message_iter_get_basic(iter, &property); + + while (property_dsc && property_dsc->dbus_property) { + /* compare property names and + * interfaces */ + if (!os_strncmp(property_dsc->dbus_property, property, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) && + !os_strncmp(property_dsc->dbus_interface, interface, + WPAS_DBUS_INTERFACE_MAX)) + break; + + property_dsc++; + } + if (property_dsc == NULL || property_dsc->dbus_property == NULL) { + wpa_printf(MSG_DEBUG, "no property handler for %s.%s on %s", + interface, property, + dbus_message_get_path(message)); + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "No such property"); + } + + if (os_strncmp(WPA_DBUS_PROPERTIES_GET, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) == 0) + return properties_get(message, property_dsc, + obj_dsc->user_data); + + return properties_set(message, property_dsc, obj_dsc->user_data); +} + + +static DBusMessage * properties_handler(DBusMessage *message, + struct wpa_dbus_object_desc *obj_dsc) +{ + DBusMessageIter iter; + char *interface; + const char *method; + + method = dbus_message_get_member(message); + dbus_message_iter_init(message, &iter); + + if (!os_strncmp(WPA_DBUS_PROPERTIES_GET, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) || + !os_strncmp(WPA_DBUS_PROPERTIES_SET, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) || + !os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) { + /* First argument: interface name (DBUS_TYPE_STRING) */ + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + { + return dbus_message_new_error(message, + DBUS_ERROR_INVALID_ARGS, + NULL); + } + + dbus_message_iter_get_basic(&iter, &interface); + + if (!os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) { + /* GetAll */ + return properties_get_all(message, interface, obj_dsc); + } + /* Get or Set */ + return properties_get_or_set(message, &iter, interface, + obj_dsc); + } + return dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD, + NULL); +} + + +static DBusMessage * msg_method_handler(DBusMessage *message, + struct wpa_dbus_object_desc *obj_dsc) +{ + const struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods; + const char *method; + const char *msg_interface; + + method = dbus_message_get_member(message); + msg_interface = dbus_message_get_interface(message); + + /* try match call to any registered method */ + while (method_dsc && method_dsc->dbus_method) { + /* compare method names and interfaces */ + if (!os_strncmp(method_dsc->dbus_method, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) && + !os_strncmp(method_dsc->dbus_interface, msg_interface, + WPAS_DBUS_INTERFACE_MAX)) + break; + + method_dsc++; + } + if (method_dsc == NULL || method_dsc->dbus_method == NULL) { + wpa_printf(MSG_DEBUG, "no method handler for %s.%s on %s", + msg_interface, method, + dbus_message_get_path(message)); + return dbus_message_new_error(message, + DBUS_ERROR_UNKNOWN_METHOD, NULL); + } + + if (!is_signature_correct(message, method_dsc)) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + } + + return method_dsc->method_handler(message, + obj_dsc->user_data); +} + + +/** + * message_handler - Handles incoming DBus messages + * @connection: DBus connection on which message was received + * @message: Received message + * @user_data: pointer to description of object to which message was sent + * Returns: Returns information whether message was handled or not + * + * Reads message interface and method name, then checks if they matches one + * of the special cases i.e. introspection call or properties get/getall/set + * methods and handles it. Else it iterates over registered methods list + * and tries to match method's name and interface to those read from message + * If appropriate method was found its handler function is called and + * response is sent. Otherwise, the DBUS_ERROR_UNKNOWN_METHOD error message + * will be sent. + */ +static DBusHandlerResult message_handler(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + struct wpa_dbus_object_desc *obj_dsc = user_data; + const char *method; + const char *path; + const char *msg_interface; + DBusMessage *reply; + + /* get method, interface and path the message is addressed to */ + method = dbus_message_get_member(message); + path = dbus_message_get_path(message); + msg_interface = dbus_message_get_interface(message); + if (!method || !path || !msg_interface) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + wpa_printf(MSG_MSGDUMP, "dbus: %s.%s (%s)", + msg_interface, method, path); + + /* if message is introspection method call */ + if (!os_strncmp(WPA_DBUS_INTROSPECTION_METHOD, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) && + !os_strncmp(WPA_DBUS_INTROSPECTION_INTERFACE, msg_interface, + WPAS_DBUS_INTERFACE_MAX)) { +#ifdef CONFIG_CTRL_IFACE_DBUS_INTRO + reply = wpa_dbus_introspect(message, obj_dsc); +#else /* CONFIG_CTRL_IFACE_DBUS_INTRO */ + reply = dbus_message_new_error( + message, DBUS_ERROR_UNKNOWN_METHOD, + "wpa_supplicant was compiled without " + "introspection support."); +#endif /* CONFIG_CTRL_IFACE_DBUS_INTRO */ + } else if (!os_strncmp(WPA_DBUS_PROPERTIES_INTERFACE, msg_interface, + WPAS_DBUS_INTERFACE_MAX)) { + /* if message is properties method call */ + reply = properties_handler(message, obj_dsc); + } else { + reply = msg_method_handler(message, obj_dsc); + } + + /* If handler succeed returning NULL, reply empty message */ + if (!reply) + reply = dbus_message_new_method_return(message); + if (reply) { + if (!dbus_message_get_no_reply(message)) + dbus_connection_send(connection, reply, NULL); + dbus_message_unref(reply); + } + + wpa_dbus_flush_all_changed_properties(connection); + + return DBUS_HANDLER_RESULT_HANDLED; +} + + +/** + * free_dbus_object_desc - Frees object description data structure + * @connection: DBus connection + * @obj_dsc: Object description to free + * + * Frees each of properties, methods and signals description lists and + * the object description structure itself. + */ +void free_dbus_object_desc(struct wpa_dbus_object_desc *obj_dsc) +{ + if (!obj_dsc) + return; + + /* free handler's argument */ + if (obj_dsc->user_data_free_func) + obj_dsc->user_data_free_func(obj_dsc->user_data); + + os_free(obj_dsc->path); + os_free(obj_dsc->prop_changed_flags); + os_free(obj_dsc); +} + + +static void free_dbus_object_desc_cb(DBusConnection *connection, void *obj_dsc) +{ + free_dbus_object_desc(obj_dsc); +} + +/** + * wpa_dbus_ctrl_iface_init - Initialize dbus control interface + * @application_data: Pointer to application specific data structure + * @dbus_path: DBus path to interface object + * @dbus_service: DBus service name to register with + * @messageHandler: a pointer to function which will handle dbus messages + * coming on interface + * Returns: 0 on success, -1 on failure + * + * Initialize the dbus control interface and start receiving commands from + * external programs over the bus. + */ +int wpa_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface, + char *dbus_path, char *dbus_service, + struct wpa_dbus_object_desc *obj_desc) +{ + DBusError error; + int ret = -1; + DBusObjectPathVTable wpa_vtable = { + &free_dbus_object_desc_cb, &message_handler, + NULL, NULL, NULL, NULL + }; + + obj_desc->connection = iface->con; + obj_desc->path = os_strdup(dbus_path); + + /* Register the message handler for the global dbus interface */ + if (!dbus_connection_register_object_path(iface->con, + dbus_path, &wpa_vtable, + obj_desc)) { + 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, 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 '%s'.", dbus_service); + + return 0; +} + + +/** + * wpa_dbus_register_object_per_iface - Register a new object with dbus + * @ctrl_iface: pointer to dbus private data + * @path: DBus path to object + * @ifname: interface name + * @obj_desc: description of object's methods, signals and properties + * Returns: 0 on success, -1 on error + * + * Registers a new interface with dbus and assigns it a dbus object path. + */ +int wpa_dbus_register_object_per_iface( + struct wpas_dbus_priv *ctrl_iface, + const char *path, const char *ifname, + struct wpa_dbus_object_desc *obj_desc) +{ + DBusConnection *con; + + DBusObjectPathVTable vtable = { + &free_dbus_object_desc_cb, &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; + obj_desc->connection = con; + obj_desc->path = os_strdup(path); + + /* Register the message handler for the interface functions */ + if (!dbus_connection_register_object_path(con, path, &vtable, + obj_desc)) { + wpa_printf(MSG_ERROR, "dbus: Could not set up message " + "handler for interface %s object %s", ifname, path); + return -1; + } + + return 0; +} + + +static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx); + + +/** + * wpa_dbus_unregister_object_per_iface - Unregisters DBus object + * @ctrl_iface: Pointer to dbus private data + * @path: DBus path to object which will be unregistered + * Returns: Zero on success and -1 on failure + * + * Unregisters DBus object given by its path + */ +int wpa_dbus_unregister_object_per_iface( + struct wpas_dbus_priv *ctrl_iface, const char *path) +{ + DBusConnection *con = ctrl_iface->con; + struct wpa_dbus_object_desc *obj_desc = NULL; + + dbus_connection_get_object_path_data(con, path, (void **) &obj_desc); + if (!obj_desc) { + wpa_printf(MSG_ERROR, "dbus: %s: Could not obtain object's " + "private data: %s", __func__, path); + } else { + eloop_cancel_timeout(flush_object_timeout_handler, con, + obj_desc); + } + + if (!dbus_connection_unregister_object_path(con, path)) + return -1; + + return 0; +} + + +static void put_changed_properties(const struct wpa_dbus_object_desc *obj_dsc, + const char *interface, + DBusMessageIter *dict_iter) +{ + DBusMessage *getter_reply; + DBusMessageIter prop_iter, entry_iter; + const struct wpa_dbus_property_desc *dsc; + int i; + + for (dsc = obj_dsc->properties, i = 0; dsc && dsc->dbus_property; + dsc++, i++) { + if (obj_dsc->prop_changed_flags == NULL || + !obj_dsc->prop_changed_flags[i]) + continue; + if (os_strcmp(dsc->dbus_interface, interface) != 0) + continue; + obj_dsc->prop_changed_flags[i] = 0; + + getter_reply = dsc->getter(NULL, obj_dsc->user_data); + if (!getter_reply || + dbus_message_get_type(getter_reply) == + DBUS_MESSAGE_TYPE_ERROR) { + wpa_printf(MSG_ERROR, "dbus: %s: Cannot get new value " + "of property %s", __func__, + dsc->dbus_property); + continue; + } + + if (!dbus_message_iter_init(getter_reply, &prop_iter) || + !dbus_message_iter_open_container(dict_iter, + DBUS_TYPE_DICT_ENTRY, + NULL, &entry_iter) || + !dbus_message_iter_append_basic(&entry_iter, + DBUS_TYPE_STRING, + &dsc->dbus_property)) + goto err; + + recursive_iter_copy(&prop_iter, &entry_iter); + + if (!dbus_message_iter_close_container(dict_iter, &entry_iter)) + goto err; + + dbus_message_unref(getter_reply); + } + + return; + +err: + wpa_printf(MSG_ERROR, "dbus: %s: Cannot construct signal", __func__); +} + + +static void send_prop_changed_signal( + DBusConnection *con, const char *path, const char *interface, + const struct wpa_dbus_object_desc *obj_dsc) +{ + DBusMessage *msg; + DBusMessageIter signal_iter, dict_iter; + + msg = dbus_message_new_signal(path, interface, "PropertiesChanged"); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &signal_iter); + + if (!dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY, + "{sv}", &dict_iter)) + goto err; + + put_changed_properties(obj_dsc, interface, &dict_iter); + + if (!dbus_message_iter_close_container(&signal_iter, &dict_iter)) + goto err; + + dbus_connection_send(con, msg, NULL); + +out: + dbus_message_unref(msg); + return; + +err: + wpa_printf(MSG_DEBUG, "dbus: %s: Failed to construct signal", + __func__); + goto out; +} + + +static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx) +{ + DBusConnection *con = eloop_ctx; + struct wpa_dbus_object_desc *obj_desc = timeout_ctx; + + wpa_printf(MSG_DEBUG, "dbus: %s: Timeout - sending changed properties " + "of object %s", __func__, obj_desc->path); + wpa_dbus_flush_object_changed_properties(con, obj_desc->path); +} + + +static void recursive_flush_changed_properties(DBusConnection *con, + const char *path) +{ + char **objects = NULL; + char subobj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + int i; + + wpa_dbus_flush_object_changed_properties(con, path); + + if (!dbus_connection_list_registered(con, path, &objects)) + goto out; + + for (i = 0; objects[i]; i++) { + os_snprintf(subobj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/%s", path, objects[i]); + recursive_flush_changed_properties(con, subobj_path); + } + +out: + dbus_free_string_array(objects); +} + + +/** + * wpa_dbus_flush_all_changed_properties - Send all PropertiesChanged signals + * @con: DBus connection + * + * Traverses through all registered objects and sends PropertiesChanged for + * each properties. + */ +void wpa_dbus_flush_all_changed_properties(DBusConnection *con) +{ + recursive_flush_changed_properties(con, WPAS_DBUS_NEW_PATH); +} + + +/** + * wpa_dbus_flush_object_changed_properties - Send PropertiesChanged for object + * @con: DBus connection + * @path: path to a DBus object for which PropertiesChanged will be sent. + * + * Iterates over all properties registered with object and for each interface + * containing properties marked as changed, sends a PropertiesChanged signal + * containing names and new values of properties that have changed. + * + * You need to call this function after wpa_dbus_mark_property_changed() + * if you want to send PropertiesChanged signal immediately (i.e., without + * waiting timeout to expire). PropertiesChanged signal for an object is sent + * automatically short time after first marking property as changed. All + * PropertiesChanged signals are sent automatically after responding on DBus + * message, so if you marked a property changed as a result of DBus call + * (e.g., param setter), you usually do not need to call this function. + */ +void wpa_dbus_flush_object_changed_properties(DBusConnection *con, + const char *path) +{ + struct wpa_dbus_object_desc *obj_desc = NULL; + const struct wpa_dbus_property_desc *dsc; + int i; + + dbus_connection_get_object_path_data(con, path, (void **) &obj_desc); + if (!obj_desc) + return; + eloop_cancel_timeout(flush_object_timeout_handler, con, obj_desc); + + dsc = obj_desc->properties; + for (dsc = obj_desc->properties, i = 0; dsc && dsc->dbus_property; + dsc++, i++) { + if (obj_desc->prop_changed_flags == NULL || + !obj_desc->prop_changed_flags[i]) + continue; + send_prop_changed_signal(con, path, dsc->dbus_interface, + obj_desc); + } +} + + +#define WPA_DBUS_SEND_PROP_CHANGED_TIMEOUT 5000 + + +/** + * wpa_dbus_mark_property_changed - Mark a property as changed and + * @iface: dbus priv struct + * @path: path to DBus object which property has changed + * @interface: interface containing changed property + * @property: property name which has changed + * + * Iterates over all properties registered with an object and marks the one + * given in parameters as changed. All parameters registered for an object + * within a single interface will be aggregated together and sent in one + * PropertiesChanged signal when function + * wpa_dbus_flush_object_changed_properties() is called. + */ +void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface, + const char *path, const char *interface, + const char *property) +{ + struct wpa_dbus_object_desc *obj_desc = NULL; + const struct wpa_dbus_property_desc *dsc; + int i = 0; + + if (iface == NULL) + return; + + dbus_connection_get_object_path_data(iface->con, path, + (void **) &obj_desc); + if (!obj_desc) { + wpa_printf(MSG_ERROR, "dbus: wpa_dbus_property_changed: " + "could not obtain object's private data: %s", path); + return; + } + + for (dsc = obj_desc->properties; dsc && dsc->dbus_property; dsc++, i++) + if (os_strcmp(property, dsc->dbus_property) == 0 && + os_strcmp(interface, dsc->dbus_interface) == 0) { + if (obj_desc->prop_changed_flags) + obj_desc->prop_changed_flags[i] = 1; + break; + } + + if (!dsc || !dsc->dbus_property) { + wpa_printf(MSG_ERROR, "dbus: wpa_dbus_property_changed: " + "no property %s in object %s", property, path); + return; + } + + if (!eloop_is_timeout_registered(flush_object_timeout_handler, + iface->con, obj_desc->path)) { + eloop_register_timeout(0, WPA_DBUS_SEND_PROP_CHANGED_TIMEOUT, + flush_object_timeout_handler, + iface->con, obj_desc); + } +} + + +/** + * wpa_dbus_get_object_properties - Put object's properties into dictionary + * @iface: dbus priv struct + * @path: path to DBus object which properties will be obtained + * @interface: interface name which properties will be obtained + * @dict_iter: correct, open DBus dictionary iterator. + * + * Iterates over all properties registered with object and execute getters + * of those, which are readable and which interface matches interface + * specified as argument. Obtained properties values are stored in + * dict_iter dictionary. + */ +void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface, + const char *path, const char *interface, + DBusMessageIter *dict_iter) +{ + struct wpa_dbus_object_desc *obj_desc = NULL; + + dbus_connection_get_object_path_data(iface->con, path, + (void **) &obj_desc); + if (!obj_desc) { + wpa_printf(MSG_ERROR, "dbus: wpa_dbus_get_object_properties: " + "could not obtain object's private data: %s", path); + return; + } + + fill_dict_with_properties(dict_iter, obj_desc->properties, + interface, obj_desc->user_data); +} diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new_helpers.h b/contrib/wpa/wpa_supplicant/dbus/dbus_new_helpers.h new file mode 100644 index 0000000..8db7a37 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new_helpers.h @@ -0,0 +1,147 @@ +/* + * WPA Supplicant / dbus-based control interface + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef WPA_DBUS_CTRL_H +#define WPA_DBUS_CTRL_H + +#include <dbus/dbus.h> + +typedef DBusMessage * (* WPADBusMethodHandler)(DBusMessage *message, + void *user_data); +typedef void (* WPADBusArgumentFreeFunction)(void *handler_arg); + +typedef DBusMessage * (* WPADBusPropertyAccessor)(DBusMessage *message, + const void *user_data); + +struct wpa_dbus_object_desc { + DBusConnection *connection; + char *path; + + /* list of methods, properties and signals registered with object */ + const struct wpa_dbus_method_desc *methods; + const struct wpa_dbus_signal_desc *signals; + const struct wpa_dbus_property_desc *properties; + + /* property changed flags */ + u8 *prop_changed_flags; + + /* argument for method handlers and properties + * getter and setter functions */ + void *user_data; + /* function used to free above argument */ + WPADBusArgumentFreeFunction user_data_free_func; +}; + +enum dbus_prop_access { R, W, RW }; + +enum dbus_arg_direction { ARG_IN, ARG_OUT }; + +struct wpa_dbus_argument { + char *name; + char *type; + enum dbus_arg_direction dir; +}; + +#define END_ARGS { NULL, NULL, ARG_IN } + +/** + * struct wpa_dbus_method_desc - DBus method description + */ +struct wpa_dbus_method_desc { + /* method name */ + const char *dbus_method; + /* method interface */ + const char *dbus_interface; + /* method handling function */ + WPADBusMethodHandler method_handler; + /* array of arguments */ + struct wpa_dbus_argument args[3]; +}; + +/** + * struct wpa_dbus_signal_desc - DBus signal description + */ +struct wpa_dbus_signal_desc { + /* signal name */ + const char *dbus_signal; + /* signal interface */ + const char *dbus_interface; + /* array of arguments */ + struct wpa_dbus_argument args[3]; +}; + +/** + * struct wpa_dbus_property_desc - DBus property description + */ +struct wpa_dbus_property_desc { + /* property name */ + const char *dbus_property; + /* property interface */ + const char *dbus_interface; + /* property type signature in DBus type notation */ + const char *type; + /* property getter function */ + WPADBusPropertyAccessor getter; + /* property setter function */ + WPADBusPropertyAccessor setter; + /* property access permissions */ + enum dbus_prop_access access; +}; + + +#define WPAS_DBUS_OBJECT_PATH_MAX 150 +#define WPAS_DBUS_INTERFACE_MAX 150 +#define WPAS_DBUS_METHOD_SIGNAL_PROP_MAX 50 + +#define WPA_DBUS_INTROSPECTION_INTERFACE "org.freedesktop.DBus.Introspectable" +#define WPA_DBUS_INTROSPECTION_METHOD "Introspect" +#define WPA_DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" +#define WPA_DBUS_PROPERTIES_GET "Get" +#define WPA_DBUS_PROPERTIES_SET "Set" +#define WPA_DBUS_PROPERTIES_GETALL "GetAll" + +void free_dbus_object_desc(struct wpa_dbus_object_desc *obj_dsc); + +int wpa_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface, char *dbus_path, + char *dbus_service, + struct wpa_dbus_object_desc *obj_desc); + +int wpa_dbus_register_object_per_iface( + struct wpas_dbus_priv *ctrl_iface, + const char *path, const char *ifname, + struct wpa_dbus_object_desc *obj_desc); + +int wpa_dbus_unregister_object_per_iface( + struct wpas_dbus_priv *ctrl_iface, + const char *path); + +void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface, + const char *path, const char *interface, + DBusMessageIter *dict_iter); + + +void wpa_dbus_flush_all_changed_properties(DBusConnection *con); + +void wpa_dbus_flush_object_changed_properties(DBusConnection *con, + const char *path); + +void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface, + const char *path, const char *interface, + const char *property); + +DBusMessage * wpa_dbus_introspect(DBusMessage *message, + struct wpa_dbus_object_desc *obj_dsc); + +#endif /* WPA_DBUS_CTRL_H */ diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new_introspect.c b/contrib/wpa/wpa_supplicant/dbus/dbus_new_introspect.c new file mode 100644 index 0000000..c660c04 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new_introspect.c @@ -0,0 +1,278 @@ +/* + * wpa_supplicant - D-Bus introspection + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> + * Copyright (c) 2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "utils/includes.h" + +#include "utils/common.h" +#include "utils/list.h" +#include "utils/wpabuf.h" +#include "dbus_common_i.h" +#include "dbus_new_helpers.h" + + +struct interfaces { + struct dl_list list; + char *dbus_interface; + struct wpabuf *xml; +}; + + +static struct interfaces * add_interface(struct dl_list *list, + const char *dbus_interface) +{ + struct interfaces *iface; + + dl_list_for_each(iface, list, struct interfaces, list) { + if (os_strcmp(iface->dbus_interface, dbus_interface) == 0) + return iface; /* already in the list */ + } + + iface = os_zalloc(sizeof(struct interfaces)); + if (!iface) + return NULL; + iface->xml = wpabuf_alloc(3000); + if (iface->xml == NULL) { + os_free(iface); + return NULL; + } + wpabuf_printf(iface->xml, "<interface name=\"%s\">", dbus_interface); + dl_list_add_tail(list, &iface->list); + iface->dbus_interface = os_strdup(dbus_interface); + return iface; +} + + +static void add_arg(struct wpabuf *xml, const char *name, const char *type, + const char *direction) +{ + wpabuf_printf(xml, "<arg name=\"%s\"", name); + if (type) + wpabuf_printf(xml, " type=\"%s\"", type); + if (direction) + wpabuf_printf(xml, " direction=\"%s\"", direction); + wpabuf_put_str(xml, "/>"); +} + + +static void add_entry(struct wpabuf *xml, const char *type, const char *name, + const struct wpa_dbus_argument *args, int include_dir) +{ + const struct wpa_dbus_argument *arg; + + if (args == NULL || args->name == NULL) { + wpabuf_printf(xml, "<%s name=\"%s\"/>", type, name); + return; + } + wpabuf_printf(xml, "<%s name=\"%s\">", type, name); + for (arg = args; arg && arg->name; arg++) { + add_arg(xml, arg->name, arg->type, + include_dir ? (arg->dir == ARG_IN ? "in" : "out") : + NULL); + } + wpabuf_printf(xml, "</%s>", type); +} + + +static void add_property(struct wpabuf *xml, + const struct wpa_dbus_property_desc *dsc) +{ + wpabuf_printf(xml, "<property name=\"%s\" type=\"%s\" access=\"%s\"/>", + dsc->dbus_property, dsc->type, + (dsc->access == R ? "read" : + (dsc->access == W ? "write" : "readwrite"))); +} + + +static void extract_interfaces_methods( + struct dl_list *list, const struct wpa_dbus_method_desc *methods) +{ + const struct wpa_dbus_method_desc *dsc; + struct interfaces *iface; + for (dsc = methods; dsc && dsc->dbus_method; dsc++) { + iface = add_interface(list, dsc->dbus_interface); + if (iface) + add_entry(iface->xml, "method", dsc->dbus_method, + dsc->args, 1); + } +} + + +static void extract_interfaces_signals( + struct dl_list *list, const struct wpa_dbus_signal_desc *signals) +{ + const struct wpa_dbus_signal_desc *dsc; + struct interfaces *iface; + for (dsc = signals; dsc && dsc->dbus_signal; dsc++) { + iface = add_interface(list, dsc->dbus_interface); + if (iface) + add_entry(iface->xml, "signal", dsc->dbus_signal, + dsc->args, 0); + } +} + + +static void extract_interfaces_properties( + struct dl_list *list, const struct wpa_dbus_property_desc *properties) +{ + const struct wpa_dbus_property_desc *dsc; + struct interfaces *iface; + for (dsc = properties; dsc && dsc->dbus_property; dsc++) { + iface = add_interface(list, dsc->dbus_interface); + if (iface) + add_property(iface->xml, dsc); + } +} + + +/** + * extract_interfaces - Extract interfaces from methods, signals and props + * @list: Interface list to be filled + * @obj_dsc: Description of object from which interfaces will be extracted + * + * Iterates over all methods, signals, and properties registered with an + * object and collects all declared DBus interfaces and create interfaces' + * node in XML root node for each. Returned list elements contain interface + * name and XML node of corresponding interface. + */ +static void extract_interfaces(struct dl_list *list, + struct wpa_dbus_object_desc *obj_dsc) +{ + extract_interfaces_methods(list, obj_dsc->methods); + extract_interfaces_signals(list, obj_dsc->signals); + extract_interfaces_properties(list, obj_dsc->properties); +} + + +static void add_interfaces(struct dl_list *list, struct wpabuf *xml) +{ + struct interfaces *iface, *n; + dl_list_for_each_safe(iface, n, list, struct interfaces, list) { + if (wpabuf_len(iface->xml) + 20 < wpabuf_tailroom(xml)) { + wpabuf_put_buf(xml, iface->xml); + wpabuf_put_str(xml, "</interface>"); + } + dl_list_del(&iface->list); + wpabuf_free(iface->xml); + os_free(iface->dbus_interface); + os_free(iface); + } +} + + +static void add_child_nodes(struct wpabuf *xml, DBusConnection *con, + const char *path) +{ + char **children; + int i; + + /* add child nodes to introspection tree */ + dbus_connection_list_registered(con, path, &children); + for (i = 0; children[i]; i++) + wpabuf_printf(xml, "<node name=\"%s\"/>", children[i]); + dbus_free_string_array(children); +} + + +static void add_introspectable_interface(struct wpabuf *xml) +{ + wpabuf_printf(xml, "<interface name=\"%s\">" + "<method name=\"%s\">" + "<arg name=\"data\" type=\"s\" direction=\"out\"/>" + "</method>" + "</interface>", + WPA_DBUS_INTROSPECTION_INTERFACE, + WPA_DBUS_INTROSPECTION_METHOD); +} + + +static void add_properties_interface(struct wpabuf *xml) +{ + wpabuf_printf(xml, "<interface name=\"%s\">", + WPA_DBUS_PROPERTIES_INTERFACE); + + wpabuf_printf(xml, "<method name=\"%s\">", WPA_DBUS_PROPERTIES_GET); + add_arg(xml, "interface", "s", "in"); + add_arg(xml, "propname", "s", "in"); + add_arg(xml, "value", "v", "out"); + wpabuf_put_str(xml, "</method>"); + + wpabuf_printf(xml, "<method name=\"%s\">", WPA_DBUS_PROPERTIES_GETALL); + add_arg(xml, "interface", "s", "in"); + add_arg(xml, "props", "a{sv}", "out"); + wpabuf_put_str(xml, "</method>"); + + wpabuf_printf(xml, "<method name=\"%s\">", WPA_DBUS_PROPERTIES_SET); + add_arg(xml, "interface", "s", "in"); + add_arg(xml, "propname", "s", "in"); + add_arg(xml, "value", "v", "in"); + wpabuf_put_str(xml, "</method>"); + + wpabuf_put_str(xml, "</interface>"); +} + + +static void add_wpas_interfaces(struct wpabuf *xml, + struct wpa_dbus_object_desc *obj_dsc) +{ + struct dl_list ifaces; + dl_list_init(&ifaces); + extract_interfaces(&ifaces, obj_dsc); + add_interfaces(&ifaces, xml); +} + + +/** + * wpa_dbus_introspect - Responds for Introspect calls on object + * @message: Message with Introspect call + * @obj_dsc: Object description on which Introspect was called + * Returns: Message with introspection result XML string as only argument + * + * Iterates over all methods, signals and properties registered with + * object and generates introspection data for the object as XML string. + */ +DBusMessage * wpa_dbus_introspect(DBusMessage *message, + struct wpa_dbus_object_desc *obj_dsc) +{ + + DBusMessage *reply; + struct wpabuf *xml; + + xml = wpabuf_alloc(4000); + if (xml == NULL) + return NULL; + + wpabuf_put_str(xml, "<?xml version=\"1.0\"?>\n"); + wpabuf_put_str(xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE); + wpabuf_put_str(xml, "<node>"); + + add_introspectable_interface(xml); + add_properties_interface(xml); + add_wpas_interfaces(xml, obj_dsc); + add_child_nodes(xml, obj_dsc->connection, + dbus_message_get_path(message)); + + wpabuf_put_str(xml, "</node>\n"); + + reply = dbus_message_new_method_return(message); + if (reply) { + const char *intro_str = wpabuf_head(xml); + dbus_message_append_args(reply, DBUS_TYPE_STRING, &intro_str, + DBUS_TYPE_INVALID); + } + wpabuf_free(xml); + + return reply; +} diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface_dbus.c b/contrib/wpa/wpa_supplicant/dbus/dbus_old.c index 8e69f4d..7f25bf0 100644 --- a/contrib/wpa/wpa_supplicant/ctrl_iface_dbus.c +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_old.c @@ -13,263 +13,18 @@ */ #include "includes.h" +#include <dbus/dbus.h> #include "common.h" #include "eloop.h" -#include "config.h" -#include "wpa_supplicant_i.h" #include "wps/wps.h" -#include "ctrl_iface_dbus.h" -#include "ctrl_iface_dbus_handlers.h" - -#define _DBUS_VERSION (DBUS_VERSION_MAJOR << 8 | DBUS_VERSION_MINOR) -#define DBUS_VER(major, minor) ((major) << 8 | (minor)) - -#if _DBUS_VERSION < DBUS_VER(1,1) -#define dbus_watch_get_unix_fd dbus_watch_get_fd -#endif - - -struct ctrl_iface_dbus_priv { - DBusConnection *con; - int should_dispatch; - struct wpa_global *global; - - u32 next_objid; -}; - - -static void process_watch(struct ctrl_iface_dbus_priv *iface, - DBusWatch *watch, eloop_event_type type) -{ - dbus_connection_ref(iface->con); - - iface->should_dispatch = 0; - - if (type == EVENT_TYPE_READ) - dbus_watch_handle(watch, DBUS_WATCH_READABLE); - else if (type == EVENT_TYPE_WRITE) - dbus_watch_handle(watch, DBUS_WATCH_WRITABLE); - else if (type == EVENT_TYPE_EXCEPTION) - dbus_watch_handle(watch, DBUS_WATCH_ERROR); - - if (iface->should_dispatch) { - while (dbus_connection_get_dispatch_status(iface->con) == - DBUS_DISPATCH_DATA_REMAINS) - dbus_connection_dispatch(iface->con); - iface->should_dispatch = 0; - } - - dbus_connection_unref(iface->con); -} - - -static void process_watch_exception(int sock, void *eloop_ctx, void *sock_ctx) -{ - process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_EXCEPTION); -} - - -static void process_watch_read(int sock, void *eloop_ctx, void *sock_ctx) -{ - process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_READ); -} - - -static void process_watch_write(int sock, void *eloop_ctx, void *sock_ctx) -{ - process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_WRITE); -} - - -static void connection_setup_add_watch(struct ctrl_iface_dbus_priv *iface, - DBusWatch *watch) -{ - unsigned int flags; - int fd; - - if (!dbus_watch_get_enabled(watch)) - return; - - flags = dbus_watch_get_flags(watch); - fd = dbus_watch_get_unix_fd(watch); - - eloop_register_sock(fd, EVENT_TYPE_EXCEPTION, process_watch_exception, - iface, watch); - - if (flags & DBUS_WATCH_READABLE) { - eloop_register_sock(fd, EVENT_TYPE_READ, process_watch_read, - iface, watch); - } - if (flags & DBUS_WATCH_WRITABLE) { - eloop_register_sock(fd, EVENT_TYPE_WRITE, process_watch_write, - iface, watch); - } - - dbus_watch_set_data(watch, iface, NULL); -} - - -static void connection_setup_remove_watch(struct ctrl_iface_dbus_priv *iface, - DBusWatch *watch) -{ - unsigned int flags; - int fd; - - flags = dbus_watch_get_flags(watch); - fd = dbus_watch_get_unix_fd(watch); - - eloop_unregister_sock(fd, EVENT_TYPE_EXCEPTION); - - if (flags & DBUS_WATCH_READABLE) - eloop_unregister_sock(fd, EVENT_TYPE_READ); - if (flags & DBUS_WATCH_WRITABLE) - eloop_unregister_sock(fd, EVENT_TYPE_WRITE); - - dbus_watch_set_data(watch, NULL, NULL); -} - - -static dbus_bool_t add_watch(DBusWatch *watch, void *data) -{ - connection_setup_add_watch(data, watch); - return TRUE; -} - - -static void remove_watch(DBusWatch *watch, void *data) -{ - connection_setup_remove_watch(data, watch); -} - - -static void watch_toggled(DBusWatch *watch, void *data) -{ - if (dbus_watch_get_enabled(watch)) - add_watch(watch, data); - else - remove_watch(watch, data); -} - - -static void process_timeout(void *eloop_ctx, void *sock_ctx) -{ - DBusTimeout *timeout = sock_ctx; - - dbus_timeout_handle(timeout); -} - - -static void connection_setup_add_timeout(struct ctrl_iface_dbus_priv *iface, - DBusTimeout *timeout) -{ - if (!dbus_timeout_get_enabled(timeout)) - return; - - eloop_register_timeout(0, dbus_timeout_get_interval(timeout) * 1000, - process_timeout, iface, timeout); - - dbus_timeout_set_data(timeout, iface, NULL); -} - - -static void connection_setup_remove_timeout(struct ctrl_iface_dbus_priv *iface, - DBusTimeout *timeout) -{ - eloop_cancel_timeout(process_timeout, iface, timeout); - dbus_timeout_set_data(timeout, NULL, NULL); -} - - -static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) -{ - if (!dbus_timeout_get_enabled(timeout)) - return TRUE; - - connection_setup_add_timeout(data, timeout); - - return TRUE; -} - - -static void remove_timeout(DBusTimeout *timeout, void *data) -{ - connection_setup_remove_timeout(data, timeout); -} - - -static void timeout_toggled(DBusTimeout *timeout, void *data) -{ - if (dbus_timeout_get_enabled(timeout)) - add_timeout(timeout, data); - else - remove_timeout(timeout, data); -} - - -static void process_wakeup_main(int sig, void *eloop_ctx, void *signal_ctx) -{ - struct ctrl_iface_dbus_priv *iface = signal_ctx; - - if (sig != SIGPOLL || !iface->con) - return; - - if (dbus_connection_get_dispatch_status(iface->con) != - DBUS_DISPATCH_DATA_REMAINS) - return; - - /* Only dispatch once - we do not want to starve other events */ - dbus_connection_ref(iface->con); - dbus_connection_dispatch(iface->con); - dbus_connection_unref(iface->con); -} - - -/** - * wakeup_main - Attempt to wake our mainloop up - * @data: dbus control interface private data - * - * Try to wake up the main eloop so it will process - * dbus events that may have happened. - */ -static void wakeup_main(void *data) -{ - struct ctrl_iface_dbus_priv *iface = data; - - /* Use SIGPOLL to break out of the eloop select() */ - raise(SIGPOLL); - iface->should_dispatch = 1; -} - - -/** - * connection_setup_wakeup_main - Tell dbus about our wakeup_main function - * @iface: dbus control interface private data - * Returns: 0 on success, -1 on failure - * - * Register our wakeup_main handler with dbus - */ -static int connection_setup_wakeup_main(struct ctrl_iface_dbus_priv *iface) -{ - if (eloop_register_signal(SIGPOLL, process_wakeup_main, iface)) - return -1; - - dbus_connection_set_wakeup_main_function(iface->con, wakeup_main, - iface, NULL); - - return 0; -} - - -/** - * wpa_supplicant_dbus_next_objid - Return next available object id - * @iface: dbus control interface private data - * Returns: Object id - */ -u32 wpa_supplicant_dbus_next_objid (struct ctrl_iface_dbus_priv *iface) -{ - return iface->next_objid++; -} +#include "../config.h" +#include "../wpa_supplicant_i.h" +#include "../bss.h" +#include "dbus_old.h" +#include "dbus_old_handlers.h" +#include "dbus_common.h" +#include "dbus_common_i.h" /** @@ -299,7 +54,7 @@ char * wpas_dbus_decompose_object_path(const char *path, char **network, if ((path + dev_path_prefix_len)[0] == '\0') return NULL; - obj_path_only = strdup(path); + obj_path_only = os_strdup(path); if (obj_path_only == NULL) return NULL; @@ -316,13 +71,13 @@ char * wpas_dbus_decompose_object_path(const char *path, char **network, strlen(WPAS_DBUS_NETWORKS_PART "/"); *network = NULL; if (strlen(net_name)) - *network = strdup(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 = strdup(bssid_name); + *bssid = os_strdup(bssid_name); else *bssid = NULL; } @@ -421,45 +176,23 @@ static DBusMessage * wpas_dispatch_network_method(DBusMessage *message, */ static DBusMessage * wpas_dispatch_bssid_method(DBusMessage *message, struct wpa_supplicant *wpa_s, - const char *bssid) + const char *bssid_txt) { - DBusMessage *reply = NULL; - const char *method = dbus_message_get_member(message); - struct wpa_scan_res *res = NULL; - size_t i; + u8 bssid[ETH_ALEN]; + struct wpa_bss *bss; - /* Ensure we actually have scan data */ - if (wpa_s->scan_res == NULL && - wpa_supplicant_get_scan_results(wpa_s) < 0) { - reply = wpas_dbus_new_invalid_bssid_error(message); - goto out; - } + if (hexstr2bin(bssid_txt, bssid, ETH_ALEN) < 0) + return wpas_dbus_new_invalid_bssid_error(message); - /* Find the bssid's scan data */ - for (i = 0; i < wpa_s->scan_res->num; i++) { - struct wpa_scan_res *search_res = wpa_s->scan_res->res[i]; - char mac_str[18]; - - memset(mac_str, 0, sizeof(mac_str)); - snprintf(mac_str, sizeof(mac_str) - 1, WPAS_DBUS_BSSID_FORMAT, - MAC2STR(search_res->bssid)); - if (!strcmp(bssid, mac_str)) { - res = search_res; - break; - } - } - - if (!res) { - reply = wpas_dbus_new_invalid_bssid_error(message); - goto out; - } + 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 (!strcmp(method, "properties")) - reply = wpas_dbus_bssid_properties(message, wpa_s, res); + if (os_strcmp(dbus_message_get_member(message), "properties") == 0) + return wpas_dbus_bssid_properties(message, wpa_s, bss); -out: - return reply; + return NULL; } @@ -546,6 +279,14 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection, reply = wpas_dbus_iface_set_blobs(message, wpa_s); else if (!strcmp(method, "removeBlobs")) reply = wpas_dbus_iface_remove_blobs(message, wpa_s); +#ifdef CONFIG_WPS + else if (!os_strcmp(method, "wpsPbc")) + reply = wpas_dbus_iface_wps_pbc(message, wpa_s); + else if (!os_strcmp(method, "wpsPin")) + reply = wpas_dbus_iface_wps_pin(message, wpa_s); + else if (!os_strcmp(method, "wpsReg")) + reply = wpas_dbus_iface_wps_reg(message, wpa_s); +#endif /* CONFIG_WPS */ } /* If the message was handled, send back the reply */ @@ -556,9 +297,9 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection, } out: - free(iface_obj_path); - free(network); - free(bssid); + os_free(iface_obj_path); + os_free(network); + os_free(bssid); return reply ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } @@ -578,7 +319,7 @@ out: static DBusHandlerResult wpas_message_handler(DBusConnection *connection, DBusMessage *message, void *user_data) { - struct ctrl_iface_dbus_priv *ctrl_iface = user_data; + struct wpas_dbus_priv *ctrl_iface = user_data; const char *method; const char *path; const char *msg_interface; @@ -632,31 +373,19 @@ static DBusHandlerResult wpas_message_handler(DBusConnection *connection, */ void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s) { - struct ctrl_iface_dbus_priv *iface = wpa_s->global->dbus_ctrl_iface; + struct wpas_dbus_priv *iface = wpa_s->global->dbus; DBusMessage *_signal; - const char *path; /* Do nothing if the control interface is not turned on */ if (iface == NULL) return; - path = wpa_supplicant_get_dbus_path(wpa_s); - if (path == NULL) { - perror("wpa_supplicant_dbus_notify_scan_results[dbus]: " - "interface didn't have a dbus path"); - wpa_printf(MSG_ERROR, - "wpa_supplicant_dbus_notify_scan_results[dbus]: " - "interface didn't have a dbus path; can't send " - "scan result signal."); - return; - } - _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE, + _signal = dbus_message_new_signal(wpa_s->dbus_path, + WPAS_DBUS_IFACE_INTERFACE, "ScanResultsAvailable"); if (_signal == NULL) { - perror("wpa_supplicant_dbus_notify_scan_results[dbus]: " - "couldn't create dbus signal; likely out of memory"); - wpa_printf(MSG_ERROR, "dbus control interface: not enough " - "memory to send scan results signal."); + wpa_printf(MSG_ERROR, "dbus: Not enough memory to send scan " + "results signal"); return; } dbus_connection_send(iface->con, _signal, NULL); @@ -674,18 +403,20 @@ void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s) * Notify listeners that wpa_supplicant has changed state */ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s, - wpa_states new_state, - wpa_states old_state) + enum wpa_states new_state, + enum wpa_states old_state) { - struct ctrl_iface_dbus_priv *iface; + struct wpas_dbus_priv *iface; DBusMessage *_signal = NULL; - const char *path; 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_ctrl_iface; + iface = wpa_s->global->dbus; if (iface == NULL) return; @@ -693,36 +424,23 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s, if (new_state == old_state) return; - path = wpa_supplicant_get_dbus_path(wpa_s); - if (path == NULL) { - perror("wpa_supplicant_dbus_notify_state_change[dbus]: " - "interface didn't have a dbus path"); - wpa_printf(MSG_ERROR, - "wpa_supplicant_dbus_notify_state_change[dbus]: " - "interface didn't have a dbus path; can't send " - "signal."); - return; - } - _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE, + _signal = dbus_message_new_signal(wpa_s->dbus_path, + WPAS_DBUS_IFACE_INTERFACE, "StateChange"); if (_signal == NULL) { - perror("wpa_supplicant_dbus_notify_state_change[dbus]: " - "couldn't create dbus signal; likely out of memory"); wpa_printf(MSG_ERROR, - "wpa_supplicant_dbus_notify_state_change[dbus]: " - "couldn't create dbus signal; likely out of " - "memory."); + "dbus: wpa_supplicant_dbus_notify_state_change: " + "could not create dbus signal; likely out of " + "memory"); return; } new_state_str = wpa_supplicant_state_txt(new_state); old_state_str = wpa_supplicant_state_txt(old_state); if (new_state_str == NULL || old_state_str == NULL) { - perror("wpa_supplicant_dbus_notify_state_change[dbus]: " - "couldn't convert state strings"); wpa_printf(MSG_ERROR, - "wpa_supplicant_dbus_notify_state_change[dbus]: " - "couldn't convert state strings."); + "dbus: wpa_supplicant_dbus_notify_state_change: " + "Could not convert state strings"); goto out; } @@ -730,12 +448,10 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s, DBUS_TYPE_STRING, &new_state_str, DBUS_TYPE_STRING, &old_state_str, DBUS_TYPE_INVALID)) { - perror("wpa_supplicant_dbus_notify_state_change[dbus]: " - "not enough memory to construct state change signal."); wpa_printf(MSG_ERROR, - "wpa_supplicant_dbus_notify_state_change[dbus]: " - "not enough memory to construct state change " - "signal."); + "dbus: wpa_supplicant_dbus_notify_state_change: " + "Not enough memory to construct state change " + "signal"); goto out; } @@ -755,32 +471,20 @@ out: */ void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s) { - struct ctrl_iface_dbus_priv *iface = wpa_s->global->dbus_ctrl_iface; + struct wpas_dbus_priv *iface = wpa_s->global->dbus; DBusMessage *_signal; - const char *path; dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE; /* Do nothing if the control interface is not turned on */ if (iface == NULL) return; - path = wpa_supplicant_get_dbus_path(wpa_s); - if (path == NULL) { - perror("wpa_supplicant_dbus_notify_scanning[dbus]: interface " - "didn't have a dbus path"); - wpa_printf(MSG_ERROR, - "%s[dbus]: interface didn't have a dbus path; " - "can't send scanning signal.", __FUNCTION__); - return; - } - _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE, + _signal = dbus_message_new_signal(wpa_s->dbus_path, + WPAS_DBUS_IFACE_INTERFACE, "Scanning"); if (_signal == NULL) { - perror("wpa_supplicant_dbus_notify_scanning[dbus]: couldn't " - "create dbus signal; likely out of memory"); - wpa_printf(MSG_ERROR, "%s[dbus]: dbus control interface: not " - "enough memory to send scan results signal.", - __FUNCTION__); + wpa_printf(MSG_ERROR, "dbus: Not enough memory to send scan " + "results signal"); return; } @@ -789,10 +493,8 @@ void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s) DBUS_TYPE_INVALID)) { dbus_connection_send(iface->con, _signal, NULL); } else { - perror("wpa_supplicant_dbus_notify_scanning[dbus]: not enough " - "memory to construct signal."); - wpa_printf(MSG_ERROR, "%s[dbus]: not enough memory to " - "construct signal.", __FUNCTION__); + wpa_printf(MSG_ERROR, "dbus: Not enough memory to construct " + "signal"); } dbus_message_unref(_signal); } @@ -802,36 +504,24 @@ void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s) void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) { - struct ctrl_iface_dbus_priv *iface; + struct wpas_dbus_priv *iface; DBusMessage *_signal = NULL; - const char *path; /* Do nothing if the control interface is not turned on */ if (wpa_s->global == NULL) return; - iface = wpa_s->global->dbus_ctrl_iface; + iface = wpa_s->global->dbus; if (iface == NULL) return; - path = wpa_supplicant_get_dbus_path(wpa_s); - if (path == NULL) { - perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: " - "interface didn't have a dbus path"); - wpa_printf(MSG_ERROR, - "wpa_supplicant_dbus_notify_wps_cred[dbus]: " - "interface didn't have a dbus path; can't send " - "signal."); - return; - } - _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE, + _signal = dbus_message_new_signal(wpa_s->dbus_path, + WPAS_DBUS_IFACE_INTERFACE, "WpsCred"); if (_signal == NULL) { - perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: " - "couldn't create dbus signal; likely out of memory"); wpa_printf(MSG_ERROR, - "wpa_supplicant_dbus_notify_wps_cred[dbus]: " - "couldn't create dbus signal; likely out of " - "memory."); + "dbus: wpa_supplicant_dbus_notify_wps_cred: " + "Could not create dbus signal; likely out of " + "memory"); return; } @@ -839,11 +529,9 @@ void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &cred->cred_attr, cred->cred_attr_len, DBUS_TYPE_INVALID)) { - perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: " - "not enough memory to construct signal."); wpa_printf(MSG_ERROR, - "wpa_supplicant_dbus_notify_wps_cred[dbus]: " - "not enough memory to construct signal."); + "dbus: wpa_supplicant_dbus_notify_wps_cred: " + "Not enough memory to construct signal"); goto out; } @@ -861,109 +549,28 @@ void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, /** - * integrate_with_eloop - Register our mainloop integration with dbus - * @connection: connection to the system message bus - * @iface: a dbus control interface data structure - * Returns: 0 on success, -1 on failure - * - * We register our mainloop integration functions with dbus here. - */ -static int integrate_with_eloop(DBusConnection *connection, - struct ctrl_iface_dbus_priv *iface) -{ - if (!dbus_connection_set_watch_functions(connection, add_watch, - remove_watch, watch_toggled, - iface, NULL)) { - perror("dbus_connection_set_watch_functions[dbus]"); - wpa_printf(MSG_ERROR, "Not enough memory to set up dbus."); - return -1; - } - - if (!dbus_connection_set_timeout_functions(connection, add_timeout, - remove_timeout, - timeout_toggled, iface, - NULL)) { - perror("dbus_connection_set_timeout_functions[dbus]"); - wpa_printf(MSG_ERROR, "Not enough memory to set up dbus."); - return -1; - } - - if (connection_setup_wakeup_main(iface) < 0) { - perror("connection_setup_wakeup_main[dbus]"); - wpa_printf(MSG_ERROR, "Could not setup main wakeup function."); - return -1; - } - - return 0; -} - - -/** - * dispatch_initial_dbus_messages - Dispatch initial dbus messages after - * claiming bus name - * @eloop_ctx: the DBusConnection to dispatch on - * @timeout_ctx: unused - * - * If clients are quick to notice that wpa_supplicant claimed its bus name, - * there may have been messages that came in before initialization was - * all finished. Dispatch those here. - */ -static void dispatch_initial_dbus_messages(void *eloop_ctx, void *timeout_ctx) -{ - DBusConnection *con = eloop_ctx; - - while (dbus_connection_get_dispatch_status(con) == - DBUS_DISPATCH_DATA_REMAINS) - dbus_connection_dispatch(con); -} - - -/** * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface * @global: Pointer to global data from wpa_supplicant_init() - * Returns: Pointer to dbus_ctrl_iface date or %NULL on failure + * Returns: 0 on success, -1 on failure * * Initialize the dbus control interface and start receiving commands from * external programs over the bus. */ -struct ctrl_iface_dbus_priv * -wpa_supplicant_dbus_ctrl_iface_init(struct wpa_global *global) +int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface) { - struct ctrl_iface_dbus_priv *iface; DBusError error; int ret = -1; DBusObjectPathVTable wpas_vtable = { NULL, &wpas_message_handler, NULL, NULL, NULL, NULL }; - iface = os_zalloc(sizeof(struct ctrl_iface_dbus_priv)); - if (iface == NULL) - return NULL; - - iface->global = global; - - /* Get a reference to the system bus */ - dbus_error_init(&error); - iface->con = dbus_bus_get(DBUS_BUS_SYSTEM, &error); - dbus_error_free(&error); - if (!iface->con) { - perror("dbus_bus_get[ctrl_iface_dbus]"); - wpa_printf(MSG_ERROR, "Could not acquire the system bus."); - goto fail; - } - - /* Tell dbus about our mainloop integration functions */ - if (integrate_with_eloop(iface->con, iface)) - goto fail; - /* Register the message handler for the global dbus interface */ if (!dbus_connection_register_object_path(iface->con, WPAS_DBUS_PATH, &wpas_vtable, iface)) { - perror("dbus_connection_register_object_path[dbus]"); - wpa_printf(MSG_ERROR, "Could not set up DBus message " - "handler."); - goto fail; + wpa_printf(MSG_ERROR, "dbus: Could not set up message " + "handler"); + return -1; } /* Register our service with the message bus */ @@ -976,67 +583,23 @@ wpa_supplicant_dbus_ctrl_iface_init(struct wpa_global *global) case DBUS_REQUEST_NAME_REPLY_EXISTS: case DBUS_REQUEST_NAME_REPLY_IN_QUEUE: case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER: - perror("dbus_bus_request_name[dbus]"); - wpa_printf(MSG_ERROR, "Could not request DBus service name: " - "already registered."); + wpa_printf(MSG_ERROR, "dbus: Could not request service name: " + "already registered"); break; default: - perror("dbus_bus_request_name[dbus]"); - wpa_printf(MSG_ERROR, "Could not request DBus service name: " - "%s %s.", error.name, error.message); + wpa_printf(MSG_ERROR, "dbus: Could not request service name: " + "%s %s", error.name, error.message); break; } dbus_error_free(&error); if (ret != 0) - goto fail; + return -1; wpa_printf(MSG_DEBUG, "Providing DBus service '" WPAS_DBUS_SERVICE "'."); - /* - * Dispatch initial DBus messages that may have come in since the bus - * name was claimed above. Happens when clients are quick to notice the - * wpa_supplicant service. - * - * FIXME: is there a better solution to this problem? - */ - eloop_register_timeout(0, 50, dispatch_initial_dbus_messages, - iface->con, NULL); - - return iface; - -fail: - wpa_supplicant_dbus_ctrl_iface_deinit(iface); - return NULL; -} - - -/** - * wpa_supplicant_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface - * @iface: Pointer to dbus private data from - * wpa_supplicant_dbus_ctrl_iface_init() - * - * Deinitialize the dbus control interface that was initialized with - * wpa_supplicant_dbus_ctrl_iface_init(). - */ -void wpa_supplicant_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_priv *iface) -{ - if (iface == NULL) - return; - - if (iface->con) { - eloop_cancel_timeout(dispatch_initial_dbus_messages, - iface->con, NULL); - dbus_connection_set_watch_functions(iface->con, NULL, NULL, - NULL, NULL, NULL); - dbus_connection_set_timeout_functions(iface->con, NULL, NULL, - NULL, NULL, NULL); - dbus_connection_unref(iface->con); - } - - memset(iface, 0, sizeof(struct ctrl_iface_dbus_priv)); - free(iface); + return 0; } @@ -1049,49 +612,37 @@ void wpa_supplicant_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_priv *iface) */ int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s) { - struct ctrl_iface_dbus_priv *ctrl_iface = - wpa_s->global->dbus_ctrl_iface; + 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 }; - char *path; - int ret = -1; /* Do nothing if the control interface is not turned on */ if (ctrl_iface == NULL) return 0; con = ctrl_iface->con; - next = wpa_supplicant_dbus_next_objid(ctrl_iface); + next = ctrl_iface->next_objid++; /* Create and set the interface's object path */ - path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); - if (path == NULL) + wpa_s->dbus_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); + if (wpa_s->dbus_path == NULL) return -1; - snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, - WPAS_DBUS_PATH_INTERFACES "/%u", - next); - if (wpa_supplicant_set_dbus_path(wpa_s, path)) { - wpa_printf(MSG_DEBUG, - "Failed to set dbus path for interface %s", - wpa_s->ifname); - goto out; - } + 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, path, &vtable, wpa_s)) { - perror("wpas_dbus_register_iface [dbus]"); - wpa_printf(MSG_ERROR, "Could not set up DBus message " - "handler for interface %s.", wpa_s->ifname); - goto out; + 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; } - ret = 0; -out: - free(path); - return ret; + return 0; } @@ -1104,24 +655,21 @@ out: */ int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s) { - struct ctrl_iface_dbus_priv *ctrl_iface; + struct wpas_dbus_priv *ctrl_iface; DBusConnection *con; - const char *path; /* 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_ctrl_iface; + ctrl_iface = wpa_s->global->dbus; if (ctrl_iface == NULL) return 0; con = ctrl_iface->con; - path = wpa_supplicant_get_dbus_path(wpa_s); - - if (!dbus_connection_unregister_object_path(con, path)) + if (!dbus_connection_unregister_object_path(con, wpa_s->dbus_path)) return -1; - free(wpa_s->dbus_path); + os_free(wpa_s->dbus_path); wpa_s->dbus_path = NULL; return 0; @@ -1145,33 +693,3 @@ struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path( } return NULL; } - - -/** - * wpa_supplicant_set_dbus_path - Assign a dbus path to an interface - * @wpa_s: wpa_supplicant interface structure - * @path: dbus path to set on the interface - * Returns: 0 on succes, -1 on error - */ -int wpa_supplicant_set_dbus_path(struct wpa_supplicant *wpa_s, - const char *path) -{ - u32 len = strlen (path); - if (len >= WPAS_DBUS_OBJECT_PATH_MAX) - return -1; - if (wpa_s->dbus_path) - return -1; - wpa_s->dbus_path = strdup(path); - return 0; -} - - -/** - * wpa_supplicant_get_dbus_path - Get an interface's dbus path - * @wpa_s: %wpa_supplicant interface structure - * Returns: Interface's dbus object path, or %NULL on error - */ -const char * wpa_supplicant_get_dbus_path(struct wpa_supplicant *wpa_s) -{ - return wpa_s->dbus_path; -} diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface_dbus.h b/contrib/wpa/wpa_supplicant/dbus/dbus_old.h index 059a373..a9840c2 100644 --- a/contrib/wpa/wpa_supplicant/ctrl_iface_dbus.h +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_old.h @@ -19,18 +19,6 @@ struct wps_credential; #ifdef CONFIG_CTRL_IFACE_DBUS -#ifndef SIGPOLL -#ifdef SIGIO -/* - * If we do not have SIGPOLL, try to use SIGIO instead. This is needed for - * FreeBSD. - */ -#define SIGPOLL SIGIO -#endif -#endif - -#include <dbus/dbus.h> - #define WPAS_DBUS_OBJECT_PATH_MAX 150 #define WPAS_DBUS_SERVICE "fi.epitest.hostap.WPASupplicant" @@ -74,19 +62,24 @@ struct wps_credential; #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; -struct ctrl_iface_dbus_priv * -wpa_supplicant_dbus_ctrl_iface_init(struct wpa_global *global); -void wpa_supplicant_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_priv *iface); +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, - wpa_states new_state, - wpa_states old_state); + 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); @@ -98,30 +91,11 @@ int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s); /* Methods internal to the dbus control interface */ -u32 wpa_supplicant_dbus_next_objid(struct ctrl_iface_dbus_priv *iface); - -int wpa_supplicant_set_dbus_path(struct wpa_supplicant *wpa_s, - const char *path); -const char *wpa_supplicant_get_dbus_path(struct wpa_supplicant *wpa_s); struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path( struct wpa_global *global, const char *path); -DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message); -DBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message); - #else /* CONFIG_CTRL_IFACE_DBUS */ -static inline struct ctrl_iface_dbus_priv * -wpa_supplicant_dbus_ctrl_iface_init(struct wpa_global *global) -{ - return (struct ctrl_iface_dbus_priv *) 1; -} - -static inline void -wpa_supplicant_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_priv *iface) -{ -} - static inline void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s) { @@ -132,12 +106,7 @@ wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s) { } -static inline void -wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s, - wpa_states new_state, - wpa_states old_state) -{ -} +#define wpa_supplicant_dbus_notify_state_change(w,n,o) do { } while (0) static inline void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface_dbus_handlers.c b/contrib/wpa/wpa_supplicant/dbus/dbus_old_handlers.c index d3250d3..d914697 100644 --- a/contrib/wpa/wpa_supplicant/ctrl_iface_dbus_handlers.c +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_old_handlers.c @@ -13,18 +13,23 @@ */ #include "includes.h" +#include <dbus/dbus.h> #include "common.h" -#include "config.h" -#include "wpa_supplicant_i.h" -#include "ctrl_iface_dbus.h" -#include "ctrl_iface_dbus_handlers.h" #include "eap_peer/eap_methods.h" -#include "dbus_dict_helpers.h" -#include "ieee802_11_defs.h" -#include "wpas_glue.h" +#include "common/ieee802_11_defs.h" #include "eapol_supp/eapol_supp_sm.h" -#include "wpa.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" extern int wpa_debug_level; extern int wpa_debug_show_keys; @@ -37,14 +42,14 @@ extern int wpa_debug_timestamp; * * Convenience function to create and return an invalid options error */ -static DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message, - const char *arg) +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."); + "Did not receive correct message " + "arguments."); if (arg != NULL) dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID); @@ -61,7 +66,7 @@ static DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message, * * Convenience function to create and return a success reply message */ -static DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message) +DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message) { DBusMessage *reply; unsigned int success = 1; @@ -73,15 +78,6 @@ static DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message) } -static void wpas_dbus_free_wpa_interface(struct wpa_interface *iface) -{ - free((char *) iface->driver); - free((char *) iface->driver_param); - free((char *) iface->confname); - free((char *) iface->bridge_ifname); -} - - /** * wpas_dbus_global_add_interface - Request registration of a network interface * @message: Pointer to incoming dbus message @@ -96,13 +92,14 @@ static void wpas_dbus_free_wpa_interface(struct wpa_interface *iface) DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, struct wpa_global *global) { - struct wpa_interface iface; char *ifname = NULL; + char *driver = NULL; + char *driver_param = NULL; + char *confname = NULL; + char *bridge_ifname = NULL; DBusMessage *reply = NULL; DBusMessageIter iter; - memset(&iface, 0, sizeof(iface)); - dbus_message_iter_init(message, &iter); /* First argument: interface name (DBUS_TYPE_STRING) @@ -111,9 +108,8 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) goto error; dbus_message_iter_get_basic(&iter, &ifname); - if (!strlen(ifname)) + if (!os_strlen(ifname)) goto error; - iface.ifname = ifname; /* Second argument: dict of options */ if (dbus_message_iter_next(&iter)) { @@ -127,29 +123,32 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, goto error; if (!strcmp(entry.key, "driver") && (entry.type == DBUS_TYPE_STRING)) { - iface.driver = strdup(entry.str_value); - if (iface.driver == NULL) + 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)) { - iface.driver_param = strdup(entry.str_value); - if (iface.driver_param == NULL) + 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)) { - iface.confname = strdup(entry.str_value); - if (iface.confname == NULL) + 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)) { - iface.bridge_ifname = strdup(entry.str_value); - if (iface.bridge_ifname == NULL) + 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; } - wpa_dbus_dict_entry_clear(&entry); } } @@ -157,16 +156,23 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, * Try to get the wpa_supplicant record for this iface, return * an error if we already control it. */ - if (wpa_supplicant_get_iface(global, iface.ifname) != NULL) { + 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. */ if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) { - const char *path = wpa_supplicant_get_dbus_path(wpa_s); + 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); @@ -178,12 +184,17 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, "interface."); } } - wpas_dbus_free_wpa_interface(&iface); + +out: + os_free(driver); + os_free(driver_param); + os_free(confname); + os_free(bridge_ifname); return reply; error: - wpas_dbus_free_wpa_interface(&iface); - return wpas_dbus_new_invalid_opts_error(message, NULL); + reply = wpas_dbus_new_invalid_opts_error(message, NULL); + goto out; } @@ -263,15 +274,7 @@ DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message, goto out; } - path = wpa_supplicant_get_dbus_path(wpa_s); - if (path == NULL) { - reply = dbus_message_new_error(message, - WPAS_ERROR_INTERNAL_ERROR, - "an internal error occurred " - "getting the interface."); - goto out; - } - + path = wpa_s->dbus_path; reply = dbus_message_new_method_return(message); dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, @@ -281,6 +284,7 @@ out: return reply; } + /** * wpas_dbus_global_set_debugparams- Set the debug params * @message: Pointer to incoming dbus message @@ -304,29 +308,21 @@ DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message, DBUS_TYPE_BOOLEAN, &debug_timestamp, DBUS_TYPE_BOOLEAN, &debug_show_keys, DBUS_TYPE_INVALID)) { - reply = wpas_dbus_new_invalid_opts_error(message, NULL); - goto out; + return wpas_dbus_new_invalid_opts_error(message, NULL); } - /* check for allowed debuglevels */ - if (debug_level != MSG_MSGDUMP && - debug_level != MSG_DEBUG && - debug_level != MSG_INFO && - debug_level != MSG_WARNING && - debug_level != MSG_ERROR) { - reply = wpas_dbus_new_invalid_opts_error(message, NULL); - goto out; + 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); } - wpa_debug_level = debug_level; - wpa_debug_timestamp = debug_timestamp ? 1 : 0; - wpa_debug_show_keys = debug_show_keys ? 1 : 0; reply = wpas_dbus_new_success_reply(message); -out: return reply; } + /** * wpas_dbus_iface_scan - Request a wireless scan on an interface * @message: Pointer to incoming dbus message @@ -363,16 +359,7 @@ DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message, DBusMessage *reply = NULL; DBusMessageIter iter; DBusMessageIter sub_iter; - size_t i; - - /* Ensure we've actually got scan results to return */ - if (wpa_s->scan_res == NULL && - wpa_supplicant_get_scan_results(wpa_s) < 0) { - reply = dbus_message_new_error(message, WPAS_ERROR_SCAN_ERROR, - "An error ocurred getting scan " - "results."); - goto out; - } + struct wpa_bss *bss; /* Create and initialize the return message */ reply = dbus_message_new_method_return(message); @@ -382,35 +369,23 @@ DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message, &sub_iter); /* Loop through scan results and append each result's object path */ - for (i = 0; i < wpa_s->scan_res->num; i++) { - struct wpa_scan_res *res = wpa_s->scan_res->res[i]; - char *path; - - path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); - if (path == NULL) { - perror("wpas_dbus_iface_scan_results[dbus]: out of " - "memory."); - wpa_printf(MSG_ERROR, "dbus control interface: not " - "enough memory to send scan results " - "signal."); - break; - } + 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. */ - snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, - "%s/" WPAS_DBUS_BSSIDS_PART "/" - WPAS_DBUS_BSSID_FORMAT, - wpa_supplicant_get_dbus_path(wpa_s), - MAC2STR(res->bssid)); + os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_BSSIDS_PART "/" + WPAS_DBUS_BSSID_FORMAT, + wpa_s->dbus_path, MAC2STR(bss->bssid)); dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_OBJECT_PATH, &path); - free(path); } dbus_message_iter_close_container(&iter, &sub_iter); -out: return reply; } @@ -427,9 +402,9 @@ out: */ DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, struct wpa_supplicant *wpa_s, - struct wpa_scan_res *res) + struct wpa_bss *bss) { - DBusMessage *reply = NULL; + DBusMessage *reply; DBusMessageIter iter, iter_dict; const u8 *ie; @@ -441,11 +416,11 @@ DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, goto error; if (!wpa_dbus_dict_append_byte_array(&iter_dict, "bssid", - (const char *) res->bssid, + (const char *) bss->bssid, ETH_ALEN)) goto error; - ie = wpa_scan_get_ie(res, WLAN_EID_SSID); + ie = wpa_bss_get_ie(bss, WLAN_EID_SSID); if (ie) { if (!wpa_dbus_dict_append_byte_array(&iter_dict, "ssid", (const char *) (ie + 2), @@ -453,7 +428,7 @@ DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, goto error; } - ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); if (ie) { if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpaie", (const char *) ie, @@ -461,7 +436,7 @@ DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, goto error; } - ie = wpa_scan_get_ie(res, WLAN_EID_RSN); + ie = wpa_bss_get_ie(bss, WLAN_EID_RSN); if (ie) { if (!wpa_dbus_dict_append_byte_array(&iter_dict, "rsnie", (const char *) ie, @@ -469,7 +444,7 @@ DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, goto error; } - ie = wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE); if (ie) { if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpsie", (const char *) ie, @@ -477,22 +452,25 @@ DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, goto error; } - if (res->freq) { + if (bss->freq) { if (!wpa_dbus_dict_append_int32(&iter_dict, "frequency", - res->freq)) + bss->freq)) goto error; } if (!wpa_dbus_dict_append_uint16(&iter_dict, "capabilities", - res->caps)) + bss->caps)) goto error; - if (!wpa_dbus_dict_append_int32(&iter_dict, "quality", res->qual)) + if (!(bss->flags & WPA_BSS_QUAL_INVALID) && + !wpa_dbus_dict_append_int32(&iter_dict, "quality", bss->qual)) goto error; - if (!wpa_dbus_dict_append_int32(&iter_dict, "noise", res->noise)) + if (!(bss->flags & WPA_BSS_NOISE_INVALID) && + !wpa_dbus_dict_append_int32(&iter_dict, "noise", bss->noise)) goto error; - if (!wpa_dbus_dict_append_int32(&iter_dict, "level", res->level)) + if (!(bss->flags & WPA_BSS_LEVEL_INVALID) && + !wpa_dbus_dict_append_int32(&iter_dict, "level", bss->level)) goto error; if (!wpa_dbus_dict_append_int32(&iter_dict, "maxrate", - wpa_scan_get_max_rate(res) * 500000)) + wpa_bss_get_max_rate(bss) * 500000)) goto error; if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) @@ -552,8 +530,8 @@ DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message, /* free returned method array */ while (eap_methods[i]) - free(eap_methods[i++]); - free(eap_methods); + os_free(eap_methods[i++]); + os_free(eap_methods); if (!success) goto error; @@ -810,17 +788,7 @@ DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message, { DBusMessage *reply = NULL; struct wpa_ssid *ssid; - char *path = NULL; - - path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); - if (path == NULL) { - perror("wpas_dbus_iface_scan_results[dbus]: out of " - "memory."); - wpa_printf(MSG_ERROR, "dbus control interface: not " - "enough memory to send scan results " - "signal."); - goto out; - } + char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf; ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) { @@ -830,21 +798,20 @@ DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message, "a network on this interface."); goto out; } + wpas_notify_network_added(wpa_s, ssid); ssid->disabled = 1; wpa_config_set_network_defaults(ssid); /* Construct the object path for this network. */ - snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, - "%s/" WPAS_DBUS_NETWORKS_PART "/%d", - wpa_supplicant_get_dbus_path(wpa_s), - ssid->id); + 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: - free(path); return reply; } @@ -880,8 +847,9 @@ DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message, reply = wpas_dbus_new_invalid_network_error(message); goto out; } + /* Ensure the network is actually a child of this interface */ - if (strcmp(iface, wpa_supplicant_get_dbus_path(wpa_s)) != 0) { + if (os_strcmp(iface, wpa_s->dbus_path) != 0) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } @@ -893,6 +861,8 @@ DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message, goto out; } + wpas_notify_network_removed(wpa_s, ssid); + if (wpa_config_remove_network(wpa_s->conf, id) < 0) { reply = dbus_message_new_error(message, WPAS_ERROR_REMOVE_NETWORK_ERROR, @@ -902,12 +872,13 @@ DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message, } if (ssid == wpa_s->current_ssid) - wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); + wpa_supplicant_deauthenticate(wpa_s, + WLAN_REASON_DEAUTH_LEAVING); reply = wpas_dbus_new_success_reply(message); out: - free(iface); - free(net_id); + os_free(iface); + os_free(net_id); return reply; } @@ -918,6 +889,7 @@ static const char *dont_quote[] = { "bssid", NULL }; + static dbus_bool_t should_quote_opt(const char *key) { int i = 0; @@ -929,6 +901,7 @@ static dbus_bool_t should_quote_opt(const char *key) return TRUE; } + /** * wpas_dbus_iface_set_network - Set options for a configured network * @message: Pointer to incoming dbus message @@ -976,13 +949,13 @@ DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message, if (value == NULL) goto error; ret = wpa_snprintf_hex(value, size, - (u8 *) entry.bytearray_value, - entry.array_len); + (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 = strlen(entry.str_value); + size = os_strlen(entry.str_value); /* Zero-length option check */ if (size <= 0) goto error; @@ -990,12 +963,12 @@ DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message, value = os_zalloc(size); if (value == NULL) goto error; - ret = snprintf(value, size, "\"%s\"", - entry.str_value); + ret = os_snprintf(value, size, "\"%s\"", + entry.str_value); if (ret < 0 || (size_t) ret != (size - 1)) goto error; } else { - value = strdup(entry.str_value); + value = os_strdup(entry.str_value); if (value == NULL) goto error; } @@ -1003,14 +976,16 @@ DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message, value = os_zalloc(size); if (value == NULL) goto error; - ret = snprintf(value, size, "%u", entry.uint32_value); + ret = os_snprintf(value, size, "%u", + entry.uint32_value); if (ret <= 0) goto error; } else if (entry.type == DBUS_TYPE_INT32) { value = os_zalloc(size); if (value == NULL) goto error; - ret = snprintf(value, size, "%d", entry.int32_value); + ret = os_snprintf(value, size, "%d", + entry.int32_value); if (ret <= 0) goto error; } else @@ -1019,17 +994,19 @@ DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message, if (wpa_config_set(ssid, entry.key, value, 0) < 0) goto error; - if ((strcmp(entry.key, "psk") == 0 && + if ((os_strcmp(entry.key, "psk") == 0 && value[0] == '"' && ssid->ssid_len) || - (strcmp(entry.key, "ssid") == 0 && ssid->passphrase)) + (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); - free(value); + os_free(value); wpa_dbus_dict_entry_clear(&entry); continue; error: - free(value); + os_free(value); reply = wpas_dbus_new_invalid_opts_error(message, entry.key); wpa_dbus_dict_entry_clear(&entry); break; @@ -1057,16 +1034,7 @@ DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { - if (wpa_s->current_ssid == NULL && ssid->disabled) { - /* - * Try to reassociate since there is no current configuration - * and a new network was made available. - */ - wpa_s->reassociate = 1; - wpa_supplicant_req_scan(wpa_s, 0, 0); - } - ssid->disabled = 0; - + wpa_supplicant_enable_network(wpa_s, ssid); return wpas_dbus_new_success_reply(message); } @@ -1085,10 +1053,7 @@ DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { - if (ssid == wpa_s->current_ssid) - wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); - ssid->disabled = 1; - + wpa_supplicant_disable_network(wpa_s, ssid); return wpas_dbus_new_success_reply(message); } @@ -1111,17 +1076,10 @@ DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message, char *iface_obj_path = NULL; char *network = NULL; - if (strlen(dbus_message_get_signature(message)) == 0) { + if (os_strlen(dbus_message_get_signature(message)) == 0) { /* Any network */ - ssid = wpa_s->conf->ssid; - while (ssid) { - ssid->disabled = 0; - ssid = ssid->next; - } - wpa_s->reassociate = 1; - wpa_supplicant_req_scan(wpa_s, 0, 0); + ssid = NULL; } else { - const char *obj_path; int nid; if (!dbus_message_get_args(message, NULL, @@ -1141,8 +1099,7 @@ DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message, goto out; } /* Ensure the object path really points to this interface */ - obj_path = wpa_supplicant_get_dbus_path(wpa_s); - if (strcmp(iface_obj_path, obj_path) != 0) { + if (os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } @@ -1158,29 +1115,16 @@ DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message, reply = wpas_dbus_new_invalid_network_error(message); goto out; } - - /* Finally, associate with the network */ - if (ssid != wpa_s->current_ssid && wpa_s->current_ssid) - wpa_supplicant_disassociate( - wpa_s, WLAN_REASON_DEAUTH_LEAVING); - - /* Mark all other networks disabled and trigger reassociation - */ - ssid = wpa_s->conf->ssid; - while (ssid) { - ssid->disabled = (nid != ssid->id); - ssid = ssid->next; - } - wpa_s->disconnected = 0; - wpa_s->reassociate = 1; - wpa_supplicant_req_scan(wpa_s, 0, 0); } + /* Finally, associate with the network */ + wpa_supplicant_select_network(wpa_s, ssid); + reply = wpas_dbus_new_success_reply(message); out: - free(iface_obj_path); - free(network); + os_free(iface_obj_path); + os_free(network); return reply; } @@ -1198,7 +1142,7 @@ DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message, struct wpa_supplicant *wpa_s) { wpa_s->disconnected = 1; - wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); + wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); return wpas_dbus_new_success_reply(message); } @@ -1225,11 +1169,11 @@ DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message, goto out; } - if (ap_scan > 2) { + if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } - wpa_s->conf->ap_scan = ap_scan; + reply = wpas_dbus_new_success_reply(message); out: @@ -1286,14 +1230,12 @@ DBusMessage * wpas_dbus_iface_set_smartcard_modules( wpa_dbus_dict_entry_clear(&entry); } -#ifdef EAP_TLS_OPENSSL 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; -#endif /* EAP_TLS_OPENSSL */ wpa_sm_set_eapol(wpa_s->wpa, NULL); eapol_sm_deinit(wpa_s->eapol); @@ -1310,6 +1252,7 @@ error: return wpas_dbus_new_invalid_opts_error(message, NULL); } + /** * wpas_dbus_iface_get_state - Get interface state * @message: Pointer to incoming dbus message @@ -1355,10 +1298,8 @@ DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message, dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &scanning, DBUS_TYPE_INVALID); } else { - perror("wpas_dbus_iface_get_scanning[dbus]: out of " - "memory."); - wpa_printf(MSG_ERROR, "dbus control interface: not enough " - "memory to return scanning state."); + wpa_printf(MSG_ERROR, "dbus: Not enough memory to return " + "scanning state"); } return reply; @@ -1438,8 +1379,11 @@ DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message, } /* Success */ - wpa_config_remove_blob(wpa_s->conf, blob->name); + 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); @@ -1458,7 +1402,7 @@ DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message, * 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) + struct wpa_supplicant *wpa_s) { DBusMessageIter iter, array; char *err_msg = NULL; @@ -1474,18 +1418,19 @@ DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message, const char *name; dbus_message_iter_get_basic(&array, &name); - if (!strlen(name)) + if (!os_strlen(name)) err_msg = "Invalid blob name."; 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) { + if (err_msg) return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR, err_msg); - } return wpas_dbus_new_success_reply(message); } diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface_dbus_handlers.h b/contrib/wpa/wpa_supplicant/dbus/dbus_old_handlers.h index 376d835..65e876f 100644 --- a/contrib/wpa/wpa_supplicant/ctrl_iface_dbus_handlers.h +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_old_handlers.h @@ -15,9 +15,10 @@ #ifndef CTRL_IFACE_DBUS_HANDLERS_H #define CTRL_IFACE_DBUS_HANDLERS_H -#ifdef CONFIG_CTRL_IFACE_DBUS +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); @@ -39,7 +40,7 @@ DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message, DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, struct wpa_supplicant *wpa_s, - struct wpa_scan_res *res); + struct wpa_bss *bss); DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message, struct wpa_supplicant *wpa_s); @@ -86,7 +87,18 @@ DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message, DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message, struct wpa_supplicant *wpa_s); -#endif /* CONFIG_CTRL_IFACE_DBUS */ +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_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/contrib/wpa/wpa_supplicant/dbus/dbus_old_handlers_wps.c b/contrib/wpa/wpa_supplicant/dbus/dbus_old_handlers_wps.c new file mode 100644 index 0000000..b5879f3 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/dbus_old_handlers_wps.c @@ -0,0 +1,161 @@ +/* + * WPA Supplicant / dbus-based control interface (WPS) + * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING 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")) + ret = wpas_wps_start_pbc(wpa_s, NULL); + else if (!hwaddr_aton(arg_bssid, bssid)) + ret = wpas_wps_start_pbc(wpa_s, bssid); + 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; + + 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")) + _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); + else + ret = wpas_wps_start_pin(wpa_s, _bssid, NULL); + + 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) { + dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin, + DBUS_TYPE_INVALID); + } else { + char npin[9]; + os_snprintf(npin, sizeof(npin), "%08d", ret); + dbus_message_append_args(reply, DBUS_TYPE_STRING, &npin, + 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 (!os_strcmp(arg_bssid, "any")) + ret = wpas_wps_start_reg(wpa_s, NULL, pin, NULL); + else 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_PBC_ERROR, + "Could not request credentials"); + } + + return wpas_dbus_new_success_reply(message); +} diff --git a/contrib/wpa/wpa_supplicant/dbus-wpa_supplicant.service b/contrib/wpa/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service index a9ce1ec..a9ce1ec 100644 --- a/contrib/wpa/wpa_supplicant/dbus-wpa_supplicant.service +++ b/contrib/wpa/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service diff --git a/contrib/wpa/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service b/contrib/wpa/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service new file mode 100644 index 0000000..df78471 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=fi.w1.wpa_supplicant1 +Exec=/sbin/wpa_supplicant -u +User=root diff --git a/contrib/wpa/wpa_supplicant/defconfig b/contrib/wpa/wpa_supplicant/defconfig index 4d0aa8a..8c32cb3 100644 --- a/contrib/wpa/wpa_supplicant/defconfig +++ b/contrib/wpa/wpa_supplicant/defconfig @@ -55,11 +55,6 @@ CONFIG_DRIVER_HOSTAP=y # Set include directory to the madwifi source tree #CFLAGS += -I../../madwifi -# Driver interface for Prism54 driver -# (Note: Prism54 is not yet supported, i.e., this will not work as-is and is -# for developers only) -#CONFIG_DRIVER_PRISM54=y - # Driver interface for ndiswrapper # Deprecated; use CONFIG_DRIVER_WEXT=y instead. #CONFIG_DRIVER_NDISWRAPPER=y @@ -92,6 +87,8 @@ CONFIG_DRIVER_WEXT=y #CONFIG_DRIVER_BSD=y #CFLAGS += -I/usr/local/include #LIBS += -L/usr/local/lib +#LIBS_p += -L/usr/local/lib +#LIBS_c += -L/usr/local/lib # Driver interface for Windows NDIS #CONFIG_DRIVER_NDIS=y @@ -112,12 +109,20 @@ CONFIG_DRIVER_WEXT=y # Driver interface for development testing #CONFIG_DRIVER_TEST=y +# Include client MLME (management frame processing) for test driver +# This can be used to test MLME operations in hostapd with the test interface. +# space. +#CONFIG_CLIENT_MLME=y + # Driver interface for wired Ethernet drivers CONFIG_DRIVER_WIRED=y # Driver interface for the Broadcom RoboSwitch family #CONFIG_DRIVER_ROBOSWITCH=y +# Driver interface for no driver (e.g., WPS ER only) +#CONFIG_DRIVER_NONE=y + # Enable IEEE 802.1X Supplicant (automatically included if any EAP method is # included) CONFIG_IEEE8021X_EAPOL=y @@ -241,11 +246,6 @@ CONFIG_CTRL_IFACE=y # wpa_passphrase). This saves about 0.5 kB in code size. #CONFIG_NO_WPA_PASSPHRASE=y -# Remove AES extra functions. This can be used to reduce code size by about -# 1.5 kB by removing extra AES modes that are not needed for commonly used -# client configurations (they are needed for some EAP types). -#CONFIG_NO_AES_EXTRAS=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 @@ -340,9 +340,17 @@ CONFIG_PEERKEY=y #CONFIG_NDIS_EVENTS_INTEGRATED=y #PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" -# Add support for DBus control interface +# 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 + +# Add introspection support for new DBus control interface +#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 # statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn). @@ -364,13 +372,6 @@ CONFIG_PEERKEY=y # amount of memory/flash. #CONFIG_DYNAMIC_EAP_METHODS=y -# Include client MLME (management frame processing). -# This can be used to move MLME processing of Linux mac80211 stack into user -# space. Please note that this is currently only available with -# driver_nl80211.c and only with a modified version of Linux kernel and -# wpa_supplicant. -#CONFIG_CLIENT_MLME=y - # IEEE Std 802.11r-2008 (Fast BSS Transition) #CONFIG_IEEE80211R=y @@ -383,3 +384,21 @@ CONFIG_PEERKEY=y # Enable mitigation against certain attacks against TKIP by delaying Michael # MIC error reports by a random amount of time between 0 and 60 seconds #CONFIG_DELAYED_MIC_ERROR_REPORT=y + +# Enable tracing code for developer debugging +# This tracks use of memory allocations and other registrations and reports +# incorrect use with a backtrace of call (or allocation) location. +#CONFIG_WPA_TRACE=y +# For BSD, comment out these. +#LIBS += -lexecinfo +#LIBS_p += -lexecinfo +#LIBS_c += -lexecinfo + +# Use libbfd to get more details for developer debugging +# This enables use of libbfd to get more detailed symbols for the backtraces +# generated by CONFIG_WPA_TRACE=y. +#CONFIG_WPA_TRACE_BFD=y +# For BSD, comment out these. +#LIBS += -lbfd -liberty -lz +#LIBS_p += -lbfd -liberty -lz +#LIBS_c += -lbfd -liberty -lz diff --git a/contrib/wpa/wpa_supplicant/doc/code_structure.doxygen b/contrib/wpa/wpa_supplicant/doc/code_structure.doxygen deleted file mode 100644 index 6398ff3..0000000 --- a/contrib/wpa/wpa_supplicant/doc/code_structure.doxygen +++ /dev/null @@ -1,322 +0,0 @@ -/** -\page code_structure Structure of the source code - -[ \ref wpa_supplicant_core "wpa_supplicant core functionality" | -\ref generic_helper_func "Generic helper functions" | -\ref crypto_func "Cryptographic functions" | -\ref tls_func "TLS library" | -\ref configuration "Configuration" | -\ref ctrl_iface "Control interface" | -\ref wpa_code "WPA supplicant" | -\ref eap_peer "EAP peer" | -\ref eapol_supp "EAPOL supplicant" | -\ref win_port "Windows port" | -\ref test_programs "Test programs" ] - -%wpa_supplicant implementation is divided into number of independent -modules. Core code includes functionality for controlling the network -selection, association, and configuration. Independent modules include -WPA code (key handshake, PMKSA caching, pre-authentication), EAPOL -state machine, and EAP state machine and methods. In addition, there -are number of separate files for generic helper functions. - -Both WPA and EAPOL/EAP state machines can be used separately in other -programs than %wpa_supplicant. As an example, the included test -programs eapol_test and preauth_test are using these modules. - -\ref driver_wrapper "Driver interface API" is defined in driver.h and -all hardware/driver dependent functionality is implemented in -driver_*.c. - - -\section wpa_supplicant_core wpa_supplicant core functionality - -wpa_supplicant.c - Program initialization, main control loop - -main.c - main() for UNIX-like operating systems and MinGW (Windows); this - uses command line arguments to configure wpa_supplicant - -events.c - Driver event processing; wpa_supplicant_event() and related functions - -wpa_supplicant_i.h - Internal definitions for %wpa_supplicant core; should not be - included into independent modules - - -\section generic_helper_func Generic helper functions - -%wpa_supplicant uses generic helper functions some of which are shared -with with hostapd. The following C files are currently used: - -eloop.c and eloop.h - Event loop (select() loop with registerable timeouts, socket read - callbacks, and signal callbacks) - -common.c and common.h - Common helper functions - -defs.h - Definitions shared by multiple files - -l2_packet.h, l2_packet_linux.c, and l2_packet_pcap.c - Layer 2 (link) access wrapper (includes native Linux implementation - and wrappers for libdnet/libpcap). A new l2_packet implementation - may need to be added when porting to new operating systems that are - not supported by libdnet/libpcap. Makefile can be used to select which - l2_packet implementation is included. l2_packet_linux.c uses Linux - packet sockets and l2_packet_pcap.c has a more portable version using - libpcap and libdnet. - -pcsc_funcs.c and pcsc_funcs.h - Wrapper for PC/SC lite SIM and smart card readers - -priv_netlink.h - Private version of netlink definitions from Linux kernel header files; - this could be replaced with C library header file once suitable - version becomes commonly available - -version.h - Version number definitions - -wireless_copy.h - Private version of Linux wireless extensions definitions from kernel - header files; this could be replaced with C library header file once - suitable version becomes commonly available - - -\section crypto_func Cryptographic functions - -md5.c and md5.h - MD5 (replaced with a crypto library if TLS support is included) - HMAC-MD5 (keyed checksum for message authenticity validation) - -rc4.c and rc4.h - RC4 (broadcast/default key encryption) - -sha1.c and sha1.h - SHA-1 (replaced with a crypto library if TLS support is included) - HMAC-SHA-1 (keyed checksum for message authenticity validation) - PRF-SHA-1 (pseudorandom (key/nonce generation) function) - PBKDF2-SHA-1 (ASCII passphrase to shared secret) - T-PRF (for EAP-FAST) - TLS-PRF (RFC 2246) - -sha256.c and sha256.h - SHA-256 (replaced with a crypto library if TLS support is included) - -aes_wrap.c, aes_wrap.h, aes.c - AES (replaced with a crypto library if TLS support is included), - AES Key Wrap Algorithm with 128-bit KEK, RFC3394 (broadcast/default - key encryption), - One-Key CBC MAC (OMAC1) hash with AES-128, - AES-128 CTR mode encryption, - AES-128 EAX mode encryption/decryption, - AES-128 CBC - -crypto.h - Definition of crypto library wrapper - -crypto_openssl.c - Wrapper functions for libcrypto (OpenSSL) - -crypto_internal.c - Wrapper functions for internal crypto implementation - -crypto_gnutls.c - Wrapper functions for libgcrypt (used by GnuTLS) - -ms_funcs.c and ms_funcs.h - Helper functions for MSCHAPV2 and LEAP - -tls.h - Definition of TLS library wrapper - -tls_none.c - Dummy implementation of TLS library wrapper for cases where TLS - functionality is not included. - -tls_openssl.c - TLS library wrapper for openssl - -tls_internal.c - TLS library for internal TLS implementation - -tls_gnutls.c - TLS library wrapper for GnuTLS - - -\section tls_func TLS library - -asn1.c and asn1.h - ASN.1 DER parsing - -bignum.c and bignum.h - Big number math - -rsa.c and rsa.h - RSA - -x509v3.c and x509v3.h - X.509v3 certificate parsing and processing - -tlsv1_client.c, tlsv1_client.h - TLSv1 client (RFC 2246) - -tlsv1_client_i.h - Internal structures for TLSv1 client - -tlsv1_client_read.c - TLSv1 client: read handshake messages - -tlsv1_client_write.c - TLSv1 client: write handshake messages - -tlsv1_common.c and tlsv1_common.h - Common TLSv1 routines and definitions - -tlsv1_cred.c and tlsv1_cred.h - TLSv1 credentials - -tlsv1_record.c and tlsv1_record.h - TLSv1 record protocol - - -\section configuration Configuration - -config_ssid.h - Definition of per network configuration items - -config.h - Definition of the %wpa_supplicant configuration - -config.c - Configuration parser and common functions - -config_file.c - Configuration backend for text files (e.g., wpa_supplicant.conf) - -config_winreg.c - Configuration backend for Windows registry - - -\section ctrl_iface Control interface - -%wpa_supplicant has a \ref ctrl_iface_page "control interface" -that can be used to get status -information and manage operations from external programs. An example -command line interface (wpa_cli) and GUI (wpa_gui) for this interface -are included in the %wpa_supplicant distribution. - -ctrl_iface.c and ctrl_iface.h - %wpa_supplicant-side of the control interface - -ctrl_iface_unix.c - UNIX domain sockets -based control interface backend - -ctrl_iface_udp.c - UDP sockets -based control interface backend - -ctrl_iface_named_pipe.c - Windows named pipes -based control interface backend - -wpa_ctrl.c and wpa_ctrl.h - Library functions for external programs to provide access to the - %wpa_supplicant control interface - -wpa_cli.c - Example program for using %wpa_supplicant control interface - - -\section wpa_code WPA supplicant - -wpa.c and wpa.h - WPA state machine and 4-Way/Group Key Handshake processing - -preauth.c and preauth.h - PMKSA caching and pre-authentication (RSN/WPA2) - -wpa_i.h - Internal definitions for WPA code; not to be included to other modules. - -\section eap_peer EAP peer - -\ref eap_module "EAP peer implementation" is a separate module that -can be used by other programs than just %wpa_supplicant. - -eap.c and eap.h - EAP state machine and method interface - -eap_defs.h - Common EAP definitions - -eap_i.h - Internal definitions for EAP state machine and EAP methods; not to be - included in other modules - -eap_sim_common.c and eap_sim_common.h - Common code for EAP-SIM and EAP-AKA - -eap_tls_common.c and eap_tls_common.h - Common code for EAP-PEAP, EAP-TTLS, and EAP-FAST - -eap_tlv.c and eap_tlv.h - EAP-TLV code for EAP-PEAP and EAP-FAST - -eap_ttls.c and eap_ttls.h - EAP-TTLS - -eap_pax.c, eap_pax_common.h, eap_pax_common.c - EAP-PAX - -eap_psk.c, eap_psk_common.h, eap_psk_common.c - EAP-PSK (note: this is not needed for WPA-PSK) - -eap_sake.c, eap_sake_common.h, eap_sake_common.c - EAP-SAKE - -eap_gpsk.c, eap_gpsk_common.h, eap_gpsk_common.c - EAP-GPSK - -eap_aka.c, eap_fast.c, eap_gtc.c, eap_leap.c, eap_md5.c, eap_mschapv2.c, -eap_otp.c, eap_peap.c, eap_sim.c, eap_tls.c - Other EAP method implementations - - -\section eapol_supp EAPOL supplicant - -eapol_supp_sm.c and eapol_supp_sm.h - EAPOL supplicant state machine and IEEE 802.1X processing - - -\section win_port Windows port - -ndis_events.c - Code for receiving NdisMIndicateStatus() events and delivering them to - %wpa_supplicant driver_ndis.c in more easier to use form - -win_if_list.c - External program for listing current network interface - - -\section test_programs Test programs - -radius_client.c and radius_client.h - RADIUS authentication client implementation for eapol_test - -radius.c and radius.h - RADIUS message processing for eapol_test - -eapol_test.c - Standalone EAP testing tool with integrated RADIUS authentication - client - -preauth_test.c - Standalone RSN pre-authentication tool - -wpa_passphrase.c - WPA ASCII passphrase to PSK conversion - -*/ diff --git a/contrib/wpa/wpa_supplicant/doc/ctrl_iface.doxygen b/contrib/wpa/wpa_supplicant/doc/ctrl_iface.doxygen deleted file mode 100644 index e908e0f..0000000 --- a/contrib/wpa/wpa_supplicant/doc/ctrl_iface.doxygen +++ /dev/null @@ -1,481 +0,0 @@ -/** -\page ctrl_iface_page Control interface - -%wpa_supplicant implements a control interface that can be used by -external programs to control the operations of the %wpa_supplicant -daemon and to get status information and event notifications. There is -a small C library, in a form of a single C file, wpa_ctrl.c, that -provides helper functions to facilitate the use of the control -interface. External programs can link this file into them and then use -the library functions documented in wpa_ctrl.h to interact with -%wpa_supplicant. This library can also be used with C++. wpa_cli.c and -wpa_gui are example programs using this library. - -There are multiple mechanisms for inter-process communication. For -example, Linux version of %wpa_supplicant is using UNIX domain sockets -for the control interface and Windows version UDP sockets. The use of -the functions defined in wpa_ctrl.h can be used to hide the details of -the used IPC from external programs. - - -\section using_ctrl_iface Using the control interface - -External programs, e.g., a GUI or a configuration utility, that need to -communicate with %wpa_supplicant should link in wpa_ctrl.c. This -allows them to use helper functions to open connection to the control -interface with wpa_ctrl_open() and to send commands with -wpa_ctrl_request(). - -%wpa_supplicant uses the control interface for two types of communication: -commands and unsolicited event messages. Commands are a pair of -messages, a request from the external program and a response from -%wpa_supplicant. These can be executed using wpa_ctrl_request(). -Unsolicited event messages are sent by %wpa_supplicant to the control -interface connection without specific request from the external program -for receiving each message. However, the external program needs to -attach to the control interface with wpa_ctrl_attach() to receive these -unsolicited messages. - -If the control interface connection is used both for commands and -unsolicited event messages, there is potential for receiving an -unsolicited message between the command request and response. -wpa_ctrl_request() caller will need to supply a callback, msg_cb, -for processing these messages. Often it is easier to open two -control interface connections by calling wpa_ctrl_open() twice and -then use one of the connections for commands and the other one for -unsolicited messages. This way command request/response pairs will -not be broken by unsolicited messages. wpa_cli is an example of how -to use only one connection for both purposes and wpa_gui demonstrates -how to use two separate connections. - -Once the control interface connection is not needed anymore, it should -be closed by calling wpa_ctrl_close(). If the connection was used for -unsolicited event messages, it should be first detached by calling -wpa_ctrl_detach(). - - -\section ctrl_iface_cmds Control interface commands - -Following commands can be used with wpa_ctrl_request(): - -\subsection ctrl_iface_PING PING - -This command can be used to test whether %wpa_supplicant is replying -to the control interface commands. The expected reply is \c PONG if the -connection is open and %wpa_supplicant is processing commands. - - -\subsection ctrl_iface_MIB MIB - -Request a list of MIB variables (dot1x, dot11). The output is a text -block with each line in \c variable=value format. For example: - -\verbatim -dot11RSNAOptionImplemented=TRUE -dot11RSNAPreauthenticationImplemented=TRUE -dot11RSNAEnabled=FALSE -dot11RSNAPreauthenticationEnabled=FALSE -dot11RSNAConfigVersion=1 -dot11RSNAConfigPairwiseKeysSupported=5 -dot11RSNAConfigGroupCipherSize=128 -dot11RSNAConfigPMKLifetime=43200 -dot11RSNAConfigPMKReauthThreshold=70 -dot11RSNAConfigNumberOfPTKSAReplayCounters=1 -dot11RSNAConfigSATimeout=60 -dot11RSNAAuthenticationSuiteSelected=00-50-f2-2 -dot11RSNAPairwiseCipherSelected=00-50-f2-4 -dot11RSNAGroupCipherSelected=00-50-f2-4 -dot11RSNAPMKIDUsed= -dot11RSNAAuthenticationSuiteRequested=00-50-f2-2 -dot11RSNAPairwiseCipherRequested=00-50-f2-4 -dot11RSNAGroupCipherRequested=00-50-f2-4 -dot11RSNAConfigNumberOfGTKSAReplayCounters=0 -dot11RSNA4WayHandshakeFailures=0 -dot1xSuppPaeState=5 -dot1xSuppHeldPeriod=60 -dot1xSuppAuthPeriod=30 -dot1xSuppStartPeriod=30 -dot1xSuppMaxStart=3 -dot1xSuppSuppControlledPortStatus=Authorized -dot1xSuppBackendPaeState=2 -dot1xSuppEapolFramesRx=0 -dot1xSuppEapolFramesTx=440 -dot1xSuppEapolStartFramesTx=2 -dot1xSuppEapolLogoffFramesTx=0 -dot1xSuppEapolRespFramesTx=0 -dot1xSuppEapolReqIdFramesRx=0 -dot1xSuppEapolReqFramesRx=0 -dot1xSuppInvalidEapolFramesRx=0 -dot1xSuppEapLengthErrorFramesRx=0 -dot1xSuppLastEapolFrameVersion=0 -dot1xSuppLastEapolFrameSource=00:00:00:00:00:00 -\endverbatim - - -\subsection ctrl_iface_STATUS STATUS - -Request current WPA/EAPOL/EAP status information. The output is a text -block with each line in \c variable=value format. For example: - -\verbatim -bssid=02:00:01:02:03:04 -ssid=test network -pairwise_cipher=CCMP -group_cipher=CCMP -key_mgmt=WPA-PSK -wpa_state=COMPLETED -ip_address=192.168.1.21 -Supplicant PAE state=AUTHENTICATED -suppPortStatus=Authorized -EAP state=SUCCESS -\endverbatim - - -\subsection ctrl_iface_STATUS-VERBOSE STATUS-VERBOSE - -Same as STATUS, but with more verbosity (i.e., more \c variable=value pairs). - -\verbatim -bssid=02:00:01:02:03:04 -ssid=test network -id=0 -pairwise_cipher=CCMP -group_cipher=CCMP -key_mgmt=WPA-PSK -wpa_state=COMPLETED -ip_address=192.168.1.21 -Supplicant PAE state=AUTHENTICATED -suppPortStatus=Authorized -heldPeriod=60 -authPeriod=30 -startPeriod=30 -maxStart=3 -portControl=Auto -Supplicant Backend state=IDLE -EAP state=SUCCESS -reqMethod=0 -methodState=NONE -decision=COND_SUCC -ClientTimeout=60 -\endverbatim - - -\subsection ctrl_iface_PMKSA PMKSA - -Show PMKSA cache - -\verbatim -Index / AA / PMKID / expiration (in seconds) / opportunistic -1 / 02:00:01:02:03:04 / 000102030405060708090a0b0c0d0e0f / 41362 / 0 -2 / 02:00:01:33:55:77 / 928389281928383b34afb34ba4212345 / 362 / 1 -\endverbatim - - -\subsection ctrl_iface_SET SET <variable> <value> - -Set variables: -- EAPOL::heldPeriod -- EAPOL::authPeriod -- EAPOL::startPeriod -- EAPOL::maxStart -- dot11RSNAConfigPMKLifetime -- dot11RSNAConfigPMKReauthThreshold -- dot11RSNAConfigSATimeout - -Example command: -\verbatim -SET EAPOL::heldPeriod 45 -\endverbatim - - -\subsection ctrl_iface_LOGON LOGON - -IEEE 802.1X EAPOL state machine logon. - - -\subsection ctrl_iface_LOGOFF LOGOFF - -IEEE 802.1X EAPOL state machine logoff. - - -\subsection ctrl_iface_REASSOCIATE REASSOCIATE - -Force reassociation. - - -\subsection ctrl_iface_RECONNECT RECONNECT - -Connect if disconnected (i.e., like \c REASSOCIATE, but only connect -if in disconnected state). - - -\subsection ctrl_iface_PREAUTH PREAUTH <BSSID> - -Start pre-authentication with the given BSSID. - - -\subsection ctrl_iface_ATTACH ATTACH - -Attach the connection as a monitor for unsolicited events. This can -be done with wpa_ctrl_attach(). - - -\subsection ctrl_iface_DETACH DETACH - -Detach the connection as a monitor for unsolicited events. This can -be done with wpa_ctrl_detach(). - - -\subsection ctrl_iface_LEVEL LEVEL <debug level> - -Change debug level. - - -\subsection ctrl_iface_RECONFIGURE RECONFIGURE - -Force %wpa_supplicant to re-read its configuration data. - - -\subsection ctrl_iface_TERMINATE TERMINATE - -Terminate %wpa_supplicant process. - - -\subsection ctrl_iface_BSSID BSSID <network id> <BSSID> - -Set preferred BSSID for a network. Network id can be received from the -\c LIST_NETWORKS command output. - - -\subsection ctrl_iface_LIST_NETWORKS LIST_NETWORKS - -List configured networks. - -\verbatim -network id / ssid / bssid / flags -0 example network any [CURRENT] -\endverbatim - -(note: fields are separated with tabs) - - -\subsection ctrl_iface_DISCONNECT DISCONNECT - -Disconnect and wait for \c REASSOCIATE or \c RECONNECT command before -connecting. - - -\subsection ctrl_iface_SCAN SCAN - -Request a new BSS scan. - - -\subsection ctrl_iface_SCAN_RESULTS SCAN_RESULTS - -Get the latest scan results. - -\verbatim -bssid / frequency / signal level / flags / ssid -00:09:5b:95:e0:4e 2412 208 [WPA-PSK-CCMP] jkm private -02:55:24:33:77:a3 2462 187 [WPA-PSK-TKIP] testing -00:09:5b:95:e0:4f 2412 209 jkm guest -\endverbatim - -(note: fields are separated with tabs) - - -\subsection ctrl_iface_BSS BSS - -Get detailed per-BSS scan results. \c BSS command can be used to -iterate through scan results one BSS at a time and to fetch all -information from the found BSSes. This provides access to the same -data that is available through \c SCAN_RESULTS but in a way that -avoids problems with large number of scan results not fitting in the -ctrl_iface messages. - -There are two options for selecting the BSS with the \c BSS command: -"BSS <idx>" requests information for the BSS identified by the index -(0 .. size-1) in the scan results table and "BSS <BSSID>" requests -information for the given BSS (based on BSSID in 00:01:02:03:04:05 -format). - -BSS information is presented in following format. Please note that new -fields may be added to this field=value data, so the ctrl_iface user -should be prepared to ignore values it does not understand. - -\verbatim -bssid=00:09:5b:95:e0:4e -freq=2412 -beacon_int=0 -capabilities=0x0011 -qual=51 -noise=161 -level=212 -tsf=0000000000000000 -ie=000b6a6b6d2070726976617465010180dd180050f20101000050f20401000050f20401000050f2020000 -ssid=jkm private -\endverbatim - - - -\subsection ctrl_iface_SELECT_NETWORK SELECT_NETWORK <network id> - -Select a network (disable others). Network id can be received from the -\c LIST_NETWORKS command output. - - -\subsection ctrl_iface_ENABLE_NETWORK ENABLE_NETWORK <network id> - -Enable a network. Network id can be received from the -\c LIST_NETWORKS command output. Special network id \c all can be -used to enable all network. - - -\subsection ctrl_iface_DISABLE_NETWORK DISABLE_NETWORK <network id> - -Disable a network. Network id can be received from the -\c LIST_NETWORKS command output. Special network id \c all can be -used to disable all network. - - -\subsection ctrl_iface_ADD_NETWORK ADD_NETWORK - -Add a new network. This command creates a new network with empty -configuration. The new network is disabled and once it has been -configured it can be enabled with \c ENABLE_NETWORK command. \c ADD_NETWORK -returns the network id of the new network or FAIL on failure. - - -\subsection ctrl_iface_REMOVE_NETWORK REMOVE_NETWORK <network id> - -Remove a network. Network id can be received from the -\c LIST_NETWORKS command output. Special network id \c all can be -used to remove all network. - - -\subsection ctrl_iface_SET_NETWORK SET_NETWORK <network id> <variable> <value> - -Set network variables. Network id can be received from the -\c LIST_NETWORKS command output. - -This command uses the same variables and data formats as the -configuration file. See example wpa_supplicant.conf for more details. - -- ssid (network name, SSID) -- psk (WPA passphrase or pre-shared key) -- key_mgmt (key management protocol) -- identity (EAP identity) -- password (EAP password) -- ... - - -\subsection ctrl_iface_GET_NETWORK GET_NETWORK <network id> <variable> - -Get network variables. Network id can be received from the -\c LIST_NETWORKS command output. - - -\subsection ctrl_iface_SAVE_CONFIG SAVE_CONFIG - -Save the current configuration. - - -\section ctrl_iface_interactive Interactive requests - -If %wpa_supplicant needs additional information during authentication -(e.g., password), it will use a specific prefix, \c CTRL-REQ- -(\a WPA_CTRL_REQ macro) in an unsolicited event message. An external -program, e.g., a GUI, can provide such information by using -\c CTRL-RSP- (\a WPA_CTRL_RSP macro) prefix in a command with matching -field name. - -The following fields can be requested in this way from the user: -- IDENTITY (EAP identity/user name) -- PASSWORD (EAP password) -- NEW_PASSWORD (New password if the server is requesting password change) -- PIN (PIN code for accessing a SIM or smartcard) -- OTP (one-time password; like password, but the value is used only once) -- PASSPHRASE (passphrase for a private key file) - -\verbatim -CTRL-REQ-<field name>-<network id>-<human readable text> -CTRL-RSP-<field name>-<network id>-<value> -\endverbatim - -For example, request from %wpa_supplicant: -\verbatim -CTRL-REQ-PASSWORD-1-Password needed for SSID test-network -\endverbatim - -And a matching reply from the GUI: -\verbatim -CTRL-RSP-PASSWORD-1-secret -\endverbatim - - -\subsection ctrl_iface_GET_CAPABILITY GET_CAPABILITY <option> [strict] - -Get list of supported functionality (eap, pairwise, group, -proto). Supported functionality is shown as space separate lists of -values used in the same format as in %wpa_supplicant configuration. -If optional argument, 'strict', is added, only the values that the -driver claims to explicitly support are included. Without this, all -available capabilities are included if the driver does not provide -a mechanism for querying capabilities. - -Example request/reply pairs: - -\verbatim -GET_CAPABILITY eap -AKA FAST GTC LEAP MD5 MSCHAPV2 OTP PAX PEAP PSK SIM TLS TTLS -\endverbatim - -\verbatim -GET_CAPABILITY pairwise -CCMP TKIP NONE -\endverbatim - -\verbatim -GET_CAPABILITY pairwise strict -\endverbatim - -\verbatim -GET_CAPABILITY group -CCMP TKIP WEP104 WEP40 -\endverbatim - -\verbatim -GET_CAPABILITY key_mgmt -WPA-PSK WPA-EAP IEEE8021X NONE -\endverbatim - -\verbatim -GET_CAPABILITY proto -RSN WPA -\endverbatim - -\verbatim -GET_CAPABILITY auth_alg -OPEN SHARED LEAP -\endverbatim - - -\subsection ctrl_iface_AP_SCAN AP_SCAN <ap_scan value> - -Change ap_scan value: -0 = no scanning, -1 = %wpa_supplicant requests scans and uses scan results to select the AP, -2 = %wpa_supplicant does not use scanning and just requests driver to -associate and take care of AP selection - - -\subsection ctrl_iface_INTERFACES INTERFACES - -List configured interfaces. - -\verbatim -wlan0 -eth0 -\endverbatim - -*/ diff --git a/contrib/wpa/wpa_supplicant/doc/docbook/.gitignore b/contrib/wpa/wpa_supplicant/doc/docbook/.gitignore new file mode 100644 index 0000000..8c3945c --- /dev/null +++ b/contrib/wpa/wpa_supplicant/doc/docbook/.gitignore @@ -0,0 +1,6 @@ +manpage.links +manpage.refs +*.8 +*.5 +*.html +*.pdf diff --git a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_background.8 b/contrib/wpa/wpa_supplicant/doc/docbook/wpa_background.8 index 81f771e..19162a3 100644 --- a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_background.8 +++ b/contrib/wpa/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" "12 January 2010" "" "" +.TH "WPA_BACKGROUND" "8" "07 September 2010" "" "" .SH NAME wpa_background \- Background information on Wi-Fi Protected Access and IEEE 802.11i diff --git a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_cli.8 b/contrib/wpa/wpa_supplicant/doc/docbook/wpa_cli.8 index 286cf06..e22fc92 100644 --- a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_cli.8 +++ b/contrib/wpa/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" "12 January 2010" "" "" +.TH "WPA_CLI" "8" "07 September 2010" "" "" .SH NAME wpa_cli \- WPA command line client diff --git a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_gui.8 b/contrib/wpa/wpa_supplicant/doc/docbook/wpa_gui.8 index 66a279d..f58a894 100644 --- a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_gui.8 +++ b/contrib/wpa/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" "12 January 2010" "" "" +.TH "WPA_GUI" "8" "07 September 2010" "" "" .SH NAME wpa_gui \- WPA Graphical User Interface diff --git a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_passphrase.8 b/contrib/wpa/wpa_supplicant/doc/docbook/wpa_passphrase.8 index d1d1800..945c1c0 100644 --- a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_passphrase.8 +++ b/contrib/wpa/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" "12 January 2010" "" "" +.TH "WPA_PASSPHRASE" "8" "07 September 2010" "" "" .SH NAME wpa_passphrase \- Generate a WPA PSK from an ASCII passphrase for a SSID diff --git a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_priv.8 b/contrib/wpa/wpa_supplicant/doc/docbook/wpa_priv.8 index a5fa2ea..05ad983 100644 --- a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_priv.8 +++ b/contrib/wpa/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" "12 January 2010" "" "" +.TH "WPA_PRIV" "8" "07 September 2010" "" "" .SH NAME wpa_priv \- wpa_supplicant privilege separation helper diff --git a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.8 b/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.8 index 69b8d2b..3334d0c 100644 --- a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.8 +++ b/contrib/wpa/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" "12 January 2010" "" "" +.TH "WPA_SUPPLICANT" "8" "07 September 2010" "" "" .SH NAME wpa_supplicant \- Wi-Fi Protected Access client and IEEE 802.1X supplicant @@ -283,8 +283,8 @@ Increase debugging verbosity (\fB-dd\fR even more). .TP \fB-D driver\fR -Driver to use. (Per interface, see the available options -below.) +Driver to use (can be multiple drivers: nl80211,wext). +(Per interface, see the available options below.) .TP \fB-f output file\fR Log output to specified file instead of stdout. @@ -352,6 +352,18 @@ wpa_supplicant -c/etc/wpa_supplicant.conf -iwlan0 -d .fi .RE .PP +If the specific driver wrapper is not known beforehand, it is +possible to specify multiple comma separated driver wrappers on the command +line. \fBwpa_supplicant\fR will use the first driver +wrapper that is able to initialize the interface. +.sp +.RS + +.nf +wpa_supplicant -Dnl80211,wext -c/etc/wpa_supplicant.conf -iwlan0 +.fi +.RE +.PP \fBwpa_supplicant\fR can control multiple interfaces (radios) either by running one process for each interface separately or by running just one process and list of diff --git a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5 b/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5 index 796d891..6371965 100644 --- a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5 +++ b/contrib/wpa/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" "12 January 2010" "" "" +.TH "WPA_SUPPLICANT.CONF" "5" "07 September 2010" "" "" .SH NAME wpa_supplicant.conf \- configuration file for wpa_supplicant diff --git a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.sgml index 9798ced..3aae51b 100644 --- a/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.sgml +++ b/contrib/wpa/wpa_supplicant/doc/docbook/wpa_supplicant.sgml @@ -388,8 +388,8 @@ <varlistentry> <term>-D driver</term> <listitem> - <para>Driver to use. (Per interface, see the available options - below.)</para> + <para>Driver to use (can be multiple drivers: nl80211,wext). + (Per interface, see the available options below.)</para> </listitem> </varlistentry> @@ -509,6 +509,15 @@ wpa_supplicant -B -c/etc/wpa_supplicant.conf -iwlan0 wpa_supplicant -c/etc/wpa_supplicant.conf -iwlan0 -d </programlisting></blockquote> + <para>If the specific driver wrapper is not known beforehand, it is + possible to specify multiple comma separated driver wrappers on the command + line. <command>wpa_supplicant</command> will use the first driver + wrapper that is able to initialize the interface.</para> + +<blockquote><programlisting> +wpa_supplicant -Dnl80211,wext -c/etc/wpa_supplicant.conf -iwlan0 +</programlisting></blockquote> + <para><command>wpa_supplicant</command> can control multiple interfaces (radios) either by running one process for each interface separately or by running just one process and list of diff --git a/contrib/wpa/wpa_supplicant/doc/doxygen.fast b/contrib/wpa/wpa_supplicant/doc/doxygen.fast deleted file mode 100644 index c6012a9..0000000 --- a/contrib/wpa/wpa_supplicant/doc/doxygen.fast +++ /dev/null @@ -1,239 +0,0 @@ -# Doxyfile 1.4.4 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = wpa_supplicant -PROJECT_NUMBER = 0.6.x -OUTPUT_DIRECTORY = wpa_supplicant/doc -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -DISTRIBUTE_GROUP_DOC = NO -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -SUBGROUPING = YES -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = NO -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = YES -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = NO -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = YES -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = wpa_supplicant \ - src/common \ - src/crypto \ - src/drivers \ - src/eap_common \ - src/eapol_supp \ - src/eap_peer \ - src/l2_packet \ - src/rsn_supp \ - src/tls \ - src/utils \ - src/wps -FILE_PATTERNS = *.c *.h *.cpp *.m *.doxygen -RECURSIVE = YES -EXCLUDE = wpa_supplicant/wpa_gui -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = */.moc/* */.ui/* -EXAMPLE_PATH = -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = wpa_supplicant/doc -INPUT_FILTER = kerneldoc2doxygen.pl -FILTER_PATTERNS = -FILTER_SOURCE_FILES = YES -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -VERBATIM_HEADERS = NO -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 3 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = IEEE8021X_EAPOL CONFIG_CTRL_IFACE -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = NO -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = NO -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = YES -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = NO -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/contrib/wpa/wpa_supplicant/doc/doxygen.full b/contrib/wpa/wpa_supplicant/doc/doxygen.full deleted file mode 100644 index 6884c62..0000000 --- a/contrib/wpa/wpa_supplicant/doc/doxygen.full +++ /dev/null @@ -1,239 +0,0 @@ -# Doxyfile 1.4.4 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = wpa_supplicant -PROJECT_NUMBER = 0.6.x -OUTPUT_DIRECTORY = wpa_supplicant/doc -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -DISTRIBUTE_GROUP_DOC = NO -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -SUBGROUPING = YES -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = NO -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = YES -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = NO -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = YES -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = wpa_supplicant \ - src/common \ - src/crypto \ - src/drivers \ - src/eap_common \ - src/eapol_supp \ - src/eap_peer \ - src/l2_packet \ - src/rsn_supp \ - src/tls \ - src/utils \ - src/wps -FILE_PATTERNS = *.c *.h *.cpp *.m *.doxygen -RECURSIVE = YES -EXCLUDE = wpa_supplicant/wpa_gui -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = */.moc/* */.ui/* -EXAMPLE_PATH = -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = wpa_supplicant/doc -INPUT_FILTER = kerneldoc2doxygen.pl -FILTER_PATTERNS = -FILTER_SOURCE_FILES = YES -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -VERBATIM_HEADERS = NO -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 3 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = YES -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = IEEE8021X_EAPOL CONFIG_CTRL_IFACE -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = NO -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = YES -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = NO -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = YES diff --git a/contrib/wpa/wpa_supplicant/doc/driver_wrapper.doxygen b/contrib/wpa/wpa_supplicant/doc/driver_wrapper.doxygen deleted file mode 100644 index 28aea50..0000000 --- a/contrib/wpa/wpa_supplicant/doc/driver_wrapper.doxygen +++ /dev/null @@ -1,180 +0,0 @@ -/** -\page driver_wrapper Driver wrapper implementation (driver.h, drivers.c) - -All hardware and driver dependent functionality is in separate C files -that implement defined wrapper functions. Other parts -of the %wpa_supplicant are designed to be hardware, driver, and operating -system independent. - -Driver wrappers need to implement whatever calls are used in the -target operating system/driver for controlling wireless LAN -devices. As an example, in case of Linux, these are mostly some glue -code and ioctl() calls and netlink message parsing for Linux Wireless -Extensions (WE). Since features required for WPA were added only recently to -Linux Wireless Extensions (in version 18), some driver specific code is used -in number of driver interface implementations. These driver dependent parts -can be replaced with generic code in driver_wext.c once the target driver -includes full support for WE-18. After that, all Linux drivers, at -least in theory, could use the same driver wrapper code. - -A driver wrapper needs to implement some or all of the functions -defined in driver.h. These functions are registered by filling struct -wpa_driver_ops with function pointers. Hardware independent parts of -%wpa_supplicant will call these functions to control the driver/wlan -card. In addition, support for driver events is required. The event -callback function, wpa_supplicant_event(), and its parameters are -documented in driver.h. In addition, a pointer to the 'struct -wpa_driver_ops' needs to be registered in drivers.c file. - -When porting to other operating systems, the driver wrapper should be -modified to use the native interface of the target OS. It is possible -that some extra requirements for the interface between the driver -wrapper and generic %wpa_supplicant code are discovered during porting -to a new operating system. These will be addressed on case by case -basis by modifying the interface and updating the other driver -wrappers for this. The goal is to avoid changing this interface -without very good reasons in order to limit the number of changes -needed to other wrappers and hardware independent parts of -%wpa_supplicant. When changes are required, recommended way is to -make them in backwards compatible way that allows existing driver -interface implementations to be compiled without any modification. - -Generic Linux Wireless Extensions functions are implemented in -driver_wext.c. All Linux driver wrappers can use these when the kernel -driver supports the generic ioctl()s and wireless events. Driver -specific functions are implemented in separate C files, e.g., -driver_hostap.c. These files need to define struct wpa_driver_ops -entry that will be used in wpa_supplicant.c when calling driver -functions. struct wpa_driver_ops entries are registered in drivers.c. - -In general, it is likely to be useful to first take a look at couple -of driver interface examples before starting on implementing a new -one. driver_hostap.c and driver_wext.c include a complete -implementation for Linux drivers that use %wpa_supplicant-based control -of WPA IE and roaming. driver_ndis.c (with help from driver_ndis_.c) -is an example of a complete interface for Windows NDIS interface for -drivers that generate WPA IE themselves and decide when to roam. These -example implementations include full support for all security modes. - - -\section driver_req Driver requirements for WPA - -WPA introduces new requirements for the device driver. At least some -of these need to be implemented in order to provide enough support for -%wpa_supplicant. - -\subsection driver_tkip_ccmp TKIP/CCMP - -WPA requires that the pairwise cipher suite (encryption algorithm for -unicast data packets) is TKIP or CCMP. These are new encryption -protocols and thus, the driver will need to be modified to support -them. Depending on the used wlan hardware, some parts of these may be -implemented by the hardware/firmware. - -Specification for both TKIP and CCMP is available from IEEE (IEEE -802.11i amendment). Fully functional, hardware independent -implementation of both encryption protocols is also available in Host -AP driver (driver/modules/hostap_{tkip,ccmp}.c). In addition, Linux 2.6 -kernel tree has generic implementations for WEP, TKIP, and CCMP that can -be used in Linux drivers. - -The driver will also need to provide configuration mechanism to allow -user space programs to configure TKIP and CCMP. Linux Wireless Extensions -v18 added support for configuring these algorithms and -individual/non-default keys. If the target kernel does not include WE-18, -private ioctls can be used to provide similar functionality. - -\subsection driver_roaming Roaming control and scanning support - -%wpa_supplicant can optionally control AP selection based on the -information received from Beacon and/or Probe Response frames -(ap_scan=1 mode in configuration). This means that the driver should -support external control for scan process. In case of Linux, use of -new Wireless Extensions scan support (i.e., 'iwlist wlan0 scan') is -recommended. The current driver wrapper (driver_wext.c) uses this for -scan results. - -Scan results must also include the WPA information element. Support for -this was added in WE-18. With older versions, a custom event can be used -to provide the full WPA IE (including element id and length) as a hex -string that is included in the scan results. - -%wpa_supplicant needs to also be able to request the driver to -associate with a specific BSS. Current Host AP driver and matching -driver_hostap.c wrapper uses following sequence for this -request. Similar/identical mechanism should be usable also with other -drivers. - -- set WPA IE for AssocReq with private ioctl -- set SSID with SIOCSIWESSID -- set channel/frequency with SIOCSIWFREQ -- set BSSID with SIOCSIWAP - (this last ioctl will trigger the driver to request association) - -\subsection driver_wpa_ie WPA IE generation - -%wpa_supplicant selects which cipher suites and key management suites -are used. Based on this information, it generates a WPA IE. This is -provided to the driver interface in the associate call. This does not -match with Windows NDIS drivers which generate the WPA IE -themselves. - -%wpa_supplicant allows Windows NDIS-like behavior by providing the -selected cipher and key management suites in the associate call. If -the driver generates its own WPA IE and that differs from the one -generated by %wpa_supplicant, the driver has to inform %wpa_supplicant -about the used WPA IE (i.e., the one it used in (Re)Associate -Request). This notification is done using EVENT_ASSOCINFO event (see -driver.h). %wpa_supplicant is normally configured to use -ap_scan=2 mode with drivers that control WPA IE generation and roaming. - -\subsection driver_events Driver events - -%wpa_supplicant needs to receive event callbacks when certain events -occur (association, disassociation, Michael MIC failure, scan results -available, PMKSA caching candidate). These events and the callback -details are defined in driver.h (wpa_supplicant_event() function -and enum wpa_event_type). - -On Linux, association and disassociation can use existing Wireless -Extensions event that is reporting new AP with SIOCGIWAP -event. Similarly, completion of a scan can be reported with SIOCGIWSCAN -event. - -Michael MIC failure event was added in WE-18. Older versions of Wireless -Extensions will need to use a custom event. Host AP driver used a custom -event with following contents: MLME-MICHAELMICFAILURE.indication(keyid=# -broadcast/unicast addr=addr2). This is the recommended format until -the driver can be moved to use WE-18 mechanism. - -\subsection driver_wext_summary Summary of Linux Wireless Extensions use - -AP selection depends on ap_scan configuration: - -ap_scan=1: - -- %wpa_supplicant requests scan with SIOCSIWSCAN -- driver reports scan complete with wireless event SIOCGIWSCAN -- %wpa_supplicant reads scan results with SIOCGIWSCAN (multiple call if - a larget buffer is needed) -- %wpa_supplicant decides which AP to use based on scan results -- %wpa_supplicant configures driver to associate with the selected BSS - (SIOCSIWMODE, SIOCSIWGENIE, SIOCSIWAUTH, SIOCSIWFREQ, - SIOCSIWESSID, SIOCSIWAP) - -ap_scan=2: - -- %wpa_supplicant configures driver to associate with an SSID - (SIOCSIWMODE, SIOCSIWGENIE, SIOCSIWAUTH, SIOCSIWESSID) - - -After this, both modes use similar steps: - -- optionally (or required for drivers that generate WPA/RSN IE for - (Re)AssocReq), driver reports association parameters (AssocReq IEs) - with wireless event IWEVASSOCREQIE (and optionally IWEVASSOCRESPIE) -- driver reports association with wireless event SIOCGIWAP -- %wpa_supplicant takes care of EAPOL frame handling (validating - information from associnfo and if needed, from scan results if WPA/RSN - IE from the Beacon frame is not reported through associnfo) -*/ diff --git a/contrib/wpa/wpa_supplicant/doc/eap.doxygen b/contrib/wpa/wpa_supplicant/doc/eap.doxygen deleted file mode 100644 index 0646128..0000000 --- a/contrib/wpa/wpa_supplicant/doc/eap.doxygen +++ /dev/null @@ -1,87 +0,0 @@ -/** -\page eap_module EAP peer implementation - -Extensible Authentication Protocol (EAP) is an authentication framework -defined in RFC 3748. %wpa_supplicant uses a separate code module for EAP -peer implementation. This module was designed to use only a minimal set -of direct function calls (mainly, to debug/event functions) in order for -it to be usable in other programs. The design of the EAP -implementation is based loosely on RFC 4137. The state machine is -defined in this RFC and so is the interface between the peer state -machine and methods. As such, this RFC provides useful information for -understanding the EAP peer implementation in %wpa_supplicant. - -Some of the terminology used in EAP state machine is referring to -EAPOL (IEEE 802.1X), but there is no strict requirement on the lower -layer being IEEE 802.1X if EAP module is built for other programs than -%wpa_supplicant. These terms should be understood to refer to the -lower layer as defined in RFC 4137. - - -\section adding_eap_methods Adding EAP methods - -Each EAP method is implemented as a separate module, usually as one C -file named eap_<name of the method>.c, e.g., eap_md5.c. All EAP -methods use the same interface between the peer state machine and -method specific functions. This allows new EAP methods to be added -without modifying the core EAP state machine implementation. - -New EAP methods need to be registered by adding them into the build -(Makefile) and the EAP method registration list in the -eap_peer_register_methods() function of eap_methods.c. Each EAP -method should use a build-time configuration option, e.g., EAP_TLS, in -order to make it possible to select which of the methods are included -in the build. - -EAP methods must implement the interface defined in eap_i.h. struct -eap_method defines the needed function pointers that each EAP method -must provide. In addition, the EAP type and name are registered using -this structure. This interface is based on section 4.4 of RFC 4137. - -It is recommended that the EAP methods would use generic helper -functions, eap_msg_alloc() and eap_hdr_validate() when processing -messages. This allows code sharing and can avoid missing some of the -needed validation steps for received packets. In addition, these -functions make it easier to change between expanded and legacy EAP -header, if needed. - -When adding an EAP method that uses a vendor specific EAP type -(Expanded Type as defined in RFC 3748, Chapter 5.7), the new method -must be registered by passing vendor id instead of EAP_VENDOR_IETF to -eap_peer_method_alloc(). These methods must not try to emulate -expanded types by registering a legacy EAP method for type 254. See -eap_vendor_test.c for an example of an EAP method implementation that -is implemented as an expanded type. - - -\section used_eap_library Using EAP implementation as a library - -The Git repository has an eap_example directory that contains an -example showing how EAP peer and server code from %wpa_supplicant and -hostapd can be used as a library. The example program initializes both -an EAP server and an EAP peer entities and then runs through an -EAP-PEAP/MSCHAPv2 authentication. - -eap_example_peer.c shows the initialization and glue code needed to -control the EAP peer implementation. eap_example_server.c does the -same for EAP server. eap_example.c is an example that ties in both the -EAP server and client parts to allow an EAP authentication to be -shown. - -In this example, the EAP messages are passed between the server and -the peer are passed by direct function calls within the same process. -In practice, server and peer functionalities would likely reside in -separate devices and the EAP messages would be transmitted between the -devices based on an external protocol. For example, in IEEE 802.11 -uses IEEE 802.1X EAPOL state machines to control the transmission of -EAP messages and WiMax supports optional PMK EAP authentication -mechanism that transmits EAP messages as defined in IEEE 802.16e. - -The EAP library links in number of helper functions from src/utils and -src/crypto directories. Most of these are suitable as-is, but it may -be desirable to replace the debug output code in src/utils/wpa_debug.c -by dropping this file from the library and re-implementing the -functions there in a way that better fits in with the main -application. - -*/ diff --git a/contrib/wpa/wpa_supplicant/doc/kerneldoc2doxygen.pl b/contrib/wpa/wpa_supplicant/doc/kerneldoc2doxygen.pl deleted file mode 100755 index 61bc367..0000000 --- a/contrib/wpa/wpa_supplicant/doc/kerneldoc2doxygen.pl +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/perl -w -# -########################################################################## -# Convert kernel-doc style comments to Doxygen comments. -########################################################################## -# -# This script reads a C source file from stdin, and writes -# to stdout. Normal usage: -# -# $ mv file.c file.c.gtkdoc -# $ kerneldoc2doxygen.pl <file.c.gtkdoc >file.c -# -# Or to do the same thing with multiple files: -# $ perl -i.gtkdoc kerneldoc2doxygen.pl *.c *.h -# -# This script may also be suitable for use as a Doxygen input filter, -# but that has not been tested. -# -# Back up your source files before using this script!! -# -########################################################################## -# Copyright (C) 2003 Jonathan Foster <jon@jon-foster.co.uk> -# Copyright (C) 2005-2008 Jouni Malinen <j@w1.fi> -# (modified for kerneldoc format used in wpa_supplicant) -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# or look at http://www.gnu.org/licenses/gpl.html -########################################################################## - - -########################################################################## -# -# This function converts a single comment from gtk-doc to Doxygen format. -# The parameter does not include the opening or closing lines -# (i.e. given a comment like this: -# "/**\n" -# " * FunctionName:\n" -# " * @foo: This describes the foo parameter\n" -# " * @bar: This describes the bar parameter\n" -# " * @Returns: This describes the return value\n" -# " *\n" -# " * This describes the function.\n" -# " */\n" -# This function gets: -# " * FunctionName:\n" -# " * @foo: This describes the foo parameter\n" -# " * @bar: This describes the bar parameter\n" -# " * @Returns: This describes the return value\n" -# " *\n" -# " * This describes the function.\n" -# And it returns: -# " * This describes the function.\n" -# " *\n" -# " * @param foo This describes the foo parameter\n" -# " * @param bar This describes the bar parameter\n" -# " * @return This describes the return value\n" -# ) -# -sub fixcomment { - $t = $_[0]; - - # wpa_supplicant -> %wpa_supplicant except for struct wpa_supplicant - $t =~ s/struct wpa_supplicant/struct STRUCTwpa_supplicant/sg; - $t =~ s/ wpa_supplicant/ \%wpa_supplicant/sg; - $t =~ s/struct STRUCTwpa_supplicant/struct wpa_supplicant/sg; - - # " * func: foo" --> "\brief foo\n" - # " * struct bar: foo" --> "\brief foo\n" - # If this fails, not a kernel-doc comment ==> return unmodified. - ($t =~ s/^[\t ]*\*[\t ]*(struct )?([^ \t\n]*) - ([^\n]*)/\\brief $3\n/s) - or return $t; - - # " * Returns: foo" --> "\return foo" - $t =~ s/\n[\t ]*\*[\t ]*Returns:/\n\\return/sig; - - # " * @foo: bar" --> "\param foo bar" - # Handle two common typos: No ":", or "," instead of ":". - $t =~ s/\n[\t ]*\*[\t ]*\@([^ :,]*)[:,]?[\t ]*/\n\\param $1 /sg; - - return $t; -} - -########################################################################## -# Start of main code - -# Read entire stdin into memory - one multi-line string. -$_ = do { local $/; <> }; - -s{^/\*\n \*}{/\*\* \\file\n\\brief}; -s{ \* Copyright}{\\par Copyright\nCopyright}; - -# Fix any comments like "/*************" so they don't match. -# "/***" ===> "/* *" -s{/\*\*\*}{/\* \*}gs; - -# The main comment-detection code. -s{ - ( # $1 = Open comment - /\*\* # Open comment - (?!\*) # Do not match /*** (redundant due to fixup above). - [\t ]*\n? # If 1st line is whitespace, match the lot (including the newline). - ) - (.*?) # $2 = Body of comment (multi-line) - ( # $3 = Close comment - ( # If possible, match the whitespace before the close-comment - (?<=\n) # This part only matches after a newline - [\t ]* # Eat whitespace - )? - \*/ # Close comment - ) - } - { - $1 . fixcomment($2) . $3 - }gesx; -# ^^^^ Modes: g - Global, match all occurances. -# e - Evaluate the replacement as an expression. -# s - Single-line - allows the pattern to match across newlines. -# x - eXtended pattern, ignore embedded whitespace -# and allow comments. - -# Write results to stdout -print $_; - diff --git a/contrib/wpa/wpa_supplicant/doc/mainpage.doxygen b/contrib/wpa/wpa_supplicant/doc/mainpage.doxygen deleted file mode 100644 index ed63f27..0000000 --- a/contrib/wpa/wpa_supplicant/doc/mainpage.doxygen +++ /dev/null @@ -1,56 +0,0 @@ -/** -\mainpage Developers' documentation for wpa_supplicant - -%wpa_supplicant is a WPA Supplicant for Linux, BSD and Windows with -support for WPA and WPA2 (IEEE 802.11i / RSN). Supplicant is the IEEE -802.1X/WPA component that is used in the client stations. It -implements key negotiation with a WPA Authenticator and it can optionally -control roaming and IEEE 802.11 authentication/association of the wlan -driver. - -The goal of this documentation and comments in the source code is to -give enough information for other developers to understand how -%wpa_supplicant has been implemented, how it can be modified, how new -drivers can be supported, and how %wpa_supplicant can be ported to -other operating systems. If any information is missing, feel free to -contact Jouni Malinen <j@w1.fi> for more -information. Contributions as patch files are also very welcome at the -same address. Please note that %wpa_supplicant is licensed under dual -license, GPLv2 or BSD at user's choice. All contributions to -%wpa_supplicant are expected to use compatible licensing terms. - -The source code and read-only access to %wpa_supplicant Git repository -is available from the project home page at -http://w1.fi/wpa_supplicant/. This developers' documentation -is also available as a PDF file from -http://w1.fi/wpa_supplicant/wpa_supplicant-devel.pdf . - -The design goal for %wpa_supplicant was to use hardware, driver, and -OS independent, portable C code for all WPA functionality. The source -code is divided into separate C files as shown on the \ref -code_structure "code structure page". All hardware/driver specific -functionality is in separate files that implement a \ref -driver_wrapper "well-defined driver API". Information about porting -to different target boards and operating systems is available on -the \ref porting "porting page". - -EAPOL (IEEE 802.1X) state machines are implemented as a separate -module that interacts with \ref eap_module "EAP peer implementation". -In addition to programs aimed at normal production use, -%wpa_supplicant source tree includes number of \ref testing_tools -"testing and development tools" that make it easier to test the -programs without having to setup a full test setup with wireless -cards. These tools can also be used to implement automatic test -suites. - -%wpa_supplicant implements a -\ref ctrl_iface_page "control interface" that can be used by -external programs to control the operations of the %wpa_supplicant -daemon and to get status information and event notifications. There is -a small C library that provides helper functions to facilitate the use of the -control interface. This library can also be used with C++. - -\image html wpa_supplicant.png "wpa_supplicant modules" -\image latex wpa_supplicant.eps "wpa_supplicant modules" width=15cm - -*/ diff --git a/contrib/wpa/wpa_supplicant/doc/porting.doxygen b/contrib/wpa/wpa_supplicant/doc/porting.doxygen deleted file mode 100644 index 7ea6a34..0000000 --- a/contrib/wpa/wpa_supplicant/doc/porting.doxygen +++ /dev/null @@ -1,208 +0,0 @@ -/** -\page porting Porting to different target boards and operating systems - -%wpa_supplicant was designed to be easily portable to different -hardware (board, CPU) and software (OS, drivers) targets. It is -already used with number of operating systems and numerous wireless -card models and drivers. The main %wpa_supplicant repository includes -support for Linux, FreeBSD, and Windows. In addition, the code has been -ported to number of other operating systems like VxWorks, PalmOS, -Windows CE, and Windows Mobile. On the hardware -side, %wpa_supplicant is used on various systems: desktops, laptops, -PDAs, and embedded devices with CPUs including x86, PowerPC, -arm/xscale, and MIPS. Both big and little endian configurations are -supported. - - -\section ansi_c_extra Extra functions on top of ANSI C - -%wpa_supplicant is mostly using ANSI C functions that are available on -most targets. However, couple of additional functions that are common -on modern UNIX systems are used. Number of these are listed with -prototypes in common.h (the \verbatim #ifdef CONFIG_ANSI_C_EXTRA \endverbatim -block). These functions may need to be implemented or at least defined -as macros to native functions in the target OS or C library. - -Many of the common ANSI C functions are used through a wrapper -definitions in os.h to allow these to be replaced easily with a -platform specific version in case standard C libraries are not -available. In addition, os.h defines couple of common platform -specific functions that are implemented in os_unix.c for UNIX like -targets and in os_win32.c for Win32 API. If the target platform does -not support either of these examples, a new os_*.c file may need to be -added. - -Unless OS_NO_C_LIB_DEFINES is defined, the standard ANSI C and POSIX -functions are used by defining the os_*() wrappers to use them -directly in order to avoid extra cost in size and speed. If the target -platform needs different versions of the functions, os.h can be -modified to define the suitable macros or alternatively, -OS_NO_C_LIB_DEFINES may be defined for the build and the wrapper -functions can then be implemented in a new os_*.c wrapper file. - -common.h defines number of helper macros for handling integers of -different size and byte order. Suitable version of these definitions -may need to be added for the target platform. - - -\section configuration_backend Configuration backend - -%wpa_supplicant implements a configuration interface that allows the -backend to be easily replaced in order to read configuration data from -a suitable source depending on the target platform. config.c -implements the generic code that can be shared with all configuration -backends. Each backend is implemented in its own config_*.c file. - -The included config_file.c backend uses a text file for configuration -and config_winreg.c uses Windows registry. These files can be used as -an example for a new configuration backend if the target platform uses -different mechanism for configuration parameters. In addition, -config_none.c can be used as an empty starting point for building a -new configuration backend. - - -\section driver_iface_porting Driver interface - -Unless the target OS and driver is already supported, most porting -projects have to implement a driver wrapper. This may be done by -adding a new driver interface module or modifying an existing module -(driver_*.c) if the new target is similar to one of them. \ref -driver_wrapper "Driver wrapper implementation" describes the details -of the driver interface and discusses the tasks involved in porting -this part of %wpa_supplicant. - - -\section l2_packet_porting l2_packet (link layer access) - -%wpa_supplicant needs to have access to sending and receiving layer 2 -(link layer) packets with two Ethertypes: EAP-over-LAN (EAPOL) 0x888e -and RSN pre-authentication 0x88c7. l2_packet.h defines the interfaces -used for this in the core %wpa_supplicant implementation. - -If the target operating system supports a generic mechanism for link -layer access, that is likely the best mechanism for providing the -needed functionality for %wpa_supplicant. Linux packet socket is an -example of such a generic mechanism. If this is not available, a -separate interface may need to be implemented to the network stack or -driver. This is usually an intermediate or protocol driver that is -operating between the device driver and the OS network stack. If such -a mechanism is not feasible, the interface can also be implemented -directly in the device driver. - -The main %wpa_supplicant repository includes l2_packet implementations -for Linux using packet sockets (l2_packet_linux.c), more portable -version using libpcap/libdnet libraries (l2_packet_pcap.c; this -supports WinPcap, too), and FreeBSD specific version of libpcap -interface (l2_packet_freebsd.c). - -If the target operating system is supported by libpcap (receiving) and -libdnet (sending), l2_packet_pcap.c can likely be used with minimal or -no changes. If this is not a case or a proprietary interface for link -layer is required, a new l2_packet module may need to be -added. Alternatively, struct wpa_driver_ops::send_eapol() handler can -be used to override the l2_packet library if the link layer access is -integrated with the driver interface implementation. - - -\section eloop_porting Event loop - -%wpa_supplicant uses a single process/thread model and an event loop -to provide callbacks on events (registered timeout, received packet, -signal). eloop.h defines the event loop interface. eloop.c is an -implementation of such an event loop using select() and sockets. This -is suitable for most UNIX/POSIX systems. When porting to other -operating systems, it may be necessary to replace that implementation -with OS specific mechanisms that provide similar functionality. - - -\section ctrl_iface_porting Control interface - -%wpa_supplicant uses a \ref ctrl_iface_page "control interface" -to allow external processed -to get status information and to control the operations. Currently, -this is implemented with socket based communication; both UNIX domain -sockets and UDP sockets are supported. If the target OS does not -support sockets, this interface will likely need to be modified to use -another mechanism like message queues. The control interface is -optional component, so it is also possible to run %wpa_supplicant -without porting this part. - -The %wpa_supplicant side of the control interface is implemented in -ctrl_iface.c. Matching client side is implemented as a control -interface library in wpa_ctrl.c. - - -\section entry_point Program entry point - -%wpa_supplicant defines a set of functions that can be used to -initialize main supplicant processing. Each operating system has a -mechanism for starting new processing or threads. This is usually a -function with a specific set of arguments and calling convention. This -function is responsible on initializing %wpa_supplicant. - -main.c includes an entry point for UNIX-like operating system, i.e., -main() function that uses command line arguments for setting -parameters for %wpa_supplicant. When porting to other operating -systems, similar OS-specific entry point implementation is needed. It -can be implemented in a new file that is then linked with -%wpa_supplicant instead of main.o. main.c is also a good example on -how the initialization process should be done. - -The supplicant initialization functions are defined in -wpa_supplicant_i.h. In most cases, the entry point function should -start by fetching configuration parameters. After this, a global -%wpa_supplicant context is initialized with a call to -wpa_supplicant_init(). After this, existing network interfaces can be -added with wpa_supplicant_add_iface(). wpa_supplicant_run() is then -used to start the main event loop. Once this returns at program -termination time, wpa_supplicant_deinit() is used to release global -context data. - -wpa_supplicant_add_iface() and wpa_supplicant_remove_iface() can be -used dynamically to add and remove interfaces based on when -%wpa_supplicant processing is needed for them. This can be done, e.g., -when hotplug network adapters are being inserted and ejected. It is -also possible to do this when a network interface is being -enabled/disabled if it is desirable that %wpa_supplicant processing -for the interface is fully enabled/disabled at the same time. - - -\section simple_build Simple build example - -One way to start a porting project is to begin with a very simple -build of %wpa_supplicant with WPA-PSK support and once that is -building correctly, start adding features. - -Following command can be used to build very simple version of -%wpa_supplicant: - -\verbatim -cc -o wpa_supplicant config.c eloop.c common.c md5.c rc4.c sha1.c \ - config_none.c l2_packet_none.c tls_none.c wpa.c preauth.c \ - aes_wrap.c wpa_supplicant.c events.c main_none.c drivers.c -\endverbatim - -The end result is not really very useful since it uses empty functions -for configuration parsing and layer 2 packet access and does not -include a driver interface. However, this is a good starting point -since the build is complete in the sense that all functions are -present and this is easy to configure to a build system by just -including the listed C files. - -Once this version can be build successfully, the end result can be -made functional by adding a proper program entry point (main*.c), -driver interface (driver_*.c and matching CONFIG_DRIVER_* define for -registration in drivers.c), configuration parser/writer (config_*.c), -and layer 2 packet access implementation (l2_packet_*.c). After these -components have been added, the end result should be a working -WPA/WPA2-PSK enabled supplicant. - -After the basic functionality has been verified to work, more features -can be added by linking in more files and defining C pre-processor -defines. Currently, the best source of information for what options -are available and which files needs to be included is in the Makefile -used for building the supplicant with make. Similar configuration will -be needed for build systems that either use different type of make -tool or a GUI-based project configuration. - -*/ diff --git a/contrib/wpa/wpa_supplicant/doc/testing_tools.doxygen b/contrib/wpa/wpa_supplicant/doc/testing_tools.doxygen deleted file mode 100644 index a2ae0c2..0000000 --- a/contrib/wpa/wpa_supplicant/doc/testing_tools.doxygen +++ /dev/null @@ -1,295 +0,0 @@ -/** -\page testing_tools Testing and development tools - -[ \ref eapol_test "eapol_test" | -\ref preauth_test "preauth_test" | -\ref driver_test "driver_test" | -\ref unit_tests "Unit tests" ] - -%wpa_supplicant source tree includes number of testing and development -tools that make it easier to test the programs without having to setup -a full test setup with wireless cards. In addition, these tools can be -used to implement automatic tests suites. - -\section eapol_test eapol_test - EAP peer and RADIUS client testing - -eapol_test is a program that links together the same EAP peer -implementation that %wpa_supplicant is using and the RADIUS -authentication client code from hostapd. In addition, it has minimal -glue code to combine these two components in similar ways to IEEE -802.1X/EAPOL Authenticator state machines. In other words, it -integrates IEEE 802.1X Authenticator (normally, an access point) and -IEEE 802.1X Supplicant (normally, a wireless client) together to -generate a single program that can be used to test EAP methods without -having to setup an access point and a wireless client. - -The main uses for eapol_test are in interoperability testing of EAP -methods against RADIUS servers and in development testing for new EAP -methods. It can be easily used to automate EAP testing for -interoperability and regression since the program can be run from -shell scripts without require additional test components apart from a -RADIUS server. For example, the automated EAP tests described in -eap_testing.txt are implemented with eapol_test. Similarly, eapol_test -could be used to implement an automated regression test suite for a -RADIUS authentication server. - -eapol_test uses the same build time configuration file, .config, as -%wpa_supplicant. This file is used to select which EAP methods are -included in eapol_test. This program is not built with the default -Makefile target, so a separate make command needs to be used to -compile the tool: - -\verbatim -make eapol_test -\endverbatim - -The resulting eapol_test binary has following command like options: - -\verbatim -usage: -eapol_test [-nWS] -c<conf> [-a<AS IP>] [-p<AS port>] [-s<AS secret>] \ - [-r<count>] [-t<timeout>] [-C<Connect-Info>] \ - [-M<client MAC address>] -eapol_test scard -eapol_test sim <PIN> <num triplets> [debug] - -options: - -c<conf> = configuration file - -a<AS IP> = IP address of the authentication server, default 127.0.0.1 - -p<AS port> = UDP port of the authentication server, default 1812 - -s<AS secret> = shared secret with the authentication server, default 'radius' - -r<count> = number of re-authentications - -W = wait for a control interface monitor before starting - -S = save configuration after authentiation - -n = no MPPE keys expected - -t<timeout> = sets timeout in seconds (default: 30 s) - -C<Connect-Info> = RADIUS Connect-Info (default: CONNECT 11Mbps 802.11b) - -M<client MAC address> = Set own MAC address (Calling-Station-Id, - default: 02:00:00:00:00:01) -\endverbatim - - -As an example, -\verbatim -eapol_test -ctest.conf -a127.0.0.1 -p1812 -ssecret -r1 -\endverbatim -tries to complete EAP authentication based on the network -configuration from test.conf against the RADIUS server running on the -local host. A re-authentication is triggered to test fast -re-authentication. The configuration file uses the same format for -network blocks as %wpa_supplicant. - - -\section preauth_test preauth_test - WPA2 pre-authentication and EAP peer testing - -preauth_test is similar to eapol_test in the sense that in combines -EAP peer implementation with something else, in this case, with WPA2 -pre-authentication. This tool can be used to test pre-authentication -based on the code that %wpa_supplicant is using. As such, it tests -both the %wpa_supplicant implementation and the functionality of an -access point. - -preauth_test is built with: - -\verbatim -make preauth_test -\endverbatim - -and it uses following command line arguments: - -\verbatim -usage: preauth_test <conf> <target MAC address> <ifname> -\endverbatim - -For example, -\verbatim -preauth_test test.conf 02:11:22:33:44:55 eth0 -\endverbatim -would use network configuration from test.conf to try to complete -pre-authentication with AP using BSSID 02:11:22:33:44:55. The -pre-authentication packets would be sent using the eth0 interface. - - -\section driver_test driver_test - driver interface for testing wpa_supplicant - -%wpa_supplicant was designed to support number of different ways to -communicate with a network device driver. This design uses \ref -driver_wrapper "driver interface API" and number of driver interface -implementations. One of these is driver_test.c, i.e., a test driver -interface that is actually not using any drivers. Instead, it provides -a mechanism for running %wpa_supplicant without having to have a -device driver or wireless LAN hardware for that matter. - -driver_test can be used to talk directly with hostapd's driver_test -component to create a test setup where one or more clients and access -points can be tested within one test host and without having to have -multiple wireless cards. This makes it easier to test the core code in -%wpa_supplicant, and hostapd for that matter. Since driver_test uses -the same driver API than any other driver interface implementation, -the core code of %wpa_supplicant and hostapd can be tested with the -same coverage as one would get when using real wireless cards. The -only area that is not tested is the driver interface implementation -(driver_*.c). - -Having the possibility to use simulated network components makes it -much easier to do development testing while adding new features and to -reproduce reported bugs. As such, it is often easiest to just do most -of the development and bug fixing without using real hardware. Once -the driver_test setup has been used to implement a new feature or fix -a bug, the end result can be verified with wireless LAN cards. In many -cases, this may even be unnecessary, depending on what area the -feature/bug is relating to. Of course, changes to driver interfaces -will still require use of real hardware. - -Since multiple components can be run within a single host, testing of -complex network configuration, e.g., large number of clients -association with an access point, becomes quite easy. All the tests -can also be automated without having to resort to complex test setup -using remote access to multiple computers. - -driver_test can be included in the %wpa_supplicant build in the same -way as any other driver interface, i.e., by adding the following line -into .config: - -\verbatim -CONFIG_DRIVER_TEST=y -\endverbatim - -When running %wpa_supplicant, the test interface is selected by using -\a -Dtest command line argument. The interface name (\a -i argument) -can be selected arbitrarily, i.e., it does not need to match with any -existing network interface. The interface name is used to generate a -MAC address, so when using multiple clients, each should use a -different interface, e.g., \a sta1, \a sta2, and so on. - -%wpa_supplicant and hostapd are configured in the same way as they -would be for normal use. Following example shows a simple test setup -for WPA-PSK. - -hostapd is configured with following psk-test.conf configuration file: - -\verbatim -driver=test - -interface=ap1 -logger_stdout=-1 -logger_stdout_level=0 -debug=2 -dump_file=/tmp/hostapd.dump - -test_socket=/tmp/Test/ap1 - -ssid=jkm-test-psk - -wpa=1 -wpa_key_mgmt=WPA-PSK -wpa_pairwise=TKIP -wpa_passphrase=12345678 -\endverbatim - -and started with following command: - -\verbatim -hostapd psk-test.conf -\endverbatim - -%wpa_supplicant uses following configuration file: - -\verbatim -driver_param=test_socket=/tmp/Test/ap1 - -network={ - ssid="jkm-test-psk" - key_mgmt=WPA-PSK - psk="12345678" -} -\endverbatim - -%wpa_supplicant can then be started with following command: - -\verbatim -wpa_supplicant -Dtest -cpsk-test.conf -ista1 -ddK -\endverbatim - -If run without debug information, i.e., with - -\verbatim -wpa_supplicant -Dtest -cpsk-test.conf -ista1 -\endverbatim - -%wpa_supplicant completes authentication and prints following events: - -\verbatim -Trying to associate with 02:b8:a6:62:08:5a (SSID='jkm-test-psk' freq=0 MHz) -Associated with 02:b8:a6:62:08:5a -WPA: Key negotiation completed with 02:b8:a6:62:08:5a [PTK=TKIP GTK=TKIP] -CTRL-EVENT-CONNECTED - Connection to 02:b8:a6:62:08:5a completed (auth) -\endverbatim - -If test setup is using multiple clients, it is possible to run -multiple %wpa_supplicant processes. Alternatively, the support for -multiple interfaces can be used with just one process to save some -resources on single-CPU systems. For example, following command runs -two clients: - -\verbatim -./wpa_supplicant -Dtest -cpsk-test.conf -ista1 \ - -N -Dtest -cpsk-test.conf -ista2 -\endverbatim - -This shows following event log: - -\verbatim -Trying to associate with 02:b8:a6:62:08:5a (SSID='jkm-test-psk' freq=0 MHz) -Associated with 02:b8:a6:62:08:5a -WPA: Key negotiation completed with 02:b8:a6:62:08:5a [PTK=TKIP GTK=TKIP] -CTRL-EVENT-CONNECTED - Connection to 02:b8:a6:62:08:5a completed (auth) -Trying to associate with 02:b8:a6:62:08:5a (SSID='jkm-test-psk' freq=0 MHz) -Associated with 02:b8:a6:62:08:5a -WPA: Key negotiation completed with 02:b8:a6:62:08:5a [PTK=TKIP GTK=TKIP] -CTRL-EVENT-CONNECTED - Connection to 02:b8:a6:62:08:5a completed (auth) -\endverbatim - -hostapd shows this with following events: - -\verbatim -ap1: STA 02:b5:64:63:30:63 IEEE 802.11: associated -ap1: STA 02:b5:64:63:30:63 WPA: pairwise key handshake completed (WPA) -ap1: STA 02:b5:64:63:30:63 WPA: group key handshake completed (WPA) -ap1: STA 02:2a:c4:18:5b:f3 IEEE 802.11: associated -ap1: STA 02:2a:c4:18:5b:f3 WPA: pairwise key handshake completed (WPA) -ap1: STA 02:2a:c4:18:5b:f3 WPA: group key handshake completed (WPA) -\endverbatim - -By default, driver_param is simulating a driver that uses the WPA/RSN -IE generated by %wpa_supplicant. Driver-generated IE and AssocInfo -events can be tested by adding \a use_associnfo=1 to the \a driver_param -line in the configuration file. For example: - -\verbatim -driver_param=test_socket=/tmp/Test/ap1 use_associnfo=1 -\endverbatim - - -\section unit_tests Unit tests - -Number of the components (.c files) used in %wpa_supplicant define -their own unit tests for automated validation of the basic -functionality. Most of the tests for cryptographic algorithms are -using standard test vectors to validate functionality. These tests can -be useful especially when verifying port to a new CPU target. - -In most cases, these tests are implemented in the end of the same file -with functions that are normally commented out, but ca be included by -defining a pre-processor variable when building the file separately. -The details of the needed build options are included in the Makefile -(test-* targets). All automated unit tests can be run with - -\verbatim -make tests -\endverbatim - -This make target builds and runs each test and terminates with zero -exit code if all tests were completed successfully. - -*/ diff --git a/contrib/wpa/wpa_supplicant/doc/wpa_supplicant.fig b/contrib/wpa/wpa_supplicant/doc/wpa_supplicant.fig deleted file mode 100644 index 06abfb5..0000000 --- a/contrib/wpa/wpa_supplicant/doc/wpa_supplicant.fig +++ /dev/null @@ -1,247 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 1875 4050 2925 4350 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 1875 4050 2925 4050 2925 4350 1875 4350 1875 4050 -4 0 0 50 -1 0 12 0.0000 4 180 735 2025 4275 l2_packet\001 --6 -6 3450 1200 4275 1500 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3450 1200 4275 1200 4275 1500 3450 1500 3450 1200 -4 0 0 50 -1 0 12 0.0000 4 180 585 3600 1425 wpa_cli\001 --6 -6 4725 1200 5925 1500 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4725 1200 5925 1200 5925 1500 4725 1500 4725 1200 -4 0 0 50 -1 0 12 0.0000 4 135 1005 4800 1425 GUI frontend\001 --6 -6 6000 2700 7200 3225 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 6000 2700 7200 2700 7200 3225 6000 3225 6000 2700 -4 0 0 50 -1 0 12 0.0000 4 135 975 6075 2925 WPA/WPA2\001 -4 0 0 50 -1 0 12 0.0000 4 135 1065 6075 3150 state machine\001 --6 -6 6000 4950 7200 5475 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 6000 4950 7200 4950 7200 5475 6000 5475 6000 4950 -4 0 0 50 -1 0 12 0.0000 4 135 360 6075 5175 EAP\001 -4 0 0 50 -1 0 12 0.0000 4 135 1065 6075 5400 state machine\001 --6 -6 8700 3000 9375 3300 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 8700 3000 9375 3000 9375 3300 8700 3300 8700 3000 -4 0 0 50 -1 0 12 0.0000 4 150 480 8775 3225 crypto\001 --6 -6 4350 3900 5025 4425 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4350 3900 5025 3900 5025 4425 4350 4425 4350 3900 -4 0 0 50 -1 0 12 0.0000 4 105 420 4500 4125 event\001 -4 0 0 50 -1 0 12 0.0000 4 180 315 4500 4350 loop\001 --6 -6 4275 2550 5100 2850 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4275 2550 5100 2550 5100 2850 4275 2850 4275 2550 -4 0 0 50 -1 0 12 0.0000 4 135 450 4425 2775 ctrl i/f\001 --6 -6 6000 3900 7200 4425 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 6000 3900 7200 3900 7200 4425 6000 4425 6000 3900 -4 0 0 50 -1 0 12 0.0000 4 135 600 6075 4125 EAPOL\001 -4 0 0 50 -1 0 12 0.0000 4 135 1065 6075 4350 state machine\001 --6 -6 1800 6000 7800 8100 -6 1800 6000 7800 7200 -6 1800 6900 2700 7200 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 1800 6900 2700 6900 2700 7200 1800 7200 1800 6900 -4 0 0 50 -1 0 12 0.0000 4 105 375 1875 7125 wext\001 --6 -6 4725 6900 5625 7200 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4725 6900 5625 6900 5625 7200 4725 7200 4725 6900 -4 0 0 50 -1 0 12 0.0000 4 135 555 4800 7125 hermes\001 --6 -6 6675 6900 7800 7200 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 6675 6900 7800 6900 7800 7200 6675 7200 6675 6900 -4 0 0 50 -1 0 12 0.0000 4 180 930 6750 7125 ndiswrapper\001 --6 -6 5700 6900 6600 7200 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 5700 6900 6600 6900 6600 7200 5700 7200 5700 6900 -4 0 0 50 -1 0 12 0.0000 4 135 420 5775 7125 atmel\001 --6 -6 4275 6000 5100 6300 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4275 6000 5100 6000 5100 6300 4275 6300 4275 6000 -4 0 0 50 -1 0 12 0.0000 4 135 630 4350 6225 driver i/f\001 --6 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2775 6900 3675 6900 3675 7200 2775 7200 2775 6900 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3750 6900 4650 6900 4650 7200 3750 7200 3750 6900 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 - 2250 6900 2250 6600 7200 6600 7200 6900 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 3225 6900 3225 6600 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 4200 6900 4200 6600 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 5175 6900 5175 6600 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 6150 6900 6150 6600 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 4650 6600 4650 6300 -4 0 0 50 -1 0 12 0.0000 4 180 510 2850 7125 hostap\001 -4 0 0 50 -1 0 12 0.0000 4 135 600 3825 7125 madwifi\001 --6 -6 3525 7800 5775 8100 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3525 7800 5775 7800 5775 8100 3525 8100 3525 7800 -4 0 0 50 -1 0 12 0.0000 4 135 2145 3600 8025 kernel network device driver\001 --6 -2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 - 2250 7200 4200 7800 -2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 - 7200 7200 5100 7800 --6 -6 9600 3000 10275 3300 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 9600 3000 10275 3000 10275 3300 9600 3300 9600 3000 -4 0 0 50 -1 0 12 0.0000 4 135 315 9750 3225 TLS\001 --6 -6 8100 4425 10425 7350 -6 8175 4725 9225 5025 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 8175 4725 9225 4725 9225 5025 8175 5025 8175 4725 -4 0 0 50 -1 0 12 0.0000 4 135 735 8250 4950 EAP-TLS\001 --6 -6 9300 4725 10350 5025 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 9300 4725 10350 4725 10350 5025 9300 5025 9300 4725 -4 0 0 50 -1 0 12 0.0000 4 135 810 9375 4950 EAP-MD5\001 --6 -6 8175 5100 9225 5400 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 8175 5100 9225 5100 9225 5400 8175 5400 8175 5100 -4 0 0 50 -1 0 12 0.0000 4 135 885 8250 5325 EAP-PEAP\001 --6 -6 9300 5100 10350 5400 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 9300 5100 10350 5100 10350 5400 9300 5400 9300 5100 -4 0 0 50 -1 0 12 0.0000 4 135 840 9375 5325 EAP-TTLS\001 --6 -6 8175 5475 9225 5775 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 8175 5475 9225 5475 9225 5775 8175 5775 8175 5475 -4 0 0 50 -1 0 12 0.0000 4 135 780 8250 5700 EAP-GTC\001 --6 -6 9300 5475 10350 5775 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 9300 5475 10350 5475 10350 5775 9300 5775 9300 5475 -4 0 0 50 -1 0 12 0.0000 4 135 765 9375 5700 EAP-OTP\001 --6 -6 8175 5850 9225 6150 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 8175 5850 9225 5850 9225 6150 8175 6150 8175 5850 -4 0 0 50 -1 0 12 0.0000 4 135 750 8250 6075 EAP-SIM\001 --6 -6 9300 6225 10350 6525 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 9300 6225 10350 6225 10350 6525 9300 6525 9300 6225 -4 0 0 50 -1 0 12 0.0000 4 135 465 9375 6450 LEAP\001 --6 -6 8175 6225 9225 6525 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 8175 6225 9225 6225 9225 6525 8175 6525 8175 6225 -4 0 0 50 -1 0 12 0.0000 4 135 765 8250 6450 EAP-PSK\001 --6 -6 9300 5850 10350 6150 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 9300 5850 10350 5850 10350 6150 9300 6150 9300 5850 -4 0 0 50 -1 0 12 0.0000 4 135 825 9375 6075 EAP-AKA\001 --6 -6 8175 6975 9675 7275 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 8175 6975 9675 6975 9675 7275 8175 7275 8175 6975 -4 0 0 50 -1 0 12 0.0000 4 135 1365 8250 7200 EAP-MSCHAPv2\001 --6 -6 9300 6600 10350 6900 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 9300 6600 10350 6600 10350 6900 9300 6900 9300 6600 -4 0 0 50 -1 0 12 0.0000 4 135 870 9375 6825 EAP-FAST\001 --6 -6 8175 6600 9225 6900 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 8175 6600 9225 6600 9225 6900 8175 6900 8175 6600 -4 0 0 50 -1 0 12 0.0000 4 135 795 8250 6825 EAP-PAX\001 --6 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 8100 7350 10425 7350 10425 4425 8100 4425 8100 7350 -4 0 0 50 -1 0 12 0.0000 4 135 1050 8700 4650 EAP methods\001 --6 -6 2775 5025 4050 5325 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2775 5025 4050 5025 4050 5325 2775 5325 2775 5025 -4 0 0 50 -1 0 12 0.0000 4 135 990 2925 5250 driver events\001 --6 -6 2775 3150 4050 3450 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2775 3150 4050 3150 4050 3450 2775 3450 2775 3150 -4 0 0 50 -1 0 12 0.0000 4 180 990 2925 3375 configuration\001 --6 -2 1 1 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 - 1275 4200 1875 4200 -2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 - 4500 2550 3900 1500 -2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 - 4800 2550 5400 1500 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 2925 4200 4350 4200 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 5025 3900 6000 3000 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 5025 4200 6000 4200 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 4650 6000 4650 4425 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 6600 4425 6600 4950 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 6600 3225 6600 3900 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7200 5250 8100 5250 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 9075 4425 9075 3300 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7200 3000 8700 3150 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 4650 3900 4650 2850 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7200 4125 8700 3300 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 6000 4350 5025 6000 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 6000 3150 4875 6000 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 1500 2100 10800 2100 10800 7500 1500 7500 1500 2100 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 9900 4425 9900 3300 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 1 - 4350 3900 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 4350 3900 4050 3450 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 4350 4425 4050 5025 -4 0 0 50 -1 0 12 0.0000 4 135 915 375 3975 EAPOL and\001 -4 0 0 50 -1 0 12 0.0000 4 180 630 375 4200 pre-auth\001 -4 0 0 50 -1 0 12 0.0000 4 180 810 375 4425 ethertypes\001 -4 0 0 50 -1 0 12 0.0000 4 135 1050 375 4650 from/to kernel\001 -4 0 0 50 -1 0 12 0.0000 4 135 1920 3675 1875 frontend control interface\001 -4 0 0 50 -1 2 14 0.0000 4 210 1440 1637 2371 wpa_supplicant\001 diff --git a/contrib/wpa/wpa_supplicant/driver_i.h b/contrib/wpa/wpa_supplicant/driver_i.h new file mode 100644 index 0000000..a70aa6a --- /dev/null +++ b/contrib/wpa/wpa_supplicant/driver_i.h @@ -0,0 +1,494 @@ +/* + * wpa_supplicant - Internal driver interface wrappers + * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef DRIVER_I_H +#define DRIVER_I_H + +#include "drivers/driver.h" + +/* driver_ops */ +static inline void * wpa_drv_init(struct wpa_supplicant *wpa_s, + const char *ifname) +{ + if (wpa_s->driver->init2) + return wpa_s->driver->init2(wpa_s, ifname, + wpa_s->global_drv_priv); + if (wpa_s->driver->init) { + return wpa_s->driver->init(wpa_s, ifname); + } + return NULL; +} + +static inline void wpa_drv_deinit(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->deinit) + wpa_s->driver->deinit(wpa_s->drv_priv); +} + +static inline int wpa_drv_set_param(struct wpa_supplicant *wpa_s, + const char *param) +{ + if (wpa_s->driver->set_param) + return wpa_s->driver->set_param(wpa_s->drv_priv, param); + return 0; +} + +static inline int wpa_drv_set_countermeasures(struct wpa_supplicant *wpa_s, + int enabled) +{ + if (wpa_s->driver->set_countermeasures) { + return wpa_s->driver->set_countermeasures(wpa_s->drv_priv, + enabled); + } + return -1; +} + +static inline int wpa_drv_authenticate(struct wpa_supplicant *wpa_s, + struct wpa_driver_auth_params *params) +{ + if (wpa_s->driver->authenticate) + return wpa_s->driver->authenticate(wpa_s->drv_priv, params); + return -1; +} + +static inline int wpa_drv_associate(struct wpa_supplicant *wpa_s, + struct wpa_driver_associate_params *params) +{ + if (wpa_s->driver->associate) { + return wpa_s->driver->associate(wpa_s->drv_priv, params); + } + return -1; +} + +static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s, + struct wpa_driver_scan_params *params) +{ + if (wpa_s->driver->scan2) + return wpa_s->driver->scan2(wpa_s->drv_priv, params); + return -1; +} + +static inline struct wpa_scan_results * wpa_drv_get_scan_results2( + struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->get_scan_results2) + return wpa_s->driver->get_scan_results2(wpa_s->drv_priv); + return NULL; +} + +static inline int wpa_drv_get_bssid(struct wpa_supplicant *wpa_s, u8 *bssid) +{ + if (wpa_s->driver->get_bssid) { + return wpa_s->driver->get_bssid(wpa_s->drv_priv, bssid); + } + return -1; +} + +static inline int wpa_drv_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid) +{ + if (wpa_s->driver->get_ssid) { + return wpa_s->driver->get_ssid(wpa_s->drv_priv, ssid); + } + return -1; +} + +static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s, + enum wpa_alg alg, const u8 *addr, + int key_idx, int set_tx, + const u8 *seq, size_t seq_len, + const u8 *key, size_t key_len) +{ + if (wpa_s->driver->set_key) { + wpa_s->keys_cleared = 0; + return wpa_s->driver->set_key(wpa_s->ifname, wpa_s->drv_priv, + alg, addr, key_idx, set_tx, + seq, seq_len, key, key_len); + } + return -1; +} + +static inline int wpa_drv_deauthenticate(struct wpa_supplicant *wpa_s, + const u8 *addr, int reason_code) +{ + if (wpa_s->driver->deauthenticate) { + return wpa_s->driver->deauthenticate(wpa_s->drv_priv, addr, + reason_code); + } + return -1; +} + +static inline int wpa_drv_disassociate(struct wpa_supplicant *wpa_s, + const u8 *addr, int reason_code) +{ + if (wpa_s->driver->disassociate) { + return wpa_s->driver->disassociate(wpa_s->drv_priv, addr, + reason_code); + } + return -1; +} + +static inline int wpa_drv_add_pmkid(struct wpa_supplicant *wpa_s, + const u8 *bssid, const u8 *pmkid) +{ + if (wpa_s->driver->add_pmkid) { + return wpa_s->driver->add_pmkid(wpa_s->drv_priv, bssid, pmkid); + } + return -1; +} + +static inline int wpa_drv_remove_pmkid(struct wpa_supplicant *wpa_s, + const u8 *bssid, const u8 *pmkid) +{ + if (wpa_s->driver->remove_pmkid) { + return wpa_s->driver->remove_pmkid(wpa_s->drv_priv, bssid, + pmkid); + } + return -1; +} + +static inline int wpa_drv_flush_pmkid(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->flush_pmkid) { + return wpa_s->driver->flush_pmkid(wpa_s->drv_priv); + } + return -1; +} + +static inline int wpa_drv_get_capa(struct wpa_supplicant *wpa_s, + struct wpa_driver_capa *capa) +{ + if (wpa_s->driver->get_capa) { + return wpa_s->driver->get_capa(wpa_s->drv_priv, capa); + } + return -1; +} + +static inline void wpa_drv_poll(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->poll) { + wpa_s->driver->poll(wpa_s->drv_priv); + } +} + +static inline const char * wpa_drv_get_ifname(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->get_ifname) { + return wpa_s->driver->get_ifname(wpa_s->drv_priv); + } + return NULL; +} + +static inline const u8 * wpa_drv_get_mac_addr(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->get_mac_addr) { + return wpa_s->driver->get_mac_addr(wpa_s->drv_priv); + } + return NULL; +} + +static inline int wpa_drv_send_eapol(struct wpa_supplicant *wpa_s, + const u8 *dst, u16 proto, + const u8 *data, size_t data_len) +{ + if (wpa_s->driver->send_eapol) + return wpa_s->driver->send_eapol(wpa_s->drv_priv, dst, proto, + data, data_len); + return -1; +} + +static inline int wpa_drv_set_operstate(struct wpa_supplicant *wpa_s, + int state) +{ + if (wpa_s->driver->set_operstate) + return wpa_s->driver->set_operstate(wpa_s->drv_priv, state); + return 0; +} + +static inline int wpa_drv_mlme_setprotection(struct wpa_supplicant *wpa_s, + const u8 *addr, int protect_type, + int key_type) +{ + if (wpa_s->driver->mlme_setprotection) + return wpa_s->driver->mlme_setprotection(wpa_s->drv_priv, addr, + protect_type, + key_type); + return 0; +} + +static inline struct hostapd_hw_modes * +wpa_drv_get_hw_feature_data(struct wpa_supplicant *wpa_s, u16 *num_modes, + u16 *flags) +{ + if (wpa_s->driver->get_hw_feature_data) + return wpa_s->driver->get_hw_feature_data(wpa_s->drv_priv, + num_modes, flags); + return NULL; +} + +static inline int wpa_drv_set_channel(struct wpa_supplicant *wpa_s, + enum hostapd_hw_mode phymode, int chan, + int freq) +{ + if (wpa_s->driver->set_channel) + return wpa_s->driver->set_channel(wpa_s->drv_priv, phymode, + chan, freq); + return -1; +} + +static inline int wpa_drv_set_ssid(struct wpa_supplicant *wpa_s, + const u8 *ssid, size_t ssid_len) +{ + if (wpa_s->driver->set_ssid) { + return wpa_s->driver->set_ssid(wpa_s->drv_priv, ssid, + ssid_len); + } + return -1; +} + +static inline int wpa_drv_set_bssid(struct wpa_supplicant *wpa_s, + const u8 *bssid) +{ + if (wpa_s->driver->set_bssid) { + return wpa_s->driver->set_bssid(wpa_s->drv_priv, bssid); + } + return -1; +} + +static inline int wpa_drv_set_country(struct wpa_supplicant *wpa_s, + const char *alpha2) +{ + if (wpa_s->driver->set_country) + return wpa_s->driver->set_country(wpa_s->drv_priv, alpha2); + return 0; +} + +static inline int wpa_drv_send_mlme(struct wpa_supplicant *wpa_s, + const u8 *data, size_t data_len) +{ + if (wpa_s->driver->send_mlme) + return wpa_s->driver->send_mlme(wpa_s->drv_priv, + data, data_len); + return -1; +} + +static inline int wpa_drv_mlme_add_sta(struct wpa_supplicant *wpa_s, + const u8 *addr, const u8 *supp_rates, + size_t supp_rates_len) +{ + if (wpa_s->driver->mlme_add_sta) + return wpa_s->driver->mlme_add_sta(wpa_s->drv_priv, addr, + supp_rates, supp_rates_len); + return -1; +} + +static inline int wpa_drv_mlme_remove_sta(struct wpa_supplicant *wpa_s, + const u8 *addr) +{ + if (wpa_s->driver->mlme_remove_sta) + return wpa_s->driver->mlme_remove_sta(wpa_s->drv_priv, addr); + return -1; +} + +static inline int wpa_drv_update_ft_ies(struct wpa_supplicant *wpa_s, + const u8 *md, + const u8 *ies, size_t ies_len) +{ + if (wpa_s->driver->update_ft_ies) + return wpa_s->driver->update_ft_ies(wpa_s->drv_priv, md, + ies, ies_len); + return -1; +} + +static inline int wpa_drv_send_ft_action(struct wpa_supplicant *wpa_s, + u8 action, const u8 *target_ap, + const u8 *ies, size_t ies_len) +{ + if (wpa_s->driver->send_ft_action) + return wpa_s->driver->send_ft_action(wpa_s->drv_priv, action, + target_ap, ies, ies_len); + return -1; +} + +static inline int wpa_drv_set_beacon(struct wpa_supplicant *wpa_s, + const u8 *head, size_t head_len, + const u8 *tail, size_t tail_len, + int dtim_period, int beacon_int) +{ + if (wpa_s->driver->set_beacon) + return wpa_s->driver->set_beacon(wpa_s->drv_priv, head, + head_len, tail, tail_len, + dtim_period, beacon_int); + return -1; +} + +static inline int wpa_drv_sta_add(struct wpa_supplicant *wpa_s, + struct hostapd_sta_add_params *params) +{ + if (wpa_s->driver->sta_add) + return wpa_s->driver->sta_add(wpa_s->drv_priv, params); + return -1; +} + +static inline int wpa_drv_sta_remove(struct wpa_supplicant *wpa_s, + const u8 *addr) +{ + if (wpa_s->driver->sta_remove) + return wpa_s->driver->sta_remove(wpa_s->drv_priv, addr); + return -1; +} + +static inline int wpa_drv_hapd_send_eapol(struct wpa_supplicant *wpa_s, + const u8 *addr, const u8 *data, + size_t data_len, int encrypt, + const u8 *own_addr) +{ + if (wpa_s->driver->hapd_send_eapol) + return wpa_s->driver->hapd_send_eapol(wpa_s->drv_priv, addr, + data, data_len, encrypt, + own_addr); + return -1; +} + +static inline int wpa_drv_sta_set_flags(struct wpa_supplicant *wpa_s, + const u8 *addr, int total_flags, + int flags_or, int flags_and) +{ + if (wpa_s->driver->sta_set_flags) + return wpa_s->driver->sta_set_flags(wpa_s->drv_priv, addr, + total_flags, flags_or, + flags_and); + return -1; +} + +static inline int wpa_drv_set_supp_port(struct wpa_supplicant *wpa_s, + int authorized) +{ + if (wpa_s->driver->set_supp_port) { + return wpa_s->driver->set_supp_port(wpa_s->drv_priv, + authorized); + } + return 0; +} + +static inline int wpa_drv_send_action(struct wpa_supplicant *wpa_s, + unsigned int freq, + const u8 *dst, const u8 *src, + const u8 *bssid, + const u8 *data, size_t data_len) +{ + if (wpa_s->driver->send_action) + return wpa_s->driver->send_action(wpa_s->drv_priv, freq, + dst, src, bssid, data, + data_len); + return -1; +} + +static inline int wpa_drv_if_add(struct wpa_supplicant *wpa_s, + enum wpa_driver_if_type type, + const char *ifname, const u8 *addr, + void *bss_ctx, char *force_ifname, + u8 *if_addr) +{ + if (wpa_s->driver->if_add) + return wpa_s->driver->if_add(wpa_s->drv_priv, type, ifname, + addr, bss_ctx, NULL, force_ifname, + if_addr); + return -1; +} + +static inline int wpa_drv_if_remove(struct wpa_supplicant *wpa_s, + enum wpa_driver_if_type type, + const char *ifname) +{ + if (wpa_s->driver->if_remove) + return wpa_s->driver->if_remove(wpa_s->drv_priv, type, ifname); + return -1; +} + +static inline int wpa_drv_remain_on_channel(struct wpa_supplicant *wpa_s, + unsigned int freq, + unsigned int duration) +{ + if (wpa_s->driver->remain_on_channel) + return wpa_s->driver->remain_on_channel(wpa_s->drv_priv, freq, + duration); + return -1; +} + +static inline int wpa_drv_cancel_remain_on_channel( + struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->cancel_remain_on_channel) + return wpa_s->driver->cancel_remain_on_channel( + wpa_s->drv_priv); + return -1; +} + +static inline int wpa_drv_probe_req_report(struct wpa_supplicant *wpa_s, + int report) +{ + if (wpa_s->driver->probe_req_report) + return wpa_s->driver->probe_req_report(wpa_s->drv_priv, + report); + return -1; +} + +static inline int wpa_drv_disable_11b_rates(struct wpa_supplicant *wpa_s, + int disabled) +{ + if (wpa_s->driver->disable_11b_rates) + return wpa_s->driver->disable_11b_rates(wpa_s->drv_priv, + disabled); + return -1; +} + +static inline int wpa_drv_deinit_ap(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->deinit_ap) + return wpa_s->driver->deinit_ap(wpa_s->drv_priv); + return 0; +} + +static inline void wpa_drv_suspend(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->suspend) + wpa_s->driver->suspend(wpa_s->drv_priv); +} + +static inline void wpa_drv_resume(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->resume) + wpa_s->driver->resume(wpa_s->drv_priv); +} + +static inline int wpa_drv_signal_monitor(struct wpa_supplicant *wpa_s, + int threshold, int hysteresis) +{ + if (wpa_s->driver->signal_monitor) + return wpa_s->driver->signal_monitor(wpa_s->drv_priv, + threshold, hysteresis); + return -1; +} + +static inline int wpa_drv_set_ap_wps_ie(struct wpa_supplicant *wpa_s, + const struct wpabuf *beacon, + const struct wpabuf *proberesp) +{ + if (!wpa_s->driver->set_ap_wps_ie) + return -1; + return wpa_s->driver->set_ap_wps_ie(wpa_s->drv_priv, beacon, + proberesp); +} + +#endif /* DRIVER_I_H */ diff --git a/contrib/wpa/wpa_supplicant/eap_register.c b/contrib/wpa/wpa_supplicant/eap_register.c new file mode 100644 index 0000000..f668874 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/eap_register.c @@ -0,0 +1,235 @@ +/* + * EAP method registration + * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "eap_peer/eap_methods.h" +#include "eap_server/eap_methods.h" + + +/** + * eap_register_methods - Register statically linked EAP methods + * Returns: 0 on success, -1 or -2 on failure + * + * This function is called at program initialization to register all EAP + * methods that were linked in statically. + */ +int eap_register_methods(void) +{ + int ret = 0; + +#ifdef EAP_MD5 + if (ret == 0) + ret = eap_peer_md5_register(); +#endif /* EAP_MD5 */ + +#ifdef EAP_TLS + if (ret == 0) + ret = eap_peer_tls_register(); +#endif /* EAP_TLS */ + +#ifdef EAP_MSCHAPv2 + if (ret == 0) + ret = eap_peer_mschapv2_register(); +#endif /* EAP_MSCHAPv2 */ + +#ifdef EAP_PEAP + if (ret == 0) + ret = eap_peer_peap_register(); +#endif /* EAP_PEAP */ + +#ifdef EAP_TTLS + if (ret == 0) + ret = eap_peer_ttls_register(); +#endif /* EAP_TTLS */ + +#ifdef EAP_GTC + if (ret == 0) + ret = eap_peer_gtc_register(); +#endif /* EAP_GTC */ + +#ifdef EAP_OTP + if (ret == 0) + ret = eap_peer_otp_register(); +#endif /* EAP_OTP */ + +#ifdef EAP_SIM + if (ret == 0) + ret = eap_peer_sim_register(); +#endif /* EAP_SIM */ + +#ifdef EAP_LEAP + if (ret == 0) + ret = eap_peer_leap_register(); +#endif /* EAP_LEAP */ + +#ifdef EAP_PSK + if (ret == 0) + ret = eap_peer_psk_register(); +#endif /* EAP_PSK */ + +#ifdef EAP_AKA + if (ret == 0) + ret = eap_peer_aka_register(); +#endif /* EAP_AKA */ + +#ifdef EAP_AKA_PRIME + if (ret == 0) + ret = eap_peer_aka_prime_register(); +#endif /* EAP_AKA_PRIME */ + +#ifdef EAP_FAST + if (ret == 0) + ret = eap_peer_fast_register(); +#endif /* EAP_FAST */ + +#ifdef EAP_PAX + if (ret == 0) + ret = eap_peer_pax_register(); +#endif /* EAP_PAX */ + +#ifdef EAP_SAKE + if (ret == 0) + ret = eap_peer_sake_register(); +#endif /* EAP_SAKE */ + +#ifdef EAP_GPSK + if (ret == 0) + ret = eap_peer_gpsk_register(); +#endif /* EAP_GPSK */ + +#ifdef EAP_WSC + if (ret == 0) + ret = eap_peer_wsc_register(); +#endif /* EAP_WSC */ + +#ifdef EAP_IKEV2 + if (ret == 0) + ret = eap_peer_ikev2_register(); +#endif /* EAP_IKEV2 */ + +#ifdef EAP_VENDOR_TEST + if (ret == 0) + ret = eap_peer_vendor_test_register(); +#endif /* EAP_VENDOR_TEST */ + +#ifdef EAP_TNC + if (ret == 0) + ret = eap_peer_tnc_register(); +#endif /* EAP_TNC */ + + +#ifdef EAP_SERVER_IDENTITY + if (ret == 0) + ret = eap_server_identity_register(); +#endif /* EAP_SERVER_IDENTITY */ + +#ifdef EAP_SERVER_MD5 + if (ret == 0) + ret = eap_server_md5_register(); +#endif /* EAP_SERVER_MD5 */ + +#ifdef EAP_SERVER_TLS + if (ret == 0) + ret = eap_server_tls_register(); +#endif /* EAP_SERVER_TLS */ + +#ifdef EAP_SERVER_MSCHAPV2 + if (ret == 0) + ret = eap_server_mschapv2_register(); +#endif /* EAP_SERVER_MSCHAPV2 */ + +#ifdef EAP_SERVER_PEAP + if (ret == 0) + ret = eap_server_peap_register(); +#endif /* EAP_SERVER_PEAP */ + +#ifdef EAP_SERVER_TLV + if (ret == 0) + ret = eap_server_tlv_register(); +#endif /* EAP_SERVER_TLV */ + +#ifdef EAP_SERVER_GTC + if (ret == 0) + ret = eap_server_gtc_register(); +#endif /* EAP_SERVER_GTC */ + +#ifdef EAP_SERVER_TTLS + if (ret == 0) + ret = eap_server_ttls_register(); +#endif /* EAP_SERVER_TTLS */ + +#ifdef EAP_SERVER_SIM + if (ret == 0) + ret = eap_server_sim_register(); +#endif /* EAP_SERVER_SIM */ + +#ifdef EAP_SERVER_AKA + if (ret == 0) + ret = eap_server_aka_register(); +#endif /* EAP_SERVER_AKA */ + +#ifdef EAP_SERVER_AKA_PRIME + if (ret == 0) + ret = eap_server_aka_prime_register(); +#endif /* EAP_SERVER_AKA_PRIME */ + +#ifdef EAP_SERVER_PAX + if (ret == 0) + ret = eap_server_pax_register(); +#endif /* EAP_SERVER_PAX */ + +#ifdef EAP_SERVER_PSK + if (ret == 0) + ret = eap_server_psk_register(); +#endif /* EAP_SERVER_PSK */ + +#ifdef EAP_SERVER_SAKE + if (ret == 0) + ret = eap_server_sake_register(); +#endif /* EAP_SERVER_SAKE */ + +#ifdef EAP_SERVER_GPSK + if (ret == 0) + ret = eap_server_gpsk_register(); +#endif /* EAP_SERVER_GPSK */ + +#ifdef EAP_SERVER_VENDOR_TEST + if (ret == 0) + ret = eap_server_vendor_test_register(); +#endif /* EAP_SERVER_VENDOR_TEST */ + +#ifdef EAP_SERVER_FAST + if (ret == 0) + ret = eap_server_fast_register(); +#endif /* EAP_SERVER_FAST */ + +#ifdef EAP_SERVER_WSC + if (ret == 0) + ret = eap_server_wsc_register(); +#endif /* EAP_SERVER_WSC */ + +#ifdef EAP_SERVER_IKEV2 + if (ret == 0) + ret = eap_server_ikev2_register(); +#endif /* EAP_SERVER_IKEV2 */ + +#ifdef EAP_SERVER_TNC + if (ret == 0) + ret = eap_server_tnc_register(); +#endif /* EAP_SERVER_TNC */ + + return ret; +} diff --git a/contrib/wpa/wpa_supplicant/eapol_test.c b/contrib/wpa/wpa_supplicant/eapol_test.c index b188549..4eed854 100644 --- a/contrib/wpa/wpa_supplicant/eapol_test.c +++ b/contrib/wpa/wpa_supplicant/eapol_test.c @@ -23,7 +23,7 @@ #include "eapol_supp/eapol_supp_sm.h" #include "eap_peer/eap.h" #include "eloop.h" -#include "wpa.h" +#include "rsn_supp/wpa.h" #include "eap_peer/eap_i.h" #include "wpa_supplicant_i.h" #include "radius/radius.h" @@ -35,7 +35,7 @@ extern int wpa_debug_level; extern int wpa_debug_show_keys; -struct wpa_driver_ops *wpa_supplicant_drivers[] = { NULL }; +struct wpa_driver_ops *wpa_drivers[] = { NULL }; struct extra_radius_attr { @@ -263,7 +263,8 @@ static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e, /* State attribute must be copied if and only if this packet is * Access-Request reply to the previous Access-Challenge */ - if (e->last_recv_radius && e->last_recv_radius->hdr->code == + if (e->last_recv_radius && + radius_msg_get_hdr(e->last_recv_radius)->code == RADIUS_CODE_ACCESS_CHALLENGE) { int res = radius_msg_copy_attr(msg, e->last_recv_radius, RADIUS_ATTR_STATE); @@ -283,7 +284,6 @@ static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e, fail: radius_msg_free(msg); - os_free(msg); } @@ -404,11 +404,9 @@ static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, ctx->eapol_send = eapol_test_eapol_send; ctx->set_config_blob = eapol_test_set_config_blob; ctx->get_config_blob = eapol_test_get_config_blob; -#ifdef EAP_TLS_OPENSSL ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; -#endif /* EAP_TLS_OPENSSL */ wpa_s->eapol = eapol_sm_init(ctx); if (wpa_s->eapol == NULL) { @@ -442,10 +440,8 @@ static void test_eapol_clean(struct eapol_test_data *e, radius_client_deinit(e->radius); os_free(e->last_eap_radius); - if (e->last_recv_radius) { - radius_msg_free(e->last_recv_radius); - os_free(e->last_recv_radius); - } + radius_msg_free(e->last_recv_radius); + e->last_recv_radius = NULL; os_free(e->eap_identity); e->eap_identity = NULL; eapol_sm_deinit(wpa_s->eapol); @@ -669,10 +665,11 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, void *data) { struct eapol_test_data *e = data; + struct radius_hdr *hdr = radius_msg_get_hdr(msg); /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be * present when packet contains an EAP-Message attribute */ - if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT && + if (hdr->code == RADIUS_CODE_ACCESS_REJECT && radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL, 0) < 0 && radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) { @@ -686,9 +683,9 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, return RADIUS_RX_UNKNOWN; } - if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT && - msg->hdr->code != RADIUS_CODE_ACCESS_REJECT && - msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { + if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && + hdr->code != RADIUS_CODE_ACCESS_REJECT && + hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { printf("Unknown RADIUS message code\n"); return RADIUS_RX_UNKNOWN; } @@ -696,14 +693,10 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, e->radius_identifier = -1; wpa_printf(MSG_DEBUG, "RADIUS packet matching with station"); - if (e->last_recv_radius) { - radius_msg_free(e->last_recv_radius); - os_free(e->last_recv_radius); - } - + radius_msg_free(e->last_recv_radius); e->last_recv_radius = msg; - switch (msg->hdr->code) { + switch (hdr->code) { case RADIUS_CODE_ACCESS_ACCEPT: e->radius_access_accept_received = 1; ieee802_1x_get_keys(e, msg, req, shared_secret, @@ -716,9 +709,9 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, ieee802_1x_decapsulate_radius(e); - if ((msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT && + if ((hdr->code == RADIUS_CODE_ACCESS_ACCEPT && e->eapol_test_num_reauths < 0) || - msg->hdr->code == RADIUS_CODE_ACCESS_REJECT) { + hdr->code == RADIUS_CODE_ACCESS_REJECT) { eloop_terminate(); } @@ -956,10 +949,9 @@ static int scard_get_triplets(int argc, char *argv[]) } -static void eapol_test_terminate(int sig, void *eloop_ctx, - void *signal_ctx) +static void eapol_test_terminate(int sig, void *signal_ctx) { - struct wpa_supplicant *wpa_s = eloop_ctx; + struct wpa_supplicant *wpa_s = signal_ctx; wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig); eloop_terminate(); } @@ -1130,12 +1122,12 @@ int main(int argc, char *argv[]) return -1; } - if (eap_peer_register_methods()) { + if (eap_register_methods()) { wpa_printf(MSG_ERROR, "Failed to register EAP methods"); return -1; } - if (eloop_init(&wpa_s)) { + if (eloop_init()) { wpa_printf(MSG_ERROR, "Failed to initialize event loop"); return -1; } @@ -1178,8 +1170,8 @@ int main(int argc, char *argv[]) eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test, NULL); eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL); - eloop_register_signal_terminate(eapol_test_terminate, NULL); - eloop_register_signal_reconfig(eapol_test_terminate, NULL); + eloop_register_signal_terminate(eapol_test_terminate, &wpa_s); + eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s); eloop_run(); eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL); diff --git a/contrib/wpa/wpa_supplicant/events.c b/contrib/wpa/wpa_supplicant/events.c index 63002a4..85dcfb2 100644 --- a/contrib/wpa/wpa_supplicant/events.c +++ b/contrib/wpa/wpa_supplicant/events.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - Driver event processing - * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> + * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,27 +16,35 @@ #include "common.h" #include "eapol_supp/eapol_supp_sm.h" -#include "wpa.h" +#include "rsn_supp/wpa.h" #include "eloop.h" -#include "drivers/driver.h" #include "config.h" #include "l2_packet/l2_packet.h" #include "wpa_supplicant_i.h" +#include "driver_i.h" #include "pcsc_funcs.h" -#include "preauth.h" -#include "pmksa_cache.h" -#include "wpa_ctrl.h" +#include "rsn_supp/preauth.h" +#include "rsn_supp/pmksa_cache.h" +#include "common/wpa_ctrl.h" #include "eap_peer/eap.h" -#include "ctrl_iface_dbus.h" -#include "ieee802_11_defs.h" +#include "ap/hostapd.h" +#include "notify.h" +#include "common/ieee802_11_defs.h" #include "blacklist.h" #include "wpas_glue.h" #include "wps_supplicant.h" +#include "ibss_rsn.h" +#include "sme.h" +#include "bgscan.h" +#include "ap.h" +#include "bss.h" +#include "mlme.h" +#include "scan.h" static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s) { - struct wpa_ssid *ssid; + struct wpa_ssid *ssid, *old_ssid; if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid) return 0; @@ -72,9 +80,12 @@ static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s) if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) eapol_sm_invalidate_cached_session(wpa_s->eapol); + old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = ssid; wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); wpa_supplicant_initiate_eapol(wpa_s); + if (old_ssid != wpa_s->current_ssid) + wpas_notify_network_changed(wpa_s); return 0; } @@ -96,9 +107,16 @@ static void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) { + int bssid_changed; + 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); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); + wpa_s->current_bss = NULL; + if (bssid_changed) + wpas_notify_bssid_changed(wpa_s); + eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) @@ -322,7 +340,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, #ifdef CONFIG_IEEE80211W if (!(ie.capabilities & WPA_CAPABILITY_MFPC) && - ssid->ieee80211w == IEEE80211W_REQUIRED) { + ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) { wpa_printf(MSG_DEBUG, " skip RSN IE - no mgmt frame " "protection"); break; @@ -376,8 +394,23 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, } -static struct wpa_scan_res * +static int freq_allowed(int *freqs, int freq) +{ + int i; + + if (freqs == NULL) + return 1; + + for (i = 0; freqs[i]; i++) + if (freqs[i] == freq) + return 1; + return 0; +} + + +static struct wpa_bss * wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s, + struct wpa_scan_results *scan_res, struct wpa_ssid *group, struct wpa_ssid **selected_ssid) { @@ -388,10 +421,10 @@ wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s, const u8 *ie; wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP"); - for (i = 0; i < wpa_s->scan_res->num; i++) { + for (i = 0; i < scan_res->num; i++) { const u8 *ssid_; u8 wpa_ie_len, rsn_ie_len, ssid_len; - bss = wpa_s->scan_res->res[i]; + bss = scan_res->res[i]; ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); ssid_ = ie ? ie + 2 : (u8 *) ""; @@ -458,12 +491,18 @@ wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s, if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss)) continue; + if (!freq_allowed(ssid->freq_list, bss->freq)) { + wpa_printf(MSG_DEBUG, " skip - " + "frequency not allowed"); + continue; + } + wpa_printf(MSG_DEBUG, " selected WPA AP " MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len)); *selected_ssid = ssid; - return bss; + return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len); } } @@ -471,8 +510,9 @@ wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s, } -static struct wpa_scan_res * +static struct wpa_bss * wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s, + struct wpa_scan_results *scan_res, struct wpa_ssid *group, struct wpa_ssid **selected_ssid) { @@ -483,10 +523,10 @@ wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s, const u8 *ie; wpa_printf(MSG_DEBUG, "Try to find non-WPA AP"); - for (i = 0; i < wpa_s->scan_res->num; i++) { + for (i = 0; i < scan_res->num; i++) { const u8 *ssid_; u8 wpa_ie_len, rsn_ie_len, ssid_len; - bss = wpa_s->scan_res->res[i]; + bss = scan_res->res[i]; ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); ssid_ = ie ? ie + 2 : (u8 *) ""; @@ -584,12 +624,18 @@ wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s, continue; } + if (!freq_allowed(ssid->freq_list, bss->freq)) { + wpa_printf(MSG_DEBUG, " skip - " + "frequency not allowed"); + continue; + } + wpa_printf(MSG_DEBUG, " selected non-WPA AP " MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len)); *selected_ssid = ssid; - return bss; + return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len); } } @@ -597,70 +643,43 @@ wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s, } -static struct wpa_scan_res * -wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group, +static struct wpa_bss * +wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, + struct wpa_scan_results *scan_res, + struct wpa_ssid *group, struct wpa_ssid **selected_ssid) { - struct wpa_scan_res *selected; + struct wpa_bss *selected; wpa_printf(MSG_DEBUG, "Selecting BSS from priority group %d", group->priority); /* First, try to find WPA-enabled AP */ - selected = wpa_supplicant_select_bss_wpa(wpa_s, group, selected_ssid); + selected = wpa_supplicant_select_bss_wpa(wpa_s, scan_res, group, + selected_ssid); if (selected) return selected; /* If no WPA-enabled AP found, try to find non-WPA AP, if configuration * allows this. */ - return wpa_supplicant_select_bss_non_wpa(wpa_s, group, selected_ssid); + return wpa_supplicant_select_bss_non_wpa(wpa_s, scan_res, group, + selected_ssid); } -static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s) +static struct wpa_bss * +wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s, + struct wpa_scan_results *scan_res, + struct wpa_ssid **selected_ssid) { - int prio, timeout; - struct wpa_scan_res *selected = NULL; - struct wpa_ssid *ssid = NULL; - - wpa_supplicant_notify_scanning(wpa_s, 0); - - if (wpa_supplicant_get_scan_results(wpa_s) < 0) { - if (wpa_s->conf->ap_scan == 2) - return; - wpa_printf(MSG_DEBUG, "Failed to get scan results - try " - "scanning again"); - timeout = 1; - goto req_scan; - } - - /* - * Don't post the results if this was the initial cached - * and there were no results. - */ - if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 && - wpa_s->scan_res->num == 0) { - wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are " - "empty - not posting"); - } else { - wpa_printf(MSG_DEBUG, "New scan results available"); - wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS); - wpa_supplicant_dbus_notify_scan_results(wpa_s); - wpas_wps_notify_scan_results(wpa_s); - } - - if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s))) - return; - - if (wpa_s->disconnected) { - wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); - return; - } + struct wpa_bss *selected = NULL; + int prio; while (selected == NULL) { for (prio = 0; prio < wpa_s->conf->num_prio; prio++) { selected = wpa_supplicant_select_bss( - wpa_s, wpa_s->conf->pssid[prio], &ssid); + wpa_s, scan_res, wpa_s->conf->pssid[prio], + selected_ssid); if (selected) break; } @@ -670,55 +689,18 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s) "and try again"); wpa_blacklist_clear(wpa_s); wpa_s->blacklist_cleared++; - } else if (selected == NULL) { + } else if (selected == NULL) break; - } } - if (selected) { - if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) { - wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP - "PBC session overlap"); - timeout = 10; - goto req_scan; - } - - /* Do not trigger new association unless the BSSID has changed - * or if reassociation is requested. If we are in process of - * associating with the selected BSSID, do not trigger new - * attempt. */ - if (wpa_s->reassociate || - (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 && - (wpa_s->wpa_state != WPA_ASSOCIATING || - os_memcmp(selected->bssid, wpa_s->pending_bssid, - ETH_ALEN) != 0))) { - if (wpa_supplicant_scard_init(wpa_s, ssid)) { - wpa_supplicant_req_scan(wpa_s, 10, 0); - return; - } - wpa_supplicant_associate(wpa_s, selected, ssid); - } else { - wpa_printf(MSG_DEBUG, "Already associated with the " - "selected AP."); - } - rsn_preauth_scan_results(wpa_s->wpa, wpa_s->scan_res); - } else { - wpa_printf(MSG_DEBUG, "No suitable AP found."); - timeout = 5; - goto req_scan; - } + return selected; +} - return; -req_scan: - if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) { - /* - * Quick recovery if the initial scan results were not - * complete when fetched before the first scan request. - */ - wpa_s->scan_res_tried++; - timeout = 0; - } else if (!wpa_supplicant_enabled_networks(wpa_s->conf)) { +static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s, + int timeout_sec, int timeout_usec) +{ + if (!wpa_supplicant_enabled_networks(wpa_s->conf)) { /* * No networks are enabled; short-circuit request so * we don't wait timeout seconds before transitioning @@ -727,16 +709,264 @@ req_scan: wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); return; } - wpa_supplicant_req_scan(wpa_s, timeout, 0); + wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec); +} + + +void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, + struct wpa_bss *selected, + struct wpa_ssid *ssid) +{ + if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) { + wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP + "PBC session overlap"); + wpa_supplicant_req_new_scan(wpa_s, 10, 0); + return; + } + + /* + * Do not trigger new association unless the BSSID has changed or if + * reassociation is requested. If we are in process of associating with + * the selected BSSID, do not trigger new attempt. + */ + if (wpa_s->reassociate || + (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 && + (wpa_s->wpa_state != WPA_ASSOCIATING || + os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) != + 0))) { + if (wpa_supplicant_scard_init(wpa_s, ssid)) { + wpa_supplicant_req_new_scan(wpa_s, 10, 0); + return; + } + wpa_supplicant_associate(wpa_s, selected, ssid); + } else { + wpa_printf(MSG_DEBUG, "Already associated with the selected " + "AP"); + } +} + + +static struct wpa_ssid * +wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s) +{ + int prio; + struct wpa_ssid *ssid; + + for (prio = 0; prio < wpa_s->conf->num_prio; prio++) { + for (ssid = wpa_s->conf->pssid[prio]; ssid; ssid = ssid->pnext) + { + if (ssid->disabled) + continue; + if (ssid->mode == IEEE80211_MODE_IBSS || + ssid->mode == IEEE80211_MODE_AP) + return ssid; + } + } + return NULL; +} + + +/* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based + * on BSS added and BSS changed events */ +static void wpa_supplicant_rsn_preauth_scan_results( + struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res) +{ + int i; + + if (rsn_preauth_scan_results(wpa_s->wpa) < 0) + return; + + for (i = scan_res->num - 1; i >= 0; i--) { + const u8 *ssid, *rsn; + struct wpa_scan_res *r; + + r = scan_res->res[i]; + + ssid = wpa_scan_get_ie(r, WLAN_EID_SSID); + if (ssid == NULL) + continue; + + rsn = wpa_scan_get_ie(r, WLAN_EID_RSN); + if (rsn == NULL) + continue; + + rsn_preauth_scan_result(wpa_s->wpa, r->bssid, ssid, rsn); + } + +} + + +static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, + struct wpa_bss *selected, + struct wpa_ssid *ssid, + struct wpa_scan_results *scan_res) +{ + size_t i; + struct wpa_scan_res *current_bss = NULL; + int min_diff; + + if (wpa_s->reassociate) + return 1; /* explicit request to reassociate */ + if (wpa_s->wpa_state < WPA_ASSOCIATED) + return 1; /* we are not associated; continue */ + if (wpa_s->current_ssid == NULL) + return 1; /* unknown current SSID */ + if (wpa_s->current_ssid != ssid) + return 1; /* different network block */ + + for (i = 0; i < scan_res->num; i++) { + struct wpa_scan_res *res = scan_res->res[i]; + const u8 *ie; + if (os_memcmp(res->bssid, wpa_s->bssid, ETH_ALEN) != 0) + continue; + + ie = wpa_scan_get_ie(res, WLAN_EID_SSID); + if (ie == NULL) + continue; + if (ie[1] != wpa_s->current_ssid->ssid_len || + os_memcmp(ie + 2, wpa_s->current_ssid->ssid, ie[1]) != 0) + continue; + current_bss = res; + break; + } + + if (!current_bss) + return 1; /* current BSS not seen in scan results */ + + wpa_printf(MSG_DEBUG, "Considering within-ESS reassociation"); + wpa_printf(MSG_DEBUG, "Current BSS: " MACSTR " level=%d", + MAC2STR(current_bss->bssid), current_bss->level); + wpa_printf(MSG_DEBUG, "Selected BSS: " MACSTR " level=%d", + MAC2STR(selected->bssid), selected->level); + + if (wpa_s->current_ssid->bssid_set && + os_memcmp(selected->bssid, wpa_s->current_ssid->bssid, ETH_ALEN) == + 0) { + wpa_printf(MSG_DEBUG, "Allow reassociation - selected BSS has " + "preferred BSSID"); + return 1; + } + + min_diff = 2; + if (current_bss->level < 0) { + if (current_bss->level < -85) + min_diff = 1; + else if (current_bss->level < -80) + min_diff = 2; + else if (current_bss->level < -75) + min_diff = 3; + else if (current_bss->level < -70) + min_diff = 4; + else + min_diff = 5; + } + if (abs(current_bss->level - selected->level) < min_diff) { + wpa_printf(MSG_DEBUG, "Skip roam - too small difference in " + "signal level"); + return 0; + } + + return 1; +} + + +static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ + struct wpa_bss *selected; + struct wpa_ssid *ssid = NULL; + struct wpa_scan_results *scan_res; + int ap = 0; + +#ifdef CONFIG_AP + if (wpa_s->ap_iface) + ap = 1; +#endif /* CONFIG_AP */ + + wpa_supplicant_notify_scanning(wpa_s, 0); + + scan_res = wpa_supplicant_get_scan_results(wpa_s, + data ? &data->scan_info : + NULL, 1); + if (scan_res == NULL) { + if (wpa_s->conf->ap_scan == 2 || ap) + return; + wpa_printf(MSG_DEBUG, "Failed to get scan results - try " + "scanning again"); + wpa_supplicant_req_new_scan(wpa_s, 1, 0); + return; + } + + if (wpa_s->scan_res_handler) { + wpa_s->scan_res_handler(wpa_s, scan_res); + wpa_s->scan_res_handler = NULL; + wpa_scan_results_free(scan_res); + return; + } + + if (ap) { + wpa_printf(MSG_DEBUG, "Ignore scan results in AP mode"); + wpa_scan_results_free(scan_res); + return; + } + + wpa_printf(MSG_DEBUG, "New scan results available"); + wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS); + wpas_notify_scan_results(wpa_s); + + wpas_notify_scan_done(wpa_s, 1); + + if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s))) { + wpa_scan_results_free(scan_res); + return; + } + + if (wpa_s->disconnected) { + wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); + wpa_scan_results_free(scan_res); + return; + } + + if (bgscan_notify_scan(wpa_s) == 1) { + wpa_scan_results_free(scan_res); + return; + } + + wpa_supplicant_rsn_preauth_scan_results(wpa_s, scan_res); + + selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid); + + if (selected) { + int skip; + skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid, + scan_res); + wpa_scan_results_free(scan_res); + if (skip) + return; + wpa_supplicant_connect(wpa_s, selected, ssid); + } else { + wpa_scan_results_free(scan_res); + wpa_printf(MSG_DEBUG, "No suitable network found"); + ssid = wpa_supplicant_pick_new_network(wpa_s); + if (ssid) { + wpa_printf(MSG_DEBUG, "Setup a new network"); + wpa_supplicant_associate(wpa_s, NULL, ssid); + } else { + int timeout_sec = 5; + int timeout_usec = 0; + wpa_supplicant_req_new_scan(wpa_s, timeout_sec, + timeout_usec); + } + } } #endif /* CONFIG_NO_SCAN_PROCESSING */ -static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, - union wpa_event_data *data) +static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) { int l, len, found = 0, wpa_found, rsn_found; - u8 *p; + const u8 *p; wpa_printf(MSG_DEBUG, "Association info event"); if (data->assoc_info.req_ies) @@ -749,6 +979,8 @@ static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, wpa_hexdump(MSG_DEBUG, "beacon_ies", data->assoc_info.beacon_ies, data->assoc_info.beacon_ies_len); + if (data->assoc_info.freq) + wpa_printf(MSG_DEBUG, "freq=%u MHz", data->assoc_info.freq); p = data->assoc_info.req_ies; l = data->assoc_info.req_ies_len; @@ -776,6 +1008,50 @@ static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, if (!found && data->assoc_info.req_ies) wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); +#ifdef CONFIG_IEEE80211R +#ifdef CONFIG_SME + if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) { + u8 bssid[ETH_ALEN]; + if (wpa_drv_get_bssid(wpa_s, bssid) < 0 || + wpa_ft_validate_reassoc_resp(wpa_s->wpa, + data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len, + bssid) < 0) { + wpa_printf(MSG_DEBUG, "FT: Validation of " + "Reassociation Response failed"); + wpa_supplicant_deauthenticate( + wpa_s, WLAN_REASON_INVALID_IE); + return -1; + } + } + + p = data->assoc_info.resp_ies; + l = data->assoc_info.resp_ies_len; + + /* Go through the IEs and make a copy of the MDIE, if present. */ + while (p && l >= 2) { + len = p[1] + 2; + if (len > l) { + wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info", + p, l); + break; + } + if (p[0] == WLAN_EID_MOBILITY_DOMAIN && + p[1] >= MOBILITY_DOMAIN_ID_LEN) { + wpa_s->sme.ft_used = 1; + os_memcpy(wpa_s->sme.mobility_domain, p + 2, + MOBILITY_DOMAIN_ID_LEN); + break; + } + l -= len; + p += len; + } +#endif /* CONFIG_SME */ + + wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len); +#endif /* CONFIG_IEEE80211R */ + /* WPA/RSN IE from Beacon/ProbeResp */ p = data->assoc_info.beacon_ies; l = data->assoc_info.beacon_ies_len; @@ -813,6 +1089,10 @@ static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0); if (wpa_found || rsn_found) wpa_s->ap_ies_from_associnfo = 1; + + wpa_s->assoc_freq = data->assoc_info.freq; + + return 0; } @@ -820,21 +1100,38 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { u8 bssid[ETH_ALEN]; - int ft_completed = wpa_ft_is_completed(wpa_s->wpa); + int ft_completed; + int bssid_changed; + struct wpa_driver_capa capa; + +#ifdef CONFIG_AP + if (wpa_s->ap_iface) { + hostapd_notif_assoc(wpa_s->ap_iface->bss[0], + data->assoc_info.addr, + data->assoc_info.req_ies, + data->assoc_info.req_ies_len); + return; + } +#endif /* CONFIG_AP */ - if (data) - wpa_supplicant_event_associnfo(wpa_s, data); + ft_completed = wpa_ft_is_completed(wpa_s->wpa); + if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0) + return; wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED); - if (wpa_s->use_client_mlme) + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) os_memcpy(bssid, wpa_s->bssid, ETH_ALEN); - if (wpa_s->use_client_mlme || + if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) || (wpa_drv_get_bssid(wpa_s, bssid) >= 0 && os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)) { wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID=" MACSTR, MAC2STR(bssid)); + bssid_changed = os_memcmp(wpa_s->bssid, bssid, ETH_ALEN); os_memcpy(wpa_s->bssid, bssid, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); + if (bssid_changed) + wpas_notify_bssid_changed(wpa_s); + if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) { wpa_clear_keys(wpa_s, bssid); } @@ -843,8 +1140,24 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, wpa_s, WLAN_REASON_DEAUTH_LEAVING); return; } + if (wpa_s->current_ssid) { + struct wpa_bss *bss = NULL; + struct wpa_ssid *ssid = wpa_s->current_ssid; + if (ssid->ssid_len > 0) + bss = wpa_bss_get(wpa_s, bssid, + ssid->ssid, ssid->ssid_len); + if (!bss) + bss = wpa_bss_get_bssid(wpa_s, bssid); + if (bss) + wpa_s->current_bss = bss; + } } +#ifdef CONFIG_SME + os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN); + wpa_s->sme.prev_bssid_set = 1; +#endif /* CONFIG_SME */ + wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid)); if (wpa_s->current_ssid) { /* When using scanning (ap_scan=1), SIM PC/SC interface can be @@ -854,7 +1167,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid); } wpa_sm_notify_assoc(wpa_s->wpa, bssid); - l2_packet_notify_auth_start(wpa_s->l2); + if (wpa_s->l2) + l2_packet_notify_auth_start(wpa_s->l2); /* * Set portEnabled first to FALSE in order to get EAP state machine out @@ -874,7 +1188,9 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); wpa_s->eapol_received = 0; if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || - wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { + wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE || + (wpa_s->current_ssid && + wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS)) { wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); } else if (!ft_completed) { @@ -883,7 +1199,7 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, } wpa_supplicant_cancel_scan(wpa_s); - if (wpa_s->driver_4way_handshake && + if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { /* * We are done; the driver will take care of RSN 4-way @@ -913,12 +1229,47 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, wpabuf_free(wpa_s->pending_eapol_rx); wpa_s->pending_eapol_rx = NULL; } + +#ifdef CONFIG_BGSCAN + if (wpa_s->current_ssid != wpa_s->bgscan_ssid) { + bgscan_deinit(wpa_s); + if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan) { + if (bgscan_init(wpa_s, wpa_s->current_ssid)) { + wpa_printf(MSG_DEBUG, "Failed to initialize " + "bgscan"); + /* + * Live without bgscan; it is only used as a + * roaming optimization, so the initial + * connection is not affected. + */ + } else + wpa_s->bgscan_ssid = wpa_s->current_ssid; + } else + wpa_s->bgscan_ssid = NULL; + } +#endif /* CONFIG_BGSCAN */ + + if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || + wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) && + wpa_s->current_ssid && wpa_drv_get_capa(wpa_s, &capa) == 0 && + capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE) { + /* Set static WEP keys again */ + wpa_set_wep_keys(wpa_s, wpa_s->current_ssid); + } } -static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) +static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, + u16 reason_code) { const u8 *bssid; +#ifdef CONFIG_SME + int authenticating; + u8 prev_pending_bssid[ETH_ALEN]; + + authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; + os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); +#endif /* CONFIG_SME */ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* @@ -943,13 +1294,31 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); - wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " - "remove keys"); + wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR + " reason=%d", + MAC2STR(bssid), reason_code); if (wpa_supplicant_dynamic_keys(wpa_s)) { + wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); + bgscan_deinit(wpa_s); + wpa_s->bgscan_ssid = NULL; +#ifdef CONFIG_SME + if (authenticating && + (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) { + /* + * mac80211-workaround to force deauth on failed auth cmd, + * requires us to remain in authenticating state to allow the + * second authentication attempt to be continued properly. + */ + wpa_printf(MSG_DEBUG, "SME: Allow pending authentication to " + "proceed after disconnection event"); + wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); + os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN); + } +#endif /* CONFIG_SME */ } @@ -1072,6 +1441,7 @@ static int any_interfaces(struct wpa_supplicant *head) } #endif /* CONFIG_TERMINATE_ONLASTIF */ + static void wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s, union wpa_event_data *data) @@ -1129,31 +1499,128 @@ wpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s, if (wpa_ft_process_response(wpa_s->wpa, data->ft_ies.ies, data->ft_ies.ies_len, data->ft_ies.ft_action, - data->ft_ies.target_ap) < 0) { + data->ft_ies.target_ap, + data->ft_ies.ric_ies, + data->ft_ies.ric_ies_len) < 0) { /* TODO: prevent MLME/driver from trying to associate? */ } } #endif /* CONFIG_IEEE80211R */ -void wpa_supplicant_event(void *ctx, wpa_event_type event, +#ifdef CONFIG_IBSS_RSN +static void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ + if (data == NULL) + return; + ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer); +} +#endif /* CONFIG_IBSS_RSN */ + + +#ifdef CONFIG_IEEE80211R +static void ft_rx_action(struct wpa_supplicant *wpa_s, const u8 *data, + size_t len) +{ + const u8 *sta_addr, *target_ap_addr; + u16 status; + + wpa_hexdump(MSG_MSGDUMP, "FT: RX Action", data, len); + if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) + return; /* only SME case supported for now */ + if (len < 1 + 2 * ETH_ALEN + 2) + return; + if (data[0] != 2) + return; /* Only FT Action Response is supported for now */ + sta_addr = data + 1; + target_ap_addr = data + 1 + ETH_ALEN; + status = WPA_GET_LE16(data + 1 + 2 * ETH_ALEN); + wpa_printf(MSG_DEBUG, "FT: Received FT Action Response: STA " MACSTR + " TargetAP " MACSTR " status %u", + MAC2STR(sta_addr), MAC2STR(target_ap_addr), status); + + if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) { + wpa_printf(MSG_DEBUG, "FT: Foreign STA Address " MACSTR + " in FT Action Response", MAC2STR(sta_addr)); + return; + } + + if (status) { + wpa_printf(MSG_DEBUG, "FT: FT Action Response indicates " + "failure (status code %d)", status); + /* TODO: report error to FT code(?) */ + return; + } + + if (wpa_ft_process_response(wpa_s->wpa, data + 1 + 2 * ETH_ALEN + 2, + len - (1 + 2 * ETH_ALEN + 2), 1, + target_ap_addr, NULL, 0) < 0) + return; + +#ifdef CONFIG_SME + { + struct wpa_bss *bss; + bss = wpa_bss_get_bssid(wpa_s, target_ap_addr); + if (bss) + wpa_s->sme.freq = bss->freq; + wpa_s->sme.auth_alg = WPA_AUTH_ALG_FT; + sme_associate(wpa_s, WPAS_MODE_INFRA, target_ap_addr, + WLAN_AUTH_FT); + } +#endif /* CONFIG_SME */ +} +#endif /* CONFIG_IEEE80211R */ + + +void wpa_supplicant_event(void *ctx, enum wpa_event_type event, union wpa_event_data *data) { struct wpa_supplicant *wpa_s = ctx; + u16 reason_code = 0; switch (event) { + case EVENT_AUTH: + sme_event_auth(wpa_s, data); + break; case EVENT_ASSOC: wpa_supplicant_event_assoc(wpa_s, data); break; case EVENT_DISASSOC: - wpa_supplicant_event_disassoc(wpa_s); + wpa_printf(MSG_DEBUG, "Disassociation notification"); +#ifdef CONFIG_AP + if (wpa_s->ap_iface && data && data->disassoc_info.addr) { + hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], + data->disassoc_info.addr); + break; + } +#endif /* CONFIG_AP */ + if (data) + reason_code = data->deauth_info.reason_code; + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) + sme_event_disassoc(wpa_s, data); + /* fall through */ + case EVENT_DEAUTH: + if (event == EVENT_DEAUTH) { + wpa_printf(MSG_DEBUG, "Deauthentication notification"); + if (data) + reason_code = data->deauth_info.reason_code; + } +#ifdef CONFIG_AP + if (wpa_s->ap_iface && data && data->deauth_info.addr) { + hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], + data->deauth_info.addr); + break; + } +#endif /* CONFIG_AP */ + wpa_supplicant_event_disassoc(wpa_s, reason_code); break; case EVENT_MICHAEL_MIC_FAILURE: wpa_supplicant_event_michael_mic_failure(wpa_s, data); break; #ifndef CONFIG_NO_SCAN_PROCESSING case EVENT_SCAN_RESULTS: - wpa_supplicant_event_scan_results(wpa_s); + wpa_supplicant_event_scan_results(wpa_s, data); break; #endif /* CONFIG_NO_SCAN_PROCESSING */ case EVENT_ASSOCINFO: @@ -1175,6 +1642,86 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event, wpa_supplicant_event_ft_response(wpa_s, data); break; #endif /* CONFIG_IEEE80211R */ +#ifdef CONFIG_IBSS_RSN + case EVENT_IBSS_RSN_START: + wpa_supplicant_event_ibss_rsn_start(wpa_s, data); + break; +#endif /* CONFIG_IBSS_RSN */ + case EVENT_ASSOC_REJECT: + sme_event_assoc_reject(wpa_s, data); + break; + case EVENT_AUTH_TIMED_OUT: + sme_event_auth_timed_out(wpa_s, data); + break; + case EVENT_ASSOC_TIMED_OUT: + sme_event_assoc_timed_out(wpa_s, data); + break; +#ifdef CONFIG_AP + case EVENT_TX_STATUS: + if (wpa_s->ap_iface == NULL) + break; + switch (data->tx_status.type) { + case WLAN_FC_TYPE_MGMT: + ap_mgmt_tx_cb(wpa_s, data->tx_status.data, + data->tx_status.data_len, + data->tx_status.stype, + data->tx_status.ack); + break; + case WLAN_FC_TYPE_DATA: + ap_tx_status(wpa_s, data->tx_status.dst, + data->tx_status.data, + data->tx_status.data_len, + data->tx_status.ack); + break; + } + break; + case EVENT_RX_FROM_UNKNOWN: + if (wpa_s->ap_iface == NULL) + break; + ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.frame, + data->rx_from_unknown.len); + break; + case EVENT_RX_MGMT: + if (wpa_s->ap_iface == NULL) + break; + ap_mgmt_rx(wpa_s, &data->rx_mgmt); + break; +#endif /* CONFIG_AP */ + case EVENT_RX_ACTION: + wpa_printf(MSG_DEBUG, "Received Action frame: SA=" MACSTR + " Category=%u DataLen=%d freq=%d MHz", + MAC2STR(data->rx_action.sa), + data->rx_action.category, (int) data->rx_action.len, + data->rx_action.freq); +#ifdef CONFIG_IEEE80211R + if (data->rx_action.category == WLAN_ACTION_FT) { + ft_rx_action(wpa_s, data->rx_action.data, + data->rx_action.len); + break; + } +#endif /* CONFIG_IEEE80211R */ + break; +#ifdef CONFIG_CLIENT_MLME + case EVENT_MLME_RX: { + struct ieee80211_rx_status rx_status; + os_memset(&rx_status, 0, sizeof(rx_status)); + rx_status.freq = data->mlme_rx.freq; + rx_status.channel = data->mlme_rx.channel; + rx_status.ssi = data->mlme_rx.ssi; + ieee80211_sta_rx(wpa_s, data->mlme_rx.buf, data->mlme_rx.len, + &rx_status); + break; + } +#endif /* CONFIG_CLIENT_MLME */ + case EVENT_EAPOL_RX: + wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src, + data->eapol_rx.data, + data->eapol_rx.data_len); + break; + case EVENT_SIGNAL_CHANGE: + bgscan_notify_signal_change( + wpa_s, data->signal_change.above_threshold); + break; default: wpa_printf(MSG_INFO, "Unknown event %d", event); break; diff --git a/contrib/wpa/wpa_supplicant/examples/60_wpa_supplicant b/contrib/wpa/wpa_supplicant/examples/60_wpa_supplicant new file mode 100755 index 0000000..39bd8e0 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/examples/60_wpa_supplicant @@ -0,0 +1,19 @@ +#!/bin/sh + +# /etc/pm/sleep.d/60_wpa_supplicant +# Action script to notify wpa_supplicant of pm-action events. + +PATH=/sbin:/usr/sbin:/bin:/usr/bin + +WPACLI=wpa_cli + +case "$1" in + suspend|hibernate) + $WPACLI suspend + ;; + resume|thaw) + $WPACLI resume + ;; +esac + +exit 0 diff --git a/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new-getall.py b/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new-getall.py new file mode 100755 index 0000000..03da187 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new-getall.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +import dbus +import sys, os +import time +import gobject + +def main(): + bus = dbus.SystemBus() + wpas_obj = bus.get_object("fi.w1.wpa_supplicant1", + "/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 + + if len(sys.argv) != 2: + os._exit(1) + + ifname = sys.argv[1] + + wpas = dbus.Interface(wpas_obj, "fi.w1.wpa_supplicant1") + path = wpas.GetInterface(ifname) + 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 + + 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 + + res = if_obj.Get("fi.w1.wpa_supplicant1.Interface", 'BSSs', + dbus_interface=dbus.PROPERTIES_IFACE) + if len(res) > 0: + 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 + + res = if_obj.Get("fi.w1.wpa_supplicant1.Interface", 'Networks', + dbus_interface=dbus.PROPERTIES_IFACE) + if len(res) > 0: + 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 + +if __name__ == "__main__": + main() + diff --git a/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new-signals.py b/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new-signals.py new file mode 100755 index 0000000..b040e0a --- /dev/null +++ b/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new-signals.py @@ -0,0 +1,203 @@ +#!/usr/bin/python + +import dbus +import sys, os +import time +import gobject +from dbus.mainloop.glib import DBusGMainLoop + +WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1" +WPAS_DBUS_INTERFACE = "fi.w1.wpa_supplicant1" +WPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1" + +WPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface" +WPAS_DBUS_INTERFACES_OPATH = "/fi/w1/wpa_supplicant1/Interfaces" +WPAS_DBUS_BSS_INTERFACE = "fi.w1.wpa_supplicant1.BSS" +WPAS_DBUS_NETWORK_INTERFACE = "fi.w1.wpa_supplicant1.Network" + +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 list_interfaces(wpas_obj): + ifaces = wpas_obj.Get(WPAS_DBUS_INTERFACE, 'Interfaces', + dbus_interface=dbus.PROPERTIES_IFACE) + for path in ifaces: + 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 + +def interfaceAdded(interface, properties): + print "InterfaceAdded(%s): Ifname=%s" % (interface, properties['Ifname']) + +def interfaceRemoved(interface): + print "InterfaceRemoved(%s)" % (interface) + +def propertiesChanged(properties): + for i in properties: + print "PropertiesChanged: %s=%s" % (i, properties[i]) + +def showBss(bss): + net_obj = bus.get_object(WPAS_DBUS_SERVICE, bss) + net = dbus.Interface(net_obj, WPAS_DBUS_BSS_INTERFACE) + + # Convert the byte-array for SSID and BSSID to printable strings + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'BSSID', + dbus_interface=dbus.PROPERTIES_IFACE) + bssid = "" + for item in val: + bssid = bssid + ":%02x" % item + bssid = bssid[1:] + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'SSID', + dbus_interface=dbus.PROPERTIES_IFACE) + ssid = byte_array_to_string(val) + + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPAIE', + dbus_interface=dbus.PROPERTIES_IFACE) + wpa = "no" + if val != None: + wpa = "yes" + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSNIE', + dbus_interface=dbus.PROPERTIES_IFACE) + wpa2 = "no" + if val != None: + wpa2 = "yes" + freq = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Frequency', + dbus_interface=dbus.PROPERTIES_IFACE) + signal = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Signal', + dbus_interface=dbus.PROPERTIES_IFACE) + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Rates', + dbus_interface=dbus.PROPERTIES_IFACE) + if len(val) > 0: + maxrate = val[0] / 1000000 + else: + maxrate = 0 + + 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 + +def scanDone2(success, path=None): + print "Scan done: success=%s [path=%s]" % (success, path) + +def bssAdded(bss, properties): + print "BSS added: %s" % (bss) + showBss(bss) + +def bssRemoved(bss): + print "BSS removed: %s" % (bss) + +def blobAdded(blob): + print "BlobAdded(%s)" % (blob) + +def blobRemoved(blob): + print "BlobRemoved(%s)" % (blob) + +def networkAdded(network, properties): + print "NetworkAdded(%s)" % (network) + +def networkRemoved(network): + print "NetworkRemoved(%s)" % (network) + +def networkSelected(network): + print "NetworkSelected(%s)" % (network) + +def propertiesChangedInterface(properties): + for i in properties: + print "PropertiesChanged(interface): %s=%s" % (i, properties[i]) + +def propertiesChangedBss(properties): + for i in properties: + print "PropertiesChanged(BSS): %s=%s" % (i, properties[i]) + +def propertiesChangedNetwork(properties): + for i in properties: + print "PropertiesChanged(Network): %s=%s" % (i, properties[i]) + +def main(): + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + global bus + bus = dbus.SystemBus() + wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH) + + if len(sys.argv) != 2: + list_interfaces(wpas_obj) + os._exit(1) + + wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE) + bus.add_signal_receiver(interfaceAdded, + dbus_interface=WPAS_DBUS_INTERFACE, + signal_name="InterfaceAdded") + bus.add_signal_receiver(interfaceRemoved, + dbus_interface=WPAS_DBUS_INTERFACE, + signal_name="InterfaceRemoved") + bus.add_signal_receiver(propertiesChanged, + dbus_interface=WPAS_DBUS_INTERFACE, + signal_name="PropertiesChanged") + + ifname = sys.argv[1] + path = wpas.GetInterface(ifname) + if_obj = bus.get_object(WPAS_DBUS_SERVICE, path) + iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE) + iface.connect_to_signal("ScanDone", scanDone2, + path_keyword='path') + + bus.add_signal_receiver(scanDone, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="ScanDone", + path=path) + bus.add_signal_receiver(bssAdded, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="BSSAdded", + path=path) + bus.add_signal_receiver(bssRemoved, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="BSSRemoved", + path=path) + bus.add_signal_receiver(blobAdded, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="BlobAdded", + path=path) + bus.add_signal_receiver(blobRemoved, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="BlobRemoved", + path=path) + bus.add_signal_receiver(networkAdded, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="NetworkAdded", + path=path) + bus.add_signal_receiver(networkRemoved, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="NetworkRemoved", + path=path) + bus.add_signal_receiver(networkSelected, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="NetworkSelected", + path=path) + bus.add_signal_receiver(propertiesChangedInterface, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="PropertiesChanged", + path=path) + + bus.add_signal_receiver(propertiesChangedBss, + dbus_interface=WPAS_DBUS_BSS_INTERFACE, + signal_name="PropertiesChanged") + + bus.add_signal_receiver(propertiesChangedNetwork, + dbus_interface=WPAS_DBUS_NETWORK_INTERFACE, + signal_name="PropertiesChanged") + + gobject.MainLoop().run() + +if __name__ == "__main__": + main() + diff --git a/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new-wps.py b/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new-wps.py new file mode 100755 index 0000000..b886385 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new-wps.py @@ -0,0 +1,80 @@ +#!/usr/bin/python + +import dbus +import sys, os +import time +import gobject +from dbus.mainloop.glib import DBusGMainLoop + +WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1" +WPAS_DBUS_INTERFACE = "fi.w1.wpa_supplicant1" +WPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1" + +WPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface" +WPAS_DBUS_WPS_INTERFACE = "fi.w1.wpa_supplicant1.Interface.WPS" + +def propertiesChanged(properties): + if properties.has_key("State"): + print "PropertiesChanged: State: %s" % (properties["State"]) + +def scanDone(success): + print "Scan done: success=%s" % success + +def bssAdded(bss, properties): + print "BSS added: %s" % (bss) + +def bssRemoved(bss): + print "BSS removed: %s" % (bss) + +def wpsEvent(name, args): + print "WPS event: %s" % (name) + print args + +def credentials(cred): + print "WPS credentials: %s" % (cred) + +def main(): + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + global bus + bus = dbus.SystemBus() + wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH) + + if len(sys.argv) != 2: + print "Missing ifname argument" + os._exit(1) + + wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE) + bus.add_signal_receiver(scanDone, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="ScanDone") + bus.add_signal_receiver(bssAdded, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="BSSAdded") + bus.add_signal_receiver(bssRemoved, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="BSSRemoved") + bus.add_signal_receiver(propertiesChanged, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="PropertiesChanged") + bus.add_signal_receiver(wpsEvent, + dbus_interface=WPAS_DBUS_WPS_INTERFACE, + signal_name="Event") + bus.add_signal_receiver(credentials, + dbus_interface=WPAS_DBUS_WPS_INTERFACE, + signal_name="Credentials") + + ifname = sys.argv[1] + + path = wpas.GetInterface(ifname) + if_obj = bus.get_object(WPAS_DBUS_SERVICE, path) + if_obj.Set(WPAS_DBUS_WPS_INTERFACE, 'ProcessCredentials', + dbus.Boolean(1), + dbus_interface=dbus.PROPERTIES_IFACE) + wps = dbus.Interface(if_obj, WPAS_DBUS_WPS_INTERFACE) + wps.Start({'Role': 'enrollee', 'Type': 'pbc'}) + + gobject.MainLoop().run() + +if __name__ == "__main__": + main() + diff --git a/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new.py b/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new.py new file mode 100755 index 0000000..25072ce --- /dev/null +++ b/contrib/wpa/wpa_supplicant/examples/wpas-dbus-new.py @@ -0,0 +1,149 @@ +#!/usr/bin/python + +import dbus +import sys, os +import time +import gobject +from dbus.mainloop.glib import DBusGMainLoop + +WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1" +WPAS_DBUS_INTERFACE = "fi.w1.wpa_supplicant1" +WPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1" + +WPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface" +WPAS_DBUS_INTERFACES_OPATH = "/fi/w1/wpa_supplicant1/Interfaces" +WPAS_DBUS_BSS_INTERFACE = "fi.w1.wpa_supplicant1.BSS" + +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 list_interfaces(wpas_obj): + ifaces = wpas_obj.Get(WPAS_DBUS_INTERFACE, 'Interfaces', + dbus_interface=dbus.PROPERTIES_IFACE) + for path in ifaces: + 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 + +def propertiesChanged(properties): + if properties.has_key("State"): + print "PropertiesChanged: State: %s" % (properties["State"]) + +def showBss(bss): + net_obj = bus.get_object(WPAS_DBUS_SERVICE, bss) + net = dbus.Interface(net_obj, WPAS_DBUS_BSS_INTERFACE) + + # Convert the byte-array for SSID and BSSID to printable strings + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'BSSID', + dbus_interface=dbus.PROPERTIES_IFACE) + bssid = "" + for item in val: + bssid = bssid + ":%02x" % item + bssid = bssid[1:] + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'SSID', + dbus_interface=dbus.PROPERTIES_IFACE) + ssid = byte_array_to_string(val) + + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPA', + dbus_interface=dbus.PROPERTIES_IFACE) + wpa = "no" + if len(val["KeyMgmt"]) > 0: + wpa = "yes" + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSN', + dbus_interface=dbus.PROPERTIES_IFACE) + wpa2 = "no" + if len(val["KeyMgmt"]) > 0: + wpa2 = "yes" + freq = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Frequency', + dbus_interface=dbus.PROPERTIES_IFACE) + signal = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Signal', + dbus_interface=dbus.PROPERTIES_IFACE) + val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Rates', + dbus_interface=dbus.PROPERTIES_IFACE) + if len(val) > 0: + maxrate = val[0] / 1000000 + else: + maxrate = 0 + + 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 + + res = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'BSSs', + dbus_interface=dbus.PROPERTIES_IFACE) + + print "Scanned wireless networks:" + for opath in res: + print opath + showBss(opath) + +def bssAdded(bss, properties): + print "BSS added: %s" % (bss) + showBss(bss) + +def bssRemoved(bss): + print "BSS removed: %s" % (bss) + +def main(): + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + global bus + bus = dbus.SystemBus() + wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH) + + if len(sys.argv) != 2: + list_interfaces(wpas_obj) + os._exit(1) + + wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE) + bus.add_signal_receiver(scanDone, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="ScanDone") + bus.add_signal_receiver(bssAdded, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="BSSAdded") + bus.add_signal_receiver(bssRemoved, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="BSSRemoved") + bus.add_signal_receiver(propertiesChanged, + dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, + signal_name="PropertiesChanged") + + ifname = sys.argv[1] + + # See if wpa_supplicant already knows about this interface + path = None + try: + path = wpas.GetInterface(ifname) + except dbus.DBusException, 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: + if not str(exc).startswith("fi.w1.wpa_supplicant1.InterfaceExists:"): + raise exc + + global if_obj + if_obj = bus.get_object(WPAS_DBUS_SERVICE, path) + global iface + iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE) + iface.Scan({'Type': 'active'}) + + gobject.MainLoop().run() + + wpas.RemoveInterface(dbus.ObjectPath(path)) + +if __name__ == "__main__": + main() + diff --git a/contrib/wpa/wpa_supplicant/ibss_rsn.c b/contrib/wpa/wpa_supplicant/ibss_rsn.c new file mode 100644 index 0000000..0e33253 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/ibss_rsn.c @@ -0,0 +1,510 @@ +/* + * wpa_supplicant - IBSS RSN + * Copyright (c) 2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "l2_packet/l2_packet.h" +#include "rsn_supp/wpa.h" +#include "rsn_supp/wpa_ie.h" +#include "ap/wpa_auth.h" +#include "wpa_supplicant_i.h" +#include "driver_i.h" +#include "ibss_rsn.h" + + +static void ibss_rsn_free(struct ibss_rsn_peer *peer) +{ + wpa_auth_sta_deinit(peer->auth); + wpa_sm_deinit(peer->supp); + os_free(peer); +} + + +static void supp_set_state(void *ctx, enum wpa_states state) +{ + struct ibss_rsn_peer *peer = ctx; + peer->supp_state = state; +} + + +static int supp_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *buf, + size_t len) +{ + struct ibss_rsn_peer *peer = ctx; + struct wpa_supplicant *wpa_s = peer->ibss_rsn->wpa_s; + + wpa_printf(MSG_DEBUG, "SUPP: %s(dest=" MACSTR " proto=0x%04x " + "len=%lu)", + __func__, MAC2STR(dest), proto, (unsigned long) len); + + if (wpa_s->l2) + return l2_packet_send(wpa_s->l2, dest, proto, buf, len); + + return wpa_drv_send_eapol(wpa_s, dest, proto, buf, len); +} + + +static u8 * supp_alloc_eapol(void *ctx, u8 type, const void *data, + u16 data_len, size_t *msg_len, void **data_pos) +{ + struct ieee802_1x_hdr *hdr; + + wpa_printf(MSG_DEBUG, "SUPP: %s(type=%d data_len=%d)", + __func__, type, data_len); + + *msg_len = sizeof(*hdr) + data_len; + hdr = os_malloc(*msg_len); + if (hdr == NULL) + return NULL; + + hdr->version = 2; + hdr->type = type; + hdr->length = host_to_be16(data_len); + + if (data) + os_memcpy(hdr + 1, data, data_len); + else + os_memset(hdr + 1, 0, data_len); + + if (data_pos) + *data_pos = hdr + 1; + + return (u8 *) hdr; +} + + +static int supp_get_beacon_ie(void *ctx) +{ + struct ibss_rsn_peer *peer = ctx; + + wpa_printf(MSG_DEBUG, "SUPP: %s", __func__); + /* TODO: get correct RSN IE */ + return wpa_sm_set_ap_rsn_ie(peer->supp, + (u8 *) "\x30\x14\x01\x00" + "\x00\x0f\xac\x04" + "\x01\x00\x00\x0f\xac\x04" + "\x01\x00\x00\x0f\xac\x02" + "\x00\x00", 22); +} + + +static int supp_set_key(void *ctx, enum wpa_alg alg, + const u8 *addr, int key_idx, int set_tx, + const u8 *seq, size_t seq_len, + const u8 *key, size_t key_len) +{ + struct ibss_rsn_peer *peer = ctx; + + wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d " + "set_tx=%d)", + __func__, alg, MAC2STR(addr), key_idx, set_tx); + wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len); + wpa_hexdump_key(MSG_DEBUG, "SUPP: set_key - key", key, key_len); + + if (key_idx == 0) { + /* + * In IBSS RSN, the pairwise key from the 4-way handshake + * initiated by the peer with highest MAC address is used. + */ + if (os_memcmp(peer->ibss_rsn->wpa_s->own_addr, peer->addr, + ETH_ALEN) > 0) { + wpa_printf(MSG_DEBUG, "SUPP: Do not use this PTK"); + return 0; + } + } + + return wpa_drv_set_key(peer->ibss_rsn->wpa_s, alg, addr, key_idx, + set_tx, seq, seq_len, key, key_len); +} + + +static void * supp_get_network_ctx(void *ctx) +{ + struct ibss_rsn_peer *peer = ctx; + return wpa_supplicant_get_ssid(peer->ibss_rsn->wpa_s); +} + + +static int supp_mlme_setprotection(void *ctx, const u8 *addr, + int protection_type, int key_type) +{ + wpa_printf(MSG_DEBUG, "SUPP: %s(addr=" MACSTR " protection_type=%d " + "key_type=%d)", + __func__, MAC2STR(addr), protection_type, key_type); + return 0; +} + + +static void supp_cancel_auth_timeout(void *ctx) +{ + wpa_printf(MSG_DEBUG, "SUPP: %s", __func__); +} + + +int ibss_rsn_supp_init(struct ibss_rsn_peer *peer, const u8 *own_addr, + const u8 *psk) +{ + struct wpa_sm_ctx *ctx = os_zalloc(sizeof(*ctx)); + if (ctx == NULL) + return -1; + + ctx->ctx = peer; + ctx->msg_ctx = peer->ibss_rsn->wpa_s; + ctx->set_state = supp_set_state; + ctx->ether_send = supp_ether_send; + ctx->get_beacon_ie = supp_get_beacon_ie; + ctx->alloc_eapol = supp_alloc_eapol; + ctx->set_key = supp_set_key; + ctx->get_network_ctx = supp_get_network_ctx; + ctx->mlme_setprotection = supp_mlme_setprotection; + ctx->cancel_auth_timeout = supp_cancel_auth_timeout; + peer->supp = wpa_sm_init(ctx); + if (peer->supp == NULL) { + wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_init() failed"); + return -1; + } + + wpa_sm_set_own_addr(peer->supp, own_addr); + wpa_sm_set_param(peer->supp, WPA_PARAM_RSN_ENABLED, 1); + wpa_sm_set_param(peer->supp, WPA_PARAM_PROTO, WPA_PROTO_RSN); + wpa_sm_set_param(peer->supp, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP); + wpa_sm_set_param(peer->supp, WPA_PARAM_GROUP, WPA_CIPHER_CCMP); + wpa_sm_set_param(peer->supp, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK); + wpa_sm_set_pmk(peer->supp, psk, PMK_LEN); + + peer->supp_ie_len = sizeof(peer->supp_ie); + if (wpa_sm_set_assoc_wpa_ie_default(peer->supp, peer->supp_ie, + &peer->supp_ie_len) < 0) { + wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_set_assoc_wpa_ie_default()" + " failed"); + return -1; + } + + wpa_sm_notify_assoc(peer->supp, peer->addr); + + return 0; +} + + +static void auth_logger(void *ctx, const u8 *addr, logger_level level, + const char *txt) +{ + if (addr) + wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " - %s", + MAC2STR(addr), txt); + else + wpa_printf(MSG_DEBUG, "AUTH: %s", txt); +} + + +static const u8 * auth_get_psk(void *ctx, const u8 *addr, const u8 *prev_psk) +{ + struct ibss_rsn *ibss_rsn = ctx; + wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)", + __func__, MAC2STR(addr), prev_psk); + if (prev_psk) + return NULL; + return ibss_rsn->psk; +} + + +static int auth_send_eapol(void *ctx, const u8 *addr, const u8 *data, + size_t data_len, int encrypt) +{ + struct ibss_rsn *ibss_rsn = ctx; + struct wpa_supplicant *wpa_s = ibss_rsn->wpa_s; + + wpa_printf(MSG_DEBUG, "AUTH: %s(addr=" MACSTR " data_len=%lu " + "encrypt=%d)", + __func__, MAC2STR(addr), (unsigned long) data_len, encrypt); + + if (wpa_s->l2) + return l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data, + data_len); + + return wpa_drv_send_eapol(wpa_s, addr, ETH_P_EAPOL, data, data_len); +} + + +static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg, + const u8 *addr, int idx, u8 *key, size_t key_len) +{ + struct ibss_rsn *ibss_rsn = ctx; + u8 seq[6]; + + os_memset(seq, 0, sizeof(seq)); + + if (addr) { + wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR + " key_idx=%d)", + __func__, alg, MAC2STR(addr), idx); + } else { + wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)", + __func__, alg, idx); + } + wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len); + + if (idx == 0) { + /* + * In IBSS RSN, the pairwise key from the 4-way handshake + * initiated by the peer with highest MAC address is used. + */ + if (addr == NULL || + os_memcmp(ibss_rsn->wpa_s->own_addr, addr, ETH_ALEN) < 0) { + wpa_printf(MSG_DEBUG, "AUTH: Do not use this PTK"); + return 0; + } + } + + return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx, + 1, seq, 6, key, key_len); +} + + +static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn, + const u8 *own_addr) +{ + struct wpa_auth_config conf; + struct wpa_auth_callbacks cb; + + wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine"); + + os_memset(&conf, 0, sizeof(conf)); + conf.wpa = 2; + conf.wpa_key_mgmt = WPA_KEY_MGMT_PSK; + conf.wpa_pairwise = WPA_CIPHER_CCMP; + conf.rsn_pairwise = WPA_CIPHER_CCMP; + conf.wpa_group = WPA_CIPHER_CCMP; + conf.eapol_version = 2; + + os_memset(&cb, 0, sizeof(cb)); + cb.ctx = ibss_rsn; + cb.logger = auth_logger; + cb.send_eapol = auth_send_eapol; + cb.get_psk = auth_get_psk; + cb.set_key = auth_set_key; + + ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb); + if (ibss_rsn->auth_group == NULL) { + wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed"); + return -1; + } + + return 0; +} + + +static int ibss_rsn_auth_init(struct ibss_rsn *ibss_rsn, + struct ibss_rsn_peer *peer) +{ + peer->auth = wpa_auth_sta_init(ibss_rsn->auth_group, peer->addr); + if (peer->auth == NULL) { + wpa_printf(MSG_DEBUG, "AUTH: wpa_auth_sta_init() failed"); + return -1; + } + + /* TODO: get peer RSN IE with Probe Request */ + if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth, + (u8 *) "\x30\x14\x01\x00" + "\x00\x0f\xac\x04" + "\x01\x00\x00\x0f\xac\x04" + "\x01\x00\x00\x0f\xac\x02" + "\x00\x00", 22, NULL, 0) != + WPA_IE_OK) { + wpa_printf(MSG_DEBUG, "AUTH: wpa_validate_wpa_ie() failed"); + return -1; + } + + if (wpa_auth_sm_event(peer->auth, WPA_ASSOC)) + return -1; + + if (wpa_auth_sta_associated(ibss_rsn->auth_group, peer->auth)) + return -1; + + return 0; +} + + +int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr) +{ + struct ibss_rsn_peer *peer; + + wpa_printf(MSG_DEBUG, "RSN: Starting IBSS Authenticator and " + "Supplicant for peer " MACSTR, MAC2STR(addr)); + + peer = os_zalloc(sizeof(*peer)); + if (peer == NULL) + return -1; + + peer->ibss_rsn = ibss_rsn; + os_memcpy(peer->addr, addr, ETH_ALEN); + + if (ibss_rsn_supp_init(peer, ibss_rsn->wpa_s->own_addr, ibss_rsn->psk) + < 0) { + ibss_rsn_free(peer); + return -1; + } + + if (ibss_rsn_auth_init(ibss_rsn, peer) < 0) { + ibss_rsn_free(peer); + return -1; + } + + peer->next = ibss_rsn->peers; + ibss_rsn->peers = peer; + + return 0; +} + + +struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s) +{ + struct ibss_rsn *ibss_rsn; + + ibss_rsn = os_zalloc(sizeof(*ibss_rsn)); + if (ibss_rsn == NULL) + return NULL; + ibss_rsn->wpa_s = wpa_s; + + if (ibss_rsn_auth_init_group(ibss_rsn, wpa_s->own_addr) < 0) { + ibss_rsn_deinit(ibss_rsn); + return NULL; + } + + return ibss_rsn; +} + + +void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn) +{ + struct ibss_rsn_peer *peer, *prev; + + if (ibss_rsn == NULL) + return; + + peer = ibss_rsn->peers; + while (peer) { + prev = peer; + peer = peer->next; + ibss_rsn_free(prev); + } + + wpa_deinit(ibss_rsn->auth_group); + os_free(ibss_rsn); + +} + + +static int ibss_rsn_eapol_dst_supp(const u8 *buf, size_t len) +{ + const struct ieee802_1x_hdr *hdr; + const struct wpa_eapol_key *key; + u16 key_info; + size_t plen; + + /* TODO: Support other EAPOL packets than just EAPOL-Key */ + + if (len < sizeof(*hdr) + sizeof(*key)) + return -1; + + hdr = (const struct ieee802_1x_hdr *) buf; + key = (const struct wpa_eapol_key *) (hdr + 1); + plen = be_to_host16(hdr->length); + + if (hdr->version < EAPOL_VERSION) { + /* TODO: backwards compatibility */ + } + if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) { + wpa_printf(MSG_DEBUG, "RSN: EAPOL frame (type %u) discarded, " + "not a Key frame", hdr->type); + return -1; + } + if (plen > len - sizeof(*hdr) || plen < sizeof(*key)) { + wpa_printf(MSG_DEBUG, "RSN: EAPOL frame payload size %lu " + "invalid (frame size %lu)", + (unsigned long) plen, (unsigned long) len); + return -1; + } + + if (key->type != EAPOL_KEY_TYPE_RSN) { + wpa_printf(MSG_DEBUG, "RSN: EAPOL-Key type (%d) unknown, " + "discarded", key->type); + return -1; + } + + key_info = WPA_GET_BE16(key->key_info); + + return !!(key_info & WPA_KEY_INFO_ACK); +} + + +static int ibss_rsn_process_rx_eapol(struct ibss_rsn *ibss_rsn, + struct ibss_rsn_peer *peer, + const u8 *buf, size_t len) +{ + int supp; + u8 *tmp; + + supp = ibss_rsn_eapol_dst_supp(buf, len); + if (supp < 0) + return -1; + + tmp = os_malloc(len); + if (tmp == NULL) + return -1; + os_memcpy(tmp, buf, len); + if (supp) { + wpa_printf(MSG_DEBUG, "RSN: IBSS RX EAPOL for Supplicant"); + wpa_sm_rx_eapol(peer->supp, peer->addr, tmp, len); + } else { + wpa_printf(MSG_DEBUG, "RSN: IBSS RX EAPOL for Authenticator"); + wpa_receive(ibss_rsn->auth_group, peer->auth, tmp, len); + } + os_free(tmp); + + return 1; +} + + +int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr, + const u8 *buf, size_t len) +{ + struct ibss_rsn_peer *peer; + + for (peer = ibss_rsn->peers; peer; peer = peer->next) { + if (os_memcmp(src_addr, peer->addr, ETH_ALEN) == 0) + return ibss_rsn_process_rx_eapol(ibss_rsn, peer, + buf, len); + } + + if (ibss_rsn_eapol_dst_supp(buf, len) > 0) { + /* + * Create new IBSS peer based on an EAPOL message from the peer + * Authenticator. + */ + if (ibss_rsn_start(ibss_rsn, src_addr) < 0) + return -1; + return ibss_rsn_process_rx_eapol(ibss_rsn, ibss_rsn->peers, + buf, len); + } + + return 0; +} + + +void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk) +{ + os_memcpy(ibss_rsn->psk, psk, PMK_LEN); +} diff --git a/contrib/wpa/wpa_supplicant/ibss_rsn.h b/contrib/wpa/wpa_supplicant/ibss_rsn.h new file mode 100644 index 0000000..11e63ad --- /dev/null +++ b/contrib/wpa/wpa_supplicant/ibss_rsn.h @@ -0,0 +1,49 @@ +/* + * wpa_supplicant - IBSS RSN + * Copyright (c) 2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef IBSS_RSN_H +#define IBSS_RSN_H + +struct ibss_rsn; + +struct ibss_rsn_peer { + struct ibss_rsn_peer *next; + struct ibss_rsn *ibss_rsn; + + u8 addr[ETH_ALEN]; + + struct wpa_sm *supp; + enum wpa_states supp_state; + u8 supp_ie[80]; + size_t supp_ie_len; + + struct wpa_state_machine *auth; +}; + +struct ibss_rsn { + struct wpa_supplicant *wpa_s; + struct wpa_authenticator *auth_group; + struct ibss_rsn_peer *peers; + u8 psk[PMK_LEN]; +}; + + +struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s); +void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn); +int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr); +int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr, + const u8 *buf, size_t len); +void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk); + +#endif /* IBSS_RSN_H */ diff --git a/contrib/wpa/wpa_supplicant/main.c b/contrib/wpa/wpa_supplicant/main.c index 1f413f1..c0aa59c 100644 --- a/contrib/wpa/wpa_supplicant/main.c +++ b/contrib/wpa/wpa_supplicant/main.c @@ -19,6 +19,9 @@ #include "common.h" #include "wpa_supplicant_i.h" +#include "driver_i.h" + +extern struct wpa_driver_ops *wpa_drivers[]; static void usage(void) @@ -26,23 +29,12 @@ static void usage(void) int i; printf("%s\n\n%s\n" "usage:\n" - " wpa_supplicant [-BddhKLqq" -#ifdef CONFIG_DEBUG_SYSLOG - "s" -#endif /* CONFIG_DEBUG_SYSLOG */ - "t" -#ifdef CONFIG_CTRL_IFACE_DBUS - "u" -#endif /* CONFIG_CTRL_IFACE_DBUS */ - "vW] [-P<pid file>] " + " wpa_supplicant [-BddhKLqqstuvW] [-P<pid file>] " "[-g<global ctrl>] \\\n" " -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] " "[-p<driver_param>] \\\n" - " [-b<br_ifname>]" -#ifdef CONFIG_DEBUG_FILE - " [-f<debug file>]" -#endif /* CONFIG_DEBUG_FILE */ - " \\\n" + " [-b<br_ifname>] [-f<debug file>] \\\n" + " [-o<override driver>] [-O<override ctrl>] \\\n" " [-N -i<ifname> -c<conf> [-C<ctrl>] " "[-D<driver>] \\\n" " [-p<driver_param>] [-b<br_ifname>] ...]\n" @@ -50,10 +42,10 @@ static void usage(void) "drivers:\n", wpa_supplicant_version, wpa_supplicant_license); - for (i = 0; wpa_supplicant_drivers[i]; i++) { + for (i = 0; wpa_drivers[i]; i++) { printf(" %s = %s\n", - wpa_supplicant_drivers[i]->name, - wpa_supplicant_drivers[i]->desc); + wpa_drivers[i]->name, + wpa_drivers[i]->desc); } #ifndef CONFIG_NO_STDOUT_DEBUG @@ -64,32 +56,33 @@ static void usage(void) " -C = ctrl_interface parameter (only used if -c is not)\n" " -i = interface name\n" " -d = increase debugging verbosity (-dd even more)\n" - " -D = driver name\n" + " -D = driver name (can be multiple drivers: nl80211,wext)\n"); #ifdef CONFIG_DEBUG_FILE - " -f = log output to debug file instead of stdout\n" + printf(" -f = log output to debug file instead of stdout\n"); #endif /* CONFIG_DEBUG_FILE */ - " -g = global ctrl_interface\n" - " -K = include keys (passwords, etc.) in debug output\n" + printf(" -g = global ctrl_interface\n" + " -K = include keys (passwords, etc.) in debug output\n"); #ifdef CONFIG_DEBUG_SYSLOG - " -s = log output to syslog instead of stdout\n" + printf(" -s = log output to syslog instead of stdout\n"); #endif /* CONFIG_DEBUG_SYSLOG */ - " -t = include timestamp in debug messages\n" + printf(" -t = include timestamp in debug messages\n" " -h = show this help text\n" - " -L = show license (GPL and BSD)\n"); - printf(" -p = driver parameters\n" + " -L = show license (GPL and BSD)\n" + " -o = override driver parameter for new interfaces\n" + " -O = override ctrl_interface parameter for new interfaces\n" + " -p = driver parameters\n" " -P = PID file\n" - " -q = decrease debugging verbosity (-qq even less)\n" -#ifdef CONFIG_CTRL_IFACE_DBUS - " -u = enable DBus control interface\n" -#endif /* CONFIG_CTRL_IFACE_DBUS */ - " -v = show version\n" + " -q = decrease debugging verbosity (-qq even less)\n"); +#ifdef CONFIG_DBUS + printf(" -u = enable DBus control interface\n"); +#endif /* CONFIG_DBUS */ + printf(" -v = show version\n" " -W = wait for a control interface monitor before starting\n" " -N = start describing new interface\n"); printf("example:\n" " wpa_supplicant -D%s -iwlan0 -c/etc/wpa_supplicant.conf\n", - wpa_supplicant_drivers[i] ? - wpa_supplicant_drivers[i]->name : "wext"); + wpa_drivers[i] ? wpa_drivers[i]->name : "wext"); #endif /* CONFIG_NO_STDOUT_DEBUG */ } @@ -150,7 +143,7 @@ int main(int argc, char *argv[]) wpa_supplicant_fd_workaround(); for (;;) { - c = getopt(argc, argv, "b:Bc:C:D:df:g:hi:KLNp:P:qstuvW"); + c = getopt(argc, argv, "b:Bc:C:D:df:g:hi:KLNo:O:p:P:qstuvW"); if (c < 0) break; switch (c) { @@ -201,6 +194,12 @@ int main(int argc, char *argv[]) license(); exitcode = 0; goto out; + case 'o': + params.override_driver = optarg; + break; + case 'O': + params.override_ctrl_interface = optarg; + break; case 'p': iface->driver_param = optarg; break; @@ -219,11 +218,11 @@ int main(int argc, char *argv[]) case 't': params.wpa_debug_timestamp++; break; -#ifdef CONFIG_CTRL_IFACE_DBUS +#ifdef CONFIG_DBUS case 'u': params.dbus_ctrl_interface = 1; break; -#endif /* CONFIG_CTRL_IFACE_DBUS */ +#endif /* CONFIG_DBUS */ case 'v': printf("%s\n", wpa_supplicant_version); exitcode = 0; diff --git a/contrib/wpa/wpa_supplicant/mlme.c b/contrib/wpa/wpa_supplicant/mlme.c index 9885e19..eb60ac5 100644 --- a/contrib/wpa/wpa_supplicant/mlme.c +++ b/contrib/wpa/wpa_supplicant/mlme.c @@ -20,10 +20,11 @@ #include "eloop.h" #include "config_ssid.h" #include "wpa_supplicant_i.h" -#include "wpa.h" -#include "drivers/driver.h" -#include "ieee802_11_defs.h" -#include "ieee802_11_common.h" +#include "notify.h" +#include "driver_i.h" +#include "rsn_supp/wpa.h" +#include "common/ieee802_11_defs.h" +#include "common/ieee802_11_common.h" #include "mlme.h" @@ -94,14 +95,17 @@ static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s); static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s); static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx); static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx); +static void ieee80211_build_tspec(struct wpabuf *buf); +static int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, + const u8 *ies, size_t ies_len); static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s, - wpa_hw_mode phymode, int chan, + enum hostapd_hw_mode phymode, int chan, int freq) { size_t i; - struct wpa_hw_modes *mode; + struct hostapd_hw_modes *mode; for (i = 0; i < wpa_s->mlme.num_modes; i++) { mode = &wpa_s->mlme.modes[i]; @@ -116,8 +120,6 @@ static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s, } - -#if 0 /* FIX */ static int ecw2cw(int ecw) { int cw = 1; @@ -127,15 +129,15 @@ static int ecw2cw(int ecw) } return cw - 1; } -#endif static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s, - u8 *wmm_param, size_t wmm_param_len) + const u8 *wmm_param, size_t wmm_param_len) { size_t left; int count; - u8 *pos; + const u8 *pos; + u8 wmm_acm; if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) return; @@ -147,54 +149,42 @@ static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s, pos = wmm_param + 8; left = wmm_param_len - 8; -#if 0 /* FIX */ wmm_acm = 0; for (; left >= 4; left -= 4, pos += 4) { int aci = (pos[0] >> 5) & 0x03; int acm = (pos[0] >> 4) & 0x01; - int queue; + int aifs, cw_max, cw_min, burst_time; switch (aci) { - case 1: - queue = IEEE80211_TX_QUEUE_DATA3; + case 1: /* AC_BK */ if (acm) - wmm_acm |= BIT(1) | BIT(2); + wmm_acm |= BIT(1) | BIT(2); /* BK/- */ break; - case 2: - queue = IEEE80211_TX_QUEUE_DATA1; + case 2: /* AC_VI */ if (acm) - wmm_acm |= BIT(4) | BIT(5); + wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ break; - case 3: - queue = IEEE80211_TX_QUEUE_DATA0; + case 3: /* AC_VO */ if (acm) - wmm_acm |= BIT(6) | BIT(7); + wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ break; - case 0: + case 0: /* AC_BE */ default: - queue = IEEE80211_TX_QUEUE_DATA2; if (acm) - wpa_s->mlme.wmm_acm |= BIT(0) | BIT(3); + wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ break; } - params.aifs = pos[0] & 0x0f; - params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); - params.cw_min = ecw2cw(pos[1] & 0x0f); + aifs = pos[0] & 0x0f; + cw_max = ecw2cw((pos[1] & 0xf0) >> 4); + cw_min = ecw2cw(pos[1] & 0x0f); /* TXOP is in units of 32 usec; burst_time in 0.1 ms */ - params.burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100; - wpa_printf(MSG_DEBUG, "MLME: WMM queue=%d aci=%d acm=%d " - "aifs=%d cWmin=%d cWmax=%d burst=%d", - queue, aci, acm, params.aifs, params.cw_min, - params.cw_max, params.burst_time); - /* TODO: handle ACM (block TX, fallback to next lowest allowed - * AC for now) */ - if (local->hw->conf_tx(local->mdev, queue, ¶ms)) { - wpa_printf(MSG_DEBUG, "MLME: failed to set TX queue " - "parameters for queue %d", queue); - } + burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100; + wpa_printf(MSG_DEBUG, "MLME: WMM aci=%d acm=%d aifs=%d " + "cWmin=%d cWmax=%d burst=%d", + aci, acm, aifs, cw_min, cw_max, burst_time); + /* TODO: driver configuration */ } -#endif } @@ -214,6 +204,7 @@ static void ieee80211_set_associated(struct wpa_supplicant *wpa_s, int assoc) data.assoc_info.req_ies_len = wpa_s->mlme.assocreq_ies_len; data.assoc_info.resp_ies = wpa_s->mlme.assocresp_ies; data.assoc_info.resp_ies_len = wpa_s->mlme.assocresp_ies_len; + data.assoc_info.freq = wpa_s->mlme.freq; wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data); } else { wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL); @@ -230,8 +221,8 @@ static int ieee80211_sta_tx(struct wpa_supplicant *wpa_s, const u8 *buf, static void ieee80211_send_auth(struct wpa_supplicant *wpa_s, - int transaction, u8 *extra, size_t extra_len, - int encrypt) + int transaction, const u8 *extra, + size_t extra_len, int encrypt) { u8 *buf; size_t len; @@ -352,7 +343,7 @@ static void ieee80211_send_assoc(struct wpa_supplicant *wpa_s) blen = 0; capab = wpa_s->mlme.capab; - if (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G) { + if (wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211G) { capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | WLAN_CAPABILITY_SHORT_PREAMBLE; } @@ -403,20 +394,16 @@ static void ieee80211_send_assoc(struct wpa_supplicant *wpa_s) blen += len + 2; *pos++ = WLAN_EID_SUPP_RATES; *pos++ = len; - for (i = 0; i < len; i++) { - int rate = wpa_s->mlme.curr_rates[i].rate; - *pos++ = (u8) (rate / 5); - } + for (i = 0; i < len; i++) + *pos++ = (u8) (wpa_s->mlme.curr_rates[i] / 5); if (wpa_s->mlme.num_curr_rates > len) { pos = buf + blen; blen += wpa_s->mlme.num_curr_rates - len + 2; *pos++ = WLAN_EID_EXT_SUPP_RATES; *pos++ = wpa_s->mlme.num_curr_rates - len; - for (i = len; i < wpa_s->mlme.num_curr_rates; i++) { - int rate = wpa_s->mlme.curr_rates[i].rate; - *pos++ = (u8) (rate / 5); - } + for (i = len; i < wpa_s->mlme.num_curr_rates; i++) + *pos++ = (u8) (wpa_s->mlme.curr_rates[i] / 5); } if (wpa_s->mlme.extra_ie && wpa_s->mlme.auth_alg != WLAN_AUTH_FT) { @@ -683,7 +670,6 @@ static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s, supp_rates[0] = WLAN_EID_SUPP_RATES; supp_rates[1] = 0; for (i = 0; i < wpa_s->mlme.num_curr_rates; i++) { - struct wpa_rate_data *rate = &wpa_s->mlme.curr_rates[i]; if (esupp_rates) { pos = buf + len; len++; @@ -699,7 +685,7 @@ static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s, len++; supp_rates[1]++; } - *pos++ = rate->rate / 5; + *pos++ = wpa_s->mlme.curr_rates[i] / 5; } if (wpa_s->mlme.extra_probe_ie) { @@ -768,7 +754,7 @@ static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s, u16 auth_alg, auth_transaction, status_code; int adhoc; - adhoc = ssid && ssid->mode == 1; + adhoc = ssid && ssid->mode == WPAS_MODE_IBSS; if (wpa_s->mlme.state != IEEE80211_AUTHENTICATE && !adhoc) { wpa_printf(MSG_DEBUG, "MLME: authentication frame received " @@ -841,12 +827,11 @@ static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s, u8 algs[num_algs]; int i, pos; algs[0] = algs[1] = algs[2] = 0xff; - if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_OPEN) + if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_OPEN) algs[0] = WLAN_AUTH_OPEN; - if (wpa_s->mlme.auth_algs & - IEEE80211_AUTH_ALG_SHARED_KEY) + if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_SHARED) algs[1] = WLAN_AUTH_SHARED_KEY; - if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_LEAP) + if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_LEAP) algs[2] = WLAN_AUTH_LEAP; if (wpa_s->mlme.auth_alg == WLAN_AUTH_OPEN) pos = 0; @@ -890,12 +875,36 @@ static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s, case WLAN_AUTH_FT: { union wpa_event_data data; + struct wpabuf *ric = NULL; os_memset(&data, 0, sizeof(data)); data.ft_ies.ies = mgmt->u.auth.variable; data.ft_ies.ies_len = len - (mgmt->u.auth.variable - (u8 *) mgmt); os_memcpy(data.ft_ies.target_ap, wpa_s->bssid, ETH_ALEN); + if (os_strcmp(wpa_s->driver->name, "test") == 0 && + wpa_s->mlme.wmm_enabled) { + ric = wpabuf_alloc(200); + if (ric) { + /* Build simple RIC-Request: RDIE | TSPEC */ + + /* RIC Data (RDIE) */ + wpabuf_put_u8(ric, WLAN_EID_RIC_DATA); + wpabuf_put_u8(ric, 4); + wpabuf_put_u8(ric, 0); /* RDIE Identifier */ + wpabuf_put_u8(ric, 1); /* Resource Descriptor + * Count */ + wpabuf_put_le16(ric, 0); /* Status Code */ + + /* WMM TSPEC */ + ieee80211_build_tspec(ric); + + data.ft_ies.ric_ies = wpabuf_head(ric); + data.ft_ies.ric_ies_len = wpabuf_len(ric); + } + } + wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data); + wpabuf_free(ric); ieee80211_auth_completed(wpa_s); break; } @@ -987,42 +996,63 @@ static void ieee80211_rx_mgmt_disassoc(struct wpa_supplicant *wpa_s, } -static int ieee80211_ft_assoc_resp(struct wpa_supplicant *wpa_s, - struct ieee802_11_elems *elems) +static void ieee80211_build_tspec(struct wpabuf *buf) { -#ifdef CONFIG_IEEE80211R - const u8 *mobility_domain = NULL; - const u8 *r0kh_id = NULL; - size_t r0kh_id_len = 0; - const u8 *r1kh_id = NULL; - struct rsn_ftie *hdr; - const u8 *pos, *end; - - if (elems->mdie && elems->mdie_len >= MOBILITY_DOMAIN_ID_LEN) - mobility_domain = elems->mdie; - if (elems->ftie && elems->ftie_len >= sizeof(struct rsn_ftie)) { - end = elems->ftie + elems->ftie_len; - hdr = (struct rsn_ftie *) elems->ftie; - pos = (const u8 *) (hdr + 1); - while (pos + 1 < end) { - if (pos + 2 + pos[1] > end) - break; - if (pos[0] == FTIE_SUBELEM_R1KH_ID && - pos[1] == FT_R1KH_ID_LEN) - r1kh_id = pos + 2; - else if (pos[0] == FTIE_SUBELEM_R0KH_ID && - pos[1] >= 1 && pos[1] <= FT_R0KH_ID_MAX_LEN) { - r0kh_id = pos + 2; - r0kh_id_len = pos[1]; - } - pos += 2 + pos[1]; - } - } - return wpa_sm_set_ft_params(wpa_s->wpa, mobility_domain, r0kh_id, - r0kh_id_len, r1kh_id); -#else /* CONFIG_IEEE80211R */ - return 0; -#endif /* CONFIG_IEEE80211R */ + struct wmm_tspec_element *tspec; + int tid, up; + + tspec = wpabuf_put(buf, sizeof(*tspec)); + tspec->eid = WLAN_EID_VENDOR_SPECIFIC; + tspec->length = sizeof(*tspec) - 2; + tspec->oui[0] = 0x00; + tspec->oui[1] = 0x50; + tspec->oui[2] = 0xf2; + tspec->oui_type = 2; + tspec->oui_subtype = 2; + tspec->version = 1; + + tid = 1; + up = 6; /* Voice */ + tspec->ts_info[0] = (tid << 1) | + (WMM_TSPEC_DIRECTION_BI_DIRECTIONAL << 5) | + BIT(7); + tspec->ts_info[1] = up << 3; + tspec->nominal_msdu_size = host_to_le16(1530); + tspec->mean_data_rate = host_to_le32(128000); /* bits per second */ + tspec->minimum_phy_rate = host_to_le32(6000000); + tspec->surplus_bandwidth_allowance = host_to_le16(0x3000); /* 150% */ +} + + +static void ieee80211_tx_addts(struct wpa_supplicant *wpa_s) +{ + struct wpabuf *buf; + struct ieee80211_mgmt *mgmt; + size_t alen; + + wpa_printf(MSG_DEBUG, "MLME: Send ADDTS Request for Voice TSPEC"); + mgmt = NULL; + alen = mgmt->u.action.u.wmm_action.variable - (u8 *) mgmt; + + buf = wpabuf_alloc(alen + sizeof(struct wmm_tspec_element)); + if (buf == NULL) + return; + + mgmt = wpabuf_put(buf, alen); + os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); + os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); + os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); + mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, + WLAN_FC_STYPE_ACTION); + mgmt->u.action.category = WLAN_ACTION_WMM; + mgmt->u.action.u.wmm_action.action_code = WMM_ACTION_CODE_ADDTS_REQ; + mgmt->u.action.u.wmm_action.dialog_token = 1; + mgmt->u.action.u.wmm_action.status_code = 0; + + ieee80211_build_tspec(buf); + + ieee80211_sta_tx(wpa_s, wpabuf_head(buf), wpabuf_len(buf)); + wpabuf_free(buf); } @@ -1125,7 +1155,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s, "Resp failed"); return; } - } else if (ieee80211_ft_assoc_resp(wpa_s, &elems) < 0) + } else if (wpa_sm_set_ft_params(wpa_s->wpa, pos, + len - (pos - (u8 *) mgmt)) < 0) return; wpa_printf(MSG_DEBUG, "MLME: associated"); @@ -1172,16 +1203,17 @@ static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s, "netstack"); } -#if 0 /* FIX? */ - sta->assoc_ap = 1; - - if (elems.wmm && wpa_s->mlme.wmm_enabled) { - sta->flags |= WLAN_STA_WMM; + if (elems.wmm && wpa_s->mlme.wmm_enabled) ieee80211_sta_wmm_params(wpa_s, elems.wmm, elems.wmm_len); - } -#endif ieee80211_associated(wpa_s); + + if (wpa_s->mlme.auth_alg != WLAN_AUTH_FT && + os_strcmp(wpa_s->driver->name, "test") == 0 && + elems.wmm && wpa_s->mlme.wmm_enabled) { + /* Test WMM-AC - send ADDTS for WMM TSPEC */ + ieee80211_tx_addts(wpa_s); + } } @@ -1528,8 +1560,8 @@ static void ieee80211_bss_info(struct wpa_supplicant *wpa_s, bss->channel = channel; bss->freq = wpa_s->mlme.freq; if (channel != wpa_s->mlme.channel && - (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G || - wpa_s->mlme.phymode == WPA_MODE_IEEE80211B) && + (wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211G || + wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211B) && channel >= 1 && channel <= 14) { static const int freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, @@ -1614,7 +1646,7 @@ static void ieee80211_rx_mgmt_probe_req(struct wpa_supplicant *wpa_s, u8 *pos, *end; struct wpa_ssid *ssid = wpa_s->current_ssid; - adhoc = ssid && ssid->mode == 1; + adhoc = ssid && ssid->mode == WPAS_MODE_IBSS; if (!adhoc || wpa_s->mlme.state != IEEE80211_IBSS_JOINED || len < 24 + 2 || wpa_s->mlme.probe_resp == NULL) @@ -1807,6 +1839,119 @@ static void ieee80211_rx_mgmt_sa_query_action( #endif /* CONFIG_IEEE80211W */ +static void dump_tspec(struct wmm_tspec_element *tspec) +{ + int up, psb, dir, tid; + u16 val; + + up = (tspec->ts_info[1] >> 3) & 0x07; + psb = (tspec->ts_info[1] >> 2) & 0x01; + dir = (tspec->ts_info[0] >> 5) & 0x03; + tid = (tspec->ts_info[0] >> 1) & 0x0f; + wpa_printf(MSG_DEBUG, "WMM: TS Info: UP=%d PSB=%d Direction=%d TID=%d", + up, psb, dir, tid); + val = le_to_host16(tspec->nominal_msdu_size); + wpa_printf(MSG_DEBUG, "WMM: Nominal MSDU Size: %d%s", + val & 0x7fff, val & 0x8000 ? " (fixed)" : ""); + wpa_printf(MSG_DEBUG, "WMM: Mean Data Rate: %u bps", + le_to_host32(tspec->mean_data_rate)); + wpa_printf(MSG_DEBUG, "WMM: Minimum PHY Rate: %u bps", + le_to_host32(tspec->minimum_phy_rate)); + val = le_to_host16(tspec->surplus_bandwidth_allowance); + wpa_printf(MSG_DEBUG, "WMM: Surplus Bandwidth Allowance: %u.%04u", + val >> 13, 10000 * (val & 0x1fff) / 0x2000); + val = le_to_host16(tspec->medium_time); + wpa_printf(MSG_DEBUG, "WMM: Medium Time: %u (= %u usec/sec)", + val, 32 * val); +} + + +static int is_wmm_tspec(const u8 *ie, size_t len) +{ + const struct wmm_tspec_element *tspec; + + if (len < sizeof(*tspec)) + return 0; + + tspec = (const struct wmm_tspec_element *) ie; + if (tspec->eid != WLAN_EID_VENDOR_SPECIFIC || + tspec->length < sizeof(*tspec) - 2 || + tspec->oui[0] != 0x00 || tspec->oui[1] != 0x50 || + tspec->oui[2] != 0xf2 || tspec->oui_type != 2 || + tspec->oui_subtype != 2 || tspec->version != 1) + return 0; + + return 1; +} + + +static void ieee80211_rx_addts_resp( + struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, + size_t var_len) +{ + struct wmm_tspec_element *tspec; + + wpa_printf(MSG_DEBUG, "WMM: Received ADDTS Response"); + wpa_hexdump(MSG_MSGDUMP, "WMM: ADDTS Response IE(s)", + mgmt->u.action.u.wmm_action.variable, var_len); + if (!is_wmm_tspec(mgmt->u.action.u.wmm_action.variable, var_len)) + return; + tspec = (struct wmm_tspec_element *) + mgmt->u.action.u.wmm_action.variable; + dump_tspec(tspec); +} + + +static void ieee80211_rx_delts( + struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, + size_t var_len) +{ + struct wmm_tspec_element *tspec; + + wpa_printf(MSG_DEBUG, "WMM: Received DELTS"); + wpa_hexdump(MSG_MSGDUMP, "WMM: DELTS IE(s)", + mgmt->u.action.u.wmm_action.variable, var_len); + if (!is_wmm_tspec(mgmt->u.action.u.wmm_action.variable, var_len)) + return; + tspec = (struct wmm_tspec_element *) + mgmt->u.action.u.wmm_action.variable; + dump_tspec(tspec); +} + + +static void ieee80211_rx_mgmt_wmm_action( + struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, + struct ieee80211_rx_status *rx_status) +{ + size_t alen; + + alen = mgmt->u.action.u.wmm_action.variable - (u8 *) mgmt; + if (len < alen) { + wpa_printf(MSG_DEBUG, "WMM: Received Action frame too short"); + return; + } + + wpa_printf(MSG_DEBUG, "WMM: Received Action frame: Action Code %d, " + "Dialog Token %d, Status Code %d", + mgmt->u.action.u.wmm_action.action_code, + mgmt->u.action.u.wmm_action.dialog_token, + mgmt->u.action.u.wmm_action.status_code); + + switch (mgmt->u.action.u.wmm_action.action_code) { + case WMM_ACTION_CODE_ADDTS_RESP: + ieee80211_rx_addts_resp(wpa_s, mgmt, len, len - alen); + break; + case WMM_ACTION_CODE_DELTS: + ieee80211_rx_delts(wpa_s, mgmt, len, len - alen); + break; + default: + wpa_printf(MSG_DEBUG, "WMM: Unsupported Action Code %d", + mgmt->u.action.u.wmm_action.action_code); + break; + } +} + + static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, @@ -1828,6 +1973,17 @@ static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s, ieee80211_rx_mgmt_sa_query_action(wpa_s, mgmt, len, rx_status); break; #endif /* CONFIG_IEEE80211W */ + case WLAN_ACTION_WMM: + ieee80211_rx_mgmt_wmm_action(wpa_s, mgmt, len, rx_status); + break; + case WLAN_ACTION_PUBLIC: + if (wpa_s->mlme.public_action_cb) { + wpa_s->mlme.public_action_cb( + wpa_s->mlme.public_action_cb_ctx, + (u8 *) mgmt, len, rx_status->freq); + return; + } + break; default: wpa_printf(MSG_DEBUG, "MLME: unknown Action Category %d", mgmt->u.action.category); @@ -1947,6 +2103,8 @@ static void ieee80211_sta_expire(struct wpa_supplicant *wpa_s) static void ieee80211_sta_merge_ibss(struct wpa_supplicant *wpa_s) { + struct wpa_driver_scan_params params; + ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL); ieee80211_sta_expire(wpa_s); @@ -1955,7 +2113,11 @@ static void ieee80211_sta_merge_ibss(struct wpa_supplicant *wpa_s) wpa_printf(MSG_DEBUG, "MLME: No active IBSS STAs - trying to scan for " "other IBSS networks with same SSID (merge)"); - ieee80211_sta_req_scan(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len); + os_memset(¶ms, 0, sizeof(params)); + params.ssids[0].ssid = wpa_s->mlme.ssid; + params.ssids[0].ssid_len = wpa_s->mlme.ssid_len; + params.num_ssids = wpa_s->mlme.ssid_len ? 1 : 0; + ieee80211_sta_req_scan(wpa_s, ¶ms); } @@ -2000,7 +2162,7 @@ static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx) static void ieee80211_sta_new_auth(struct wpa_supplicant *wpa_s) { struct wpa_ssid *ssid = wpa_s->current_ssid; - if (ssid && ssid->mode != 0) + if (ssid && ssid->mode != WPAS_MODE_INFRA) return; #if 0 /* FIX */ @@ -2013,11 +2175,11 @@ static void ieee80211_sta_new_auth(struct wpa_supplicant *wpa_s) wpa_s->mlme.wmm_last_param_set = -1; /* allow any WMM update */ - if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_OPEN) + if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_OPEN) wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN; - else if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY) + else if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_SHARED) wpa_s->mlme.auth_alg = WLAN_AUTH_SHARED_KEY; - else if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_LEAP) + else if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_LEAP) wpa_s->mlme.auth_alg = WLAN_AUTH_LEAP; else wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN; @@ -2057,7 +2219,7 @@ static int ieee80211_ibss_allowed(struct wpa_supplicant *wpa_s) static int ieee80211_sta_join_ibss(struct wpa_supplicant *wpa_s, struct ieee80211_sta_bss *bss) { - int res = 0, rates, done = 0; + int res = 0, rates, done = 0, bssid_changed; struct ieee80211_mgmt *mgmt; #if 0 /* FIX */ struct ieee80211_tx_control control; @@ -2076,7 +2238,10 @@ static int ieee80211_sta_join_ibss(struct wpa_supplicant *wpa_s, local->hw->reset_tsf(local->mdev); } #endif + bssid_changed = os_memcmp(wpa_s->bssid, bss->bssid, ETH_ALEN); os_memcpy(wpa_s->bssid, bss->bssid, ETH_ALEN); + if (bssid_changed) + wpas_notify_bssid_changed(wpa_s); #if 0 /* FIX */ local->conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10; @@ -2207,7 +2372,7 @@ static int ieee80211_sta_join_ibss(struct wpa_supplicant *wpa_s, if (local->conf.phymode == MODE_ATHEROS_TURBO) rate *= 2; for (j = 0; j < local->num_curr_rates; j++) - if (local->curr_rates[j].rate == rate) + if (local->curr_rates[j] == rate) rates |= BIT(j); } wpa_s->mlme.supp_rates_bits = rates; @@ -2276,7 +2441,7 @@ static int ieee80211_sta_create_ibss(struct wpa_supplicant *wpa_s) pos = bss->supp_rates; #if 0 /* FIX */ for (i = 0; i < local->num_curr_rates; i++) { - int rate = local->curr_rates[i].rate; + int rate = local->curr_rates[i]; if (local->conf.phymode == MODE_ATHEROS_TURBO) rate /= 2; *pos++ = (u8) (rate / 5); @@ -2392,11 +2557,17 @@ int ieee80211_sta_associate(struct wpa_supplicant *wpa_s, struct wpa_driver_associate_params *params) { struct ieee80211_sta_bss *bss; + int bssid_changed; wpa_s->mlme.bssid_set = 0; wpa_s->mlme.freq = params->freq; if (params->bssid) { + bssid_changed = os_memcmp(wpa_s->bssid, params->bssid, + ETH_ALEN); os_memcpy(wpa_s->bssid, params->bssid, ETH_ALEN); + if (bssid_changed) + wpas_notify_bssid_changed(wpa_s); + if (!is_zero_ether_addr(params->bssid)) wpa_s->mlme.bssid_set = 1; bss = ieee80211_bss_get(wpa_s, wpa_s->bssid); @@ -2463,7 +2634,7 @@ int ieee80211_sta_associate(struct wpa_supplicant *wpa_s, ieee80211_sta_set_channel(wpa_s, wpa_s->mlme.phymode, wpa_s->mlme.channel, wpa_s->mlme.freq); - if (params->mode == 1 && !wpa_s->mlme.bssid_set) { + if (params->mode == WPAS_MODE_IBSS && !wpa_s->mlme.bssid_set) { os_get_time(&wpa_s->mlme.ibss_join_req); wpa_s->mlme.state = IEEE80211_IBSS_SEARCH; return ieee80211_sta_find_ibss(wpa_s); @@ -2503,14 +2674,14 @@ static int ieee80211_active_scan(struct wpa_supplicant *wpa_s) int c; for (m = 0; m < wpa_s->mlme.num_modes; m++) { - struct wpa_hw_modes *mode = &wpa_s->mlme.modes[m]; + struct hostapd_hw_modes *mode = &wpa_s->mlme.modes[m]; if ((int) mode->mode != (int) wpa_s->mlme.phymode) continue; for (c = 0; c < mode->num_channels; c++) { - struct wpa_channel_data *chan = &mode->channels[c]; - if (chan->flag & WPA_CHAN_W_SCAN && + struct hostapd_channel_data *chan = &mode->channels[c]; + if (!(chan->flag & HOSTAPD_CHAN_DISABLED) && chan->chan == wpa_s->mlme.channel) { - if (chan->flag & WPA_CHAN_W_ACTIVE_SCAN) + if (!(chan->flag & HOSTAPD_CHAN_PASSIVE_SCAN)) return 1; break; } @@ -2524,8 +2695,8 @@ static int ieee80211_active_scan(struct wpa_supplicant *wpa_s) static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; - struct wpa_hw_modes *mode; - struct wpa_channel_data *chan; + struct hostapd_hw_modes *mode; + struct hostapd_channel_data *chan; int skip = 0; int timeout = 0; struct wpa_ssid *ssid = wpa_s->current_ssid; @@ -2564,12 +2735,23 @@ static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx) } skip = !(wpa_s->mlme.hw_modes & (1 << mode->mode)); chan = &mode->channels[wpa_s->mlme.scan_channel_idx]; - if (!(chan->flag & WPA_CHAN_W_SCAN) || - (adhoc && !(chan->flag & WPA_CHAN_W_IBSS)) || - (wpa_s->mlme.hw_modes & (1 << WPA_MODE_IEEE80211G) && - mode->mode == WPA_MODE_IEEE80211B && + if ((chan->flag & HOSTAPD_CHAN_DISABLED) || + (adhoc && (chan->flag & HOSTAPD_CHAN_NO_IBSS)) || + (wpa_s->mlme.hw_modes & (1 << HOSTAPD_MODE_IEEE80211G) && + mode->mode == HOSTAPD_MODE_IEEE80211B && wpa_s->mlme.scan_skip_11b)) skip = 1; + if (!skip && wpa_s->mlme.scan_freqs) { + int i, found = 0; + for (i = 0; wpa_s->mlme.scan_freqs[i]; i++) { + if (wpa_s->mlme.scan_freqs[i] == chan->freq) { + found = 1; + break; + } + } + if (!found) + skip = 1; + } if (!skip) { wpa_printf(MSG_MSGDUMP, @@ -2623,9 +2805,12 @@ static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx) } -int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, const u8 *ssid, - size_t ssid_len) +int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, + struct wpa_driver_scan_params *params) { + const u8 *ssid = params->ssids[0].ssid; + size_t ssid_len = params->ssids[0].ssid_len; + if (ssid_len > MAX_SSID_LEN) return -1; @@ -2654,6 +2839,21 @@ int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, const u8 *ssid, wpa_printf(MSG_DEBUG, "MLME: starting scan"); + ieee80211_sta_set_probe_req_ie(wpa_s, params->extra_ies, + params->extra_ies_len); + + os_free(wpa_s->mlme.scan_freqs); + if (params->freqs) { + int i; + for (i = 0; params->freqs[i]; i++) + ; + wpa_s->mlme.scan_freqs = os_malloc((i + 1) * sizeof(int)); + if (wpa_s->mlme.scan_freqs) + os_memcpy(wpa_s->mlme.scan_freqs, params->freqs, + (i + 1) * sizeof(int)); + } else + wpa_s->mlme.scan_freqs = NULL; + ieee80211_sta_save_oper_chan(wpa_s); wpa_s->mlme.sta_scanning = 1; @@ -2830,7 +3030,7 @@ void ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len, } -void ieee80211_sta_free_hw_features(struct wpa_hw_modes *hw_features, +void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features, size_t num_hw_features) { size_t i; @@ -2861,9 +3061,11 @@ int ieee80211_sta_init(struct wpa_supplicant *wpa_s) wpa_s->mlme.num_modes = num_modes; - wpa_s->mlme.hw_modes = 1 << WPA_MODE_IEEE80211A; - wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211B; - wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211G; + wpa_s->mlme.hw_modes = 1 << HOSTAPD_MODE_IEEE80211A; + wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211B; + wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211G; + + wpa_s->mlme.wmm_enabled = 1; return 0; } @@ -2889,6 +3091,9 @@ void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s) wpa_s->mlme.ft_ies = NULL; wpa_s->mlme.ft_ies_len = 0; #endif /* CONFIG_IEEE80211R */ + + os_free(wpa_s->mlme.scan_freqs); + wpa_s->mlme.scan_freqs = NULL; } @@ -2972,8 +3177,8 @@ int ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action, #endif /* CONFIG_IEEE80211R */ -int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, const u8 *ies, - size_t ies_len) +static int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, + const u8 *ies, size_t ies_len) { os_free(wpa_s->mlme.extra_probe_ie); wpa_s->mlme.extra_probe_ie = NULL; diff --git a/contrib/wpa/wpa_supplicant/mlme.h b/contrib/wpa/wpa_supplicant/mlme.h index cc58a5b..5db3665 100644 --- a/contrib/wpa/wpa_supplicant/mlme.h +++ b/contrib/wpa/wpa_supplicant/mlme.h @@ -19,19 +19,25 @@ struct wpa_supplicant; +struct ieee80211_rx_status { + int freq; + int channel; + int ssi; +}; + #ifdef CONFIG_CLIENT_MLME int ieee80211_sta_init(struct wpa_supplicant *wpa_s); void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s); -int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, const u8 *ssid, - size_t ssid_len); +int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, + struct wpa_driver_scan_params *params); int ieee80211_sta_deauthenticate(struct wpa_supplicant *wpa_s, u16 reason); int ieee80211_sta_disassociate(struct wpa_supplicant *wpa_s, u16 reason); int ieee80211_sta_associate(struct wpa_supplicant *wpa_s, struct wpa_driver_associate_params *params); int ieee80211_sta_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid, size_t *len); -void ieee80211_sta_free_hw_features(struct wpa_hw_modes *hw_features, +void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features, size_t num_hw_features); void ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len, struct ieee80211_rx_status *rx_status); @@ -42,8 +48,6 @@ int ieee80211_sta_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, int ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action, const u8 *target_ap, const u8 *ies, size_t ies_len); -int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, const u8 *ies, - size_t ies_len); #else /* CONFIG_CLIENT_MLME */ @@ -57,7 +61,7 @@ static inline void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s) } static inline int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, - const u8 *ssid, size_t ssid_len) + struct wpa_driver_scan_params *params) { return -1; } @@ -88,7 +92,7 @@ static inline int ieee80211_sta_get_ssid(struct wpa_supplicant *wpa_s, } static inline void -ieee80211_sta_free_hw_features(struct wpa_hw_modes *hw_features, +ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features, size_t num_hw_features) { } @@ -120,13 +124,6 @@ ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action, return -1; } -static inline int -ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, const u8 *ies, - size_t ies_len) -{ - return -1; -} - #endif /* CONFIG_CLIENT_MLME */ #endif /* MLME_H */ diff --git a/contrib/wpa/wpa_supplicant/nmake.mak b/contrib/wpa/wpa_supplicant/nmake.mak index 5e39c11..80e0ac8 100644 --- a/contrib/wpa/wpa_supplicant/nmake.mak +++ b/contrib/wpa/wpa_supplicant/nmake.mak @@ -28,7 +28,6 @@ CFLAGS = $(CFLAGS) /DCONFIG_NDIS_EVENTS_INTEGRATED CFLAGS = $(CFLAGS) /DCONFIG_ANSI_C_EXTRA CFLAGS = $(CFLAGS) /DCONFIG_WINPCAP CFLAGS = $(CFLAGS) /DIEEE8021X_EAPOL -CFLAGS = $(CFLAGS) /DEAP_TLS_FUNCS CFLAGS = $(CFLAGS) /DPKCS12_FUNCS CFLAGS = $(CFLAGS) /DEAP_MD5 CFLAGS = $(CFLAGS) /DEAP_TLS @@ -48,8 +47,8 @@ CFLAGS = $(CFLAGS) /DPCSC_FUNCS CFLAGS = $(CFLAGS) /DCONFIG_CTRL_IFACE CFLAGS = $(CFLAGS) /DCONFIG_CTRL_IFACE_NAMED_PIPE CFLAGS = $(CFLAGS) /DCONFIG_DRIVER_NDIS -CFLAGS = $(CFLAGS) /I..\src /I..\src\utils /I..\src\common /I..\src\crypto -CFLAGS = $(CFLAGS) /I..\src\rsn_supp /I..\src\eapol_supp /I. +CFLAGS = $(CFLAGS) /I..\src /I..\src\utils +CFLAGS = $(CFLAGS) /I. CFLAGS = $(CFLAGS) /DWIN32 CFLAGS = $(CFLAGS) /Fo$(OBJDIR)\\ /c CFLAGS = $(CFLAGS) /W3 @@ -64,9 +63,16 @@ OBJS = \ $(OBJDIR)\os_win32.obj \ $(OBJDIR)\eloop_win.obj \ $(OBJDIR)\sha1.obj \ + $(OBJDIR)\sha1-tlsprf.obj \ + $(OBJDIR)\sha1-pbkdf2.obj \ $(OBJDIR)\md5.obj \ - $(OBJDIR)\rc4.obj \ - $(OBJDIR)\aes_wrap.obj \ + $(OBJDIR)\aes-cbc.obj \ + $(OBJDIR)\aes-ctr.obj \ + $(OBJDIR)\aes-eax.obj \ + $(OBJDIR)\aes-encblock.obj \ + $(OBJDIR)\aes-omac1.obj \ + $(OBJDIR)\aes-unwrap.obj \ + $(OBJDIR)\aes-wrap.obj \ $(OBJDIR)\common.obj \ $(OBJDIR)\wpa_debug.obj \ $(OBJDIR)\wpabuf.obj \ @@ -111,12 +117,15 @@ OBJS = \ $(OBJDIR)\blacklist.obj \ $(OBJDIR)\scan.obj \ $(OBJDIR)\wpas_glue.obj \ + $(OBJDIR)\eap_register.obj \ $(OBJDIR)\config.obj \ $(OBJDIR)\l2_packet_winpcap.obj \ $(OBJDIR)\tls_openssl.obj \ $(OBJDIR)\ms_funcs.obj \ $(OBJDIR)\crypto_openssl.obj \ + $(OBJDIR)\fips_prf_openssl.obj \ $(OBJDIR)\pcsc_funcs.obj \ + $(OBJDIR)\notify.obj \ $(OBJDIR)\ndis_events.obj # OBJS = $(OBJS) $(OBJDIR)\eap_fast.obj @@ -148,9 +157,12 @@ OBJS_c = \ OBJS_p = \ $(OBJDIR)\os_win32.obj \ $(OBJDIR)\common.obj \ + $(OBJDIR)\wpa_debug.obj \ + $(OBJDIR)\wpabuf.obj \ $(OBJDIR)\sha1.obj \ $(OBJDIR)\md5.obj \ $(OBJDIR)\crypto_openssl.obj \ + $(OBJDIR)\sha1-pbkdf2.obj \ $(OBJDIR)\wpa_passphrase.obj LIBS = wbemuuid.lib libcmt.lib kernel32.lib uuid.lib ole32.lib oleaut32.lib \ diff --git a/contrib/wpa/wpa_supplicant/notify.c b/contrib/wpa/wpa_supplicant/notify.c new file mode 100644 index 0000000..ac65b4f --- /dev/null +++ b/contrib/wpa/wpa_supplicant/notify.c @@ -0,0 +1,339 @@ +/* + * wpa_supplicant - Event notifications + * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "utils/includes.h" + +#include "utils/common.h" +#include "common/wpa_ctrl.h" +#include "config.h" +#include "wpa_supplicant_i.h" +#include "wps_supplicant.h" +#include "dbus/dbus_common.h" +#include "dbus/dbus_old.h" +#include "dbus/dbus_new.h" +#include "driver_i.h" +#include "scan.h" +#include "notify.h" + +int wpas_notify_supplicant_initialized(struct wpa_global *global) +{ +#ifdef CONFIG_DBUS + if (global->params.dbus_ctrl_interface) { + global->dbus = wpas_dbus_init(global); + if (global->dbus == NULL) + return -1; + } +#endif /* CONFIG_DBUS */ + + return 0; +} + + +void wpas_notify_supplicant_deinitialized(struct wpa_global *global) +{ +#ifdef CONFIG_DBUS + if (global->dbus) + wpas_dbus_deinit(global->dbus); +#endif /* CONFIG_DBUS */ +} + + +int wpas_notify_iface_added(struct wpa_supplicant *wpa_s) +{ + if (wpas_dbus_register_iface(wpa_s)) + return -1; + + if (wpas_dbus_register_interface(wpa_s)) + return -1; + + return 0; +} + + +void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s) +{ + /* 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); +} + + +void wpas_notify_state_changed(struct wpa_supplicant *wpa_s, + enum wpa_states new_state, + enum wpa_states old_state) +{ + /* 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); +} + + +void wpas_notify_network_changed(struct wpa_supplicant *wpa_s) +{ + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_NETWORK); +} + + +void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s) +{ + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_AP_SCAN); +} + + +void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s) +{ + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_BSS); +} + + +void wpas_notify_network_enabled_changed(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + wpas_dbus_signal_network_enabled_changed(wpa_s, ssid); +} + + +void wpas_notify_network_selected(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + wpas_dbus_signal_network_selected(wpa_s, ssid->id); +} + + +void wpas_notify_scanning(struct wpa_supplicant *wpa_s) +{ + /* 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); +} + + +void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success) +{ + wpas_dbus_signal_scan_done(wpa_s, success); +} + + +void wpas_notify_scan_results(struct wpa_supplicant *wpa_s) +{ + /* notify the old DBus API */ + wpa_supplicant_dbus_notify_scan_results(wpa_s); + + wpas_wps_notify_scan_results(wpa_s); +} + + +void wpas_notify_wps_credential(struct wpa_supplicant *wpa_s, + const struct wps_credential *cred) +{ +#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 */ +} + + +void wpas_notify_wps_event_m2d(struct wpa_supplicant *wpa_s, + struct wps_event_m2d *m2d) +{ +#ifdef CONFIG_WPS + wpas_dbus_signal_wps_event_m2d(wpa_s, m2d); +#endif /* CONFIG_WPS */ +} + + +void wpas_notify_wps_event_fail(struct wpa_supplicant *wpa_s, + struct wps_event_fail *fail) +{ +#ifdef CONFIG_WPS + wpas_dbus_signal_wps_event_fail(wpa_s, fail); +#endif /* CONFIG_WPS */ +} + + +void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s) +{ +#ifdef CONFIG_WPS + wpas_dbus_signal_wps_event_success(wpa_s); +#endif /* CONFIG_WPS */ +} + + +void wpas_notify_network_added(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + wpas_dbus_register_network(wpa_s, ssid); +} + + +void wpas_notify_network_removed(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + wpas_dbus_unregister_network(wpa_s, ssid->id); +} + + +void wpas_notify_bss_added(struct wpa_supplicant *wpa_s, + u8 bssid[], unsigned int id) +{ + wpas_dbus_register_bss(wpa_s, bssid, id); + wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_ADDED "%u " MACSTR, + id, MAC2STR(bssid)); +} + + +void wpas_notify_bss_removed(struct wpa_supplicant *wpa_s, + u8 bssid[], unsigned int id) +{ + wpas_dbus_unregister_bss(wpa_s, bssid, id); + wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_REMOVED "%u " MACSTR, + id, MAC2STR(bssid)); +} + + +void wpas_notify_bss_freq_changed(struct wpa_supplicant *wpa_s, + unsigned int id) +{ + wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_FREQ, id); +} + + +void wpas_notify_bss_signal_changed(struct wpa_supplicant *wpa_s, + unsigned int id) +{ + wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_SIGNAL, + id); +} + + +void wpas_notify_bss_privacy_changed(struct wpa_supplicant *wpa_s, + unsigned int id) +{ + wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_PRIVACY, + id); +} + + +void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s, + unsigned int id) +{ + wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_MODE, id); +} + + +void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s, + unsigned int id) +{ + wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPA, id); +} + + +void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s, + unsigned int id) +{ + wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RSN, id); +} + + +void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s, + unsigned int id) +{ +} + + +void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s, + unsigned int id) +{ + wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_IES, id); +} + + +void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s, + unsigned int id) +{ + wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RATES, id); +} + + +void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name) +{ + wpas_dbus_signal_blob_added(wpa_s, name); +} + + +void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name) +{ + wpas_dbus_signal_blob_removed(wpa_s, name); +} + + +void wpas_notify_debug_level_changed(struct wpa_global *global) +{ + wpas_dbus_signal_debug_level_changed(global); +} + + +void wpas_notify_debug_timestamp_changed(struct wpa_global *global) +{ + wpas_dbus_signal_debug_timestamp_changed(global); +} + + +void wpas_notify_debug_show_keys_changed(struct wpa_global *global) +{ + wpas_dbus_signal_debug_show_keys_changed(global); +} + + +void wpas_notify_suspend(struct wpa_global *global) +{ + struct wpa_supplicant *wpa_s; + + os_get_time(&global->suspend_time); + wpa_printf(MSG_DEBUG, "System suspend notification"); + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) + wpa_drv_suspend(wpa_s); +} + + +void wpas_notify_resume(struct wpa_global *global) +{ + struct os_time now; + int slept; + struct wpa_supplicant *wpa_s; + + if (global->suspend_time.sec == 0) + slept = -1; + else { + os_get_time(&now); + slept = now.sec - global->suspend_time.sec; + } + wpa_printf(MSG_DEBUG, "System resume notification (slept %d seconds)", + slept); + + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { + wpa_drv_resume(wpa_s); + if (wpa_s->wpa_state == WPA_DISCONNECTED) + wpa_supplicant_req_scan(wpa_s, 0, 100000); + } +} diff --git a/contrib/wpa/wpa_supplicant/notify.h b/contrib/wpa/wpa_supplicant/notify.h new file mode 100644 index 0000000..2e70bdb --- /dev/null +++ b/contrib/wpa/wpa_supplicant/notify.h @@ -0,0 +1,81 @@ +/* + * wpa_supplicant - Event notifications + * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef NOTIFY_H +#define NOTIFY_H + +struct wps_credential; +struct wps_event_m2d; +struct wps_event_fail; + +int wpas_notify_supplicant_initialized(struct wpa_global *global); +void wpas_notify_supplicant_deinitialized(struct wpa_global *global); +int wpas_notify_iface_added(struct wpa_supplicant *wpa_s); +void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s); +void wpas_notify_state_changed(struct wpa_supplicant *wpa_s, + enum wpa_states new_state, + enum wpa_states old_state); +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); +void wpas_notify_network_enabled_changed(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +void wpas_notify_network_selected(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +void wpas_notify_scanning(struct wpa_supplicant *wpa_s); +void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success); +void wpas_notify_scan_results(struct wpa_supplicant *wpa_s); +void wpas_notify_wps_credential(struct wpa_supplicant *wpa_s, + const struct wps_credential *cred); +void wpas_notify_wps_event_m2d(struct wpa_supplicant *wpa_s, + struct wps_event_m2d *m2d); +void wpas_notify_wps_event_fail(struct wpa_supplicant *wpa_s, + struct wps_event_fail *fail); +void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s); +void wpas_notify_network_added(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +void wpas_notify_network_removed(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +void wpas_notify_bss_added(struct wpa_supplicant *wpa_s, u8 bssid[], + unsigned int id); +void wpas_notify_bss_removed(struct wpa_supplicant *wpa_s, u8 bssid[], + unsigned int id); +void wpas_notify_bss_freq_changed(struct wpa_supplicant *wpa_s, + unsigned int id); +void wpas_notify_bss_signal_changed(struct wpa_supplicant *wpa_s, + unsigned int id); +void wpas_notify_bss_privacy_changed(struct wpa_supplicant *wpa_s, + unsigned int id); +void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s, + unsigned int id); +void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s, + unsigned int id); +void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s, + unsigned int id); +void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s, + unsigned int id); +void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s, + unsigned int id); +void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s, + unsigned int id); +void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name); +void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name); + +void wpas_notify_debug_level_changed(struct wpa_global *global); +void wpas_notify_debug_timestamp_changed(struct wpa_global *global); +void wpas_notify_debug_show_keys_changed(struct wpa_global *global); +void wpas_notify_suspend(struct wpa_global *global); +void wpas_notify_resume(struct wpa_global *global); + +#endif /* NOTIFY_H */ diff --git a/contrib/wpa/wpa_supplicant/preauth_test.c b/contrib/wpa/wpa_supplicant/preauth_test.c index 86307a8..d38a6bb 100644 --- a/contrib/wpa/wpa_supplicant/preauth_test.c +++ b/contrib/wpa/wpa_supplicant/preauth_test.c @@ -22,20 +22,21 @@ #include "config.h" #include "eapol_supp/eapol_supp_sm.h" #include "eloop.h" -#include "wpa.h" +#include "rsn_supp/wpa.h" #include "eap_peer/eap.h" #include "wpa_supplicant_i.h" #include "l2_packet/l2_packet.h" #include "ctrl_iface.h" #include "pcsc_funcs.h" -#include "preauth.h" -#include "pmksa_cache.h" +#include "rsn_supp/preauth.h" +#include "rsn_supp/pmksa_cache.h" +#include "drivers/driver.h" extern int wpa_debug_level; extern int wpa_debug_show_keys; -struct wpa_driver_ops *wpa_supplicant_drivers[] = { NULL }; +struct wpa_driver_ops *wpa_drivers[] = { NULL }; struct preauth_test_data { @@ -90,14 +91,14 @@ static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type, } -static void _wpa_supplicant_set_state(void *ctx, wpa_states state) +static void _wpa_supplicant_set_state(void *ctx, enum wpa_states state) { struct wpa_supplicant *wpa_s = ctx; wpa_s->wpa_state = state; } -static wpa_states _wpa_supplicant_get_state(void *ctx) +static enum wpa_states _wpa_supplicant_get_state(void *ctx) { struct wpa_supplicant *wpa_s = ctx; return wpa_s->wpa_state; @@ -138,7 +139,7 @@ static int wpa_supplicant_get_bssid(void *wpa_s, u8 *bssid) } -static int wpa_supplicant_set_key(void *wpa_s, wpa_alg alg, +static int wpa_supplicant_set_key(void *wpa_s, enum wpa_alg alg, const u8 *addr, int key_idx, int set_tx, const u8 *seq, size_t seq_len, const u8 *key, size_t key_len) @@ -239,6 +240,7 @@ static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *ifname) assert(ctx != NULL); ctx->ctx = wpa_s; + ctx->msg_ctx = wpa_s; ctx->set_state = _wpa_supplicant_set_state; ctx->get_state = _wpa_supplicant_get_state; ctx->deauthenticate = _wpa_supplicant_deauthenticate; @@ -275,10 +277,9 @@ static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *ifname) } -static void eapol_test_terminate(int sig, void *eloop_ctx, - void *signal_ctx) +static void eapol_test_terminate(int sig, void *signal_ctx) { - struct wpa_supplicant *wpa_s = eloop_ctx; + struct wpa_supplicant *wpa_s = signal_ctx; wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig); eloop_terminate(); } @@ -310,12 +311,12 @@ int main(int argc, char *argv[]) return -1; } - if (eap_peer_register_methods()) { + if (eap_register_methods()) { wpa_printf(MSG_ERROR, "Failed to register EAP methods"); return -1; } - if (eloop_init(&wpa_s)) { + if (eloop_init()) { wpa_printf(MSG_ERROR, "Failed to initialize event loop"); return -1; } @@ -352,8 +353,8 @@ int main(int argc, char *argv[]) eloop_register_timeout(30, 0, eapol_test_timeout, &preauth_test, NULL); eloop_register_timeout(0, 100000, eapol_test_poll, &wpa_s, NULL); - eloop_register_signal_terminate(eapol_test_terminate, NULL); - eloop_register_signal_reconfig(eapol_test_terminate, NULL); + eloop_register_signal_terminate(eapol_test_terminate, &wpa_s); + eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s); eloop_run(); if (preauth_test.auth_timed_out) diff --git a/contrib/wpa/wpa_supplicant/scan.c b/contrib/wpa/wpa_supplicant/scan.c index 8cb7a42..edc8c83 100644 --- a/contrib/wpa/wpa_supplicant/scan.c +++ b/contrib/wpa/wpa_supplicant/scan.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - Scanning - * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> + * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -12,15 +12,19 @@ * See README and COPYING for more details. */ -#include "includes.h" +#include "utils/includes.h" -#include "common.h" -#include "eloop.h" +#include "utils/common.h" +#include "utils/eloop.h" +#include "common/ieee802_11_defs.h" #include "config.h" #include "wpa_supplicant_i.h" +#include "driver_i.h" #include "mlme.h" #include "wps_supplicant.h" -#include "ctrl_iface_dbus.h" +#include "notify.h" +#include "bss.h" +#include "scan.h" static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s) @@ -32,8 +36,11 @@ static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s) if (ssid == NULL) return; - if (wpa_s->current_ssid == NULL) + if (wpa_s->current_ssid == NULL) { wpa_s->current_ssid = ssid; + if (wpa_s->current_ssid != NULL) + wpas_notify_network_changed(wpa_s); + } wpa_supplicant_initiate_eapol(wpa_s); wpa_printf(MSG_DEBUG, "Already associated with a configured network - " "generating associated event"); @@ -79,18 +86,170 @@ int wpa_supplicant_enabled_networks(struct wpa_config *conf) } +static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + while (ssid) { + if (!ssid->disabled) + break; + ssid = ssid->next; + } + + /* ap_scan=2 mode - try to associate with each SSID. */ + if (ssid == NULL) { + wpa_printf(MSG_DEBUG, "wpa_supplicant_scan: Reached " + "end of scan list - go back to beginning"); + wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; + wpa_supplicant_req_scan(wpa_s, 0, 0); + return; + } + if (ssid->next) { + /* Continue from the next SSID on the next attempt. */ + wpa_s->prev_scan_ssid = ssid; + } else { + /* Start from the beginning of the SSID list. */ + wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; + } + wpa_supplicant_associate(wpa_s, NULL, ssid); +} + + +static int int_array_len(const int *a) +{ + int i; + for (i = 0; a && a[i]; i++) + ; + return i; +} + + +static void int_array_concat(int **res, const int *a) +{ + int reslen, alen, i; + int *n; + + reslen = int_array_len(*res); + alen = int_array_len(a); + + n = os_realloc(*res, (reslen + alen + 1) * sizeof(int)); + if (n == NULL) { + os_free(*res); + *res = NULL; + return; + } + for (i = 0; i <= alen; i++) + n[reslen + i] = a[i]; + *res = n; +} + + +static int freq_cmp(const void *a, const void *b) +{ + int _a = *(int *) a; + int _b = *(int *) b; + + if (_a == 0) + return 1; + if (_b == 0) + return -1; + return _a - _b; +} + + +static void int_array_sort_unique(int *a) +{ + int alen; + int i, j; + + if (a == NULL) + return; + + alen = int_array_len(a); + qsort(a, alen, sizeof(int), freq_cmp); + + i = 0; + j = 1; + while (a[i] && a[j]) { + if (a[i] == a[j]) { + j++; + continue; + } + a[++i] = a[j++]; + } + if (a[i]) + i++; + a[i] = 0; +} + + +int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, + struct wpa_driver_scan_params *params) +{ + int ret; + + wpa_supplicant_notify_scanning(wpa_s, 1); + + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) + ret = ieee80211_sta_req_scan(wpa_s, params); + else + ret = wpa_drv_scan(wpa_s, params); + + if (ret) { + wpa_supplicant_notify_scanning(wpa_s, 0); + wpas_notify_scan_done(wpa_s, 0); + } else + wpa_s->scan_runs++; + + return ret; +} + + +static struct wpa_driver_scan_filter * +wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids) +{ + struct wpa_driver_scan_filter *ssids; + struct wpa_ssid *ssid; + size_t count; + + *num_ssids = 0; + if (!conf->filter_ssids) + return NULL; + + for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) { + if (ssid->ssid && ssid->ssid_len) + count++; + } + if (count == 0) + return NULL; + ssids = os_zalloc(count * sizeof(struct wpa_driver_scan_filter)); + if (ssids == NULL) + return NULL; + + for (ssid = conf->ssid; ssid; ssid = ssid->next) { + if (!ssid->ssid || !ssid->ssid_len) + continue; + os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len); + ssids[*num_ssids].ssid_len = ssid->ssid_len; + (*num_ssids)++; + } + + return ssids; +} + + static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; struct wpa_ssid *ssid; int scan_req = 0, ret; struct wpabuf *wps_ie = NULL; - const u8 *extra_ie = NULL; - size_t extra_ie_len = 0; - int wps = 0; #ifdef CONFIG_WPS + int wps = 0; enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO; #endif /* CONFIG_WPS */ + struct wpa_driver_scan_params params; + size_t max_ssids; + enum wpa_states prev_state; if (wpa_s->disconnected && !wpa_s->scan_req) { wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); @@ -103,14 +262,13 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); return; } - scan_req = wpa_s->scan_req; - wpa_s->scan_req = 0; if (wpa_s->conf->ap_scan != 0 && - wpa_s->driver && IS_WIRED(wpa_s->driver)) { + (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) { wpa_printf(MSG_DEBUG, "Using wired authentication - " "overriding ap_scan configuration"); wpa_s->conf->ap_scan = 0; + wpas_notify_ap_scan_changed(wpa_s); } if (wpa_s->conf->ap_scan == 0) { @@ -118,12 +276,32 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) return; } + if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) || + wpa_s->conf->ap_scan == 2) + max_ssids = 1; + else { + max_ssids = wpa_s->max_scan_ssids; + if (max_ssids > WPAS_MAX_SCAN_SSIDS) + max_ssids = WPAS_MAX_SCAN_SSIDS; + } + +#ifdef CONFIG_WPS + wps = wpas_wps_in_use(wpa_s->conf, &req_type); +#endif /* CONFIG_WPS */ + + scan_req = wpa_s->scan_req; + wpa_s->scan_req = 0; + + os_memset(¶ms, 0, sizeof(params)); + + prev_state = wpa_s->wpa_state; if (wpa_s->wpa_state == WPA_DISCONNECTED || wpa_s->wpa_state == WPA_INACTIVE) wpa_supplicant_set_state(wpa_s, WPA_SCANNING); + /* Find the starting point from which to continue scanning */ ssid = wpa_s->conf->ssid; - if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) { + if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) { while (ssid) { if (ssid == wpa_s->prev_scan_ssid) { ssid = ssid->next; @@ -132,91 +310,111 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) ssid = ssid->next; } } - while (ssid) { - if (!ssid->disabled && - (ssid->scan_ssid || wpa_s->conf->ap_scan == 2)) - break; - ssid = ssid->next; - } - if (scan_req != 2 && wpa_s->conf->ap_scan == 2) { + if (scan_req != 2 && (wpa_s->conf->ap_scan == 2 || + wpa_s->connect_without_scan)) { + wpa_s->connect_without_scan = 0; + wpa_supplicant_assoc_try(wpa_s, ssid); + return; + } else if (wpa_s->conf->ap_scan == 2) { /* - * ap_scan=2 mode - try to associate with each SSID instead of - * scanning for each scan_ssid=1 network. + * User-initiated scan request in ap_scan == 2; scan with + * wildcard SSID. */ - if (ssid == NULL) { - wpa_printf(MSG_DEBUG, "wpa_supplicant_scan: Reached " - "end of scan list - go back to beginning"); - wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; - wpa_supplicant_req_scan(wpa_s, 0, 0); - return; + ssid = NULL; + } else { + struct wpa_ssid *start = ssid, *tssid; + int freqs_set = 0; + if (ssid == NULL && max_ssids > 1) + ssid = wpa_s->conf->ssid; + while (ssid) { + if (!ssid->disabled && ssid->scan_ssid) { + wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID", + ssid->ssid, ssid->ssid_len); + params.ssids[params.num_ssids].ssid = + ssid->ssid; + params.ssids[params.num_ssids].ssid_len = + ssid->ssid_len; + params.num_ssids++; + if (params.num_ssids + 1 >= max_ssids) + break; + } + ssid = ssid->next; + if (ssid == start) + break; + if (ssid == NULL && max_ssids > 1 && + start != wpa_s->conf->ssid) + ssid = wpa_s->conf->ssid; } - if (ssid->next) { - /* Continue from the next SSID on the next attempt. */ - wpa_s->prev_scan_ssid = ssid; - } else { - /* Start from the beginning of the SSID list. */ - wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; + + for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) { + if (tssid->disabled) + continue; + if ((params.freqs || !freqs_set) && tssid->scan_freq) { + int_array_concat(¶ms.freqs, + tssid->scan_freq); + } else { + os_free(params.freqs); + params.freqs = NULL; + } + freqs_set = 1; } - wpa_supplicant_associate(wpa_s, NULL, ssid); - return; + int_array_sort_unique(params.freqs); } - wpa_printf(MSG_DEBUG, "Starting AP scan (%s SSID)", - ssid ? "specific": "broadcast"); if (ssid) { - wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID", - ssid->ssid, ssid->ssid_len); wpa_s->prev_scan_ssid = ssid; - } else - wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; + if (max_ssids > 1) { + wpa_printf(MSG_DEBUG, "Include wildcard SSID in the " + "scan request"); + params.num_ssids++; + } + wpa_printf(MSG_DEBUG, "Starting AP scan for specific SSID(s)"); + } else { + wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; + params.num_ssids++; + wpa_printf(MSG_DEBUG, "Starting AP scan for wildcard SSID"); + } #ifdef CONFIG_WPS - wps = wpas_wps_in_use(wpa_s->conf, &req_type); -#endif /* CONFIG_WPS */ - - if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1 && - !wpa_s->use_client_mlme && wps != 2) { - wpa_s->scan_res_tried++; - wpa_s->scan_req = scan_req; - wpa_printf(MSG_DEBUG, "Trying to get current scan results " - "first without requesting a new scan to speed up " - "initial association"); - wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL); - return; + if (params.freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) { + /* + * Optimize post-provisioning scan based on channel used + * during provisioning. + */ + wpa_printf(MSG_DEBUG, "WPS: Scan only frequency %u MHz that " + "was used during provisioning", wpa_s->wps_freq); + params.freqs = os_zalloc(2 * sizeof(int)); + if (params.freqs) + params.freqs[0] = wpa_s->wps_freq; + wpa_s->after_wps--; } -#ifdef CONFIG_WPS if (wps) { wps_ie = wps_build_probe_req_ie(wps == 2, &wpa_s->wps->dev, wpa_s->wps->uuid, req_type); if (wps_ie) { - extra_ie = wpabuf_head(wps_ie); - extra_ie_len = wpabuf_len(wps_ie); + params.extra_ies = wpabuf_head(wps_ie); + params.extra_ies_len = wpabuf_len(wps_ie); } } #endif /* CONFIG_WPS */ - wpa_supplicant_notify_scanning(wpa_s, 1); + params.filter_ssids = wpa_supplicant_build_filter_ssids( + wpa_s->conf, ¶ms.num_filter_ssids); - if (wpa_s->use_client_mlme) { - ieee80211_sta_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len); - ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL, - ssid ? ssid->ssid_len : 0); - } else { - wpa_drv_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len); - ret = wpa_drv_scan(wpa_s, ssid ? ssid->ssid : NULL, - ssid ? ssid->ssid_len : 0); - } + ret = wpa_supplicant_trigger_scan(wpa_s, ¶ms); wpabuf_free(wps_ie); + os_free(params.freqs); + os_free(params.filter_ssids); if (ret) { wpa_printf(MSG_WARNING, "Failed to initiate AP scan."); - wpa_supplicant_notify_scanning(wpa_s, 0); - wpa_supplicant_req_scan(wpa_s, 10, 0); - } else - wpa_s->scan_runs++; + if (prev_state != wpa_s->wpa_state) + wpa_supplicant_set_state(wpa_s, prev_state); + wpa_supplicant_req_scan(wpa_s, 1, 0); + } } @@ -279,7 +477,213 @@ void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s, { if (wpa_s->scanning != scanning) { wpa_s->scanning = scanning; - wpa_supplicant_dbus_notify_scanning(wpa_s); + wpas_notify_scanning(wpa_s); + } +} + + +static int wpa_scan_get_max_rate(const struct wpa_scan_res *res) +{ + int rate = 0; + const u8 *ie; + int i; + + ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES); + for (i = 0; ie && i < ie[1]; i++) { + if ((ie[i + 2] & 0x7f) > rate) + rate = ie[i + 2] & 0x7f; + } + + ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES); + for (i = 0; ie && i < ie[1]; i++) { + if ((ie[i + 2] & 0x7f) > rate) + rate = ie[i + 2] & 0x7f; + } + + return rate; +} + + +const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie) +{ + const u8 *end, *pos; + + pos = (const u8 *) (res + 1); + end = pos + res->ie_len; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + break; + if (pos[0] == ie) + return pos; + pos += 2 + pos[1]; + } + + return NULL; +} + + +const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res, + u32 vendor_type) +{ + const u8 *end, *pos; + + pos = (const u8 *) (res + 1); + end = pos + res->ie_len; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + break; + if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && + vendor_type == WPA_GET_BE32(&pos[2])) + return pos; + pos += 2 + pos[1]; + } + + return NULL; +} + + +struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res, + u32 vendor_type) +{ + struct wpabuf *buf; + const u8 *end, *pos; + + buf = wpabuf_alloc(res->ie_len); + if (buf == NULL) + return NULL; + + pos = (const u8 *) (res + 1); + end = pos + res->ie_len; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + break; + if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && + vendor_type == WPA_GET_BE32(&pos[2])) + wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4); + pos += 2 + pos[1]; + } + + if (wpabuf_len(buf) == 0) { + wpabuf_free(buf); + buf = NULL; + } + + return buf; +} + + +/* Compare function for sorting scan results. Return >0 if @b is considered + * better. */ +static int wpa_scan_result_compar(const void *a, const void *b) +{ + struct wpa_scan_res **_wa = (void *) a; + struct wpa_scan_res **_wb = (void *) b; + struct wpa_scan_res *wa = *_wa; + struct wpa_scan_res *wb = *_wb; + int wpa_a, wpa_b, maxrate_a, maxrate_b; + + /* WPA/WPA2 support preferred */ + wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL || + wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL; + wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL || + wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL; + + if (wpa_b && !wpa_a) + return 1; + if (!wpa_b && wpa_a) + return -1; + + /* privacy support preferred */ + if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 && + (wb->caps & IEEE80211_CAP_PRIVACY)) + return 1; + if ((wa->caps & IEEE80211_CAP_PRIVACY) && + (wb->caps & IEEE80211_CAP_PRIVACY) == 0) + return -1; + + /* best/max rate preferred if signal level close enough XXX */ + if ((wa->level && wb->level && abs(wb->level - wa->level) < 5) || + (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) { + maxrate_a = wpa_scan_get_max_rate(wa); + maxrate_b = wpa_scan_get_max_rate(wb); + if (maxrate_a != maxrate_b) + return maxrate_b - maxrate_a; + } + + /* use freq for channel preference */ + + /* all things being equal, use signal level; if signal levels are + * identical, use quality values since some drivers may only report + * that value and leave the signal level zero */ + if (wb->level == wa->level) + return wb->qual - wa->qual; + return wb->level - wa->level; +} + + +/** + * wpa_supplicant_get_scan_results - Get scan results + * @wpa_s: Pointer to wpa_supplicant data + * @info: Information about what was scanned or %NULL if not available + * @new_scan: Whether a new scan was performed + * Returns: Scan results, %NULL on failure + * + * This function request the current scan results from the driver and updates + * the local BSS list wpa_s->bss. The caller is responsible for freeing the + * results with wpa_scan_results_free(). + */ +struct wpa_scan_results * +wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, + struct scan_info *info, int new_scan) +{ + struct wpa_scan_results *scan_res; + size_t i; + + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) + scan_res = ieee80211_sta_get_scan_results(wpa_s); + else + scan_res = wpa_drv_get_scan_results2(wpa_s); + if (scan_res == NULL) { + wpa_printf(MSG_DEBUG, "Failed to get scan results"); + return NULL; } + + qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), + wpa_scan_result_compar); + + wpa_bss_update_start(wpa_s); + for (i = 0; i < scan_res->num; i++) + wpa_bss_update_scan_res(wpa_s, scan_res->res[i]); + wpa_bss_update_end(wpa_s, info, new_scan); + + return scan_res; } + +int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s) +{ + struct wpa_scan_results *scan_res; + scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0); + if (scan_res == NULL) + return -1; + wpa_scan_results_free(scan_res); + + return 0; +} + + +void wpa_scan_results_free(struct wpa_scan_results *res) +{ + size_t i; + + if (res == NULL) + return; + + for (i = 0; i < res->num; i++) + os_free(res->res[i]); + os_free(res->res); + os_free(res); +} diff --git a/contrib/wpa/wpa_supplicant/scan.h b/contrib/wpa/wpa_supplicant/scan.h new file mode 100644 index 0000000..441fdbb --- /dev/null +++ b/contrib/wpa/wpa_supplicant/scan.h @@ -0,0 +1,37 @@ +/* + * WPA Supplicant - Scanning + * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef SCAN_H +#define SCAN_H + +int wpa_supplicant_enabled_networks(struct wpa_config *conf); +void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec); +void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s); +void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s, + int scanning); +struct wpa_driver_scan_params; +int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, + struct wpa_driver_scan_params *params); +struct wpa_scan_results * +wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, + struct scan_info *info, int new_scan); +int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s); +const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie); +const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res, + u32 vendor_type); +struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res, + u32 vendor_type); +void wpa_scan_results_free(struct wpa_scan_results *res); + +#endif /* SCAN_H */ diff --git a/contrib/wpa/wpa_supplicant/sme.c b/contrib/wpa/wpa_supplicant/sme.c new file mode 100644 index 0000000..5604e97 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/sme.c @@ -0,0 +1,490 @@ +/* + * wpa_supplicant - SME + * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "common/ieee802_11_defs.h" +#include "common/ieee802_11_common.h" +#include "eapol_supp/eapol_supp_sm.h" +#include "common/wpa_common.h" +#include "rsn_supp/wpa.h" +#include "rsn_supp/pmksa_cache.h" +#include "config.h" +#include "wpa_supplicant_i.h" +#include "driver_i.h" +#include "wpas_glue.h" +#include "wps_supplicant.h" +#include "notify.h" +#include "blacklist.h" +#include "bss.h" +#include "scan.h" +#include "sme.h" + +void sme_authenticate(struct wpa_supplicant *wpa_s, + struct wpa_bss *bss, struct wpa_ssid *ssid) +{ + struct wpa_driver_auth_params params; + struct wpa_ssid *old_ssid; +#ifdef CONFIG_IEEE80211R + const u8 *ie; +#endif /* CONFIG_IEEE80211R */ +#ifdef CONFIG_IEEE80211R + const u8 *md = NULL; +#endif /* CONFIG_IEEE80211R */ + int i, bssid_changed; + + if (bss == NULL) { + wpa_printf(MSG_ERROR, "SME: No scan result available for the " + "network"); + return; + } + + wpa_s->current_bss = bss; + + os_memset(¶ms, 0, sizeof(params)); + wpa_s->reassociate = 0; + + params.freq = bss->freq; + params.bssid = bss->bssid; + params.ssid = bss->ssid; + params.ssid_len = bss->ssid_len; + + if (wpa_s->sme.ssid_len != params.ssid_len || + os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0) + wpa_s->sme.prev_bssid_set = 0; + + wpa_s->sme.freq = params.freq; + os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len); + wpa_s->sme.ssid_len = params.ssid_len; + + params.auth_alg = WPA_AUTH_ALG_OPEN; +#ifdef IEEE8021X_EAPOL + if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { + if (ssid->leap) { + if (ssid->non_leap == 0) + params.auth_alg = WPA_AUTH_ALG_LEAP; + else + params.auth_alg |= WPA_AUTH_ALG_LEAP; + } + } +#endif /* IEEE8021X_EAPOL */ + wpa_printf(MSG_DEBUG, "Automatic auth_alg selection: 0x%x", + params.auth_alg); + if (ssid->auth_alg) { + params.auth_alg = ssid->auth_alg; + wpa_printf(MSG_DEBUG, "Overriding auth_alg selection: 0x%x", + params.auth_alg); + } + + for (i = 0; i < NUM_WEP_KEYS; i++) { + if (ssid->wep_key_len[i]) + params.wep_key[i] = ssid->wep_key[i]; + params.wep_key_len[i] = ssid->wep_key_len[i]; + } + params.wep_tx_keyidx = ssid->wep_tx_keyidx; + + bssid_changed = !is_zero_ether_addr(wpa_s->bssid); + os_memset(wpa_s->bssid, 0, ETH_ALEN); + os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); + if (bssid_changed) + wpas_notify_bssid_changed(wpa_s); + + if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || + wpa_bss_get_ie(bss, WLAN_EID_RSN)) && + (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK | + WPA_KEY_MGMT_FT_IEEE8021X | + WPA_KEY_MGMT_FT_PSK | + WPA_KEY_MGMT_IEEE8021X_SHA256 | + WPA_KEY_MGMT_PSK_SHA256))) { + int try_opportunistic; + try_opportunistic = ssid->proactive_key_caching && + (ssid->proto & WPA_PROTO_RSN); + if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, + wpa_s->current_ssid, + try_opportunistic) == 0) + eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1); + wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); + if (wpa_supplicant_set_suites(wpa_s, bss, ssid, + wpa_s->sme.assoc_req_ie, + &wpa_s->sme.assoc_req_ie_len)) { + wpa_printf(MSG_WARNING, "SME: Failed to set WPA key " + "management and encryption suites"); + return; + } + } else if (ssid->key_mgmt & + (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X | + WPA_KEY_MGMT_WPA_NONE | WPA_KEY_MGMT_FT_PSK | + WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_PSK_SHA256 | + WPA_KEY_MGMT_IEEE8021X_SHA256)) { + wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); + if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, + wpa_s->sme.assoc_req_ie, + &wpa_s->sme.assoc_req_ie_len)) { + wpa_printf(MSG_WARNING, "SME: Failed to set WPA key " + "management and encryption suites (no scan " + "results)"); + return; + } +#ifdef CONFIG_WPS + } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) { + struct wpabuf *wps_ie; + wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid)); + if (wps_ie && wpabuf_len(wps_ie) <= + sizeof(wpa_s->sme.assoc_req_ie)) { + wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie); + os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie), + wpa_s->sme.assoc_req_ie_len); + } else + wpa_s->sme.assoc_req_ie_len = 0; + wpabuf_free(wps_ie); + wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); +#endif /* CONFIG_WPS */ + } else { + wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); + wpa_s->sme.assoc_req_ie_len = 0; + } + +#ifdef CONFIG_IEEE80211R + ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); + 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) { + /* Prepare for the next transition */ + wpa_ft_prepare_auth_request(wpa_s->wpa, ie); + } + + if (md && ssid->key_mgmt & (WPA_KEY_MGMT_FT_PSK | + WPA_KEY_MGMT_FT_IEEE8021X)) { + if (wpa_s->sme.assoc_req_ie_len + 5 < + sizeof(wpa_s->sme.assoc_req_ie)) { + struct rsn_mdie *mdie; + u8 *pos = wpa_s->sme.assoc_req_ie + + wpa_s->sme.assoc_req_ie_len; + *pos++ = WLAN_EID_MOBILITY_DOMAIN; + *pos++ = sizeof(*mdie); + mdie = (struct rsn_mdie *) pos; + os_memcpy(mdie->mobility_domain, md, + MOBILITY_DOMAIN_ID_LEN); + mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN]; + wpa_s->sme.assoc_req_ie_len += 5; + } + + if (wpa_s->sme.ft_used && + os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 && + wpa_sm_has_ptk(wpa_s->wpa)) { + wpa_printf(MSG_DEBUG, "SME: Trying to use FT " + "over-the-air"); + params.auth_alg = WPA_AUTH_ALG_FT; + params.ie = wpa_s->sme.ft_ies; + params.ie_len = wpa_s->sme.ft_ies_len; + } + } +#endif /* CONFIG_IEEE80211R */ + +#ifdef CONFIG_IEEE80211W + wpa_s->sme.mfp = ssid->ieee80211w; + if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION) { + const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); + struct wpa_ie_data _ie; + if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 && + _ie.capabilities & + (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) { + wpa_printf(MSG_DEBUG, "WPA: Selected AP supports MFP: " + "require MFP"); + wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED; + } + } +#endif /* CONFIG_IEEE80211W */ + + wpa_supplicant_cancel_scan(wpa_s); + + wpa_msg(wpa_s, MSG_INFO, "Trying to authenticate with " MACSTR + " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), + wpa_ssid_txt(params.ssid, params.ssid_len), params.freq); + + wpa_clear_keys(wpa_s, bss->bssid); + wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); + old_ssid = wpa_s->current_ssid; + wpa_s->current_ssid = ssid; + wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); + wpa_supplicant_initiate_eapol(wpa_s); + if (old_ssid != wpa_s->current_ssid) + wpas_notify_network_changed(wpa_s); + + wpa_s->sme.auth_alg = params.auth_alg; + if (wpa_drv_authenticate(wpa_s, ¶ms) < 0) { + wpa_msg(wpa_s, MSG_INFO, "Authentication request to the " + "driver failed"); + wpa_supplicant_req_scan(wpa_s, 1, 0); + return; + } + + /* TODO: add timeout on authentication */ + + /* + * Association will be started based on the authentication event from + * the driver. + */ +} + + +void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) +{ + struct wpa_ssid *ssid = wpa_s->current_ssid; + + if (ssid == NULL) { + wpa_printf(MSG_DEBUG, "SME: Ignore authentication event when " + "network is not selected"); + return; + } + + if (wpa_s->wpa_state != WPA_AUTHENTICATING) { + wpa_printf(MSG_DEBUG, "SME: Ignore authentication event when " + "not in authenticating state"); + return; + } + + if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0) { + wpa_printf(MSG_DEBUG, "SME: Ignore authentication with " + "unexpected peer " MACSTR, + MAC2STR(data->auth.peer)); + return; + } + + wpa_printf(MSG_DEBUG, "SME: Authentication response: peer=" MACSTR + " auth_type=%d status_code=%d", + MAC2STR(data->auth.peer), data->auth.auth_type, + data->auth.status_code); + wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs", + data->auth.ies, data->auth.ies_len); + + if (data->auth.status_code != WLAN_STATUS_SUCCESS) { + wpa_printf(MSG_DEBUG, "SME: Authentication failed (status " + "code %d)", data->auth.status_code); + + if (data->auth.status_code != + WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG || + wpa_s->sme.auth_alg == data->auth.auth_type || + wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) + return; + + switch (data->auth.auth_type) { + case WLAN_AUTH_OPEN: + wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED; + + wpa_printf(MSG_DEBUG, "SME: Trying SHARED auth"); + wpa_supplicant_associate(wpa_s, wpa_s->current_bss, + wpa_s->current_ssid); + return; + + case WLAN_AUTH_SHARED_KEY: + wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP; + + wpa_printf(MSG_DEBUG, "SME: Trying LEAP auth"); + wpa_supplicant_associate(wpa_s, wpa_s->current_bss, + wpa_s->current_ssid); + return; + + default: + return; + } + } + +#ifdef CONFIG_IEEE80211R + if (data->auth.auth_type == WLAN_AUTH_FT) { + union wpa_event_data edata; + os_memset(&edata, 0, sizeof(edata)); + edata.ft_ies.ies = data->auth.ies; + edata.ft_ies.ies_len = data->auth.ies_len; + os_memcpy(edata.ft_ies.target_ap, data->auth.peer, ETH_ALEN); + wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &edata); + } +#endif /* CONFIG_IEEE80211R */ + + sme_associate(wpa_s, ssid->mode, data->auth.peer, + data->auth.auth_type); +} + + +void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, + const u8 *bssid, u16 auth_type) +{ + struct wpa_driver_associate_params params; + struct ieee802_11_elems elems; + + os_memset(¶ms, 0, sizeof(params)); + params.bssid = bssid; + params.ssid = wpa_s->sme.ssid; + params.ssid_len = wpa_s->sme.ssid_len; + params.freq = wpa_s->sme.freq; + params.wpa_ie = wpa_s->sme.assoc_req_ie_len ? + wpa_s->sme.assoc_req_ie : NULL; + params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len; +#ifdef CONFIG_IEEE80211R + if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) { + params.wpa_ie = wpa_s->sme.ft_ies; + params.wpa_ie_len = wpa_s->sme.ft_ies_len; + } +#endif /* CONFIG_IEEE80211R */ + params.mode = mode; + params.mgmt_frame_protection = wpa_s->sme.mfp; + if (wpa_s->sme.prev_bssid_set) + params.prev_bssid = wpa_s->sme.prev_bssid; + + wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR + " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), + params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "", + params.freq); + + wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); + + if (params.wpa_ie == NULL || + ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0) + < 0) { + wpa_printf(MSG_DEBUG, "SME: Could not parse own IEs?!"); + os_memset(&elems, 0, sizeof(elems)); + } + if (elems.rsn_ie) + wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2, + elems.rsn_ie_len + 2); + else if (elems.wpa_ie) + wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2, + elems.wpa_ie_len + 2); + else + wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); + + if (wpa_drv_associate(wpa_s, ¶ms) < 0) { + wpa_msg(wpa_s, MSG_INFO, "Association request to the driver " + "failed"); + wpa_supplicant_req_scan(wpa_s, 5, 0); + return; + } + + /* TODO: add timeout on association */ +} + + +int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, + const u8 *ies, size_t ies_len) +{ + if (md == NULL || ies == NULL) { + wpa_printf(MSG_DEBUG, "SME: Remove mobility domain"); + os_free(wpa_s->sme.ft_ies); + wpa_s->sme.ft_ies = NULL; + wpa_s->sme.ft_ies_len = 0; + wpa_s->sme.ft_used = 0; + return 0; + } + + os_memcpy(wpa_s->sme.mobility_domain, md, MOBILITY_DOMAIN_ID_LEN); + wpa_hexdump(MSG_DEBUG, "SME: FT IEs", ies, ies_len); + os_free(wpa_s->sme.ft_ies); + wpa_s->sme.ft_ies = os_malloc(ies_len); + if (wpa_s->sme.ft_ies == NULL) + return -1; + os_memcpy(wpa_s->sme.ft_ies, ies, ies_len); + wpa_s->sme.ft_ies_len = ies_len; + return 0; +} + + +void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ + int bssid_changed; + int timeout = 5000; + + wpa_printf(MSG_DEBUG, "SME: Association with " MACSTR " failed: " + "status code %d", MAC2STR(wpa_s->pending_bssid), + data->assoc_reject.status_code); + + bssid_changed = !is_zero_ether_addr(wpa_s->bssid); + + /* + * For now, unconditionally terminate the previous authentication. In + * theory, this should not be needed, but mac80211 gets quite confused + * if the authentication is left pending.. Some roaming cases might + * benefit from using the previous authentication, so this could be + * optimized in the future. + */ + if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, + WLAN_REASON_DEAUTH_LEAVING) < 0) { + wpa_msg(wpa_s, MSG_INFO, + "Deauth request to the driver failed"); + } + wpa_s->sme.prev_bssid_set = 0; + + if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) { + struct wpa_blacklist *b; + b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid); + if (b && b->count < 3) { + /* + * Speed up next attempt if there could be other APs + * that could accept association. + */ + timeout = 100; + } + } + wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); + os_memset(wpa_s->bssid, 0, ETH_ALEN); + os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); + if (bssid_changed) + wpas_notify_bssid_changed(wpa_s); + + /* + * TODO: if more than one possible AP is available in scan results, + * could try the other ones before requesting a new scan. + */ + wpa_supplicant_req_scan(wpa_s, timeout / 1000, + 1000 * (timeout % 1000)); +} + + +void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ + wpa_printf(MSG_DEBUG, "SME: Authentication timed out"); + wpa_supplicant_req_scan(wpa_s, 5, 0); +} + + +void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ + wpa_printf(MSG_DEBUG, "SME: Association timed out"); + wpa_supplicant_mark_disassoc(wpa_s); + wpa_supplicant_req_scan(wpa_s, 5, 0); +} + + +void sme_event_disassoc(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ + wpa_printf(MSG_DEBUG, "SME: Disassociation event received"); + if (wpa_s->sme.prev_bssid_set && + !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)) { + /* + * cfg80211/mac80211 can get into somewhat confused state if + * the AP only disassociates us and leaves us in authenticated + * state. For now, force the state to be cleared to avoid + * confusing errors if we try to associate with the AP again. + */ + wpa_printf(MSG_DEBUG, "SME: Deauthenticate to clear driver " + "state"); + wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid, + WLAN_REASON_DEAUTH_LEAVING); + } +} diff --git a/contrib/wpa/wpa_supplicant/sme.h b/contrib/wpa/wpa_supplicant/sme.h new file mode 100644 index 0000000..3ec8cc9 --- /dev/null +++ b/contrib/wpa/wpa_supplicant/sme.h @@ -0,0 +1,78 @@ +/* + * wpa_supplicant - SME + * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef SME_H +#define SME_H + +#ifdef CONFIG_SME + +void sme_authenticate(struct wpa_supplicant *wpa_s, + struct wpa_bss *bss, struct wpa_ssid *ssid); +void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, + const u8 *bssid, u16 auth_type); +void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data); +int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, + const u8 *ies, size_t ies_len); +void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, + union wpa_event_data *data); +void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data); +void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data); +void sme_event_disassoc(struct wpa_supplicant *wpa_s, + union wpa_event_data *data); + +#else /* CONFIG_SME */ + +static inline void sme_authenticate(struct wpa_supplicant *wpa_s, + struct wpa_bss *bss, + struct wpa_ssid *ssid) +{ +} + +static inline void sme_event_auth(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ +} + +static inline int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, + const u8 *ies, size_t ies_len) +{ + return -1; +} + + +static inline void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ +} + +static inline void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ +} + +static inline void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ +} + +static inline void sme_event_disassoc(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ +} + +#endif /* CONFIG_SME */ + +#endif /* SME_H */ diff --git a/contrib/wpa/wpa_supplicant/tests/test_aes.c b/contrib/wpa/wpa_supplicant/tests/test_aes.c deleted file mode 100644 index 38a9cf5..0000000 --- a/contrib/wpa/wpa_supplicant/tests/test_aes.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Test program for AES - * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" - -#include "common.h" -#include "crypto.h" -#include "aes_wrap.h" - -#define BLOCK_SIZE 16 - -static void test_aes_perf(void) -{ -#if 0 /* this did not seem to work with new compiler?! */ -#ifdef __i386__ -#define rdtscll(val) \ - __asm__ __volatile__("rdtsc" : "=A" (val)) - const int num_iters = 10; - int i; - unsigned int start, end; - u8 key[16], pt[16], ct[16]; - void *ctx; - - printf("keySetupEnc:"); - for (i = 0; i < num_iters; i++) { - rdtscll(start); - ctx = aes_encrypt_init(key, 16); - rdtscll(end); - aes_encrypt_deinit(ctx); - printf(" %d", end - start); - } - printf("\n"); - - printf("Encrypt:"); - ctx = aes_encrypt_init(key, 16); - for (i = 0; i < num_iters; i++) { - rdtscll(start); - aes_encrypt(ctx, pt, ct); - rdtscll(end); - printf(" %d", end - start); - } - aes_encrypt_deinit(ctx); - printf("\n"); -#endif /* __i386__ */ -#endif -} - - -static int test_eax(void) -{ - u8 msg[] = { 0xF7, 0xFB }; - u8 key[] = { 0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B, - 0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4 }; - u8 nonce[] = { 0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84, - 0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD }; - u8 hdr[] = { 0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA }; - u8 cipher[] = { 0x19, 0xDD, 0x5C, 0x4C, 0x93, 0x31, 0x04, 0x9D, - 0x0B, 0xDA, 0xB0, 0x27, 0x74, 0x08, 0xF6, 0x79, - 0x67, 0xE5 }; - u8 data[sizeof(msg)], tag[BLOCK_SIZE]; - - memcpy(data, msg, sizeof(msg)); - if (aes_128_eax_encrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr), - data, sizeof(data), tag)) { - printf("AES-128 EAX mode encryption failed\n"); - return 1; - } - if (memcmp(data, cipher, sizeof(data)) != 0) { - printf("AES-128 EAX mode encryption returned invalid cipher " - "text\n"); - return 1; - } - if (memcmp(tag, cipher + sizeof(data), BLOCK_SIZE) != 0) { - printf("AES-128 EAX mode encryption returned invalid tag\n"); - return 1; - } - - if (aes_128_eax_decrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr), - data, sizeof(data), tag)) { - printf("AES-128 EAX mode decryption failed\n"); - return 1; - } - if (memcmp(data, msg, sizeof(data)) != 0) { - printf("AES-128 EAX mode decryption returned invalid plain " - "text\n"); - return 1; - } - - return 0; -} - - -static int test_cbc(void) -{ - struct cbc_test_vector { - u8 key[16]; - u8 iv[16]; - u8 plain[32]; - u8 cipher[32]; - size_t len; - } vectors[] = { - { - { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, - 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 }, - { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30, - 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 }, - "Single block msg", - { 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8, - 0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a }, - 16 - }, - { - { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, - 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a }, - { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, - 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - { 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, - 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a, - 0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, - 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 }, - 32 - } - }; - int ret = 0; - u8 *buf; - unsigned int i; - - for (i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) { - struct cbc_test_vector *tv = &vectors[i]; - buf = malloc(tv->len); - if (buf == NULL) { - ret++; - break; - } - memcpy(buf, tv->plain, tv->len); - aes_128_cbc_encrypt(tv->key, tv->iv, buf, tv->len); - if (memcmp(buf, tv->cipher, tv->len) != 0) { - printf("AES-CBC encrypt %d failed\n", i); - ret++; - } - memcpy(buf, tv->cipher, tv->len); - aes_128_cbc_decrypt(tv->key, tv->iv, buf, tv->len); - if (memcmp(buf, tv->plain, tv->len) != 0) { - printf("AES-CBC decrypt %d failed\n", i); - ret++; - } - free(buf); - } - - return ret; -} - - -/* OMAC1 AES-128 test vectors from - * http://csrc.nist.gov/CryptoToolkit/modes/proposedmodes/omac/omac-ad.pdf - * which are same as the examples from NIST SP800-38B - * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf - */ - -struct omac1_test_vector { - u8 k[16]; - u8 msg[64]; - int msg_len; - u8 tag[16]; -}; - -static struct omac1_test_vector test_vectors[] = -{ - { - { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, - { }, - 0, - { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, - 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 } - }, - { - { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, - { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, - 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, - 16, - { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, - 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c } - }, - { - { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, - { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, - 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, - 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 }, - 40, - { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, - 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 } - }, - { - { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, - { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, - 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, - 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, - 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, - 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, - 64, - { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, - 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe } - }, -}; - - -int main(int argc, char *argv[]) -{ - u8 kek[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f - }; - u8 plain[] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff - }; - u8 crypt[] = { - 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47, - 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82, - 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5 - }; - u8 result[24]; - int ret = 0; - unsigned int i; - struct omac1_test_vector *tv; - - if (aes_wrap(kek, 2, plain, result)) { - printf("AES-WRAP-128-128 reported failure\n"); - ret++; - } - if (memcmp(result, crypt, 24) != 0) { - printf("AES-WRAP-128-128 failed\n"); - ret++; - } - if (aes_unwrap(kek, 2, crypt, result)) { - printf("AES-UNWRAP-128-128 reported failure\n"); - ret++; - } - if (memcmp(result, plain, 16) != 0) { - printf("AES-UNWRAP-128-128 failed\n"); - ret++; - for (i = 0; i < 16; i++) - printf(" %02x", result[i]); - printf("\n"); - } - - test_aes_perf(); - - for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) { - tv = &test_vectors[i]; - omac1_aes_128(tv->k, tv->msg, tv->msg_len, result); - if (memcmp(result, tv->tag, 16) != 0) { - printf("OMAC1-AES-128 test vector %d failed\n", i); - ret++; - } - - if (tv->msg_len > 1) { - const u8 *addr[2]; - size_t len[2]; - - addr[0] = tv->msg; - len[0] = 1; - addr[1] = tv->msg + 1; - len[1] = tv->msg_len - 1; - - omac1_aes_128_vector(tv->k, 2, addr, len, result); - if (memcmp(result, tv->tag, 16) != 0) { - printf("OMAC1-AES-128(vector) test vector %d " - "failed\n", i); - ret++; - } - } - } - - ret += test_eax(); - - ret += test_cbc(); - - if (ret) - printf("FAILED!\n"); - - return ret; -} diff --git a/contrib/wpa/wpa_supplicant/tests/test_eap_sim_common.c b/contrib/wpa/wpa_supplicant/tests/test_eap_sim_common.c index ee3eee4..deb19f6 100644 --- a/contrib/wpa/wpa_supplicant/tests/test_eap_sim_common.c +++ b/contrib/wpa/wpa_supplicant/tests/test_eap_sim_common.c @@ -12,7 +12,7 @@ * See README and COPYING for more details. */ -#include "eap_sim_common.c" +#include "eap_common/eap_sim_common.c" static int test_eap_sim_prf(void) diff --git a/contrib/wpa/wpa_supplicant/tests/test_md4.c b/contrib/wpa/wpa_supplicant/tests/test_md4.c deleted file mode 100644 index e92e9a5..0000000 --- a/contrib/wpa/wpa_supplicant/tests/test_md4.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Test program for MD4 (test vectors from RFC 1320) - * Copyright (c) 2006, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" - -#include "common.h" -#include "crypto.h" - -int main(int argc, char *argv[]) -{ - struct { - char *data; - u8 *hash; - } tests[] = { - { - "", - "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31" - "\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0" - }, - { - "a", - "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46" - "\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" - }, - { - "abc", - "\xa4\x48\x01\x7a\xaf\x21\xd8\x52" - "\x5f\xc1\x0a\xe8\x7a\xa6\x72\x9d" - }, - { - "message digest", - "\xd9\x13\x0a\x81\x64\x54\x9f\xe8" - "\x18\x87\x48\x06\xe1\xc7\x01\x4b" - }, - { - "abcdefghijklmnopqrstuvwxyz", - "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd" - "\xee\xa8\xed\x63\xdf\x41\x2d\xa9" - }, - { - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - "0123456789", - "\x04\x3f\x85\x82\xf2\x41\xdb\x35" - "\x1c\xe6\x27\xe1\x53\xe7\xf0\xe4" - }, - { - "12345678901234567890123456789012345678901234567890" - "123456789012345678901234567890", - "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19" - "\x9c\x3e\x7b\x16\x4f\xcc\x05\x36" - } - }; - unsigned int i; - u8 hash[16]; - const u8 *addr[2]; - size_t len[2]; - int errors = 0; - - for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { - printf("MD4 test case %d:", i); - - addr[0] = tests[i].data; - len[0] = strlen(tests[i].data); - md4_vector(1, addr, len, hash); - if (memcmp(hash, tests[i].hash, 16) != 0) { - printf(" FAIL"); - errors++; - } else - printf(" OK"); - - if (len[0]) { - addr[0] = tests[i].data; - len[0] = strlen(tests[i].data); - addr[1] = tests[i].data + 1; - len[1] = strlen(tests[i].data) - 1; - md4_vector(1, addr, len, hash); - if (memcmp(hash, tests[i].hash, 16) != 0) { - printf(" FAIL"); - errors++; - } else - printf(" OK"); - } - - printf("\n"); - } - - return errors; -} diff --git a/contrib/wpa/wpa_supplicant/tests/test_md5.c b/contrib/wpa/wpa_supplicant/tests/test_md5.c deleted file mode 100644 index d8fb41e..0000000 --- a/contrib/wpa/wpa_supplicant/tests/test_md5.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Test program for MD5 (test vectors from RFC 1321) - * Copyright (c) 2006, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" - -#include "common.h" -#include "crypto.h" - -int main(int argc, char *argv[]) -{ - struct { - char *data; - u8 *hash; - } tests[] = { - { - "", - "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04" - "\xe9\x80\x09\x98\xec\xf8\x42\x7e" - }, - { - "a", - "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8" - "\x31\xc3\x99\xe2\x69\x77\x26\x61" - }, - { - "abc", - "\x90\x01\x50\x98\x3c\xd2\x4f\xb0" - "\xd6\x96\x3f\x7d\x28\xe1\x7f\x72" - }, - { - "message digest", - "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d" - "\x52\x5a\x2f\x31\xaa\xf1\x61\xd0" - }, - { - "abcdefghijklmnopqrstuvwxyz", - "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00" - "\x7d\xfb\x49\x6c\xca\x67\xe1\x3b" - }, - { - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - "0123456789", - "\xd1\x74\xab\x98\xd2\x77\xd9\xf5" - "\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f" - }, - { - "12345678901234567890123456789012345678901234567890" - "123456789012345678901234567890", - "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55" - "\xac\x49\xda\x2e\x21\x07\xb6\x7a" - } - }; - unsigned int i; - u8 hash[16]; - const u8 *addr[2]; - size_t len[2]; - int errors = 0; - - for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { - printf("MD5 test case %d:", i); - - addr[0] = tests[i].data; - len[0] = strlen(tests[i].data); - md5_vector(1, addr, len, hash); - if (memcmp(hash, tests[i].hash, 16) != 0) { - printf(" FAIL"); - errors++; - } else - printf(" OK"); - - if (len[0]) { - addr[0] = tests[i].data; - len[0] = strlen(tests[i].data); - addr[1] = tests[i].data + 1; - len[1] = strlen(tests[i].data) - 1; - md5_vector(1, addr, len, hash); - if (memcmp(hash, tests[i].hash, 16) != 0) { - printf(" FAIL"); - errors++; - } else - printf(" OK"); - } - - printf("\n"); - } - - return errors; -} diff --git a/contrib/wpa/wpa_supplicant/tests/test_ms_funcs.c b/contrib/wpa/wpa_supplicant/tests/test_ms_funcs.c deleted file mode 100644 index 09b53c4..0000000 --- a/contrib/wpa/wpa_supplicant/tests/test_ms_funcs.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Test program for ms_funcs - * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "ms_funcs.c" - - -int main(int argc, char *argv[]) -{ - /* Test vector from RFC2759 example */ - u8 *username = "User"; - u8 *password = "clientPass"; - u8 auth_challenge[] = { - 0x5B, 0x5D, 0x7C, 0x7D, 0x7B, 0x3F, 0x2F, 0x3E, - 0x3C, 0x2C, 0x60, 0x21, 0x32, 0x26, 0x26, 0x28 - }; - u8 peer_challenge[] = { - 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, - 0x28, 0x29, 0x5F, 0x2B, 0x3A, 0x33, 0x7C, 0x7E - }; - u8 challenge[] = { 0xD0, 0x2E, 0x43, 0x86, 0xBC, 0xE9, 0x12, 0x26 }; - u8 password_hash[] = { - 0x44, 0xEB, 0xBA, 0x8D, 0x53, 0x12, 0xB8, 0xD6, - 0x11, 0x47, 0x44, 0x11, 0xF5, 0x69, 0x89, 0xAE - }; - u8 nt_response[] = { - 0x82, 0x30, 0x9E, 0xCD, 0x8D, 0x70, 0x8B, 0x5E, - 0xA0, 0x8F, 0xAA, 0x39, 0x81, 0xCD, 0x83, 0x54, - 0x42, 0x33, 0x11, 0x4A, 0x3D, 0x85, 0xD6, 0xDF - }; - u8 password_hash_hash[] = { - 0x41, 0xC0, 0x0C, 0x58, 0x4B, 0xD2, 0xD9, 0x1C, - 0x40, 0x17, 0xA2, 0xA1, 0x2F, 0xA5, 0x9F, 0x3F - }; - u8 authenticator_response[] = { - 0x40, 0x7A, 0x55, 0x89, 0x11, 0x5F, 0xD0, 0xD6, - 0x20, 0x9F, 0x51, 0x0F, 0xE9, 0xC0, 0x45, 0x66, - 0x93, 0x2C, 0xDA, 0x56 - }; - u8 master_key[] = { - 0xFD, 0xEC, 0xE3, 0x71, 0x7A, 0x8C, 0x83, 0x8C, - 0xB3, 0x88, 0xE5, 0x27, 0xAE, 0x3C, 0xDD, 0x31 - }; - u8 send_start_key[] = { - 0x8B, 0x7C, 0xDC, 0x14, 0x9B, 0x99, 0x3A, 0x1B, - 0xA1, 0x18, 0xCB, 0x15, 0x3F, 0x56, 0xDC, 0xCB - }; - u8 buf[32]; - - int errors = 0; - - printf("Testing ms_funcs.c\n"); - - challenge_hash(peer_challenge, auth_challenge, - username, strlen(username), - buf); - if (memcmp(challenge, buf, sizeof(challenge)) != 0) { - printf("challenge_hash failed\n"); - errors++; - } - - nt_password_hash(password, strlen(password), buf); - if (memcmp(password_hash, buf, sizeof(password_hash)) != 0) { - printf("nt_password_hash failed\n"); - errors++; - } - - generate_nt_response(auth_challenge, peer_challenge, - username, strlen(username), - password, strlen(password), - buf); - if (memcmp(nt_response, buf, sizeof(nt_response)) != 0) { - printf("generate_nt_response failed\n"); - errors++; - } - - hash_nt_password_hash(password_hash, buf); - if (memcmp(password_hash_hash, buf, sizeof(password_hash_hash)) != 0) { - printf("hash_nt_password_hash failed\n"); - errors++; - } - - generate_authenticator_response(password, strlen(password), - peer_challenge, auth_challenge, - username, strlen(username), - nt_response, buf); - if (memcmp(authenticator_response, buf, sizeof(authenticator_response)) - != 0) { - printf("generate_authenticator_response failed\n"); - errors++; - } - - get_master_key(password_hash_hash, nt_response, buf); - if (memcmp(master_key, buf, sizeof(master_key)) != 0) { - printf("get_master_key failed\n"); - errors++; - } - - get_asymetric_start_key(master_key, buf, sizeof(send_start_key), 1, 1); - if (memcmp(send_start_key, buf, sizeof(send_start_key)) != 0) { - printf("get_asymetric_start_key failed\n"); - errors++; - } - - if (errors) - printf("FAILED! %d errors\n", errors); - - return errors; -} diff --git a/contrib/wpa/wpa_supplicant/tests/test_sha1.c b/contrib/wpa/wpa_supplicant/tests/test_sha1.c deleted file mode 100644 index d2e6a99..0000000 --- a/contrib/wpa/wpa_supplicant/tests/test_sha1.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Test program for SHA1 and MD5 - * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" - -#include "common.h" -#include "sha1.h" -#include "md5.h" -#include "crypto.h" - - -static int test_eap_fast(void) -{ - /* RFC 4851, Appendix B.1 */ - const u8 pac_key[] = { - 0x0B, 0x97, 0x39, 0x0F, 0x37, 0x51, 0x78, 0x09, - 0x81, 0x1E, 0xFD, 0x9C, 0x6E, 0x65, 0x94, 0x2B, - 0x63, 0x2C, 0xE9, 0x53, 0x89, 0x38, 0x08, 0xBA, - 0x36, 0x0B, 0x03, 0x7C, 0xD1, 0x85, 0xE4, 0x14 - }; - const u8 seed[] = { - 0x3F, 0xFB, 0x11, 0xC4, 0x6C, 0xBF, 0xA5, 0x7A, - 0x54, 0x40, 0xDA, 0xE8, 0x22, 0xD3, 0x11, 0xD3, - 0xF7, 0x6D, 0xE4, 0x1D, 0xD9, 0x33, 0xE5, 0x93, - 0x70, 0x97, 0xEB, 0xA9, 0xB3, 0x66, 0xF4, 0x2A, - 0x00, 0x00, 0x00, 0x02, 0x6A, 0x66, 0x43, 0x2A, - 0x8D, 0x14, 0x43, 0x2C, 0xEC, 0x58, 0x2D, 0x2F, - 0xC7, 0x9C, 0x33, 0x64, 0xBA, 0x04, 0xAD, 0x3A, - 0x52, 0x54, 0xD6, 0xA5, 0x79, 0xAD, 0x1E, 0x00 - }; - const u8 master_secret[] = { - 0x4A, 0x1A, 0x51, 0x2C, 0x01, 0x60, 0xBC, 0x02, - 0x3C, 0xCF, 0xBC, 0x83, 0x3F, 0x03, 0xBC, 0x64, - 0x88, 0xC1, 0x31, 0x2F, 0x0B, 0xA9, 0xA2, 0x77, - 0x16, 0xA8, 0xD8, 0xE8, 0xBD, 0xC9, 0xD2, 0x29, - 0x38, 0x4B, 0x7A, 0x85, 0xBE, 0x16, 0x4D, 0x27, - 0x33, 0xD5, 0x24, 0x79, 0x87, 0xB1, 0xC5, 0xA2 - }; - const u8 key_block[] = { - 0x59, 0x59, 0xBE, 0x8E, 0x41, 0x3A, 0x77, 0x74, - 0x8B, 0xB2, 0xE5, 0xD3, 0x60, 0xAC, 0x4D, 0x35, - 0xDF, 0xFB, 0xC8, 0x1E, 0x9C, 0x24, 0x9C, 0x8B, - 0x0E, 0xC3, 0x1D, 0x72, 0xC8, 0x84, 0x9D, 0x57, - 0x48, 0x51, 0x2E, 0x45, 0x97, 0x6C, 0x88, 0x70, - 0xBE, 0x5F, 0x01, 0xD3, 0x64, 0xE7, 0x4C, 0xBB, - 0x11, 0x24, 0xE3, 0x49, 0xE2, 0x3B, 0xCD, 0xEF, - 0x7A, 0xB3, 0x05, 0x39, 0x5D, 0x64, 0x8A, 0x44, - 0x11, 0xB6, 0x69, 0x88, 0x34, 0x2E, 0x8E, 0x29, - 0xD6, 0x4B, 0x7D, 0x72, 0x17, 0x59, 0x28, 0x05, - 0xAF, 0xF9, 0xB7, 0xFF, 0x66, 0x6D, 0xA1, 0x96, - 0x8F, 0x0B, 0x5E, 0x06, 0x46, 0x7A, 0x44, 0x84, - 0x64, 0xC1, 0xC8, 0x0C, 0x96, 0x44, 0x09, 0x98, - 0xFF, 0x92, 0xA8, 0xB4, 0xC6, 0x42, 0x28, 0x71 - }; - const u8 sks[] = { - 0xD6, 0x4B, 0x7D, 0x72, 0x17, 0x59, 0x28, 0x05, - 0xAF, 0xF9, 0xB7, 0xFF, 0x66, 0x6D, 0xA1, 0x96, - 0x8F, 0x0B, 0x5E, 0x06, 0x46, 0x7A, 0x44, 0x84, - 0x64, 0xC1, 0xC8, 0x0C, 0x96, 0x44, 0x09, 0x98, - 0xFF, 0x92, 0xA8, 0xB4, 0xC6, 0x42, 0x28, 0x71 - }; - const u8 isk[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - const u8 imck[] = { - 0x16, 0x15, 0x3C, 0x3F, 0x21, 0x55, 0xEF, 0xD9, - 0x7F, 0x34, 0xAE, 0xC8, 0x1A, 0x4E, 0x66, 0x80, - 0x4C, 0xC3, 0x76, 0xF2, 0x8A, 0xA9, 0x6F, 0x96, - 0xC2, 0x54, 0x5F, 0x8C, 0xAB, 0x65, 0x02, 0xE1, - 0x18, 0x40, 0x7B, 0x56, 0xBE, 0xEA, 0xA7, 0xC5, - 0x76, 0x5D, 0x8F, 0x0B, 0xC5, 0x07, 0xC6, 0xB9, - 0x04, 0xD0, 0x69, 0x56, 0x72, 0x8B, 0x6B, 0xB8, - 0x15, 0xEC, 0x57, 0x7B - }; - const u8 msk[] = { - 0x4D, 0x83, 0xA9, 0xBE, 0x6F, 0x8A, 0x74, 0xED, - 0x6A, 0x02, 0x66, 0x0A, 0x63, 0x4D, 0x2C, 0x33, - 0xC2, 0xDA, 0x60, 0x15, 0xC6, 0x37, 0x04, 0x51, - 0x90, 0x38, 0x63, 0xDA, 0x54, 0x3E, 0x14, 0xB9, - 0x27, 0x99, 0x18, 0x1E, 0x07, 0xBF, 0x0F, 0x5A, - 0x5E, 0x3C, 0x32, 0x93, 0x80, 0x8C, 0x6C, 0x49, - 0x67, 0xED, 0x24, 0xFE, 0x45, 0x40, 0xA0, 0x59, - 0x5E, 0x37, 0xC2, 0xE9, 0xD0, 0x5D, 0x0A, 0xE3 - }; - const u8 emsk[] = { - 0x3A, 0xD4, 0xAB, 0xDB, 0x76, 0xB2, 0x7F, 0x3B, - 0xEA, 0x32, 0x2C, 0x2B, 0x74, 0xF4, 0x28, 0x55, - 0xEF, 0x2D, 0xBA, 0x78, 0xC9, 0x57, 0x2F, 0x0D, - 0x06, 0xCD, 0x51, 0x7C, 0x20, 0x93, 0x98, 0xA9, - 0x76, 0xEA, 0x70, 0x21, 0xD7, 0x0E, 0x25, 0x54, - 0x97, 0xED, 0xB2, 0x8A, 0xF6, 0xED, 0xFD, 0x0A, - 0x2A, 0xE7, 0xA1, 0x58, 0x90, 0x10, 0x50, 0x44, - 0xB3, 0x82, 0x85, 0xDB, 0x06, 0x14, 0xD2, 0xF9 - }; - /* RFC 4851, Appendix B.2 */ - u8 tlv[] = { - 0x80, 0x0C, 0x00, 0x38, 0x00, 0x01, 0x01, 0x00, - 0xD8, 0x6A, 0x8C, 0x68, 0x3C, 0x32, 0x31, 0xA8, - 0x56, 0x63, 0xB6, 0x40, 0x21, 0xFE, 0x21, 0x14, - 0x4E, 0xE7, 0x54, 0x20, 0x79, 0x2D, 0x42, 0x62, - 0xC9, 0xBF, 0x53, 0x7F, 0x54, 0xFD, 0xAC, 0x58, - 0x43, 0x24, 0x6E, 0x30, 0x92, 0x17, 0x6D, 0xCF, - 0xE6, 0xE0, 0x69, 0xEB, 0x33, 0x61, 0x6A, 0xCC, - 0x05, 0xC5, 0x5B, 0xB7 - }; - const u8 compound_mac[] = { - 0x43, 0x24, 0x6E, 0x30, 0x92, 0x17, 0x6D, 0xCF, - 0xE6, 0xE0, 0x69, 0xEB, 0x33, 0x61, 0x6A, 0xCC, - 0x05, 0xC5, 0x5B, 0xB7 - }; - u8 buf[512]; - const u8 *simck, *cmk; - int errors = 0; - - printf("EAP-FAST test cases\n"); - - printf("- T-PRF (SHA1) test case / master_secret\n"); - sha1_t_prf(pac_key, sizeof(pac_key), "PAC to master secret label hash", - seed, sizeof(seed), buf, sizeof(master_secret)); - if (memcmp(master_secret, buf, sizeof(master_secret)) != 0) { - printf("T-PRF test - FAILED!\n"); - errors++; - } - - printf("- PRF (TLS, SHA1/MD5) test case / key_block\n"); - tls_prf(master_secret, sizeof(master_secret), "key expansion", - seed, sizeof(seed), buf, sizeof(key_block)); - if (memcmp(key_block, buf, sizeof(key_block)) != 0) { - printf("PRF test - FAILED!\n"); - errors++; - } - - printf("- T-PRF (SHA1) test case / IMCK\n"); - sha1_t_prf(sks, sizeof(sks), "Inner Methods Compound Keys", - isk, sizeof(isk), buf, sizeof(imck)); - if (memcmp(imck, buf, sizeof(imck)) != 0) { - printf("T-PRF test - FAILED!\n"); - errors++; - } - - simck = imck; - cmk = imck + 40; - - printf("- T-PRF (SHA1) test case / MSK\n"); - sha1_t_prf(simck, 40, "Session Key Generating Function", - (u8 *) "", 0, buf, sizeof(msk)); - if (memcmp(msk, buf, sizeof(msk)) != 0) { - printf("T-PRF test - FAILED!\n"); - errors++; - } - - printf("- T-PRF (SHA1) test case / EMSK\n"); - sha1_t_prf(simck, 40, "Extended Session Key Generating Function", - (u8 *) "", 0, buf, sizeof(msk)); - if (memcmp(emsk, buf, sizeof(emsk)) != 0) { - printf("T-PRF test - FAILED!\n"); - errors++; - } - - printf("- Compound MAC test case\n"); - memset(tlv + sizeof(tlv) - 20, 0, 20); - hmac_sha1(cmk, 20, tlv, sizeof(tlv), tlv + sizeof(tlv) - 20); - if (memcmp(tlv + sizeof(tlv) - 20, compound_mac, sizeof(compound_mac)) - != 0) { - printf("Compound MAC test - FAILED!\n"); - errors++; - } - - return errors; -} - - -static u8 key0[] = -{ - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b -}; -static u8 data0[] = "Hi There"; -static u8 prf0[] = -{ - 0xbc, 0xd4, 0xc6, 0x50, 0xb3, 0x0b, 0x96, 0x84, - 0x95, 0x18, 0x29, 0xe0, 0xd7, 0x5f, 0x9d, 0x54, - 0xb8, 0x62, 0x17, 0x5e, 0xd9, 0xf0, 0x06, 0x06, - 0xe1, 0x7d, 0x8d, 0xa3, 0x54, 0x02, 0xff, 0xee, - 0x75, 0xdf, 0x78, 0xc3, 0xd3, 0x1e, 0x0f, 0x88, - 0x9f, 0x01, 0x21, 0x20, 0xc0, 0x86, 0x2b, 0xeb, - 0x67, 0x75, 0x3e, 0x74, 0x39, 0xae, 0x24, 0x2e, - 0xdb, 0x83, 0x73, 0x69, 0x83, 0x56, 0xcf, 0x5a -}; - -static u8 key1[] = "Jefe"; -static u8 data1[] = "what do ya want for nothing?"; -static u8 prf1[] = -{ - 0x51, 0xf4, 0xde, 0x5b, 0x33, 0xf2, 0x49, 0xad, - 0xf8, 0x1a, 0xeb, 0x71, 0x3a, 0x3c, 0x20, 0xf4, - 0xfe, 0x63, 0x14, 0x46, 0xfa, 0xbd, 0xfa, 0x58, - 0x24, 0x47, 0x59, 0xae, 0x58, 0xef, 0x90, 0x09, - 0xa9, 0x9a, 0xbf, 0x4e, 0xac, 0x2c, 0xa5, 0xfa, - 0x87, 0xe6, 0x92, 0xc4, 0x40, 0xeb, 0x40, 0x02, - 0x3e, 0x7b, 0xab, 0xb2, 0x06, 0xd6, 0x1d, 0xe7, - 0xb9, 0x2f, 0x41, 0x52, 0x90, 0x92, 0xb8, 0xfc -}; - - -static u8 key2[] = -{ - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa -}; -static u8 data2[] = -{ - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd -}; -static u8 prf2[] = -{ - 0xe1, 0xac, 0x54, 0x6e, 0xc4, 0xcb, 0x63, 0x6f, - 0x99, 0x76, 0x48, 0x7b, 0xe5, 0xc8, 0x6b, 0xe1, - 0x7a, 0x02, 0x52, 0xca, 0x5d, 0x8d, 0x8d, 0xf1, - 0x2c, 0xfb, 0x04, 0x73, 0x52, 0x52, 0x49, 0xce, - 0x9d, 0xd8, 0xd1, 0x77, 0xea, 0xd7, 0x10, 0xbc, - 0x9b, 0x59, 0x05, 0x47, 0x23, 0x91, 0x07, 0xae, - 0xf7, 0xb4, 0xab, 0xd4, 0x3d, 0x87, 0xf0, 0xa6, - 0x8f, 0x1c, 0xbd, 0x9e, 0x2b, 0x6f, 0x76, 0x07 -}; - - -struct passphrase_test { - char *passphrase; - char *ssid; - char psk[32]; -}; - -static struct passphrase_test passphrase_tests[] = -{ - { - "password", - "IEEE", - { - 0xf4, 0x2c, 0x6f, 0xc5, 0x2d, 0xf0, 0xeb, 0xef, - 0x9e, 0xbb, 0x4b, 0x90, 0xb3, 0x8a, 0x5f, 0x90, - 0x2e, 0x83, 0xfe, 0x1b, 0x13, 0x5a, 0x70, 0xe2, - 0x3a, 0xed, 0x76, 0x2e, 0x97, 0x10, 0xa1, 0x2e - } - }, - { - "ThisIsAPassword", - "ThisIsASSID", - { - 0x0d, 0xc0, 0xd6, 0xeb, 0x90, 0x55, 0x5e, 0xd6, - 0x41, 0x97, 0x56, 0xb9, 0xa1, 0x5e, 0xc3, 0xe3, - 0x20, 0x9b, 0x63, 0xdf, 0x70, 0x7d, 0xd5, 0x08, - 0xd1, 0x45, 0x81, 0xf8, 0x98, 0x27, 0x21, 0xaf - } - }, - { - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", - { - 0xbe, 0xcb, 0x93, 0x86, 0x6b, 0xb8, 0xc3, 0x83, - 0x2c, 0xb7, 0x77, 0xc2, 0xf5, 0x59, 0x80, 0x7c, - 0x8c, 0x59, 0xaf, 0xcb, 0x6e, 0xae, 0x73, 0x48, - 0x85, 0x00, 0x13, 0x00, 0xa9, 0x81, 0xcc, 0x62 - } - }, -}; - -#define NUM_PASSPHRASE_TESTS \ -(sizeof(passphrase_tests) / sizeof(passphrase_tests[0])) - - -int main(int argc, char *argv[]) -{ - u8 res[512]; - int ret = 0; - unsigned int i; - - printf("PRF-SHA1 test cases:\n"); - - sha1_prf(key0, sizeof(key0), "prefix", data0, sizeof(data0) - 1, - res, sizeof(prf0)); - if (memcmp(res, prf0, sizeof(prf0)) == 0) - printf("Test case 0 - OK\n"); - else { - printf("Test case 0 - FAILED!\n"); - ret++; - } - - sha1_prf(key1, sizeof(key1) - 1, "prefix", data1, sizeof(data1) - 1, - res, sizeof(prf1)); - if (memcmp(res, prf1, sizeof(prf1)) == 0) - printf("Test case 1 - OK\n"); - else { - printf("Test case 1 - FAILED!\n"); - ret++; - } - - sha1_prf(key2, sizeof(key2), "prefix", data2, sizeof(data2), - res, sizeof(prf2)); - if (memcmp(res, prf2, sizeof(prf2)) == 0) - printf("Test case 2 - OK\n"); - else { - printf("Test case 2 - FAILED!\n"); - ret++; - } - - ret += test_eap_fast(); - - printf("PBKDF2-SHA1 Passphrase test cases:\n"); - for (i = 0; i < NUM_PASSPHRASE_TESTS; i++) { - u8 psk[32]; - struct passphrase_test *test = &passphrase_tests[i]; - pbkdf2_sha1(test->passphrase, - test->ssid, strlen(test->ssid), - 4096, psk, 32); - if (memcmp(psk, test->psk, 32) == 0) - printf("Test case %d - OK\n", i); - else { - printf("Test case %d - FAILED!\n", i); - ret++; - } - } - - return ret; -} diff --git a/contrib/wpa/wpa_supplicant/tests/test_sha256.c b/contrib/wpa/wpa_supplicant/tests/test_sha256.c deleted file mode 100644 index 7dc460d..0000000 --- a/contrib/wpa/wpa_supplicant/tests/test_sha256.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Test program for SHA256 - * Copyright (c) 2006, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" - -#include "common.h" -#include "sha256.h" -#include "crypto.h" - -struct { - char *data; - u8 hash[32]; -} tests[] = { - { - "abc", - { - 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, - 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, - 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, - 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad - } - }, - { - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - { - 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, - 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, - 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, - 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 - } - } -}; - -struct hmac_test { - u8 key[80]; - size_t key_len; - u8 data[128]; - size_t data_len; - u8 hash[32]; -} hmac_tests[] = { - /* draft-ietf-ipsec-ciph-sha-256-01.txt */ - { - { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 - }, - 32, - "abc", 3, - { - 0xa2, 0x1b, 0x1f, 0x5d, 0x4c, 0xf4, 0xf7, 0x3a, - 0x4d, 0xd9, 0x39, 0x75, 0x0f, 0x7a, 0x06, 0x6a, - 0x7f, 0x98, 0xcc, 0x13, 0x1c, 0xb1, 0x6a, 0x66, - 0x92, 0x75, 0x90, 0x21, 0xcf, 0xab, 0x81, 0x81 - } - }, - { - { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 - }, - 32, - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - 56, - { - 0x10, 0x4f, 0xdc, 0x12, 0x57, 0x32, 0x8f, 0x08, - 0x18, 0x4b, 0xa7, 0x31, 0x31, 0xc5, 0x3c, 0xae, - 0xe6, 0x98, 0xe3, 0x61, 0x19, 0x42, 0x11, 0x49, - 0xea, 0x8c, 0x71, 0x24, 0x56, 0x69, 0x7d, 0x30 - } - }, - { - { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 - }, - 32, - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - 112, - { - 0x47, 0x03, 0x05, 0xfc, 0x7e, 0x40, 0xfe, 0x34, - 0xd3, 0xee, 0xb3, 0xe7, 0x73, 0xd9, 0x5a, 0xab, - 0x73, 0xac, 0xf0, 0xfd, 0x06, 0x04, 0x47, 0xa5, - 0xeb, 0x45, 0x95, 0xbf, 0x33, 0xa9, 0xd1, 0xa3 - } - }, - { - { - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b - }, - 32, - "Hi There", - 8, - { - 0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6, - 0x99, 0x03, 0xa0, 0xf1, 0xcf, 0x2b, 0xbd, 0xc5, - 0xba, 0x0a, 0xa3, 0xf3, 0xd9, 0xae, 0x3c, 0x1c, - 0x7a, 0x3b, 0x16, 0x96, 0xa0, 0xb6, 0x8c, 0xf7 - } - }, - { - "Jefe", - 4, - "what do ya want for nothing?", - 28, - { - 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, - 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, - 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, - 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 - } - }, - { - { - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa - }, - 32, - { - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd - }, - 50, - { - 0xcd, 0xcb, 0x12, 0x20, 0xd1, 0xec, 0xcc, 0xea, - 0x91, 0xe5, 0x3a, 0xba, 0x30, 0x92, 0xf9, 0x62, - 0xe5, 0x49, 0xfe, 0x6c, 0xe9, 0xed, 0x7f, 0xdc, - 0x43, 0x19, 0x1f, 0xbd, 0xe4, 0x5c, 0x30, 0xb0 - } - }, - { - { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25 - }, - 37, - { - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd - }, - 50, - { - 0xd4, 0x63, 0x3c, 0x17, 0xf6, 0xfb, 0x8d, 0x74, - 0x4c, 0x66, 0xde, 0xe0, 0xf8, 0xf0, 0x74, 0x55, - 0x6e, 0xc4, 0xaf, 0x55, 0xef, 0x07, 0x99, 0x85, - 0x41, 0x46, 0x8e, 0xb4, 0x9b, 0xd2, 0xe9, 0x17 - } - }, - { - { - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c - }, - 32, - "Test With Truncation", - 20, - { - 0x75, 0x46, 0xaf, 0x01, 0x84, 0x1f, 0xc0, 0x9b, - 0x1a, 0xb9, 0xc3, 0x74, 0x9a, 0x5f, 0x1c, 0x17, - 0xd4, 0xf5, 0x89, 0x66, 0x8a, 0x58, 0x7b, 0x27, - 0x00, 0xa9, 0xc9, 0x7c, 0x11, 0x93, 0xcf, 0x42 - } - }, - { - { - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa - }, - 80, - "Test Using Larger Than Block-Size Key - Hash Key First", - 54, - { - 0x69, 0x53, 0x02, 0x5e, 0xd9, 0x6f, 0x0c, 0x09, - 0xf8, 0x0a, 0x96, 0xf7, 0x8e, 0x65, 0x38, 0xdb, - 0xe2, 0xe7, 0xb8, 0x20, 0xe3, 0xdd, 0x97, 0x0e, - 0x7d, 0xdd, 0x39, 0x09, 0x1b, 0x32, 0x35, 0x2f - } - }, - { - { - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa - }, - 80, - "Test Using Larger Than Block-Size Key and Larger Than One " - "Block-Size Data", - 73, - { - 0x63, 0x55, 0xac, 0x22, 0xe8, 0x90, 0xd0, 0xa3, - 0xc8, 0x48, 0x1a, 0x5c, 0xa4, 0x82, 0x5b, 0xc8, - 0x84, 0xd3, 0xe7, 0xa1, 0xff, 0x98, 0xa2, 0xfc, - 0x2a, 0xc7, 0xd8, 0xe0, 0x64, 0xc3, 0xb2, 0xe6 - } - } -}; - - -int main(int argc, char *argv[]) -{ - - unsigned int i; - u8 hash[32]; - const u8 *addr[2]; - size_t len[2]; - int errors = 0; - - for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { - printf("SHA256 test case %d:", i + 1); - - addr[0] = (u8 *) tests[i].data; - len[0] = strlen(tests[i].data); - sha256_vector(1, addr, len, hash); - if (memcmp(hash, tests[i].hash, 32) != 0) { - printf(" FAIL"); - errors++; - } else - printf(" OK"); - - if (len[0]) { - addr[0] = (u8 *) tests[i].data; - len[0] = 1; - addr[1] = (u8 *) tests[i].data + 1; - len[1] = strlen(tests[i].data) - 1; - sha256_vector(2, addr, len, hash); - if (memcmp(hash, tests[i].hash, 32) != 0) { - printf(" FAIL"); - errors++; - } else - printf(" OK"); - } - - printf("\n"); - } - - for (i = 0; i < sizeof(hmac_tests) / sizeof(hmac_tests[0]); i++) { - struct hmac_test *t = &hmac_tests[i]; - printf("HMAC-SHA256 test case %d:", i + 1); - - hmac_sha256(t->key, t->key_len, t->data, t->data_len, hash); - if (memcmp(hash, t->hash, 32) != 0) { - printf(" FAIL"); - errors++; - } else - printf(" OK"); - - addr[0] = t->data; - len[0] = t->data_len; - hmac_sha256_vector(t->key, t->key_len, 1, addr, len, hash); - if (memcmp(hash, t->hash, 32) != 0) { - printf(" FAIL"); - errors++; - } else - printf(" OK"); - - if (len[0]) { - addr[0] = t->data; - len[0] = 1; - addr[1] = t->data + 1; - len[1] = t->data_len - 1; - hmac_sha256_vector(t->key, t->key_len, 2, addr, len, - hash); - if (memcmp(hash, t->hash, 32) != 0) { - printf(" FAIL"); - errors++; - } else - printf(" OK"); - } - - printf("\n"); - } - - printf("Test IEEE 802.11r KDF\n"); - sha256_prf((u8 *) "abc", 3, "KDF test", (u8 *) "data", 4, - hash, sizeof(hash)); - /* TODO: add proper test case for this */ - - return errors; -} diff --git a/contrib/wpa/wpa_supplicant/tests/test_wpa.c b/contrib/wpa/wpa_supplicant/tests/test_wpa.c index 74bb5f8..7947137 100644 --- a/contrib/wpa/wpa_supplicant/tests/test_wpa.c +++ b/contrib/wpa/wpa_supplicant/tests/test_wpa.c @@ -16,10 +16,10 @@ #include "common.h" #include "eloop.h" -#include "ieee802_11_defs.h" -#include "config.h" -#include "wpa.h" -#include "wpa_ie.h" +#include "common/ieee802_11_defs.h" +#include "../config.h" +#include "rsn_supp/wpa.h" +#include "rsn_supp/wpa_ie.h" #include "../hostapd/wpa.h" @@ -51,14 +51,6 @@ struct wpa { }; -static struct wpa_ssid * supp_get_ssid(void *ctx) -{ - struct wpa *wpa = ctx; - wpa_printf(MSG_DEBUG, "SUPP: %s", __func__); - return &wpa->ssid; -} - - static int supp_get_bssid(void *ctx, u8 *bssid) { struct wpa *wpa = ctx; @@ -68,7 +60,7 @@ static int supp_get_bssid(void *ctx, u8 *bssid) } -static void supp_set_state(void *ctx, wpa_states state) +static void supp_set_state(void *ctx, enum wpa_states state) { wpa_printf(MSG_DEBUG, "SUPP: %s(state=%d)", __func__, state); } @@ -151,7 +143,7 @@ static int supp_get_beacon_ie(void *ctx) } -static int supp_set_key(void *ctx, wpa_alg alg, +static int supp_set_key(void *ctx, enum wpa_alg alg, const u8 *addr, int key_idx, int set_tx, const u8 *seq, size_t seq_len, const u8 *key, size_t key_len) @@ -175,12 +167,6 @@ static int supp_mlme_setprotection(void *ctx, const u8 *addr, } -static void supp_cancel_scan(void *ctx) -{ - wpa_printf(MSG_DEBUG, "SUPP: %s", __func__); -} - - static void supp_cancel_auth_timeout(void *ctx) { wpa_printf(MSG_DEBUG, "SUPP: %s", __func__); @@ -194,15 +180,14 @@ static int supp_init(struct wpa *wpa) return -1; ctx->ctx = wpa; + ctx->msg_ctx = wpa; ctx->set_state = supp_set_state; - ctx->get_ssid = supp_get_ssid; ctx->get_bssid = supp_get_bssid; ctx->ether_send = supp_ether_send; ctx->get_beacon_ie = supp_get_beacon_ie; ctx->alloc_eapol = supp_alloc_eapol; ctx->set_key = supp_set_key; ctx->mlme_setprotection = supp_mlme_setprotection; - ctx->cancel_scan = supp_cancel_scan; ctx->cancel_auth_timeout = supp_cancel_auth_timeout; wpa->supp = wpa_sm_init(ctx); if (wpa->supp == NULL) { @@ -366,7 +351,7 @@ int main(int argc, char *argv[]) wpa_debug_level = 0; wpa_debug_show_keys = 1; - if (eloop_init(&wpa)) { + if (eloop_init()) { wpa_printf(MSG_ERROR, "Failed to initialize event loop"); return -1; } diff --git a/contrib/wpa/wpa_supplicant/tests/test_x509v3.c b/contrib/wpa/wpa_supplicant/tests/test_x509v3.c deleted file mode 100644 index c472c8a..0000000 --- a/contrib/wpa/wpa_supplicant/tests/test_x509v3.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Testing tool for X.509v3 routines - * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" - -#include "common.h" -#include "tls/asn1.h" -#include "tls/x509v3.h" - -extern int wpa_debug_level; - - -int main(int argc, char *argv[]) -{ - char *buf; - size_t len; - struct x509_certificate *certs = NULL, *last = NULL, *cert; - int i, reason; - - wpa_debug_level = 0; - - if (argc < 3 || strcmp(argv[1], "-v") != 0) { - printf("usage: test_x509v3 -v <cert1.der> <cert2.der> ..\n"); - return -1; - } - - for (i = 2; i < argc; i++) { - printf("Reading: %s\n", argv[i]); - buf = os_readfile(argv[i], &len); - if (buf == NULL) { - printf("Failed to read '%s'\n", argv[i]); - return -1; - } - - cert = x509_certificate_parse((u8 *) buf, len); - if (cert == NULL) { - printf("Failed to parse X.509 certificate\n"); - return -1; - } - - free(buf); - - if (certs == NULL) - certs = cert; - else - last->next = cert; - last = cert; - } - - printf("\n\nValidating certificate chain\n"); - if (x509_certificate_chain_validate(last, certs, &reason) < 0) { - printf("\nCertificate chain validation failed: %d\n", reason); - return -1; - } - printf("\nCertificate chain is valid\n"); - - return 0; -} diff --git a/contrib/wpa/wpa_supplicant/tests/test_x509v3_nist.sh b/contrib/wpa/wpa_supplicant/tests/test_x509v3_nist.sh deleted file mode 100755 index c33e362..0000000 --- a/contrib/wpa/wpa_supplicant/tests/test_x509v3_nist.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/sh - -# X.509 Path Validation Test Suite, Version 1.07 -# http://csrc.nist.gov/pki/testing/x509paths_old.html -# http://csrc.nist.gov/pki/testing/x509tests.tgz - -if [ -z "$1" ]; then - echo "usage: $0 <path to X509tests directory>" - exit 1 -fi - -TESTS=$1 - -if [ ! -d $TESTS ]; then - echo "Not a directory: $TESTS" - exit 1 -fi - -X509TEST="./test_x509v3 -v" -TMPOUT=test_x509v3_nist.out - -# TODO: add support for validating CRLs - -END="End Certificate " -ROOT="Trust Anchor " -ICA="Intermediate Certificate " - -SUCCESS="" -FAILURE="" - -function run_test -{ - NUM=$1 - RES=$2 - shift 2 - $X509TEST "$@" > $TMPOUT.$NUM - VALRES=$? - OK=0 - if [ $RES -eq 0 ]; then - # expecting success - if [ $VALRES -eq 0 ]; then - OK=1 - else - echo "test$NUM failed - expected validation success" - OK=0 - fi - else - # expecting failure - if [ $VALRES -eq 0 ]; then - echo "test$NUM failed - expected validation failure" - OK=0 - else - REASON=`grep "Certificate chain validation failed: " $TMPOUT.$NUM` - if [ $? -eq 0 ]; then - REASONNUM=`echo "$REASON" | colrm 1 37` - if [ $REASONNUM -eq $RES ]; then - OK=1 - else - echo "test$NUM failed - expected validation result $RES; result was $REASONNUM" - OK=0 - fi - else - echo "test$NUM failed - expected validation failure; other type of error detected" - OK=0 - fi - fi - fi - if [ $OK -eq 1 ]; then - rm $TMPOUT.$NUM - SUCCESS="$SUCCESS $NUM" - else - FAILURE="$FAILURE $NUM" - fi -} - -P=$TESTS/test - -run_test 1 0 "${P}1/${END}CP.01.01.crt" "${P}1/${ROOT}CP.01.01.crt" -run_test 2 1 "${P}2/${END}CP.01.02.crt" "${P}2/${ICA}CP.01.02.crt" "${P}2/${ROOT}CP.01.01.crt" -run_test 3 1 "${P}3/${END}CP.01.03.crt" "${P}3/${ICA}CP.01.03.crt" "${P}3/${ROOT}CP.01.01.crt" -run_test 4 0 "${P}4/${END}CP.02.01.crt" "${P}4/${ICA}2 CP.02.01.crt" "${P}4/${ICA}1 CP.02.01.crt" "${P}4/${ROOT}CP.01.01.crt" -run_test 5 4 "${P}5/${END}CP.02.02.crt" "${P}5/${ICA}CP.02.02.crt" "${P}5/${ROOT}CP.01.01.crt" -run_test 6 4 "${P}6/${END}CP.02.03.crt" "${P}6/${ICA}CP.02.03.crt" "${P}6/${ROOT}CP.01.01.crt" -run_test 7 0 "${P}7/${END}CP.02.04.crt" "${P}7/${ICA}CP.02.04.crt" "${P}7/${ROOT}CP.01.01.crt" -run_test 8 4 "${P}8/${END}CP.02.05.crt" "${P}8/${ICA}CP.02.05.crt" "${P}8/${ROOT}CP.01.01.crt" -run_test 9 4 "${P}9/${END}CP.03.01.crt" "${P}9/${ICA}CP.03.01.crt" "${P}9/${ROOT}CP.01.01.crt" -run_test 10 4 "${P}10/${END}CP.03.02.crt" "${P}10/${ICA}CP.03.02.crt" "${P}10/${ROOT}CP.01.01.crt" -run_test 11 4 "${P}11/${END}CP.03.03.crt" "${P}11/${ICA}CP.03.03.crt" "${P}11/${ROOT}CP.01.01.crt" -run_test 12 0 "${P}12/${END}CP.03.04.crt" "${P}12/${ICA}CP.03.04.crt" "${P}12/${ROOT}CP.01.01.crt" -run_test 13 5 "${P}13/${END}CP.04.01.crt" "${P}13/${ICA}CP.04.01.crt" "${P}13/${ROOT}CP.01.01.crt" -run_test 14 5 "${P}14/${END}CP.04.02.crt" "${P}14/${ICA}CP.04.02.crt" "${P}14/${ROOT}CP.01.01.crt" -run_test 15 0 "${P}15/${END}CP.04.03.crt" "${P}15/${ICA}CP.04.03.crt" "${P}15/${ROOT}CP.01.01.crt" -run_test 16 0 "${P}16/${END}CP.04.04.crt" "${P}16/${ICA}CP.04.04.crt" "${P}16/${ROOT}CP.01.01.crt" -run_test 17 0 "${P}17/${END}CP.04.05.crt" "${P}17/${ICA}CP.04.05.crt" "${P}17/${ROOT}CP.01.01.crt" -run_test 18 0 "${P}18/${END}CP.04.06.crt" "${P}18/${ICA}CP.04.06.crt" "${P}18/${ROOT}CP.01.01.crt" -run_test 19 1 "${P}19/${END}CP.05.01.crt" "${P}19/${ICA}CP.05.01.crt" "${P}19/${ROOT}CP.01.01.crt" -run_test 20 3 "${P}20/${END}CP.06.01.crt" "${P}20/${ICA}CP.06.01.crt" "${P}20/${ROOT}CP.01.01.crt" -run_test 21 3 "${P}21/${END}CP.06.02.crt" "${P}21/${ICA}CP.06.02.crt" "${P}21/${ROOT}CP.01.01.crt" -run_test 22 1 "${P}22/${END}IC.01.01.crt" "${P}22/${ICA}IC.01.01.crt" "${P}22/${ROOT}CP.01.01.crt" -run_test 23 1 "${P}23/${END}IC.02.01.crt" "${P}23/${ICA}IC.02.01.crt" "${P}23/${ROOT}CP.01.01.crt" -run_test 24 0 "${P}24/${END}IC.02.02.crt" "${P}24/${ICA}IC.02.02.crt" "${P}24/${ROOT}CP.01.01.crt" -run_test 25 1 "${P}25/${END}IC.02.03.crt" "${P}25/${ICA}IC.02.03.crt" "${P}25/${ROOT}CP.01.01.crt" -run_test 26 0 "${P}26/${END}IC.02.04.crt" "${P}26/${ICA}IC.02.04.crt" "${P}26/${ROOT}CP.01.01.crt" -run_test 27 0 "${P}27/${END}IC.04.01.crt" "${P}27/${ICA}IC.04.01.crt" "${P}27/${ROOT}CP.01.01.crt" -run_test 28 1 "${P}28/${END}IC.05.01.crt" "${P}28/${ICA}IC.05.01.crt" "${P}28/${ROOT}CP.01.01.crt" -run_test 29 1 "${P}29/${END}IC.05.02.crt" "${P}29/${ICA}IC.05.02.crt" "${P}29/${ROOT}CP.01.01.crt" -run_test 30 0 "${P}30/${END}IC.05.03.crt" "${P}30/${ICA}IC.05.03.crt" "${P}30/${ROOT}CP.01.01.crt" -run_test 31 1 "${P}31/${END}IC.06.01.crt" "${P}31/${ICA}IC.06.01.crt" "${P}31/${ROOT}CP.01.01.crt" -run_test 32 1 "${P}32/${END}IC.06.02.crt" "${P}32/${ICA}IC.06.02.crt" "${P}32/${ROOT}CP.01.01.crt" -run_test 33 0 "${P}33/${END}IC.06.03.crt" "${P}33/${ICA}IC.06.03.crt" "${P}33/${ROOT}CP.01.01.crt" -run_test 34 0 "${P}34/${END}PP.01.01.crt" "${P}34/${ICA}PP.01.01.crt" "${P}34/${ROOT}CP.01.01.crt" -run_test 35 0 "${P}35/${END}PP.01.02.crt" "${P}35/${ICA}PP.01.02.crt" "${P}35/${ROOT}CP.01.01.crt" -run_test 36 0 "${P}36/${END}PP.01.03.crt" "${P}36/${ICA}2 PP.01.03.crt" "${P}36/${ICA}1 PP.01.03.crt" "${P}36/${ROOT}CP.01.01.crt" -run_test 37 0 "${P}37/${END}PP.01.04.crt" "${P}37/${ICA}2 PP.01.04.crt" "${P}37/${ICA}1 PP.01.04.crt" "${P}37/${ROOT}CP.01.01.crt" -run_test 38 0 "${P}38/${END}PP.01.05.crt" "${P}38/${ICA}2 PP.01.05.crt" "${P}38/${ICA}1 PP.01.05.crt" "${P}38/${ROOT}CP.01.01.crt" -run_test 39 0 "${P}39/${END}PP.01.06.crt" "${P}39/${ICA}3 PP.01.06.crt" "${P}39/${ICA}2 PP.01.06.crt" "${P}39/${ICA}1 PP.01.06.crt" "${P}39/${ROOT}CP.01.01.crt" -run_test 40 0 "${P}40/${END}PP.01.07.crt" "${P}40/${ICA}3 PP.01.07.crt" "${P}40/${ICA}2 PP.01.07.crt" "${P}40/${ICA}1 PP.01.07.crt" "${P}40/${ROOT}CP.01.01.crt" -run_test 41 0 "${P}41/${END}PP.01.08.crt" "${P}41/${ICA}3 PP.01.08.crt" "${P}41/${ICA}2 PP.01.08.crt" "${P}41/${ICA}1 PP.01.08.crt" "${P}41/${ROOT}CP.01.01.crt" -run_test 42 0 "${P}42/${END}PP.01.09.crt" "${P}42/${ICA}4 PP.01.09.crt" "${P}42/${ICA}3 PP.01.09.crt" "${P}42/${ICA}2 PP.01.09.crt" "${P}42/${ICA}1 PP.01.09.crt" "${P}42/${ROOT}CP.01.01.crt" -run_test 43 0 "${P}43/${END}PP.06.01.crt" "${P}43/${ICA}4 PP.06.01.crt" "${P}43/${ICA}3 PP.06.01.crt" "${P}43/${ICA}2 PP.06.01.crt" "${P}43/${ICA}1 PP.06.01.crt" "${P}43/${ROOT}CP.01.01.crt" -run_test 44 0 "${P}44/${END}PP.06.02.crt" "${P}44/${ICA}4 PP.06.02.crt" "${P}44/${ICA}3 PP.06.02.crt" "${P}44/${ICA}2 PP.06.02.crt" "${P}44/${ICA}1 PP.06.02.crt" "${P}44/${ROOT}CP.01.01.crt" -run_test 45 0 "${P}45/${END}PP.06.03.crt" "${P}45/${ICA}4 PP.06.03.crt" "${P}45/${ICA}3 PP.06.03.crt" "${P}45/${ICA}2 PP.06.03.crt" "${P}45/${ICA}1 PP.06.03.crt" "${P}45/${ROOT}CP.01.01.crt" -run_test 46 0 "${P}46/${END}PP.06.04.crt" "${P}46/${ICA}4 PP.06.04.crt" "${P}46/${ICA}3 PP.06.04.crt" "${P}46/${ICA}2 PP.06.04.crt" "${P}46/${ICA}1 PP.06.04.crt" "${P}46/${ROOT}CP.01.01.crt" -run_test 47 0 "${P}47/${END}PP.06.05.crt" "${P}47/${ICA}4 PP.06.05.crt" "${P}47/${ICA}3 PP.06.05.crt" "${P}47/${ICA}2 PP.06.05.crt" "${P}47/${ICA}1 PP.06.05.crt" "${P}47/${ROOT}CP.01.01.crt" -run_test 48 0 "${P}48/${END}PP.08.01.crt" "${P}48/${ICA}PP.08.01.crt" "${P}48/${ROOT}CP.01.01.crt" -run_test 49 0 "${P}49/${END}PP.08.02.crt" "${P}49/${ICA}PP.08.02.crt" "${P}49/${ROOT}CP.01.01.crt" -run_test 50 0 "${P}50/${END}PP.08.03.crt" "${P}50/${ICA}PP.08.03.crt" "${P}50/${ROOT}CP.01.01.crt" -run_test 51 0 "${P}51/${END}PP.08.04.crt" "${P}51/${ICA}PP.08.04.crt" "${P}51/${ROOT}CP.01.01.crt" -run_test 52 0 "${P}52/${END}PP.08.05.crt" "${P}52/${ICA}PP.08.05.crt" "${P}52/${ROOT}CP.01.01.crt" -run_test 53 0 "${P}53/${END}PP.08.06.crt" "${P}53/${ICA}PP.08.06.crt" "${P}53/${ROOT}CP.01.01.crt" -run_test 54 1 "${P}54/${END}PL.01.01.crt" "${P}54/${ICA}2 PL.01.01.crt" "${P}54/${ICA}1 PL.01.01.crt" "${P}54/${ROOT}CP.01.01.crt" -run_test 55 1 "${P}55/${END}PL.01.02.crt" "${P}55/${ICA}2 PL.01.02.crt" "${P}55/${ICA}1 PL.01.02.crt" "${P}55/${ROOT}CP.01.01.crt" -run_test 56 0 "${P}56/${END}PL.01.03.crt" "${P}56/${ICA}PL.01.03.crt" "${P}56/${ROOT}CP.01.01.crt" -run_test 57 0 "${P}57/${END}PL.01.04.crt" "${P}57/${ICA}PL.01.04.crt" "${P}57/${ROOT}CP.01.01.crt" -run_test 58 1 "${P}58/${END}PL.01.05.crt" "${P}58/${ICA}3 PL.01.05.crt" "${P}58/${ICA}2 PL.01.05.crt" "${P}58/${ICA}1 PL.01.05.crt" "${P}58/${ROOT}CP.01.01.crt" -run_test 59 1 "${P}59/${END}PL.01.06.crt" "${P}59/${ICA}3 PL.01.06.crt" "${P}59/${ICA}2 PL.01.06.crt" "${P}59/${ICA}1 PL.01.06.crt" "${P}59/${ROOT}CP.01.01.crt" -run_test 60 1 "${P}60/${END}PL.01.07.crt" "${P}60/${ICA}4 PL.01.07.crt" "${P}60/${ICA}3 PL.01.07.crt" "${P}60/${ICA}2 PL.01.07.crt" "${P}60/${ICA}1 PL.01.07.crt" "${P}60/${ROOT}CP.01.01.crt" -run_test 61 1 "${P}61/${END}PL.01.08.crt" "${P}61/${ICA}4 PL.01.08.crt" "${P}61/${ICA}3 PL.01.08.crt" "${P}61/${ICA}2 PL.01.08.crt" "${P}61/${ICA}1 PL.01.08.crt" "${P}61/${ROOT}CP.01.01.crt" -run_test 62 0 "${P}62/${END}PL.01.09.crt" "${P}62/${ICA}4 PL.01.09.crt" "${P}62/${ICA}3 PL.01.09.crt" "${P}62/${ICA}2 PL.01.09.crt" "${P}62/${ICA}1 PL.01.09.crt" "${P}62/${ROOT}CP.01.01.crt" -run_test 63 0 "${P}63/${END}PL.01.10.crt" "${P}63/${ICA}4 PL.01.10.crt" "${P}63/${ICA}3 PL.01.10.crt" "${P}63/${ICA}2 PL.01.10.crt" "${P}63/${ICA}1 PL.01.10.crt" "${P}63/${ROOT}CP.01.01.crt" - - -echo "Successful tests:$SUCCESS" -echo "Failed tests:$FAILURE" diff --git a/contrib/wpa/wpa_supplicant/tests/test_x509v3_nist2.sh b/contrib/wpa/wpa_supplicant/tests/test_x509v3_nist2.sh deleted file mode 100755 index 0be29b7..0000000 --- a/contrib/wpa/wpa_supplicant/tests/test_x509v3_nist2.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/bin/sh - -# Public Key Interoperability Test Suite (PKITS) -# http://csrc.nist.gov/pki/testing/x509paths.html -# http://csrc.nist.gov/pki/testing/PKITS_data.zip - -if [ -z "$1" ]; then - echo "usage: $0 <path to root test directory>" - exit 1 -fi - -TESTS=$1 - -if [ ! -d $TESTS ]; then - echo "Not a directory: $TESTS" - exit 1 -fi - -X509TEST="$PWD/test_x509v3 -v" -TMPOUT="$PWD/test_x509v3_nist2.out" - -# TODO: add support for validating CRLs - -SUCCESS="" -FAILURE="" - -function run_test -{ - NUM=$1 - RES=$2 - shift 2 - $X509TEST "$@" TrustAnchorRootCertificate.crt > $TMPOUT.$NUM - VALRES=$? - OK=0 - if [ $RES -eq 0 ]; then - # expecting success - if [ $VALRES -eq 0 ]; then - OK=1 - else - echo "$NUM failed - expected validation success" - OK=0 - fi - else - # expecting failure - if [ $VALRES -eq 0 ]; then - echo "$NUM failed - expected validation failure" - OK=0 - else - REASON=`grep "Certificate chain validation failed: " $TMPOUT.$NUM` - if [ $? -eq 0 ]; then - REASONNUM=`echo "$REASON" | colrm 1 37` - if [ $REASONNUM -eq $RES ]; then - OK=1 - else - echo "$NUM failed - expected validation result $RES; result was $REASONNUM" - OK=0 - fi - else - echo "$NUM failed - expected validation failure; other type of error detected" - OK=0 - fi - fi - fi - if [ $OK -eq 1 ]; then - rm $TMPOUT.$NUM - SUCCESS="$SUCCESS $NUM" - else - FAILURE="$FAILURE $NUM" - fi -} - -pushd $TESTS/certs - -run_test 4.1.1 0 ValidCertificatePathTest1EE.crt GoodCACert.crt -run_test 4.1.2 1 InvalidCASignatureTest2EE.crt BadSignedCACert.crt -run_test 4.1.3 1 InvalidEESignatureTest3EE.crt GoodCACert.crt - -run_test 4.2.1 4 InvalidCAnotBeforeDateTest1EE.crt BadnotBeforeDateCACert.crt -run_test 4.2.2 4 InvalidEEnotBeforeDateTest2EE.crt GoodCACert.crt -run_test 4.2.3 0 Validpre2000UTCnotBeforeDateTest3EE.crt GoodCACert.crt -run_test 4.2.4 0 ValidGeneralizedTimenotBeforeDateTest4EE.crt GoodCACert.crt -run_test 4.2.5 4 InvalidCAnotAfterDateTest5EE.crt BadnotAfterDateCACert.crt -run_test 4.2.6 4 InvalidEEnotAfterDateTest6EE.crt GoodCACert.crt -run_test 4.2.7 4 Invalidpre2000UTCEEnotAfterDateTest7EE.crt GoodCACert.crt -run_test 4.2.8 0 ValidGeneralizedTimenotAfterDateTest8EE.crt GoodCACert.crt - -run_test 4.3.1 5 InvalidNameChainingTest1EE.crt GoodCACert.crt -run_test 4.3.2 5 InvalidNameChainingOrderTest2EE.crt NameOrderingCACert.crt -run_test 4.3.3 0 ValidNameChainingWhitespaceTest3EE.crt GoodCACert.crt -run_test 4.3.4 0 ValidNameChainingWhitespaceTest4EE.crt GoodCACert.crt -run_test 4.3.5 0 ValidNameChainingCapitalizationTest5EE.crt GoodCACert.crt -run_test 4.3.6 0 ValidNameUIDsTest6EE.crt UIDCACert.crt -run_test 4.3.7 0 ValidRFC3280MandatoryAttributeTypesTest7EE.crt RFC3280MandatoryAttributeTypesCACert.crt -run_test 4.3.8 0 ValidRFC3280OptionalAttributeTypesTest8EE.crt RFC3280OptionalAttributeTypesCACert.crt -run_test 4.3.9 0 ValidUTF8StringEncodedNamesTest9EE.crt UTF8StringEncodedNamesCACert.crt -run_test 4.3.10 0 ValidRolloverfromPrintableStringtoUTF8StringTest10EE.crt RolloverfromPrintableStringtoUTF8StringCACert.crt -run_test 4.3.11 0 ValidUTF8StringCaseInsensitiveMatchTest11EE.crt UTF8StringCaseInsensitiveMatchCACert.crt - -run_test 4.4.1 1 InvalidMissingCRLTest1EE.crt NoCRLCACert.crt -# skip rest of 4.4.x tests since CRLs are not yet supported - -run_test 4.5.1 0 ValidBasicSelfIssuedOldWithNewTest1EE.crt BasicSelfIssuedNewKeyOldWithNewCACert.crt BasicSelfIssuedNewKeyCACert.crt -run_test 4.5.2 3 InvalidBasicSelfIssuedOldWithNewTest2EE.crt BasicSelfIssuedNewKeyOldWithNewCACert.crt BasicSelfIssuedNewKeyCACert.crt -run_test 4.5.3 0 ValidBasicSelfIssuedNewWithOldTest3EE.crt BasicSelfIssuedOldKeyNewWithOldCACert.crt BasicSelfIssuedOldKeyCACert.crt -run_test 4.5.4 0 ValidBasicSelfIssuedNewWithOldTest4EE.crt BasicSelfIssuedOldKeyNewWithOldCACert.crt BasicSelfIssuedOldKeyCACert.crt -run_test 4.5.5 3 InvalidBasicSelfIssuedNewWithOldTest5EE.crt BasicSelfIssuedOldKeyNewWithOldCACert.crt BasicSelfIssuedOldKeyCACert.crt -run_test 4.5.6 0 ValidBasicSelfIssuedCRLSigningKeyTest6EE.crt BasicSelfIssuedCRLSigningKeyCRLCert.crt BasicSelfIssuedCRLSigningKeyCACert.crt -run_test 4.5.7 3 InvalidBasicSelfIssuedCRLSigningKeyTest7EE.crt BasicSelfIssuedCRLSigningKeyCRLCert.crt BasicSelfIssuedCRLSigningKeyCACert.crt -run_test 4.5.8 1 InvalidBasicSelfIssuedCRLSigningKeyTest8EE.crt BasicSelfIssuedCRLSigningKeyCRLCert.crt BasicSelfIssuedCRLSigningKeyCACert.crt - -run_test 4.6.1 1 InvalidMissingbasicConstraintsTest1EE.crt MissingbasicConstraintsCACert.crt -run_test 4.6.2 1 InvalidcAFalseTest2EE.crt basicConstraintsCriticalcAFalseCACert.crt -run_test 4.6.3 1 InvalidcAFalseTest3EE.crt basicConstraintsNotCriticalcAFalseCACert.crt -run_test 4.6.4 0 ValidbasicConstraintsNotCriticalTest4EE.crt basicConstraintsNotCriticalCACert.crt -run_test 4.6.5 1 InvalidpathLenConstraintTest5EE.crt pathLenConstraint0subCACert.crt pathLenConstraint0CACert.crt -run_test 4.6.6 1 InvalidpathLenConstraintTest6EE.crt pathLenConstraint0subCACert.crt pathLenConstraint0CACert.crt -run_test 4.6.7 0 ValidpathLenConstraintTest7EE.crt pathLenConstraint0CACert.crt -run_test 4.6.8 0 ValidpathLenConstraintTest8EE.crt pathLenConstraint0CACert.crt -run_test 4.6.9 1 InvalidpathLenConstraintTest9EE.crt pathLenConstraint6subsubCA00Cert.crt pathLenConstraint6subCA0Cert.crt pathLenConstraint6CACert.crt -run_test 4.6.10 1 InvalidpathLenConstraintTest10EE.crt pathLenConstraint6subsubCA00Cert.crt pathLenConstraint6subCA0Cert.crt pathLenConstraint6CACert.crt -run_test 4.6.11 1 InvalidpathLenConstraintTest11EE.crt pathLenConstraint6subsubsubCA11XCert.crt pathLenConstraint6subsubCA11Cert.crt pathLenConstraint6subCA1Cert.crt pathLenConstraint6CACert.crt -run_test 4.6.12 1 InvalidpathLenConstraintTest12EE.crt pathLenConstraint6subsubsubCA11XCert.crt pathLenConstraint6subsubCA11Cert.crt pathLenConstraint6subCA1Cert.crt pathLenConstraint6CACert.crt -run_test 4.6.13 0 ValidpathLenConstraintTest13EE.crt pathLenConstraint6subsubsubCA41XCert.crt pathLenConstraint6subsubCA41Cert.crt pathLenConstraint6subCA4Cert.crt pathLenConstraint6CACert.crt -run_test 4.6.14 0 ValidpathLenConstraintTest14EE.crt pathLenConstraint6subsubsubCA41XCert.crt pathLenConstraint6subsubCA41Cert.crt pathLenConstraint6subCA4Cert.crt pathLenConstraint6CACert.crt -run_test 4.6.15 0 ValidSelfIssuedpathLenConstraintTest15EE.crt pathLenConstraint0SelfIssuedCACert.crt pathLenConstraint0CACert.crt -run_test 4.6.16 1 InvalidSelfIssuedpathLenConstraintTest16EE.crt pathLenConstraint0subCA2Cert.crt pathLenConstraint0SelfIssuedCACert.crt pathLenConstraint0CACert.crt -run_test 4.6.17 0 ValidSelfIssuedpathLenConstraintTest17EE.crt pathLenConstraint1SelfIssuedsubCACert.crt pathLenConstraint1subCACert.crt pathLenConstraint1SelfIssuedCACert.crt pathLenConstraint1CACert.crt - -run_test 4.7.1 1 InvalidkeyUsageCriticalkeyCertSignFalseTest1EE.crt keyUsageCriticalkeyCertSignFalseCACert.crt -run_test 4.7.2 1 InvalidkeyUsageNotCriticalkeyCertSignFalseTest2EE.crt keyUsageNotCriticalkeyCertSignFalseCACert.crt -run_test 4.7.3 0 ValidkeyUsageNotCriticalTest3EE.crt keyUsageNotCriticalCACert.crt -run_test 4.7.4 1 InvalidkeyUsageCriticalcRLSignFalseTest4EE.crt keyUsageCriticalcRLSignFalseCACert.crt -run_test 4.7.5 1 InvalidkeyUsageNotCriticalcRLSignFalseTest5EE.crt keyUsageNotCriticalcRLSignFalseCACert.crt - -run_test 4.8.1 0 ValidCertificatePathTest1EE.crt GoodCACert.crt -run_test 4.8.2 0 AllCertificatesNoPoliciesTest2EE.crt NoPoliciesCACert.crt -run_test 4.8.3 0 DifferentPoliciesTest3EE.crt PoliciesP2subCACert.crt GoodCACert.crt -run_test 4.8.4 0 DifferentPoliciesTest4EE.crt GoodsubCACert.crt GoodCACert.crt -run_test 4.8.5 0 DifferentPoliciesTest5EE.crt PoliciesP2subCA2Cert.crt GoodCACert.crt -run_test 4.8.6 0 OverlappingPoliciesTest6EE.crt PoliciesP1234subsubCAP123P12Cert.crt PoliciesP1234subCAP123Cert.crt PoliciesP1234CACert.crt -run_test 4.8.7 0 DifferentPoliciesTest7EE.crt PoliciesP123subsubCAP12P1Cert.crt PoliciesP123subCAP12Cert.crt PoliciesP123CACert.crt -run_test 4.8.8 0 DifferentPoliciesTest8EE.crt PoliciesP12subsubCAP1P2Cert.crt PoliciesP12subCAP1Cert.crt PoliciesP12CACert.crt -run_test 4.8.9 0 DifferentPoliciesTest9EE.crt PoliciesP123subsubsubCAP12P2P1Cert.crt PoliciesP123subsubCAP12P2Cert.crt PoliciesP123subCAP12Cert.crt PoliciesP123CACert.crt -run_test 4.8.10 0 AllCertificatesSamePoliciesTest10EE.crt PoliciesP12CACert.crt -run_test 4.8.11 0 AllCertificatesanyPolicyTest11EE.crt anyPolicyCACert.crt -run_test 4.8.12 0 DifferentPoliciesTest12EE.crt PoliciesP3CACert.crt -run_test 4.8.13 0 AllCertificatesSamePoliciesTest13EE.crt PoliciesP123CACert.crt -run_test 4.8.14 0 AnyPolicyTest14EE.crt anyPolicyCACert.crt -run_test 4.8.15 0 UserNoticeQualifierTest15EE.crt -run_test 4.8.16 0 UserNoticeQualifierTest16EE.crt GoodCACert.crt -run_test 4.8.17 0 UserNoticeQualifierTest17EE.crt GoodCACert.crt -run_test 4.8.18 0 UserNoticeQualifierTest18EE.crt PoliciesP12CACert.crt -run_test 4.8.19 0 UserNoticeQualifierTest19EE.crt TrustAnchorRootCertificate.crt -run_test 4.8.20 0 CPSPointerQualifierTest20EE.crt GoodCACert.crt - -if false; then -# DSA tests -run_test 4.1.4 0 ValidDSASignaturesTest4EE.crt DSACACert.crt -fi - -popd - - -echo "Successful tests:$SUCCESS" -echo "Failed tests:$FAILURE" diff --git a/contrib/wpa/wpa_supplicant/todo.txt b/contrib/wpa/wpa_supplicant/todo.txt index a02a937..b84cccc 100644 --- a/contrib/wpa/wpa_supplicant/todo.txt +++ b/contrib/wpa/wpa_supplicant/todo.txt @@ -1,7 +1,4 @@ To do: -- hostap: try other roaming modes - NOTE: current mode (manual roaming) does not really roam at all.. - Firmware did not notice the current AP disappearing.. - add support for WPA with ap_scan=0 (update selected cipher etc. based on AssocInfo; make sure these match with configuration) - consider closing smart card / PCSC connection when EAP-SIM/EAP-AKA @@ -35,8 +32,6 @@ To do: - EAP-POTP/RSA SecurID profile (RFC 4793) - document wpa_gui build and consider adding it to 'make install' - test madwifi with pairwise=TKIP group=WEP104 -- possibility to link in WPA Authenticator state machine to wpa_supplicant - (new PeerKey handshake, WPA2/IEEE 802.11 (RSN) IBSS) - consider merging hostapd and wpa_supplicant PMKSA cache implementations - consider redesigning pending EAP requests (identity/password/otp from ctrl_iface) by moving the retrying of the previous request into EAP @@ -59,6 +54,9 @@ To do: could very well be done before EAP has been started - try to work around race in receiving association event and first EAPOL message +- try to work around race in configuring PTK and sending msg 4/4 (some NDIS + drivers with ndiswrapper end up not being able to complete 4-way handshake + in some cases; extra delay before setting the key seems to help) - add wpa_secure_memzero() macro and secure implementation (volatile u8*) to clear memory; this would be used to clear temporary buffers containing private data (e.g., keys); the macro can be defined to NOP in order to save @@ -72,18 +70,13 @@ To do: - add support for fetching full user cert chain from Windows certificate stores even when there are intermediate CA certs that are not in the configured ca_cert store (e.g., ROOT) (they could be, e.g., in CA store) - - -0.6.x branch: - clean up common.[ch] - change TLS/crypto library interface to use a structure of function pointers and helper inline functions (like driver_ops) instead of requiring every TLS wrapper to implement all functions - add support for encrypted configuration fields (e.g., password, psk, passphrase, pin) -- wpa_gui: add support for setting and showing priority, auth_alg - (open/shared for static WEP) - +- wpa_gui: add support for setting and showing priority - cleanup TLS/PEAP/TTLS/FAST fragmentation: both the handshake and Appl. Data phases should be able to use the same functions for this; the last step in processing sent should be this code and rest of the code diff --git a/contrib/wpa/wpa_supplicant/wpa_cli.c b/contrib/wpa/wpa_supplicant/wpa_cli.c index 7de6534..162a0b8 100644 --- a/contrib/wpa/wpa_supplicant/wpa_cli.c +++ b/contrib/wpa/wpa_supplicant/wpa_cli.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - command line interface for wpa_supplicant daemon - * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> + * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -23,15 +23,18 @@ #include <readline/readline.h> #include <readline/history.h> #endif /* CONFIG_READLINE */ +#ifdef CONFIG_WPA_CLI_FORK +#include <sys/wait.h> +#endif /* CONFIG_WPA_CLI_FORK */ -#include "wpa_ctrl.h" +#include "common/wpa_ctrl.h" #include "common.h" -#include "version.h" +#include "common/version.h" static const char *wpa_cli_version = "wpa_cli v" VERSION_STR "\n" -"Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> and contributors"; +"Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors"; static const char *wpa_cli_license = @@ -87,6 +90,10 @@ static const char *wpa_cli_full_license = "\n"; static struct wpa_ctrl *ctrl_conn; +static struct wpa_ctrl *mon_conn; +#ifdef CONFIG_WPA_CLI_FORK +static pid_t mon_pid = 0; +#endif /* CONFIG_WPA_CLI_FORK */ static int wpa_cli_quit = 0; static int wpa_cli_attached = 0; static int wpa_cli_connected = 0; @@ -96,6 +103,7 @@ static char *ctrl_ifname = NULL; static const char *pid_file = NULL; static const char *action_file = NULL; static int ping_interval = 5; +static int interactive = 0; static void print_help(); @@ -119,32 +127,126 @@ static void usage(void) } -static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname) +#ifdef CONFIG_WPA_CLI_FORK +static int in_query = 0; + +static void wpa_cli_monitor_sig(int sig) +{ + if (sig == SIGUSR1) + in_query = 1; + else if (sig == SIGUSR2) + in_query = 0; +} + +static void wpa_cli_monitor(void) +{ + char buf[256]; + size_t len = sizeof(buf) - 1; + struct timeval tv; + fd_set rfds; + + signal(SIGUSR1, wpa_cli_monitor_sig); + signal(SIGUSR2, wpa_cli_monitor_sig); + + while (mon_conn) { + int s = wpa_ctrl_get_fd(mon_conn); + tv.tv_sec = 5; + tv.tv_usec = 0; + FD_ZERO(&rfds); + FD_SET(s, &rfds); + if (select(s + 1, &rfds, NULL, NULL, &tv) < 0) { + if (errno == EINTR) + continue; + perror("select"); + break; + } + if (mon_conn == NULL) + break; + if (FD_ISSET(s, &rfds)) { + len = sizeof(buf) - 1; + int res = wpa_ctrl_recv(mon_conn, buf, &len); + if (res < 0) { + perror("wpa_ctrl_recv"); + break; + } + buf[len] = '\0'; + if (in_query) + printf("\r"); + printf("%s\n", buf); + kill(getppid(), SIGUSR1); + } + } +} +#endif /* CONFIG_WPA_CLI_FORK */ + + +static int wpa_cli_open_connection(const char *ifname, int attach) { #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE) ctrl_conn = wpa_ctrl_open(ifname); - return ctrl_conn; + if (ctrl_conn == NULL) + return -1; + + if (attach && interactive) + mon_conn = wpa_ctrl_open(ifname); + else + mon_conn = NULL; #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ char *cfile; int flen, res; if (ifname == NULL) - return NULL; + return -1; flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2; cfile = os_malloc(flen); if (cfile == NULL) - return NULL; + return -1L; res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname); if (res < 0 || res >= flen) { os_free(cfile); - return NULL; + return -1; } ctrl_conn = wpa_ctrl_open(cfile); + if (ctrl_conn == NULL) { + os_free(cfile); + return -1; + } + + if (attach && interactive) + mon_conn = wpa_ctrl_open(cfile); + else + mon_conn = NULL; os_free(cfile); - return ctrl_conn; #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ + + if (mon_conn) { + if (wpa_ctrl_attach(mon_conn) == 0) { + wpa_cli_attached = 1; + } else { + printf("Warning: Failed to attach to " + "wpa_supplicant.\n"); + return -1; + } + +#ifdef CONFIG_WPA_CLI_FORK + { + pid_t p = fork(); + if (p < 0) { + perror("fork"); + return -1; + } + if (p == 0) { + wpa_cli_monitor(); + exit(0); + } else + mon_pid = p; + } +#endif /* CONFIG_WPA_CLI_FORK */ + } + + return 0; } @@ -153,12 +255,25 @@ static void wpa_cli_close_connection(void) if (ctrl_conn == NULL) return; +#ifdef CONFIG_WPA_CLI_FORK + if (mon_pid) { + int status; + kill(mon_pid, SIGPIPE); + wait(&status); + mon_pid = 0; + } +#endif /* CONFIG_WPA_CLI_FORK */ + if (wpa_cli_attached) { - wpa_ctrl_detach(ctrl_conn); + wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn); wpa_cli_attached = 0; } wpa_ctrl_close(ctrl_conn); ctrl_conn = NULL; + if (mon_conn) { + wpa_ctrl_close(mon_conn); + mon_conn = NULL; + } } @@ -446,19 +561,85 @@ static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +#ifdef CONFIG_WPS_OOB +static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char cmd[256]; + int res; + + if (argc != 3 && argc != 4) { + printf("Invalid WPS_OOB command: need three or four " + "arguments:\n" + "- DEV_TYPE: use 'ufd' or 'nfc'\n" + "- PATH: path of OOB device like '/mnt'\n" + "- METHOD: OOB method 'pin-e' or 'pin-r', " + "'cred'\n" + "- DEV_NAME: (only for NFC) device name like " + "'pn531'\n"); + return -1; + } + + if (argc == 3) + res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s", + argv[0], argv[1], argv[2]); + else + res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s", + argv[0], argv[1], argv[2], argv[3]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long WPS_OOB command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} +#endif /* CONFIG_WPS_OOB */ + + static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) { char cmd[256]; int res; - if (argc != 2) { + if (argc == 2) + res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", + argv[0], argv[1]); + else if (argc == 6) { + char ssid_hex[2 * 32 + 1]; + char key_hex[2 * 64 + 1]; + int i; + + ssid_hex[0] = '\0'; + for (i = 0; i < 32; i++) { + if (argv[2][i] == '\0') + break; + os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); + } + + key_hex[0] = '\0'; + for (i = 0; i < 64; i++) { + if (argv[5][i] == '\0') + break; + os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]); + } + + res = os_snprintf(cmd, sizeof(cmd), + "WPS_REG %s %s %s %s %s %s", + argv[0], argv[1], ssid_hex, argv[3], argv[4], + key_hex); + } else { printf("Invalid WPS_REG command: need two arguments:\n" "- BSSID: use 'any' to select any\n" "- AP PIN\n"); + printf("Alternatively, six arguments can be used to " + "reconfigure the AP:\n" + "- BSSID: use 'any' to select any\n" + "- AP PIN\n" + "- new SSID\n" + "- new auth (OPEN, WPAPSK, WPA2PSK)\n" + "- new encr (NONE, WEP, TKIP, CCMP)\n" + "- new key\n"); return -1; } - res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", argv[0], argv[1]); if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { printf("Too long WPS_REG command.\n"); return -1; @@ -467,6 +648,110 @@ static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_ctrl_command(ctrl, "WPS_ER_START"); + +} + + +static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_ctrl_command(ctrl, "WPS_ER_STOP"); + +} + + +static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char cmd[256]; + int res; + + if (argc != 2) { + printf("Invalid WPS_ER_PIN command: need two arguments:\n" + "- UUID: use 'any' to select any\n" + "- PIN: Enrollee PIN\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s", + argv[0], argv[1]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long WPS_ER_PIN command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + + +static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char cmd[256]; + int res; + + if (argc != 1) { + printf("Invalid WPS_ER_PBC command: need one argument:\n" + "- UUID: Specify the Enrollee\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s", + argv[0]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long WPS_ER_PBC command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + + +static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char cmd[256]; + int res; + + if (argc != 2) { + printf("Invalid WPS_ER_LEARN command: need two arguments:\n" + "- UUID: specify which AP to use\n" + "- PIN: AP PIN\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s", + argv[0], argv[1]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long WPS_ER_LEARN command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + + +static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char cmd[256]; + int res; + + if (argc != 1) { + printf("Invalid IBSS_RSN command: needs one argument " + "(Peer STA MAC address)\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long IBSS_RSN command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + + static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) { char cmd[256]; @@ -990,14 +1275,8 @@ static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[]) os_free(ctrl_ifname); ctrl_ifname = os_strdup(argv[0]); - if (wpa_cli_open_connection(ctrl_ifname)) { + if (wpa_cli_open_connection(ctrl_ifname, 1)) { printf("Connected to interface '%s.\n", ctrl_ifname); - if (wpa_ctrl_attach(ctrl_conn) == 0) { - wpa_cli_attached = 1; - } else { - printf("Warning: Failed to attach to " - "wpa_supplicant.\n"); - } } else { printf("Could not connect to interface '%s' - re-trying\n", ctrl_ifname); @@ -1078,6 +1357,109 @@ static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc, } +#ifdef CONFIG_AP +static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char buf[64]; + if (argc != 1) { + printf("Invalid 'sta' command - exactly one argument, STA " + "address, is required.\n"); + return -1; + } + os_snprintf(buf, sizeof(buf), "STA %s", argv[0]); + return wpa_ctrl_command(ctrl, buf); +} + + +static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd, + char *addr, size_t addr_len) +{ + char buf[4096], *pos; + size_t len; + int ret; + + if (ctrl_conn == NULL) { + printf("Not connected to hostapd - command dropped.\n"); + return -1; + } + len = sizeof(buf) - 1; + ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, + wpa_cli_msg_cb); + if (ret == -2) { + printf("'%s' command timed out.\n", cmd); + return -2; + } else if (ret < 0) { + printf("'%s' command failed.\n", cmd); + return -1; + } + + buf[len] = '\0'; + if (memcmp(buf, "FAIL", 4) == 0) + return -1; + printf("%s", buf); + + pos = buf; + while (*pos != '\0' && *pos != '\n') + pos++; + *pos = '\0'; + os_strlcpy(addr, buf, addr_len); + return 0; +} + + +static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char addr[32], cmd[64]; + + if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr))) + return 0; + do { + os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); + } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0); + + return -1; +} +#endif /* CONFIG_AP */ + + +static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_ctrl_command(ctrl, "SUSPEND"); +} + + +static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_ctrl_command(ctrl, "RESUME"); +} + + +static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_ctrl_command(ctrl, "DROP_SA"); +} + + +static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char cmd[128]; + int res; + + if (argc != 1) { + printf("Invalid ROAM command: needs one argument " + "(target AP's BSSID)\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long ROAM command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + + enum wpa_cli_cmd_flags { cli_cmd_flag_none = 0x00, cli_cmd_flag_sensitive = 0x01 @@ -1238,9 +1620,49 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { cli_cmd_flag_sensitive, "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " "hardcoded)" }, +#ifdef CONFIG_WPS_OOB + { "wps_oob", wpa_cli_cmd_wps_oob, + cli_cmd_flag_sensitive, + "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" }, +#endif /* CONFIG_WPS_OOB */ { "wps_reg", wpa_cli_cmd_wps_reg, cli_cmd_flag_sensitive, "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, + { "wps_er_start", wpa_cli_cmd_wps_er_start, + cli_cmd_flag_none, + "= start Wi-Fi Protected Setup External Registrar" }, + { "wps_er_stop", wpa_cli_cmd_wps_er_stop, + cli_cmd_flag_none, + "= stop Wi-Fi Protected Setup External Registrar" }, + { "wps_er_pin", wpa_cli_cmd_wps_er_pin, + cli_cmd_flag_sensitive, + "<UUID> <PIN> = add an Enrollee PIN to External Registrar" }, + { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, + cli_cmd_flag_none, + "<UUID> = accept an Enrollee PBC using External Registrar" }, + { "wps_er_learn", wpa_cli_cmd_wps_er_learn, + cli_cmd_flag_sensitive, + "<UUID> <PIN> = learn AP configuration" }, + { "ibss_rsn", wpa_cli_cmd_ibss_rsn, + cli_cmd_flag_none, + "<addr> = request RSN authentication with <addr> in IBSS" }, +#ifdef CONFIG_AP + { "sta", wpa_cli_cmd_sta, + cli_cmd_flag_none, + "<addr> = get information about an associated station (AP)" }, + { "all_sta", wpa_cli_cmd_all_sta, + cli_cmd_flag_none, + "= get information about all associated stations (AP)" }, +#endif /* CONFIG_AP */ + { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none, + "= notification of suspend/hibernate" }, + { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none, + "= notification of resume/thaw" }, + { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none, + "= drop SA without deauth/disassoc (test command)" }, + { "roam", wpa_cli_cmd_roam, + cli_cmd_flag_none, + "<addr> = roam to the specified BSS" }, { NULL, NULL, cli_cmd_flag_none, NULL } }; @@ -1448,16 +1870,7 @@ static void wpa_cli_action_cb(char *msg, size_t len) static void wpa_cli_reconnect(void) { wpa_cli_close_connection(); - ctrl_conn = wpa_cli_open_connection(ctrl_ifname); - if (ctrl_conn) { - printf("Connection to wpa_supplicant re-established\n"); - if (wpa_ctrl_attach(ctrl_conn) == 0) { - wpa_cli_attached = 1; - } else { - printf("Warning: Failed to attach to " - "wpa_supplicant.\n"); - } - } + wpa_cli_open_connection(ctrl_ifname, 1); } @@ -1478,9 +1891,13 @@ static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read, wpa_cli_action_process(buf); else { if (in_read && first) - printf("\n"); + printf("\r"); first = 0; printf("%s\n", buf); +#ifdef CONFIG_READLINE + rl_on_new_line(); + rl_redisplay(); +#endif /* CONFIG_READLINE */ } } else { printf("Could not read pending message.\n"); @@ -1510,7 +1927,7 @@ static char * wpa_cli_cmd_gen(const char *text, int state) while ((cmd = wpa_cli_commands[i].cmd)) { i++; if (os_strncasecmp(cmd, text, len) == 0) - return os_strdup(cmd); + return strdup(cmd); } return NULL; @@ -1519,14 +1936,60 @@ static char * wpa_cli_cmd_gen(const char *text, int state) static char * wpa_cli_dummy_gen(const char *text, int state) { + int i; + + for (i = 0; wpa_cli_commands[i].cmd; i++) { + const char *cmd = wpa_cli_commands[i].cmd; + size_t len = os_strlen(cmd); + if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 && + rl_line_buffer[len] == ' ') { + printf("\n%s\n", wpa_cli_commands[i].usage); + rl_on_new_line(); + rl_redisplay(); + break; + } + } + + rl_attempted_completion_over = 1; + return NULL; +} + + +static char * wpa_cli_status_gen(const char *text, int state) +{ + static int i, len; + char *options[] = { + "verbose", NULL + }; + char *t; + + if (state == 0) { + i = 0; + len = os_strlen(text); + } + + while ((t = options[i])) { + i++; + if (os_strncasecmp(t, text, len) == 0) + return strdup(t); + } + + rl_attempted_completion_over = 1; return NULL; } static char ** wpa_cli_completion(const char *text, int start, int end) { - return rl_completion_matches(text, start == 0 ? - wpa_cli_cmd_gen : wpa_cli_dummy_gen); + char * (*func)(const char *text, int state); + + if (start == 0) + func = wpa_cli_cmd_gen; + else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0) + func = wpa_cli_status_gen; + else + func = wpa_cli_dummy_gen; + return rl_completion_matches(text, func); } #endif /* CONFIG_READLINE */ @@ -1563,10 +2026,14 @@ static void wpa_cli_interactive(void) #endif /* CONFIG_READLINE */ do { - wpa_cli_recv_pending(ctrl_conn, 0, 0); + wpa_cli_recv_pending(mon_conn, 0, 0); #ifndef CONFIG_NATIVE_WINDOWS alarm(ping_interval); #endif /* CONFIG_NATIVE_WINDOWS */ +#ifdef CONFIG_WPA_CLI_FORK + if (mon_pid) + kill(mon_pid, SIGUSR1); +#endif /* CONFIG_WPA_CLI_FORK */ #ifdef CONFIG_READLINE cmd = readline("> "); if (cmd && *cmd) { @@ -1587,7 +2054,7 @@ static void wpa_cli_interactive(void) #endif /* CONFIG_NATIVE_WINDOWS */ if (cmd == NULL) break; - wpa_cli_recv_pending(ctrl_conn, 0, 0); + wpa_cli_recv_pending(mon_conn, 0, 0); pos = cmd; while (*pos != '\0') { if (*pos == '\n') { @@ -1621,7 +2088,11 @@ static void wpa_cli_interactive(void) wpa_request(ctrl_conn, argc, argv); if (cmd != cmdbuf) - os_free(cmd); + free(cmd); +#ifdef CONFIG_WPA_CLI_FORK + if (mon_pid) + kill(mon_pid, SIGUSR2); +#endif /* CONFIG_WPA_CLI_FORK */ } while (!wpa_cli_quit); #ifdef CONFIG_READLINE @@ -1711,6 +2182,17 @@ static void wpa_cli_terminate(int sig) } +#ifdef CONFIG_WPA_CLI_FORK +static void wpa_cli_usr1(int sig) +{ +#ifdef CONFIG_READLINE + rl_on_new_line(); + rl_redisplay(); +#endif /* CONFIG_READLINE */ +} +#endif /* CONFIG_WPA_CLI_FORK */ + + #ifndef CONFIG_NATIVE_WINDOWS static void wpa_cli_alarm(int sig) { @@ -1721,8 +2203,8 @@ static void wpa_cli_alarm(int sig) } if (!ctrl_conn) wpa_cli_reconnect(); - if (ctrl_conn) - wpa_cli_recv_pending(ctrl_conn, 1, 0); + if (mon_conn) + wpa_cli_recv_pending(mon_conn, 1, 0); alarm(ping_interval); } #endif /* CONFIG_NATIVE_WINDOWS */ @@ -1785,7 +2267,6 @@ static char * wpa_cli_get_default_ifname(void) int main(int argc, char *argv[]) { - int interactive; int warning_displayed = 0; int c; int daemonize = 0; @@ -1852,31 +2333,6 @@ int main(int argc, char *argv[]) } } - for (; !global;) { - if (ctrl_ifname == NULL) - ctrl_ifname = wpa_cli_get_default_ifname(); - ctrl_conn = wpa_cli_open_connection(ctrl_ifname); - if (ctrl_conn) { - if (warning_displayed) - printf("Connection established.\n"); - break; - } - - if (!interactive) { - perror("Failed to connect to wpa_supplicant - " - "wpa_ctrl_open"); - return -1; - } - - if (!warning_displayed) { - printf("Could not connect to wpa_supplicant - " - "re-trying\n"); - warning_displayed = 1; - } - os_sleep(1, 0); - continue; - } - #ifndef _WIN32_WCE signal(SIGINT, wpa_cli_terminate); signal(SIGTERM, wpa_cli_terminate); @@ -1884,15 +2340,45 @@ int main(int argc, char *argv[]) #ifndef CONFIG_NATIVE_WINDOWS signal(SIGALRM, wpa_cli_alarm); #endif /* CONFIG_NATIVE_WINDOWS */ +#ifdef CONFIG_WPA_CLI_FORK + signal(SIGUSR1, wpa_cli_usr1); +#endif /* CONFIG_WPA_CLI_FORK */ + + if (ctrl_ifname == NULL) + ctrl_ifname = wpa_cli_get_default_ifname(); + + if (interactive) { + for (; !global;) { + if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) { + if (warning_displayed) + printf("Connection established.\n"); + break; + } - if (interactive || action_file) { - if (wpa_ctrl_attach(ctrl_conn) == 0) { - wpa_cli_attached = 1; - } else { - printf("Warning: Failed to attach to " - "wpa_supplicant.\n"); - if (!interactive) + if (!warning_displayed) { + printf("Could not connect to wpa_supplicant - " + "re-trying\n"); + warning_displayed = 1; + } + os_sleep(1, 0); + continue; + } + } else { + if (!global && + wpa_cli_open_connection(ctrl_ifname, 0) < 0) { + perror("Failed to connect to wpa_supplicant - " + "wpa_ctrl_open"); + return -1; + } + + if (action_file) { + if (wpa_ctrl_attach(ctrl_conn) == 0) { + wpa_cli_attached = 1; + } else { + printf("Warning: Failed to attach to " + "wpa_supplicant.\n"); return -1; + } } } diff --git a/contrib/wpa/wpa_supplicant/wpa_passphrase.c b/contrib/wpa/wpa_supplicant/wpa_passphrase.c index 96b0c32..67465aa 100644 --- a/contrib/wpa/wpa_supplicant/wpa_passphrase.c +++ b/contrib/wpa/wpa_supplicant/wpa_passphrase.c @@ -15,7 +15,7 @@ #include "includes.h" #include "common.h" -#include "sha1.h" +#include "crypto/sha1.h" int main(int argc, char *argv[]) diff --git a/contrib/wpa/wpa_supplicant/wpa_priv.c b/contrib/wpa/wpa_supplicant/wpa_priv.c index 4ff0284..d2a991b 100644 --- a/contrib/wpa/wpa_supplicant/wpa_priv.c +++ b/contrib/wpa/wpa_supplicant/wpa_priv.c @@ -21,19 +21,11 @@ #include "common.h" #include "eloop.h" -#include "version.h" +#include "common/version.h" #include "drivers/driver.h" #include "l2_packet/l2_packet.h" -#include "privsep_commands.h" -#include "ieee802_11_defs.h" - -#ifndef ETH_P_EAPOL -#define ETH_P_EAPOL 0x888e -#endif - -#ifndef ETH_P_RSN_PREAUTH -#define ETH_P_RSN_PREAUTH 0x88c7 -#endif +#include "common/privsep_commands.h" +#include "common/ieee802_11_defs.h" struct wpa_priv_interface { @@ -59,8 +51,6 @@ static void wpa_priv_cmd_register(struct wpa_priv_interface *iface, { if (iface->drv_priv) { wpa_printf(MSG_DEBUG, "Cleaning up forgotten driver instance"); - if (iface->driver->set_wpa) - iface->driver->set_wpa(iface->drv_priv, 0); if (iface->driver->deinit) iface->driver->deinit(iface->drv_priv); iface->drv_priv = NULL; @@ -93,9 +83,6 @@ static void wpa_priv_cmd_register(struct wpa_priv_interface *iface, iface->driver->set_param(iface->drv_priv, NULL) < 0) { wpa_printf(MSG_ERROR, "Driver interface rejected param"); } - - if (iface->driver->set_wpa) - iface->driver->set_wpa(iface->drv_priv, 1); } @@ -103,8 +90,6 @@ static void wpa_priv_cmd_unregister(struct wpa_priv_interface *iface, struct sockaddr_un *from) { if (iface->drv_priv) { - if (iface->driver->set_wpa) - iface->driver->set_wpa(iface->drv_priv, 0); if (iface->driver->deinit) iface->driver->deinit(iface->drv_priv); iface->drv_priv = NULL; @@ -113,26 +98,23 @@ static void wpa_priv_cmd_unregister(struct wpa_priv_interface *iface, } -static void wpa_priv_cmd_set_wpa(struct wpa_priv_interface *iface, - char *buf, size_t len) -{ - if (iface->drv_priv == NULL || len != sizeof(int)) - return; - - if (iface->driver->set_wpa) - iface->driver->set_wpa(iface->drv_priv, *((int *) buf)); -} - - static void wpa_priv_cmd_scan(struct wpa_priv_interface *iface, char *buf, size_t len) { + struct wpa_driver_scan_params params; + if (iface->drv_priv == NULL) return; - if (iface->driver->scan) - iface->driver->scan(iface->drv_priv, len ? (u8 *) buf : NULL, - len); + os_memset(¶ms, 0, sizeof(params)); + if (len) { + params.ssids[0].ssid = (u8 *) buf; + params.ssids[0].ssid_len = len; + params.num_ssids = 1; + } + + if (iface->driver->scan2) + iface->driver->scan2(iface->drv_priv, ¶ms); } @@ -182,104 +164,6 @@ fail: } -static void wpa_priv_send_old_scan_results(struct wpa_priv_interface *iface, - struct sockaddr_un *from) -{ -#define SCAN_AP_LIMIT 128 - int i, res, val; - struct wpa_scan_result *results = NULL; - u8 *buf = NULL, *pos, *end; - struct wpa_scan_res nres; - - results = os_malloc(SCAN_AP_LIMIT * sizeof(*results)); - if (results == NULL) - goto fail; - - res = iface->driver->get_scan_results(iface->drv_priv, results, - SCAN_AP_LIMIT); - if (res < 0 || res > SCAN_AP_LIMIT) - goto fail; - - buf = os_malloc(60000); - if (buf == NULL) - goto fail; - pos = buf; - end = buf + 60000; - os_memcpy(pos, &res, sizeof(int)); - pos += sizeof(int); - - os_memset(&nres, 0, sizeof(nres)); - for (i = 0; i < res; i++) { - struct wpa_scan_result *r = &results[i]; - size_t ie_len; - - ie_len = 2 + r->ssid_len + r->rsn_ie_len + r->wpa_ie_len; - if (r->maxrate) - ie_len += 3; - if (r->mdie_present) - ie_len += 5; - - val = sizeof(nres) + ie_len; - if (end - pos < (int) sizeof(int) + val) - break; - os_memcpy(pos, &val, sizeof(int)); - pos += sizeof(int); - - os_memcpy(nres.bssid, r->bssid, ETH_ALEN); - nres.freq = r->freq; - nres.caps = r->caps; - nres.qual = r->qual; - nres.noise = r->noise; - nres.level = r->level; - nres.tsf = r->tsf; - nres.ie_len = ie_len; - - os_memcpy(pos, &nres, sizeof(nres)); - pos += sizeof(nres); - - /* SSID IE */ - *pos++ = WLAN_EID_SSID; - *pos++ = r->ssid_len; - os_memcpy(pos, r->ssid, r->ssid_len); - pos += r->ssid_len; - - if (r->maxrate) { - /* Fake Supported Rate IE to include max rate */ - *pos++ = WLAN_EID_SUPP_RATES; - *pos++ = 1; - *pos++ = r->maxrate; - } - - if (r->rsn_ie_len) { - os_memcpy(pos, r->rsn_ie, r->rsn_ie_len); - pos += r->rsn_ie_len; - } - - if (r->mdie_present) { - os_memcpy(pos, r->mdie, 5); - pos += 5; - } - - if (r->wpa_ie_len) { - os_memcpy(pos, r->wpa_ie, r->wpa_ie_len); - pos += r->wpa_ie_len; - } - } - - sendto(iface->fd, buf, pos - buf, 0, (struct sockaddr *) from, - sizeof(*from)); - - os_free(buf); - os_free(results); - return; - -fail: - os_free(buf); - os_free(results); - sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); -} - - static void wpa_priv_cmd_get_scan_results(struct wpa_priv_interface *iface, struct sockaddr_un *from) { @@ -288,8 +172,6 @@ static void wpa_priv_cmd_get_scan_results(struct wpa_priv_interface *iface, if (iface->driver->get_scan_results2) wpa_priv_get_scan_results2(iface, from); - else if (iface->driver->get_scan_results) - wpa_priv_send_old_scan_results(iface, from); else sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); @@ -405,7 +287,8 @@ static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface, params = buf; - res = iface->driver->set_key(iface->drv_priv, params->alg, + res = iface->driver->set_key(iface->ifname, iface->drv_priv, + params->alg, params->addr, params->key_idx, params->set_tx, params->seq_len ? params->seq : NULL, @@ -564,17 +447,6 @@ static void wpa_priv_cmd_l2_send(struct wpa_priv_interface *iface, } -static void wpa_priv_cmd_set_mode(struct wpa_priv_interface *iface, - void *buf, size_t len) -{ - if (iface->drv_priv == NULL || iface->driver->set_mode == NULL || - len != sizeof(int)) - return; - - iface->driver->set_mode(iface->drv_priv, *((int *) buf)); -} - - static void wpa_priv_cmd_set_country(struct wpa_priv_interface *iface, char *buf) { @@ -621,9 +493,6 @@ static void wpa_priv_receive(int sock, void *eloop_ctx, void *sock_ctx) case PRIVSEP_CMD_UNREGISTER: wpa_priv_cmd_unregister(iface, &from); break; - case PRIVSEP_CMD_SET_WPA: - wpa_priv_cmd_set_wpa(iface, cmd_buf, cmd_len); - break; case PRIVSEP_CMD_SCAN: wpa_priv_cmd_scan(iface, cmd_buf, cmd_len); break; @@ -657,9 +526,6 @@ static void wpa_priv_receive(int sock, void *eloop_ctx, void *sock_ctx) case PRIVSEP_CMD_L2_SEND: wpa_priv_cmd_l2_send(iface, &from, cmd_buf, cmd_len); break; - case PRIVSEP_CMD_SET_MODE: - wpa_priv_cmd_set_mode(iface, cmd_buf, cmd_len); - break; case PRIVSEP_CMD_SET_COUNTRY: pos = cmd_buf; if (pos + cmd_len >= buf + sizeof(buf)) @@ -692,7 +558,7 @@ static void wpa_priv_interface_deinit(struct wpa_priv_interface *iface) } -extern struct wpa_driver_ops *wpa_supplicant_drivers[]; +extern struct wpa_driver_ops *wpa_drivers[]; static struct wpa_priv_interface * wpa_priv_interface_init(const char *dir, const char *params) @@ -721,10 +587,10 @@ wpa_priv_interface_init(const char *dir, const char *params) os_memcpy(iface->driver_name, params, len); iface->driver_name[len] = '\0'; - for (i = 0; wpa_supplicant_drivers[i]; i++) { + for (i = 0; wpa_drivers[i]; i++) { if (os_strcmp(iface->driver_name, - wpa_supplicant_drivers[i]->name) == 0) { - iface->driver = wpa_supplicant_drivers[i]; + wpa_drivers[i]->name) == 0) { + iface->driver = wpa_drivers[i]; break; } } @@ -1049,52 +915,6 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, } -#ifdef CONFIG_CLIENT_MLME -void wpa_supplicant_sta_free_hw_features(struct wpa_hw_modes *hw_features, - size_t num_hw_features) -{ - size_t i; - - if (hw_features == NULL) - return; - - for (i = 0; i < num_hw_features; i++) { - os_free(hw_features[i].channels); - os_free(hw_features[i].rates); - } - - os_free(hw_features); -} - - -void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len, - struct ieee80211_rx_status *rx_status) -{ - struct wpa_priv_interface *iface = ctx; - struct msghdr msg; - struct iovec io[3]; - int event = PRIVSEP_EVENT_STA_RX; - - wpa_printf(MSG_DEBUG, "STA RX from driver"); - io[0].iov_base = &event; - io[0].iov_len = sizeof(event); - io[1].iov_base = (u8 *) rx_status; - io[1].iov_len = sizeof(*rx_status); - io[2].iov_base = (u8 *) buf; - io[2].iov_len = len; - - os_memset(&msg, 0, sizeof(msg)); - msg.msg_iov = io; - msg.msg_iovlen = 3; - msg.msg_name = &iface->drv_addr; - msg.msg_namelen = sizeof(iface->drv_addr); - - if (sendmsg(iface->fd, &msg, 0) < 0) - perror("sendmsg(wpas_socket)"); -} -#endif /* CONFIG_CLIENT_MLME */ - - static void wpa_priv_terminate(int sig, void *eloop_ctx, void *signal_ctx) { wpa_printf(MSG_DEBUG, "wpa_priv termination requested"); @@ -1180,7 +1000,7 @@ int main(int argc, char *argv[]) wpa_printf(MSG_DEBUG, "wpa_priv control directory: '%s'", ctrl_dir); - if (eloop_init(NULL)) { + if (eloop_init()) { wpa_printf(MSG_ERROR, "Failed to initialize event loop"); goto out; } diff --git a/contrib/wpa/wpa_supplicant/wpa_supplicant.c b/contrib/wpa/wpa_supplicant/wpa_supplicant.c index 54bbcd9..37a539d 100644 --- a/contrib/wpa/wpa_supplicant/wpa_supplicant.c +++ b/contrib/wpa/wpa_supplicant/wpa_supplicant.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> + * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -21,28 +21,35 @@ #include "common.h" #include "eapol_supp/eapol_supp_sm.h" #include "eap_peer/eap.h" -#include "wpa.h" +#include "eap_server/eap_methods.h" +#include "rsn_supp/wpa.h" #include "eloop.h" -#include "drivers/driver.h" #include "config.h" #include "l2_packet/l2_packet.h" #include "wpa_supplicant_i.h" +#include "driver_i.h" #include "ctrl_iface.h" -#include "ctrl_iface_dbus.h" #include "pcsc_funcs.h" -#include "version.h" -#include "preauth.h" -#include "pmksa_cache.h" -#include "wpa_ctrl.h" +#include "common/version.h" +#include "rsn_supp/preauth.h" +#include "rsn_supp/pmksa_cache.h" +#include "common/wpa_ctrl.h" #include "mlme.h" -#include "ieee802_11_defs.h" +#include "common/ieee802_11_defs.h" #include "blacklist.h" #include "wpas_glue.h" #include "wps_supplicant.h" +#include "ibss_rsn.h" +#include "sme.h" +#include "ap.h" +#include "notify.h" +#include "bgscan.h" +#include "bss.h" +#include "scan.h" const char *wpa_supplicant_version = "wpa_supplicant v" VERSION_STR "\n" -"Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> and contributors"; +"Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> and contributors"; const char *wpa_supplicant_license = "This program is free software. You can distribute it and/or modify it\n" @@ -111,10 +118,10 @@ const char *wpa_supplicant_full_license5 = extern int wpa_debug_level; extern int wpa_debug_show_keys; extern int wpa_debug_timestamp; +extern struct wpa_driver_ops *wpa_drivers[]; /* Configure default/group WEP keys for static WEP */ -static int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, - struct wpa_ssid *ssid) +int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { int i, set = 0; @@ -138,13 +145,13 @@ static int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s, { u8 key[32]; size_t keylen; - wpa_alg alg; + enum wpa_alg alg; u8 seq[6] = { 0 }; /* IBSS/WPA-None uses only one key (Group) for both receiving and * sending unicast and multicast packets. */ - if (ssid->mode != IEEE80211_MODE_IBSS) { + if (ssid->mode != WPAS_MODE_IBSS) { wpa_printf(MSG_INFO, "WPA: Invalid mode %d (not IBSS/ad-hoc) " "for WPA-None", ssid->mode); return -1; @@ -211,7 +218,7 @@ void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s, int sec, int usec) { if (wpa_s->conf && wpa_s->conf->ap_scan == 0 && - wpa_s->driver && IS_WIRED(wpa_s->driver)) + (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) return; wpa_msg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec " @@ -250,6 +257,21 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s) struct eapol_config eapol_conf; struct wpa_ssid *ssid = wpa_s->current_ssid; +#ifdef CONFIG_IBSS_RSN + if (ssid->mode == WPAS_MODE_IBSS && + wpa_s->key_mgmt != WPA_KEY_MGMT_NONE && + wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) { + /* + * RSN IBSS authentication is per-STA and we can disable the + * per-BSSID EAPOL authentication. + */ + eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized); + eapol_sm_notify_eap_success(wpa_s->eapol, TRUE); + eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE); + return; + } +#endif /* CONFIG_IBSS_RSN */ + eapol_sm_notify_eap_success(wpa_s->eapol, FALSE); eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE); @@ -271,9 +293,8 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s) EAPOL_REQUIRE_KEY_BROADCAST; } - if (wpa_s->conf && wpa_s->driver && IS_WIRED(wpa_s->driver)) { + if (wpa_s->conf && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) eapol_conf.required_keys = 0; - } } if (wpa_s->conf) eapol_conf.fast_reauth = wpa_s->conf->fast_reauth; @@ -342,6 +363,7 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s, static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) { + bgscan_deinit(wpa_s); scard_deinit(wpa_s->scard); wpa_s->scard = NULL; wpa_sm_set_scard_ctx(wpa_s->wpa, NULL); @@ -358,6 +380,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpa_s->ctrl_iface = NULL; } if (wpa_s->conf != NULL) { + struct wpa_ssid *ssid; + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) + wpas_notify_network_removed(wpa_s, ssid); wpa_config_free(wpa_s->conf); wpa_s->conf = NULL; } @@ -376,8 +401,7 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpa_s->wpa = NULL; wpa_blacklist_clear(wpa_s); - wpa_scan_results_free(wpa_s->scan_res); - wpa_s->scan_res = NULL; + wpa_bss_deinit(wpa_s); wpa_supplicant_cancel_scan(wpa_s); wpa_supplicant_cancel_auth_timeout(wpa_s); @@ -388,6 +412,21 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpabuf_free(wpa_s->pending_eapol_rx); wpa_s->pending_eapol_rx = NULL; + +#ifdef CONFIG_IBSS_RSN + ibss_rsn_deinit(wpa_s->ibss_rsn); + wpa_s->ibss_rsn = NULL; +#endif /* CONFIG_IBSS_RSN */ + +#ifdef CONFIG_SME + os_free(wpa_s->sme.ft_ies); + wpa_s->sme.ft_ies = NULL; + wpa_s->sme.ft_ies_len = 0; +#endif /* CONFIG_SME */ + +#ifdef CONFIG_AP + wpa_supplicant_ap_deinit(wpa_s); +#endif /* CONFIG_AP */ } @@ -443,7 +482,7 @@ void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr) * @state: State (wpa_state; WPA_*) * Returns: The state name as a printable text string */ -const char * wpa_supplicant_state_txt(int state) +const char * wpa_supplicant_state_txt(enum wpa_states state) { switch (state) { case WPA_DISCONNECTED: @@ -452,6 +491,8 @@ const char * wpa_supplicant_state_txt(int state) return "INACTIVE"; case WPA_SCANNING: return "SCANNING"; + case WPA_AUTHENTICATING: + return "AUTHENTICATING"; case WPA_ASSOCIATING: return "ASSOCIATING"; case WPA_ASSOCIATED: @@ -476,8 +517,11 @@ const char * wpa_supplicant_state_txt(int state) * This function is called whenever the connection state changes, e.g., * association is completed for WPA/WPA2 4-Way Handshake is started. */ -void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state) +void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, + enum wpa_states state) { + enum wpa_states old_state = wpa_s->wpa_state; + wpa_printf(MSG_DEBUG, "State: %s -> %s", wpa_supplicant_state_txt(wpa_s->wpa_state), wpa_supplicant_state_txt(state)); @@ -485,9 +529,6 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state) if (state != WPA_SCANNING) wpa_supplicant_notify_scanning(wpa_s, 0); - wpa_supplicant_dbus_notify_state_change(wpa_s, state, - wpa_s->wpa_state); - if (state == WPA_COMPLETED && wpa_s->new_connection) { #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) struct wpa_ssid *ssid = wpa_s->current_ssid; @@ -501,35 +542,60 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state) wpa_s->new_connection = 0; wpa_s->reassociated_connection = 1; wpa_drv_set_operstate(wpa_s, 1); + wpa_s->after_wps = 0; } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING || state == WPA_ASSOCIATED) { wpa_s->new_connection = 1; wpa_drv_set_operstate(wpa_s, 0); } wpa_s->wpa_state = state; + + if (wpa_s->wpa_state != old_state) + wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state); +} + + +void wpa_supplicant_terminate_proc(struct wpa_global *global) +{ + int pending = 0; +#ifdef CONFIG_WPS + struct wpa_supplicant *wpa_s = global->ifaces; + while (wpa_s) { + if (wpas_wps_terminate_pending(wpa_s) == 1) + pending = 1; + wpa_s = wpa_s->next; + } +#endif /* CONFIG_WPS */ + if (pending) + return; + eloop_terminate(); } -static void wpa_supplicant_terminate(int sig, void *eloop_ctx, - void *signal_ctx) +static void wpa_supplicant_terminate(int sig, void *signal_ctx) { - struct wpa_global *global = eloop_ctx; + struct wpa_global *global = signal_ctx; struct wpa_supplicant *wpa_s; for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING "- signal %d " "received", sig); } - eloop_terminate(); + wpa_supplicant_terminate_proc(global); } static void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s) { + enum wpa_states old_state = wpa_s->wpa_state; + wpa_s->pairwise_cipher = 0; wpa_s->group_cipher = 0; wpa_s->mgmt_group_cipher = 0; wpa_s->key_mgmt = 0; wpa_s->wpa_state = WPA_DISCONNECTED; + + if (wpa_s->wpa_state != old_state) + wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state); } @@ -547,7 +613,10 @@ static void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s) int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) { struct wpa_config *conf; + struct wpa_ssid *old_ssid; int reconf_ctrl; + int old_ap_scan; + if (wpa_s->confname == NULL) return -1; conf = wpa_config_read(wpa_s->confname); @@ -568,7 +637,11 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) } eapol_sm_invalidate_cached_session(wpa_s->eapol); + old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = NULL; + if (old_ssid != wpa_s->current_ssid) + wpas_notify_network_changed(wpa_s); + /* * TODO: should notify EAPOL SM about changes in opensc_engine_path, * pkcs11_engine_path, pkcs11_module_path. @@ -584,8 +657,13 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) wpa_sm_set_config(wpa_s->wpa, NULL); wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth); rsn_preauth_deinit(wpa_s->wpa); + + old_ap_scan = wpa_s->conf->ap_scan; wpa_config_free(wpa_s->conf); wpa_s->conf = conf; + if (old_ap_scan != wpa_s->conf->ap_scan) + wpas_notify_ap_scan_changed(wpa_s); + if (reconf_ctrl) wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s); @@ -597,21 +675,20 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) } -static void wpa_supplicant_reconfig(int sig, void *eloop_ctx, - void *signal_ctx) +static void wpa_supplicant_reconfig(int sig, void *signal_ctx) { - struct wpa_global *global = eloop_ctx; + struct wpa_global *global = signal_ctx; struct wpa_supplicant *wpa_s; wpa_printf(MSG_DEBUG, "Signal %d received - reconfiguring", sig); for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { if (wpa_supplicant_reload_configuration(wpa_s) < 0) { - eloop_terminate(); + wpa_supplicant_terminate_proc(global); } } } -static wpa_cipher cipher_suite2driver(int cipher) +enum wpa_cipher cipher_suite2driver(int cipher) { switch (cipher) { case WPA_CIPHER_NONE: @@ -629,7 +706,7 @@ static wpa_cipher cipher_suite2driver(int cipher) } -static wpa_key_mgmt key_mgmt2driver(int key_mgmt) +enum wpa_key_mgmt key_mgmt2driver(int key_mgmt) { switch (key_mgmt) { case WPA_KEY_MGMT_NONE: @@ -693,7 +770,7 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s, #ifdef CONFIG_IEEE80211W if (!(ie->capabilities & WPA_CAPABILITY_MFPC) && - ssid->ieee80211w == IEEE80211W_REQUIRED) { + ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) { wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP " "that does not support management frame protection - " "reject"); @@ -720,8 +797,7 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s, * available). */ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *bss, - struct wpa_ssid *ssid, + struct wpa_bss *bss, struct wpa_ssid *ssid, u8 *wpa_ie, size_t *wpa_ie_len) { struct wpa_ie_data ie; @@ -729,8 +805,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, const u8 *bss_wpa, *bss_rsn; if (bss) { - bss_wpa = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); - bss_rsn = wpa_scan_get_ie(bss, WLAN_EID_RSN); + bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); + bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); } else bss_wpa = bss_rsn = NULL; @@ -763,7 +839,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, ie.key_mgmt = ssid->key_mgmt; #ifdef CONFIG_IEEE80211W ie.mgmt_group_cipher = - ssid->ieee80211w != NO_IEEE80211W ? + ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ? WPA_CIPHER_AES_128_CMAC : 0; #endif /* CONFIG_IEEE80211W */ wpa_printf(MSG_DEBUG, "WPA: Set cipher suites based " @@ -870,7 +946,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, #ifdef CONFIG_IEEE80211W sel = ie.mgmt_group_cipher; - if (ssid->ieee80211w == NO_IEEE80211W || + if (ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION || !(ie.capabilities & WPA_CAPABILITY_MFPC)) sel = 0; if (sel & WPA_CIPHER_AES_128_CMAC) { @@ -883,6 +959,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, } wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP, wpa_s->mgmt_group_cipher); + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, ssid->ieee80211w); #endif /* CONFIG_IEEE80211W */ if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) { @@ -909,37 +986,62 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, * This function is used to request %wpa_supplicant to associate with a BSS. */ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *bss, struct wpa_ssid *ssid) + struct wpa_bss *bss, struct wpa_ssid *ssid) { u8 wpa_ie[80]; size_t wpa_ie_len; - int use_crypt, ret, i; - int algs = AUTH_ALG_OPEN_SYSTEM; - wpa_cipher cipher_pairwise, cipher_group; + int use_crypt, ret, i, bssid_changed; + int algs = WPA_AUTH_ALG_OPEN; + enum wpa_cipher cipher_pairwise, cipher_group; struct wpa_driver_associate_params params; int wep_keys_set = 0; struct wpa_driver_capa capa; int assoc_failed = 0; + struct wpa_ssid *old_ssid; + + if (ssid->mode == WPAS_MODE_AP) { +#ifdef CONFIG_AP + if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) { + wpa_printf(MSG_INFO, "Driver does not support AP " + "mode"); + return; + } + wpa_supplicant_create_ap(wpa_s, ssid); + wpa_s->current_bss = bss; +#else /* CONFIG_AP */ + wpa_printf(MSG_ERROR, "AP mode support not included in the " + "build"); +#endif /* CONFIG_AP */ + return; + } + + if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) && + ssid->mode == IEEE80211_MODE_INFRA) { + sme_authenticate(wpa_s, bss, ssid); + return; + } wpa_s->reassociate = 0; if (bss) { #ifdef CONFIG_IEEE80211R - const u8 *md = NULL; + const u8 *ie, *md = NULL; #endif /* CONFIG_IEEE80211R */ - const u8 *ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid), - ie ? wpa_ssid_txt(ie + 2, ie[1]) : "", bss->freq); + wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq); + bssid_changed = !is_zero_ether_addr(wpa_s->bssid); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); + if (bssid_changed) + wpas_notify_bssid_changed(wpa_s); #ifdef CONFIG_IEEE80211R - ie = wpa_scan_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); + ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN) md = ie + 2; - wpa_sm_set_ft_params(wpa_s->wpa, md, NULL, 0, NULL); + wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0); if (md) { /* Prepare for the next transition */ - wpa_ft_prepare_auth_request(wpa_s->wpa); + wpa_ft_prepare_auth_request(wpa_s->wpa, ie); } #endif /* CONFIG_IEEE80211R */ #ifdef CONFIG_WPS @@ -964,37 +1066,25 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, * previous association. */ wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); - if (wpa_drv_set_mode(wpa_s, ssid->mode)) { - wpa_printf(MSG_WARNING, "Failed to set operating mode"); - assoc_failed = 1; - } - #ifdef IEEE8021X_EAPOL if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { if (ssid->leap) { if (ssid->non_leap == 0) - algs = AUTH_ALG_LEAP; + algs = WPA_AUTH_ALG_LEAP; else - algs |= AUTH_ALG_LEAP; + algs |= WPA_AUTH_ALG_LEAP; } } #endif /* IEEE8021X_EAPOL */ wpa_printf(MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs); if (ssid->auth_alg) { - algs = 0; - if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) - algs |= AUTH_ALG_OPEN_SYSTEM; - if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) - algs |= AUTH_ALG_SHARED_KEY; - if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) - algs |= AUTH_ALG_LEAP; + algs = ssid->auth_alg; wpa_printf(MSG_DEBUG, "Overriding auth_alg selection: 0x%x", algs); } - wpa_drv_set_auth_alg(wpa_s, algs); - if (bss && (wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || - wpa_scan_get_ie(bss, WLAN_EID_RSN)) && + if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || + wpa_bss_get_ie(bss, WLAN_EID_RSN)) && (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK | @@ -1081,20 +1171,19 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, wpa_supplicant_set_wpa_none_key(wpa_s, ssid); } - wpa_drv_set_drop_unencrypted(wpa_s, use_crypt); wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); os_memset(¶ms, 0, sizeof(params)); if (bss) { - const u8 *ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); params.bssid = bss->bssid; - params.ssid = ie ? ie + 2 : (u8 *) ""; - params.ssid_len = ie ? ie[1] : 0; + params.ssid = bss->ssid; + params.ssid_len = bss->ssid_len; params.freq = bss->freq; } else { params.ssid = ssid->ssid; params.ssid_len = ssid->ssid_len; } - if (ssid->mode == 1 && ssid->frequency > 0 && params.freq == 0) + if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 && + params.freq == 0) params.freq = ssid->frequency; /* Initial channel for IBSS */ params.wpa_ie = wpa_ie; params.wpa_ie_len = wpa_ie_len; @@ -1110,7 +1199,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, } params.wep_tx_keyidx = ssid->wep_tx_keyidx; - if (wpa_s->driver_4way_handshake && + if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) && (params.key_mgmt_suite == KEY_MGMT_PSK || params.key_mgmt_suite == KEY_MGMT_FT_PSK)) { params.passphrase = ssid->passphrase; @@ -1118,20 +1207,12 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, params.psk = ssid->psk; } + params.drop_unencrypted = use_crypt; + #ifdef CONFIG_IEEE80211W - switch (ssid->ieee80211w) { - case NO_IEEE80211W: - params.mgmt_frame_protection = NO_MGMT_FRAME_PROTECTION; - break; - case IEEE80211W_OPTIONAL: - params.mgmt_frame_protection = MGMT_FRAME_PROTECTION_OPTIONAL; - break; - case IEEE80211W_REQUIRED: - params.mgmt_frame_protection = MGMT_FRAME_PROTECTION_REQUIRED; - break; - } - if (ssid->ieee80211w != NO_IEEE80211W && bss) { - const u8 *rsn = wpa_scan_get_ie(bss, WLAN_EID_RSN); + params.mgmt_frame_protection = ssid->ieee80211w; + if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION && bss) { + const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); struct wpa_ie_data ie; if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 && ie.capabilities & @@ -1144,7 +1225,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_IEEE80211W */ - if (wpa_s->use_client_mlme) + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) ret = ieee80211_sta_associate(wpa_s, ¶ms); else ret = wpa_drv_associate(wpa_s, ¶ms); @@ -1164,16 +1245,27 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, * management. */ wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); +#ifdef CONFIG_IBSS_RSN + } else if (ssid->mode == WPAS_MODE_IBSS && + wpa_s->key_mgmt != WPA_KEY_MGMT_NONE && + wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) { + ibss_rsn_set_psk(wpa_s->ibss_rsn, ssid->psk); + /* + * RSN IBSS authentication is per-STA and we can disable the + * per-BSSID authentication. + */ + wpa_supplicant_cancel_auth_timeout(wpa_s); +#endif /* CONFIG_IBSS_RSN */ } else { /* Timeout for IEEE 802.11 authentication and association */ int timeout = 60; if (assoc_failed) { /* give IBSS a bit more time */ - timeout = ssid->mode ? 10 : 5; + timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5; } else if (wpa_s->conf->ap_scan == 1) { /* give IBSS a bit more time */ - timeout = ssid->mode ? 20 : 10; + timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10; } wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0); } @@ -1191,9 +1283,13 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, */ eapol_sm_invalidate_cached_session(wpa_s->eapol); } + old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = ssid; + wpa_s->current_bss = bss; wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); wpa_supplicant_initiate_eapol(wpa_s); + if (old_ssid != wpa_s->current_ssid) + wpas_notify_network_changed(wpa_s); } @@ -1208,9 +1304,11 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, int reason_code) { + struct wpa_ssid *old_ssid; u8 *addr = NULL; + if (!is_zero_ether_addr(wpa_s->bssid)) { - if (wpa_s->use_client_mlme) + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) ieee80211_sta_disassociate(wpa_s, reason_code); else wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code); @@ -1218,9 +1316,14 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, } wpa_clear_keys(wpa_s, addr); wpa_supplicant_mark_disassoc(wpa_s); + old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = NULL; + wpa_s->current_bss = NULL; wpa_sm_set_config(wpa_s->wpa, NULL); eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); + if (old_ssid != wpa_s->current_ssid) + wpas_notify_network_changed(wpa_s); + eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL); } @@ -1235,9 +1338,11 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, int reason_code) { + struct wpa_ssid *old_ssid; u8 *addr = NULL; + if (!is_zero_ether_addr(wpa_s->bssid)) { - if (wpa_s->use_client_mlme) + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) ieee80211_sta_deauthenticate(wpa_s, reason_code); else wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, @@ -1246,156 +1351,215 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, } wpa_clear_keys(wpa_s, addr); wpa_supplicant_mark_disassoc(wpa_s); + old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = NULL; + wpa_s->current_bss = NULL; wpa_sm_set_config(wpa_s->wpa, NULL); eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); + if (old_ssid != wpa_s->current_ssid) + wpas_notify_network_changed(wpa_s); + eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL); } -static int wpa_supplicant_get_scan_results_old(struct wpa_supplicant *wpa_s) +/** + * wpa_supplicant_enable_network - Mark a configured network as enabled + * @wpa_s: wpa_supplicant structure for a network interface + * @ssid: wpa_ssid structure for a configured network or %NULL + * + * Enables the specified network or all networks if no network specified. + */ +void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) { -#define SCAN_AP_LIMIT 128 - struct wpa_scan_result *results; - int num, i; - struct wpa_scan_results *res; - - results = os_malloc(SCAN_AP_LIMIT * sizeof(struct wpa_scan_result)); - if (results == NULL) { - wpa_printf(MSG_WARNING, "Failed to allocate memory for scan " - "results"); - return -1; - } + struct wpa_ssid *other_ssid; + int was_disabled; - num = wpa_drv_get_scan_results(wpa_s, results, SCAN_AP_LIMIT); - wpa_printf(MSG_DEBUG, "Scan results: %d", num); - if (num < 0) { - wpa_printf(MSG_DEBUG, "Failed to get scan results"); - os_free(results); - return -1; - } - if (num > SCAN_AP_LIMIT) { - wpa_printf(MSG_INFO, "Not enough room for all APs (%d < %d)", - num, SCAN_AP_LIMIT); - num = SCAN_AP_LIMIT; - } + if (ssid == NULL) { + other_ssid = wpa_s->conf->ssid; + while (other_ssid) { + if (other_ssid == wpa_s->current_ssid && + other_ssid->disabled) + wpa_s->reassociate = 1; - wpa_scan_results_free(wpa_s->scan_res); - wpa_s->scan_res = NULL; + was_disabled = other_ssid->disabled; - /* Convert old scan result data structure to the new one */ - res = os_zalloc(sizeof(*res)); - if (res == NULL) { - os_free(results); - return -1; - } - res->res = os_zalloc(num * sizeof(struct wpa_scan_res *)); - if (res->res == NULL) { - os_free(results); - os_free(res); - return -1; + other_ssid->disabled = 0; + + if (was_disabled != other_ssid->disabled) + wpas_notify_network_enabled_changed( + wpa_s, other_ssid); + + other_ssid = other_ssid->next; + } + if (wpa_s->reassociate) + wpa_supplicant_req_scan(wpa_s, 0, 0); + } else if (ssid->disabled) { + if (wpa_s->current_ssid == NULL) { + /* + * Try to reassociate since there is no current + * configuration and a new network was made available. + */ + wpa_s->reassociate = 1; + wpa_supplicant_req_scan(wpa_s, 0, 0); + } + + was_disabled = ssid->disabled; + + ssid->disabled = 0; + + if (was_disabled != ssid->disabled) + wpas_notify_network_enabled_changed(wpa_s, ssid); } +} + - for (i = 0; i < num; i++) { - struct wpa_scan_result *bss = &results[i]; - struct wpa_scan_res *r; - size_t ie_len; - u8 *pos; +/** + * wpa_supplicant_disable_network - Mark a configured network as disabled + * @wpa_s: wpa_supplicant structure for a network interface + * @ssid: wpa_ssid structure for a configured network or %NULL + * + * Disables the specified network or all networks if no network specified. + */ +void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + struct wpa_ssid *other_ssid; + int was_disabled; - ie_len = 2 + bss->ssid_len + bss->rsn_ie_len + bss->wpa_ie_len; - if (bss->maxrate) - ie_len += 3; - if (bss->mdie_present) - ie_len += 5; + if (ssid == NULL) { + other_ssid = wpa_s->conf->ssid; + while (other_ssid) { + was_disabled = other_ssid->disabled; - r = os_zalloc(sizeof(*r) + ie_len); - if (r == NULL) - break; + other_ssid->disabled = 1; - os_memcpy(r->bssid, bss->bssid, ETH_ALEN); - r->freq = bss->freq; - r->caps = bss->caps; - r->qual = bss->qual; - r->noise = bss->noise; - r->level = bss->level; - r->tsf = bss->tsf; - r->ie_len = ie_len; - - pos = (u8 *) (r + 1); - - /* SSID IE */ - *pos++ = WLAN_EID_SSID; - *pos++ = bss->ssid_len; - os_memcpy(pos, bss->ssid, bss->ssid_len); - pos += bss->ssid_len; - - if (bss->maxrate) { - /* Fake Supported Rate IE to include max rate */ - *pos++ = WLAN_EID_SUPP_RATES; - *pos++ = 1; - *pos++ = bss->maxrate; - } + if (was_disabled != other_ssid->disabled) + wpas_notify_network_enabled_changed( + wpa_s, other_ssid); - if (bss->rsn_ie_len) { - os_memcpy(pos, bss->rsn_ie, bss->rsn_ie_len); - pos += bss->rsn_ie_len; + other_ssid = other_ssid->next; } + if (wpa_s->current_ssid) + wpa_supplicant_disassociate( + wpa_s, WLAN_REASON_DEAUTH_LEAVING); + } else { + if (ssid == wpa_s->current_ssid) + wpa_supplicant_disassociate( + wpa_s, WLAN_REASON_DEAUTH_LEAVING); - if (bss->mdie_present) { - os_memcpy(pos, bss->mdie, 5); - pos += 5; - } + was_disabled = ssid->disabled; - if (bss->wpa_ie_len) { - os_memcpy(pos, bss->wpa_ie, bss->wpa_ie_len); - pos += bss->wpa_ie_len; - } + ssid->disabled = 1; - res->res[res->num++] = r; + if (was_disabled != ssid->disabled) + wpas_notify_network_enabled_changed(wpa_s, ssid); } +} - os_free(results); - wpa_s->scan_res = res; - return 0; +/** + * wpa_supplicant_select_network - Attempt association with a network + * @wpa_s: wpa_supplicant structure for a network interface + * @ssid: wpa_ssid structure for a configured network or %NULL for any network + */ +void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + + struct wpa_ssid *other_ssid; + + if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) + wpa_supplicant_disassociate( + wpa_s, WLAN_REASON_DEAUTH_LEAVING); + + /* + * Mark all other networks disabled or mark all networks enabled if no + * network specified. + */ + other_ssid = wpa_s->conf->ssid; + while (other_ssid) { + int was_disabled = other_ssid->disabled; + + other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0; + + if (was_disabled != other_ssid->disabled) + wpas_notify_network_enabled_changed(wpa_s, other_ssid); + + other_ssid = other_ssid->next; + } + wpa_s->disconnected = 0; + wpa_s->reassociate = 1; + wpa_supplicant_req_scan(wpa_s, 0, 0); + + if (ssid) + wpas_notify_network_selected(wpa_s, ssid); } /** - * wpa_supplicant_get_scan_results - Get scan results - * @wpa_s: Pointer to wpa_supplicant data - * Returns: 0 on success, -1 on failure + * wpa_supplicant_set_ap_scan - Set AP scan mode for interface + * @wpa_s: wpa_supplicant structure for a network interface + * @ap_scan: AP scan mode + * Returns: 0 if succeed or -1 if ap_scan has an invalid value * - * This function is request the current scan results from the driver and stores - * a local copy of the results in wpa_s->scan_res. */ -int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s) +int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan) { - int ret; - - if (wpa_s->use_client_mlme) { - wpa_scan_results_free(wpa_s->scan_res); - wpa_s->scan_res = ieee80211_sta_get_scan_results(wpa_s); - if (wpa_s->scan_res == NULL) { - wpa_printf(MSG_DEBUG, "Failed to get scan results"); - ret = -1; - } else - ret = 0; - } else if (wpa_s->driver->get_scan_results2 == NULL) - ret = wpa_supplicant_get_scan_results_old(wpa_s); - else { - wpa_scan_results_free(wpa_s->scan_res); - wpa_s->scan_res = wpa_drv_get_scan_results2(wpa_s); - if (wpa_s->scan_res == NULL) { - wpa_printf(MSG_DEBUG, "Failed to get scan results"); - ret = -1; - } else - ret = 0; - } - if (wpa_s->scan_res) - wpa_scan_sort_results(wpa_s->scan_res); + int old_ap_scan; + + if (ap_scan < 0 || ap_scan > 2) + return -1; + + old_ap_scan = wpa_s->conf->ap_scan; + wpa_s->conf->ap_scan = ap_scan; + + if (old_ap_scan != wpa_s->conf->ap_scan) + wpas_notify_ap_scan_changed(wpa_s); + + return 0; +} + + +/** + * wpa_supplicant_set_debug_params - Set global debug params + * @global: wpa_global structure + * @debug_level: debug level + * @debug_timestamp: determines if show timestamp in debug data + * @debug_show_keys: determines if show keys in debug data + * Returns: 0 if succeed or -1 if debug_level has wrong value + */ +int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level, + int debug_timestamp, int debug_show_keys) +{ + + int old_level, old_timestamp, old_show_keys; + + /* check for allowed debuglevels */ + if (debug_level != MSG_MSGDUMP && + debug_level != MSG_DEBUG && + debug_level != MSG_INFO && + debug_level != MSG_WARNING && + debug_level != MSG_ERROR) + return -1; + + old_level = wpa_debug_level; + old_timestamp = wpa_debug_timestamp; + old_show_keys = wpa_debug_show_keys; + + wpa_debug_level = debug_level; + wpa_debug_timestamp = debug_timestamp ? 1 : 0; + wpa_debug_show_keys = debug_show_keys ? 1 : 0; - return ret; + if (wpa_debug_level != old_level) + wpas_notify_debug_level_changed(global); + if (wpa_debug_timestamp != old_timestamp) + wpas_notify_debug_timestamp_changed(global); + if (wpa_debug_show_keys != old_show_keys) + wpas_notify_debug_show_keys_changed(global); + + return 0; } @@ -1413,7 +1577,7 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s) u8 bssid[ETH_ALEN]; int wired; - if (wpa_s->use_client_mlme) { + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) { if (ieee80211_sta_get_ssid(wpa_s, ssid, &ssid_len)) { wpa_printf(MSG_WARNING, "Could not read SSID from " "MLME."); @@ -1429,15 +1593,15 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s) ssid_len = res; } - if (wpa_s->use_client_mlme) + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) os_memcpy(bssid, wpa_s->bssid, ETH_ALEN); else if (wpa_drv_get_bssid(wpa_s, bssid) < 0) { wpa_printf(MSG_WARNING, "Could not read BSSID from driver."); return NULL; } - wired = wpa_s->conf->ap_scan == 0 && wpa_s->driver && - IS_WIRED(wpa_s->driver); + wired = wpa_s->conf->ap_scan == 0 && + (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED); entry = wpa_s->conf->ssid; while (entry) { @@ -1466,11 +1630,13 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s, const char *name) { int i; + size_t len; + const char *pos; if (wpa_s == NULL) return -1; - if (wpa_supplicant_drivers[0] == NULL) { + if (wpa_drivers[0] == NULL) { wpa_printf(MSG_ERROR, "No driver interfaces build into " "wpa_supplicant."); return -1; @@ -1478,24 +1644,45 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s, if (name == NULL) { /* default to first driver in the list */ - wpa_s->driver = wpa_supplicant_drivers[0]; + wpa_s->driver = wpa_drivers[0]; wpa_s->global_drv_priv = wpa_s->global->drv_priv[0]; return 0; } - for (i = 0; wpa_supplicant_drivers[i]; i++) { - if (os_strcmp(name, wpa_supplicant_drivers[i]->name) == 0) { - wpa_s->driver = wpa_supplicant_drivers[i]; + pos = os_strchr(name, ','); + if (pos) + len = pos - name; + else + len = os_strlen(name); + for (i = 0; wpa_drivers[i]; i++) { + if (os_strlen(wpa_drivers[i]->name) == len && + os_strncmp(name, wpa_drivers[i]->name, len) == + 0) { + wpa_s->driver = wpa_drivers[i]; wpa_s->global_drv_priv = wpa_s->global->drv_priv[i]; return 0; } } - wpa_printf(MSG_ERROR, "Unsupported driver '%s'.\n", name); + wpa_printf(MSG_ERROR, "Unsupported driver '%s'.", name); return -1; } +/** + * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant + * @ctx: Context pointer (wpa_s); this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @src_addr: Source address of the EAPOL frame + * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header) + * @len: Length of the EAPOL data + * + * This function is called for each received EAPOL frame. Most driver + * interfaces rely on more generic OS mechanism for receiving frames through + * l2_packet, but if such a mechanism is not available, the driver wrapper may + * take care of received EAPOL frames and deliver them to the core supplicant + * code by calling this function. + */ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) { @@ -1525,6 +1712,13 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, return; } +#ifdef CONFIG_AP + if (wpa_s->ap_iface) { + wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len); + return; + } +#endif /* CONFIG_AP */ + if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) { wpa_printf(MSG_DEBUG, "Ignored received EAPOL frame since " "no key management is configured"); @@ -1532,9 +1726,11 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, } if (wpa_s->eapol_received == 0 && - (!wpa_s->driver_4way_handshake || + (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) || !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || - wpa_s->wpa_state != WPA_COMPLETED)) { + wpa_s->wpa_state != WPA_COMPLETED) && + (wpa_s->current_ssid == NULL || + wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) { /* Timeout for completing IEEE 802.1X and WPA authentication */ wpa_supplicant_req_auth_timeout( wpa_s, @@ -1551,6 +1747,14 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, return; } +#ifdef CONFIG_IBSS_RSN + if (wpa_s->current_ssid && + wpa_s->current_ssid->mode == WPAS_MODE_IBSS) { + ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len); + return; + } +#endif /* CONFIG_IBSS_RSN */ + /* Source address of the incoming EAPOL frame could be compared to the * current BSSID. However, it is possible that a centralized * Authenticator could be using another MAC address than the BSSID of @@ -1562,7 +1766,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->driver_4way_handshake) + if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len); else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { /* @@ -1576,21 +1780,6 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, } -void wpa_supplicant_sta_free_hw_features(struct wpa_hw_modes *hw_features, - size_t num_hw_features) -{ - ieee80211_sta_free_hw_features(hw_features, num_hw_features); -} - - -void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len, - struct ieee80211_rx_status *rx_status) -{ - struct wpa_supplicant *wpa_s = ctx; - ieee80211_sta_rx(wpa_s, buf, len, rx_status); -} - - /** * wpa_supplicant_driver_init - Initialize driver interface parameters * @wpa_s: Pointer to wpa_supplicant data @@ -1641,37 +1830,21 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s) } } - /* Backwards compatibility call to set_wpa() handler. This is called - * only just after init and just before deinit, so these handler can be - * used to implement same functionality. */ - if (wpa_drv_set_wpa(wpa_s, 1) < 0) { - struct wpa_driver_capa capa; - if (wpa_drv_get_capa(wpa_s, &capa) < 0 || - !(capa.flags & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | - WPA_DRIVER_CAPA_KEY_MGMT_WPA2))) { - wpa_printf(MSG_DEBUG, "Driver does not support WPA."); - /* Continue to allow non-WPA modes to be used. */ - } else { - wpa_printf(MSG_ERROR, "Failed to enable WPA in the " - "driver."); - return -1; - } - } - wpa_clear_keys(wpa_s, NULL); /* Make sure that TKIP countermeasures are not left enabled (could * happen if wpa_supplicant is killed during countermeasures. */ wpa_drv_set_countermeasures(wpa_s, 0); - wpa_drv_set_drop_unencrypted(wpa_s, 1); - wpa_printf(MSG_DEBUG, "RSN: flushing PMKID list in the driver"); wpa_drv_flush_pmkid(wpa_s); - wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; - wpa_supplicant_req_scan(wpa_s, interface_count, 100000); - interface_count++; + wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; + if (wpa_supplicant_enabled_networks(wpa_s->conf)) { + wpa_supplicant_req_scan(wpa_s, interface_count, 100000); + interface_count++; + } else + wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); return 0; } @@ -1692,6 +1865,7 @@ static struct wpa_supplicant * wpa_supplicant_alloc(void) if (wpa_s == NULL) return NULL; wpa_s->scan_req = 1; + wpa_s->new_connection = 1; return wpa_s; } @@ -1700,6 +1874,9 @@ static struct wpa_supplicant * wpa_supplicant_alloc(void) static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, struct wpa_interface *iface) { + const char *ifname, *driver; + struct wpa_driver_capa capa; + wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver " "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname, iface->confname ? iface->confname : "N/A", @@ -1707,10 +1884,6 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, iface->ctrl_interface ? iface->ctrl_interface : "N/A", iface->bridge_ifname ? iface->bridge_ifname : "N/A"); - if (wpa_supplicant_set_driver(wpa_s, iface->driver) < 0) { - return -1; - } - if (iface->confname) { #ifdef CONFIG_BACKEND_FILE wpa_s->confname = os_rel2abs_path(iface->confname); @@ -1778,18 +1951,6 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, sizeof(wpa_s->bridge_ifname)); } - return 0; -} - - -static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s) -{ - const char *ifname; - struct wpa_driver_capa capa; - - wpa_printf(MSG_DEBUG, "Initializing interface (2) '%s'", - wpa_s->ifname); - /* RSNA Supplicant Key Management - INITIALIZE */ eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); @@ -1798,8 +1959,21 @@ static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s) * L2 receive handler so that association events are processed before * EAPOL-Key packets if both become available for the same select() * call. */ + driver = iface->driver; +next_driver: + if (wpa_supplicant_set_driver(wpa_s, driver) < 0) + return -1; + wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname); if (wpa_s->drv_priv == NULL) { + const char *pos; + pos = driver ? os_strchr(driver, ',') : NULL; + if (pos) { + wpa_printf(MSG_DEBUG, "Failed to initialize driver " + "interface - try next driver wrapper"); + driver = pos + 1; + goto next_driver; + } wpa_printf(MSG_ERROR, "Failed to initialize driver interface"); return -1; } @@ -1848,6 +2022,18 @@ static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s) return -1; } + if (wpa_drv_get_capa(wpa_s, &capa) == 0) { + wpa_s->drv_flags = capa.flags; + if (capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) { + if (ieee80211_sta_init(wpa_s)) + return -1; + } + wpa_s->max_scan_ssids = capa.max_scan_ssids; + wpa_s->max_remain_on_chan = capa.max_remain_on_chan; + } + if (wpa_s->max_remain_on_chan == 0) + wpa_s->max_remain_on_chan = 1000; + if (wpa_supplicant_driver_init(wpa_s) < 0) return -1; @@ -1880,43 +2066,37 @@ static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s) return -1; } - if (wpa_drv_get_capa(wpa_s, &capa) == 0) { - if (capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) { - wpa_s->use_client_mlme = 1; - if (ieee80211_sta_init(wpa_s)) - return -1; - } - if (capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) - wpa_s->driver_4way_handshake = 1; +#ifdef CONFIG_IBSS_RSN + wpa_s->ibss_rsn = ibss_rsn_init(wpa_s); + if (!wpa_s->ibss_rsn) { + wpa_printf(MSG_DEBUG, "Failed to init IBSS RSN"); + return -1; } +#endif /* CONFIG_IBSS_RSN */ + + if (wpa_bss_init(wpa_s) < 0) + return -1; return 0; } -static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s) +static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, + int notify) { if (wpa_s->drv_priv) { wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); - /* Backwards compatibility call to set_wpa() handler. This is - * called only just after init and just before deinit, so these - * handler can be used to implement same functionality. */ - if (wpa_drv_set_wpa(wpa_s, 0) < 0) { - wpa_printf(MSG_ERROR, "Failed to disable WPA in the " - "driver."); - } - - wpa_drv_set_drop_unencrypted(wpa_s, 0); wpa_drv_set_countermeasures(wpa_s, 0); wpa_clear_keys(wpa_s, NULL); } - wpas_dbus_unregister_iface(wpa_s); - wpa_supplicant_cleanup(wpa_s); + if (notify) + wpas_notify_iface_removed(wpa_s); + if (wpa_s->drv_priv) wpa_drv_deinit(wpa_s); } @@ -1938,6 +2118,8 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, struct wpa_interface *iface) { struct wpa_supplicant *wpa_s; + struct wpa_interface t_iface; + struct wpa_ssid *ssid; if (global == NULL || iface == NULL) return NULL; @@ -1948,22 +2130,39 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, wpa_s->global = global; - if (wpa_supplicant_init_iface(wpa_s, iface) || - wpa_supplicant_init_iface2(wpa_s)) { + t_iface = *iface; + if (global->params.override_driver) { + wpa_printf(MSG_DEBUG, "Override interface parameter: driver " + "('%s' -> '%s')", + iface->driver, global->params.override_driver); + t_iface.driver = global->params.override_driver; + } + if (global->params.override_ctrl_interface) { + wpa_printf(MSG_DEBUG, "Override interface parameter: " + "ctrl_interface ('%s' -> '%s')", + iface->ctrl_interface, + global->params.override_ctrl_interface); + t_iface.ctrl_interface = + global->params.override_ctrl_interface; + } + if (wpa_supplicant_init_iface(wpa_s, &t_iface)) { wpa_printf(MSG_DEBUG, "Failed to add interface %s", iface->ifname); - wpa_supplicant_deinit_iface(wpa_s); + wpa_supplicant_deinit_iface(wpa_s, 0); os_free(wpa_s); return NULL; } - /* Register the interface with the dbus control interface */ - if (wpas_dbus_register_iface(wpa_s)) { - wpa_supplicant_deinit_iface(wpa_s); + /* Notify the control interfaces about new iface */ + if (wpas_notify_iface_added(wpa_s)) { + wpa_supplicant_deinit_iface(wpa_s, 1); os_free(wpa_s); return NULL; } + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) + wpas_notify_network_added(wpa_s, ssid); + wpa_s->next = global->ifaces; global->ifaces = wpa_s; @@ -2003,7 +2202,7 @@ int wpa_supplicant_remove_iface(struct wpa_global *global, wpa_printf(MSG_DEBUG, "Removing interface %s", wpa_s->ifname); - wpa_supplicant_deinit_iface(wpa_s); + wpa_supplicant_deinit_iface(wpa_s, 1); os_free(wpa_s); return 0; @@ -2050,7 +2249,7 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) if (params->wpa_debug_syslog) wpa_debug_open_syslog(); - ret = eap_peer_register_methods(); + ret = eap_register_methods(); if (ret) { wpa_printf(MSG_ERROR, "Failed to register EAP methods"); if (ret == -2) @@ -2070,6 +2269,12 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) if (params->ctrl_interface) global->params.ctrl_interface = os_strdup(params->ctrl_interface); + if (params->override_driver) + global->params.override_driver = + os_strdup(params->override_driver); + if (params->override_ctrl_interface) + global->params.override_ctrl_interface = + os_strdup(params->override_ctrl_interface); wpa_debug_level = global->params.wpa_debug_level = params->wpa_debug_level; wpa_debug_show_keys = global->params.wpa_debug_show_keys = @@ -2077,7 +2282,7 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) wpa_debug_timestamp = global->params.wpa_debug_timestamp = params->wpa_debug_timestamp; - if (eloop_init(global)) { + if (eloop_init()) { wpa_printf(MSG_ERROR, "Failed to initialize event loop"); wpa_supplicant_deinit(global); return NULL; @@ -2089,16 +2294,12 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) return NULL; } - if (global->params.dbus_ctrl_interface) { - global->dbus_ctrl_iface = - wpa_supplicant_dbus_ctrl_iface_init(global); - if (global->dbus_ctrl_iface == NULL) { - wpa_supplicant_deinit(global); - return NULL; - } + if (wpas_notify_supplicant_initialized(global)) { + wpa_supplicant_deinit(global); + return NULL; } - for (i = 0; wpa_supplicant_drivers[i]; i++) + for (i = 0; wpa_drivers[i]; i++) global->drv_count++; if (global->drv_count == 0) { wpa_printf(MSG_ERROR, "No drivers enabled"); @@ -2110,13 +2311,13 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) wpa_supplicant_deinit(global); return NULL; } - for (i = 0; wpa_supplicant_drivers[i]; i++) { - if (!wpa_supplicant_drivers[i]->global_init) + for (i = 0; wpa_drivers[i]; i++) { + if (!wpa_drivers[i]->global_init) continue; - global->drv_priv[i] = wpa_supplicant_drivers[i]->global_init(); + global->drv_priv[i] = wpa_drivers[i]->global_init(); if (global->drv_priv[i] == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize driver " - "'%s'", wpa_supplicant_drivers[i]->name); + "'%s'", wpa_drivers[i]->name); wpa_supplicant_deinit(global); return NULL; } @@ -2150,8 +2351,8 @@ int wpa_supplicant_run(struct wpa_global *global) wpa_s->ctrl_iface); } - eloop_register_signal_terminate(wpa_supplicant_terminate, NULL); - eloop_register_signal_reconfig(wpa_supplicant_reconfig, NULL); + eloop_register_signal_terminate(wpa_supplicant_terminate, global); + eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); eloop_run(); @@ -2178,15 +2379,18 @@ void wpa_supplicant_deinit(struct wpa_global *global) if (global->ctrl_iface) wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface); - if (global->dbus_ctrl_iface) - wpa_supplicant_dbus_ctrl_iface_deinit(global->dbus_ctrl_iface); + + wpas_notify_supplicant_deinitialized(global); eap_peer_unregister_methods(); +#ifdef CONFIG_AP + eap_server_unregister_methods(); +#endif /* CONFIG_AP */ - for (i = 0; wpa_supplicant_drivers[i] && global->drv_priv; i++) { + for (i = 0; wpa_drivers[i] && global->drv_priv; i++) { if (!global->drv_priv[i]) continue; - wpa_supplicant_drivers[i]->global_deinit(global->drv_priv[i]); + wpa_drivers[i]->global_deinit(global->drv_priv[i]); } os_free(global->drv_priv); @@ -2197,6 +2401,8 @@ void wpa_supplicant_deinit(struct wpa_global *global) os_free(global->params.pid_file); } os_free(global->params.ctrl_interface); + os_free(global->params.override_driver); + os_free(global->params.override_ctrl_interface); os_free(global); wpa_debug_close_syslog(); diff --git a/contrib/wpa/wpa_supplicant/wpa_supplicant.conf b/contrib/wpa/wpa_supplicant/wpa_supplicant.conf index f5143c8..1b175ad 100644 --- a/contrib/wpa/wpa_supplicant/wpa_supplicant.conf +++ b/contrib/wpa/wpa_supplicant/wpa_supplicant.conf @@ -78,7 +78,9 @@ eapol_version=1 # allow the driver to take care of AP scanning and selection and use # wpa_supplicant just to process EAPOL frames based on IEEE 802.11 association # information from the driver. -# 1: wpa_supplicant initiates scanning and AP selection +# 1: wpa_supplicant initiates scanning and AP selection; if no APs matching to +# the currently enabled networks are found, a new network (IBSS or AP mode +# operation) may be initialized (if configured) (default) # 0: driver takes care of scanning, AP selection, and IEEE 802.11 association # parameters (e.g., WPA IE generation); this mode can also be used with # non-WPA drivers when using IEEE 802.1X mode; do not try to associate with @@ -93,6 +95,10 @@ eapol_version=1 # key_mgmt, pairwise, group, proto variables # # For use in FreeBSD with the wlan module ap_scan must be set to 1. +# When using IBSS or AP mode, ap_scan=2 mode can force the new network to be +# created immediately regardless of scan results. ap_scan=1 mode will first try +# to scan for existing networks and only if no matches with the enabled +# networks are found, a new IBSS or AP mode network is created. ap_scan=1 # EAP fast re-authentication @@ -181,6 +187,12 @@ fast_reauth=1 # 4-octet operating system version number (hex string) #os_version=01020300 +# Config Methods +# List of the supported configuration methods +# Available methods: usba ethernet label display ext_nfc_token int_nfc_token +# nfc_interface push_button keypad +#config_methods=label display push_button keypad + # Credential processing # 0 = process received credentials internally (default) # 1 = do not process received credentials; just pass them over ctrl_iface to @@ -189,6 +201,20 @@ fast_reauth=1 # to external program(s) #wps_cred_processing=0 +# Maximum number of BSS entries to keep in memory +# Default: 200 +# This can be used to limit memory use on the BSS entries (cached scan +# results). A larger value may be needed in environments that have huge number +# of APs when using ap_scan=1 mode. +#bss_max_count=200 + + +# filter_ssids - SSID-based scan result filtering +# 0 = do not filter scan results (default) +# 1 = only include configured SSIDs in scan results/BSS table +#filter_ssids=0 + + # network block # # Each network (usually AP's sharing the same SSID) is configured as a separate @@ -233,9 +259,10 @@ fast_reauth=1 # mode: IEEE 802.11 operation mode # 0 = infrastructure (Managed) mode, i.e., associate with an AP (default) # 1 = IBSS (ad-hoc, peer-to-peer) +# 2 = AP (access point) # Note: IBSS can only be used with key_mgmt NONE (plaintext and static WEP) -# and key_mgmt=WPA-NONE (fixed group key TKIP/CCMP). In addition, ap_scan has -# to be set to 2 for IBSS. WPA-None requires following network block options: +# and key_mgmt=WPA-NONE (fixed group key TKIP/CCMP). WPA-None requires +# following network block options: # proto=WPA, key_mgmt=WPA-NONE, pairwise=NONE, group=TKIP (or CCMP, but not # both), and psk must also be set. # @@ -246,6 +273,17 @@ fast_reauth=1 # an IBSS network with the configured SSID is already present, the frequency of # the network will be used instead of this configured value. # +# scan_freq: List of frequencies to scan +# Space-separated list of frequencies in MHz to scan when searching for this +# BSS. If the subset of channels used by the network is known, this option can +# be used to optimize scanning to not occur on channels that the network does +# not use. Example: scan_freq=2412 2437 2462 +# +# freq_list: Array of allowed frequencies +# Space-separated list of frequencies in MHz to allow for selecting the BSS. If +# set, scan results that do not match any of the specified frequencies are not +# considered when selecting a BSS. +# # proto: list of accepted protocols # WPA = WPA/IEEE 802.11i/D3.0 # RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN) @@ -362,6 +400,16 @@ fast_reauth=1 # a trusted CA certificate should always be configured when using # EAP-TLS/TTLS/PEAP. Full path should be used since working directory may # change when wpa_supplicant is run in the background. +# +# Alternatively, this can be used to only perform matching of the server +# certificate (SHA-256 hash of the DER encoded X.509 certificate). In +# this case, the possible CA certificates in the server certificate chain +# are ignored and only the server certificate is verified. This is +# configured with the following format: +# hash:://server/sha256/cert_hash_in_hex +# For example: "hash://server/sha256/ +# 5a1bc1296205e6fdbe3979728efe3920798885c1c4590b5f90f43222d239ca6a" +# # On Windows, trusted CA certificates can be loaded from the system # certificate store by setting this to cert_store://<name>, e.g., # ca_cert="cert_store://CA" or ca_cert="cert_store://ROOT". diff --git a/contrib/wpa/wpa_supplicant/wpa_supplicant.nsi b/contrib/wpa/wpa_supplicant/wpa_supplicant.nsi index 2783ca3..b9f0162 100644 --- a/contrib/wpa/wpa_supplicant/wpa_supplicant.nsi +++ b/contrib/wpa/wpa_supplicant/wpa_supplicant.nsi @@ -13,8 +13,8 @@ Page InstFiles section -Prerequisites SetOutPath $INSTDIR\Prerequisites MessageBox MB_YESNO "Install WinPcap?" /SD IDYES IDNO endWinPcap - File "/opt/Qt-Win/files/WinPcap_4_0_2.exe" - ExecWait "$INSTDIR\Prerequisites\WinPcap_4_0_2.exe" + File "/opt/Qt-Win/files/WinPcap_4_1_2.exe" + ExecWait "$INSTDIR\Prerequisites\WinPcap_4_1_2.exe" Goto endWinPcap endWinPcap: sectionEnd @@ -24,6 +24,7 @@ section setOutPath $INSTDIR File wpa_gui.exe + File wpa_gui_de.qm File wpa_cli.exe File COPYING File README @@ -36,6 +37,7 @@ section File wpasvc.exe File /opt/Qt-Win/files/mingwm10.dll + File /opt/Qt-Win/files/libgcc_s_dw2-1.dll File /opt/Qt-Win/files/QtCore4.dll File /opt/Qt-Win/files/QtGui4.dll @@ -82,6 +84,7 @@ section "uninstall" DeleteRegKey HKLM "Software\wpa_supplicant" delete "$INSTDIR\wpa_gui.exe" + delete "$INSTDIR\wpa_gui_de.qm" delete "$INSTDIR\wpa_cli.exe" delete "$INSTDIR\COPYING" delete "$INSTDIR\README" @@ -94,10 +97,11 @@ section "uninstall" delete "$INSTDIR\wpasvc.exe" delete "$INSTDIR\mingwm10.dll" + delete "$INSTDIR\libgcc_s_dw2-1.dll" delete "$INSTDIR\QtCore4.dll" delete "$INSTDIR\QtGui4.dll" - delete "$INSTDIR\Prerequisites\WinPcap_4_0_2.exe" + delete "$INSTDIR\Prerequisites\WinPcap_4_1_2.exe" rmdir "$INSTDIR\Prerequisites" rmdir "$INSTDIR" diff --git a/contrib/wpa/wpa_supplicant/wpa_supplicant_i.h b/contrib/wpa/wpa_supplicant/wpa_supplicant_i.h index 248ada5..6c36a1a 100644 --- a/contrib/wpa/wpa_supplicant/wpa_supplicant_i.h +++ b/contrib/wpa/wpa_supplicant/wpa_supplicant_i.h @@ -1,6 +1,6 @@ /* * wpa_supplicant - Internal definitions - * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> + * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,7 +15,8 @@ #ifndef WPA_SUPPLICANT_I_H #define WPA_SUPPLICANT_I_H -#include "drivers/driver.h" +#include "utils/list.h" +#include "common/defs.h" extern const char *wpa_supplicant_version; extern const char *wpa_supplicant_license; @@ -27,12 +28,12 @@ extern const char *wpa_supplicant_full_license4; extern const char *wpa_supplicant_full_license5; #endif /* CONFIG_NO_STDOUT_DEBUG */ -extern struct wpa_driver_ops *wpa_supplicant_drivers[]; - - -struct wpa_scan_result; struct wpa_sm; struct wpa_supplicant; +struct ibss_rsn; +struct scan_info; +struct wpa_bss; +struct wpa_scan_results; /* * Forward declarations of private structures used within the ctrl_iface @@ -41,7 +42,7 @@ struct wpa_supplicant; */ struct ctrl_iface_priv; struct ctrl_iface_global_priv; -struct ctrl_iface_dbus_priv; +struct wpas_dbus_priv; /** * struct wpa_interface - Parameters for wpa_supplicant_add_iface() @@ -160,7 +161,25 @@ struct wpa_params { /** * wpa_debug_syslog - Enable log output through syslog */ - const char *wpa_debug_syslog; + int wpa_debug_syslog; + + /** + * override_driver - Optional driver parameter override + * + * This parameter can be used to override the driver parameter in + * dynamic interface addition to force a specific driver wrapper to be + * used instead. + */ + char *override_driver; + + /** + * override_ctrl_interface - Optional ctrl_interface override + * + * This parameter can be used to override the ctrl_interface parameter + * in dynamic interface addition to force a control interface to be + * created. + */ + char *override_ctrl_interface; }; /** @@ -173,9 +192,10 @@ struct wpa_global { struct wpa_supplicant *ifaces; struct wpa_params params; struct ctrl_iface_global_priv *ctrl_iface; - struct ctrl_iface_dbus_priv *dbus_ctrl_iface; + struct wpas_dbus_priv *dbus; void **drv_priv; size_t drv_count; + struct os_time suspend_time; }; @@ -195,7 +215,7 @@ struct wpa_client_mlme { size_t extra_ie_len; u8 *extra_probe_ie; /* to be added to the end of ProbeReq */ size_t extra_probe_ie_len; - wpa_key_mgmt key_mgmt; + enum wpa_key_mgmt key_mgmt; /* The last AssocReq/Resp IEs */ u8 *assocreq_ies, *assocresp_ies; @@ -216,10 +236,8 @@ struct wpa_client_mlme { struct os_time last_probe; -#define IEEE80211_AUTH_ALG_OPEN BIT(0) -#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1) -#define IEEE80211_AUTH_ALG_LEAP BIT(2) - unsigned int auth_algs; /* bitfield of allowed auth algs */ + unsigned int auth_algs; /* bitfield of allowed auth algs + * (WPA_AUTH_ALG_*) */ int auth_alg; /* currently used IEEE 802.11 authentication algorithm */ int auth_transaction; @@ -241,6 +259,7 @@ struct wpa_client_mlme { u8 scan_ssid[32]; size_t scan_ssid_len; int scan_skip_11b; + int *scan_freqs; struct ieee80211_sta_bss *sta_bss_list; #define STA_HASH_SIZE 256 @@ -249,13 +268,13 @@ struct wpa_client_mlme { int cts_protect_erp_frames; - int phymode; /* current mode; WPA_MODE_IEEE80211A, .. */ - struct wpa_hw_modes *modes; + enum hostapd_hw_mode phymode; /* current mode */ + struct hostapd_hw_modes *modes; size_t num_modes; unsigned int hw_modes; /* bitfield of allowed hardware modes; - * (1 << MODE_*) */ + * (1 << HOSTAPD_MODE_*) */ int num_curr_rates; - struct wpa_rate_data *curr_rates; + int *curr_rates; int freq; /* The current frequency in MHz */ int channel; /* The current IEEE 802.11 channel number */ @@ -265,6 +284,10 @@ struct wpa_client_mlme { size_t ft_ies_len; #endif /* CONFIG_IEEE80211R */ + void (*public_action_cb)(void *ctx, const u8 *buf, size_t len, + int freq); + void *public_action_cb_ctx; + #else /* CONFIG_CLIENT_MLME */ int dummy; /* to keep MSVC happy */ #endif /* CONFIG_CLIENT_MLME */ @@ -288,6 +311,9 @@ struct wpa_supplicant { #ifdef CONFIG_CTRL_IFACE_DBUS char *dbus_path; #endif /* CONFIG_CTRL_IFACE_DBUS */ +#ifdef CONFIG_CTRL_IFACE_DBUS_NEW + char *dbus_new_path; +#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ char bridge_ifname[16]; char *confname; @@ -301,7 +327,9 @@ struct wpa_supplicant { int disconnected; /* all connections disabled; i.e., do no reassociate * before this has been cleared */ struct wpa_ssid *current_ssid; + struct wpa_bss *current_bss; int ap_ies_from_associnfo; + unsigned int assoc_freq; /* Selected configuration (based on Beacon/ProbeResp WPA IE) */ int pairwise_cipher; @@ -314,13 +342,19 @@ struct wpa_supplicant { struct wpa_ssid *prev_scan_ssid; /* previously scanned SSID; * NULL = not yet initialized (start - * with broadcast SSID) - * BROADCAST_SSID_SCAN = broadcast + * with wildcard SSID) + * WILDCARD_SSID_SCAN = wildcard * SSID was used in the previous scan */ -#define BROADCAST_SSID_SCAN ((struct wpa_ssid *) 1) +#define WILDCARD_SSID_SCAN ((struct wpa_ssid *) 1) - struct wpa_scan_results *scan_res; + void (*scan_res_handler)(struct wpa_supplicant *wpa_s, + struct wpa_scan_results *scan_res); + struct dl_list bss; /* struct wpa_bss::list */ + struct dl_list bss_id; /* struct wpa_bss::list_id */ + size_t num_bss; + unsigned int bss_update_idx; + unsigned int bss_next_id; struct wpa_driver_ops *driver; int interface_removed; /* whether the network interface has been @@ -330,7 +364,7 @@ struct wpa_supplicant { struct ctrl_iface_priv *ctrl_iface; - wpa_states wpa_state; + enum wpa_states wpa_state; int scanning; int new_connection; int reassociated_connection; @@ -348,15 +382,12 @@ struct wpa_supplicant { int scan_req; /* manual scan request; this forces a scan even if there * are no enabled networks in the configuration */ - int scan_res_tried; /* whether ap_scan=1 mode has tried to fetch scan - * results without a new scan request; this is used - * to speed up the first association if the driver - * has already available scan results. */ int scan_runs; /* number of scan runs since WPS was started */ struct wpa_client_mlme mlme; - int use_client_mlme; - int driver_4way_handshake; + unsigned int drv_flags; + int max_scan_ssids; + unsigned int max_remain_on_chan; int pending_mic_error_report; int pending_mic_error_pairwise; @@ -364,34 +395,72 @@ struct wpa_supplicant { struct wps_context *wps; int wps_success; /* WPS success event received */ + struct wps_er *wps_er; int blacklist_cleared; struct wpabuf *pending_eapol_rx; struct os_time pending_eapol_rx_time; u8 pending_eapol_rx_src[ETH_ALEN]; + + struct ibss_rsn *ibss_rsn; + +#ifdef CONFIG_SME + struct { + u8 ssid[32]; + size_t ssid_len; + int freq; + u8 assoc_req_ie[80]; + size_t assoc_req_ie_len; + int mfp; + int ft_used; + u8 mobility_domain[2]; + u8 *ft_ies; + size_t ft_ies_len; + u8 prev_bssid[ETH_ALEN]; + int prev_bssid_set; + int auth_alg; + } sme; +#endif /* CONFIG_SME */ + +#ifdef CONFIG_AP + struct hostapd_iface *ap_iface; + void (*ap_configured_cb)(void *ctx, void *data); + void *ap_configured_cb_ctx; + void *ap_configured_cb_data; +#endif /* CONFIG_AP */ + + struct wpa_ssid *bgscan_ssid; + const struct bgscan_ops *bgscan; + void *bgscan_priv; + + int connect_without_scan; + + int after_wps; + unsigned int wps_freq; }; /* wpa_supplicant.c */ +int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); + int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s); -const char * wpa_supplicant_state_txt(int state); +const char * wpa_supplicant_state_txt(enum wpa_states state); int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s); int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *bss, - struct wpa_ssid *ssid, + struct wpa_bss *bss, struct wpa_ssid *ssid, u8 *wpa_ie, size_t *wpa_ie_len); void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *bss, + struct wpa_bss *bss, struct wpa_ssid *ssid); void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s); -int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s); void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr); void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s, int sec, int usec); -void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state); +void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, + enum wpa_states state); struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s); void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s); void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, @@ -399,6 +468,18 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, int reason_code); +void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, + int ap_scan); +int wpa_supplicant_set_debug_params(struct wpa_global *global, + int debug_level, int debug_timestamp, + int debug_show_keys); + void wpa_show_license(void); struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, @@ -413,366 +494,19 @@ void wpa_supplicant_deinit(struct wpa_global *global); int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); - -/* scan.c */ -int wpa_supplicant_enabled_networks(struct wpa_config *conf); -void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec); -void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s); -void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s, - int scanning); +void wpa_supplicant_terminate_proc(struct wpa_global *global); +void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, + const u8 *buf, size_t len); +enum wpa_key_mgmt key_mgmt2driver(int key_mgmt); +enum wpa_cipher cipher_suite2driver(int cipher); /* events.c */ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s); +void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, + struct wpa_bss *selected, + struct wpa_ssid *ssid); -/* driver_ops */ -static inline void * wpa_drv_init(struct wpa_supplicant *wpa_s, - const char *ifname) -{ - if (wpa_s->driver->init2) - return wpa_s->driver->init2(wpa_s, ifname, - wpa_s->global_drv_priv); - if (wpa_s->driver->init) { - return wpa_s->driver->init(wpa_s, ifname); - } - return NULL; -} - -static inline void wpa_drv_deinit(struct wpa_supplicant *wpa_s) -{ - if (wpa_s->driver->deinit) - wpa_s->driver->deinit(wpa_s->drv_priv); -} - -static inline int wpa_drv_set_param(struct wpa_supplicant *wpa_s, - const char *param) -{ - if (wpa_s->driver->set_param) - return wpa_s->driver->set_param(wpa_s->drv_priv, param); - return 0; -} - -static inline int wpa_drv_set_drop_unencrypted(struct wpa_supplicant *wpa_s, - int enabled) -{ - if (wpa_s->driver->set_drop_unencrypted) { - return wpa_s->driver->set_drop_unencrypted(wpa_s->drv_priv, - enabled); - } - return -1; -} - -static inline int wpa_drv_set_countermeasures(struct wpa_supplicant *wpa_s, - int enabled) -{ - if (wpa_s->driver->set_countermeasures) { - return wpa_s->driver->set_countermeasures(wpa_s->drv_priv, - enabled); - } - return -1; -} - -static inline int wpa_drv_set_auth_alg(struct wpa_supplicant *wpa_s, - int auth_alg) -{ - if (wpa_s->driver->set_auth_alg) { - return wpa_s->driver->set_auth_alg(wpa_s->drv_priv, - auth_alg); - } - return -1; -} - -static inline int wpa_drv_set_wpa(struct wpa_supplicant *wpa_s, int enabled) -{ - if (wpa_s->driver->set_wpa) { - return wpa_s->driver->set_wpa(wpa_s->drv_priv, enabled); - } - return 0; -} - -static inline int wpa_drv_set_mode(struct wpa_supplicant *wpa_s, int mode) -{ - if (wpa_s->driver->set_mode) { - return wpa_s->driver->set_mode(wpa_s->drv_priv, mode); - } - return 0; -} - -static inline int wpa_drv_associate(struct wpa_supplicant *wpa_s, - struct wpa_driver_associate_params *params) -{ - if (wpa_s->driver->associate) { - return wpa_s->driver->associate(wpa_s->drv_priv, params); - } - return -1; -} - -static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s, const u8 *ssid, - size_t ssid_len) -{ - if (wpa_s->driver->scan) { - return wpa_s->driver->scan(wpa_s->drv_priv, ssid, ssid_len); - } - return -1; -} - -static inline int wpa_drv_get_scan_results(struct wpa_supplicant *wpa_s, - struct wpa_scan_result *results, - size_t max_size) -{ - if (wpa_s->driver->get_scan_results) { - return wpa_s->driver->get_scan_results(wpa_s->drv_priv, - results, max_size); - } - return -1; -} - -static inline struct wpa_scan_results * wpa_drv_get_scan_results2( - struct wpa_supplicant *wpa_s) -{ - if (wpa_s->driver->get_scan_results2) - return wpa_s->driver->get_scan_results2(wpa_s->drv_priv); - return NULL; -} - -static inline int wpa_drv_get_bssid(struct wpa_supplicant *wpa_s, u8 *bssid) -{ - if (wpa_s->driver->get_bssid) { - return wpa_s->driver->get_bssid(wpa_s->drv_priv, bssid); - } - return -1; -} - -static inline int wpa_drv_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid) -{ - if (wpa_s->driver->get_ssid) { - return wpa_s->driver->get_ssid(wpa_s->drv_priv, ssid); - } - return -1; -} - -static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s, wpa_alg alg, - const u8 *addr, int key_idx, int set_tx, - const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - if (wpa_s->driver->set_key) { - wpa_s->keys_cleared = 0; - return wpa_s->driver->set_key(wpa_s->drv_priv, alg, addr, - key_idx, set_tx, seq, seq_len, - key, key_len); - } - return -1; -} - -static inline int wpa_drv_deauthenticate(struct wpa_supplicant *wpa_s, - const u8 *addr, int reason_code) -{ - if (wpa_s->driver->deauthenticate) { - return wpa_s->driver->deauthenticate(wpa_s->drv_priv, addr, - reason_code); - } - return -1; -} - -static inline int wpa_drv_disassociate(struct wpa_supplicant *wpa_s, - const u8 *addr, int reason_code) -{ - if (wpa_s->driver->disassociate) { - return wpa_s->driver->disassociate(wpa_s->drv_priv, addr, - reason_code); - } - return -1; -} - -static inline int wpa_drv_add_pmkid(struct wpa_supplicant *wpa_s, - const u8 *bssid, const u8 *pmkid) -{ - if (wpa_s->driver->add_pmkid) { - return wpa_s->driver->add_pmkid(wpa_s->drv_priv, bssid, pmkid); - } - return -1; -} - -static inline int wpa_drv_remove_pmkid(struct wpa_supplicant *wpa_s, - const u8 *bssid, const u8 *pmkid) -{ - if (wpa_s->driver->remove_pmkid) { - return wpa_s->driver->remove_pmkid(wpa_s->drv_priv, bssid, - pmkid); - } - return -1; -} - -static inline int wpa_drv_flush_pmkid(struct wpa_supplicant *wpa_s) -{ - if (wpa_s->driver->flush_pmkid) { - return wpa_s->driver->flush_pmkid(wpa_s->drv_priv); - } - return -1; -} - -static inline int wpa_drv_get_capa(struct wpa_supplicant *wpa_s, - struct wpa_driver_capa *capa) -{ - if (wpa_s->driver->get_capa) { - return wpa_s->driver->get_capa(wpa_s->drv_priv, capa); - } - return -1; -} - -static inline void wpa_drv_poll(struct wpa_supplicant *wpa_s) -{ - if (wpa_s->driver->poll) { - wpa_s->driver->poll(wpa_s->drv_priv); - } -} - -static inline const char * wpa_drv_get_ifname(struct wpa_supplicant *wpa_s) -{ - if (wpa_s->driver->get_ifname) { - return wpa_s->driver->get_ifname(wpa_s->drv_priv); - } - return NULL; -} - -static inline const u8 * wpa_drv_get_mac_addr(struct wpa_supplicant *wpa_s) -{ - if (wpa_s->driver->get_mac_addr) { - return wpa_s->driver->get_mac_addr(wpa_s->drv_priv); - } - return NULL; -} - -static inline int wpa_drv_send_eapol(struct wpa_supplicant *wpa_s, - const u8 *dst, u16 proto, - const u8 *data, size_t data_len) -{ - if (wpa_s->driver->send_eapol) - return wpa_s->driver->send_eapol(wpa_s->drv_priv, dst, proto, - data, data_len); - return -1; -} - -static inline int wpa_drv_set_operstate(struct wpa_supplicant *wpa_s, - int state) -{ - if (wpa_s->driver->set_operstate) - return wpa_s->driver->set_operstate(wpa_s->drv_priv, state); - return 0; -} - -static inline int wpa_drv_mlme_setprotection(struct wpa_supplicant *wpa_s, - const u8 *addr, int protect_type, - int key_type) -{ - if (wpa_s->driver->mlme_setprotection) - return wpa_s->driver->mlme_setprotection(wpa_s->drv_priv, addr, - protect_type, - key_type); - return 0; -} - -static inline struct wpa_hw_modes * -wpa_drv_get_hw_feature_data(struct wpa_supplicant *wpa_s, u16 *num_modes, - u16 *flags) -{ - if (wpa_s->driver->get_hw_feature_data) - return wpa_s->driver->get_hw_feature_data(wpa_s->drv_priv, - num_modes, flags); - return NULL; -} - -static inline int wpa_drv_set_channel(struct wpa_supplicant *wpa_s, - wpa_hw_mode phymode, int chan, - int freq) -{ - if (wpa_s->driver->set_channel) - return wpa_s->driver->set_channel(wpa_s->drv_priv, phymode, - chan, freq); - return -1; -} - -static inline int wpa_drv_set_ssid(struct wpa_supplicant *wpa_s, - const u8 *ssid, size_t ssid_len) -{ - if (wpa_s->driver->set_ssid) { - return wpa_s->driver->set_ssid(wpa_s->drv_priv, ssid, - ssid_len); - } - return -1; -} - -static inline int wpa_drv_set_bssid(struct wpa_supplicant *wpa_s, - const u8 *bssid) -{ - if (wpa_s->driver->set_bssid) { - return wpa_s->driver->set_bssid(wpa_s->drv_priv, bssid); - } - return -1; -} - -static inline int wpa_drv_set_country(struct wpa_supplicant *wpa_s, - const char *alpha2) -{ - if (wpa_s->driver->set_country) - return wpa_s->driver->set_country(wpa_s->drv_priv, alpha2); - return 0; -} - -static inline int wpa_drv_send_mlme(struct wpa_supplicant *wpa_s, - const u8 *data, size_t data_len) -{ - if (wpa_s->driver->send_mlme) - return wpa_s->driver->send_mlme(wpa_s->drv_priv, - data, data_len); - return -1; -} - -static inline int wpa_drv_mlme_add_sta(struct wpa_supplicant *wpa_s, - const u8 *addr, const u8 *supp_rates, - size_t supp_rates_len) -{ - if (wpa_s->driver->mlme_add_sta) - return wpa_s->driver->mlme_add_sta(wpa_s->drv_priv, addr, - supp_rates, supp_rates_len); - return -1; -} - -static inline int wpa_drv_mlme_remove_sta(struct wpa_supplicant *wpa_s, - const u8 *addr) -{ - if (wpa_s->driver->mlme_remove_sta) - return wpa_s->driver->mlme_remove_sta(wpa_s->drv_priv, addr); - return -1; -} - -static inline int wpa_drv_update_ft_ies(struct wpa_supplicant *wpa_s, - const u8 *md, - const u8 *ies, size_t ies_len) -{ - if (wpa_s->driver->update_ft_ies) - return wpa_s->driver->update_ft_ies(wpa_s->drv_priv, md, - ies, ies_len); - return -1; -} - -static inline int wpa_drv_send_ft_action(struct wpa_supplicant *wpa_s, - u8 action, const u8 *target_ap, - const u8 *ies, size_t ies_len) -{ - if (wpa_s->driver->send_ft_action) - return wpa_s->driver->send_ft_action(wpa_s->drv_priv, action, - target_ap, ies, ies_len); - return -1; -} - -static inline int wpa_drv_set_probe_req_ie(struct wpa_supplicant *wpa_s, - const u8 *ies, size_t ies_len) -{ - if (wpa_s->driver->set_probe_req_ie) - return wpa_s->driver->set_probe_req_ie(wpa_s->drv_priv, ies, - ies_len); - return -1; -} +/* eap_register.c */ +int eap_register_methods(void); #endif /* WPA_SUPPLICANT_I_H */ diff --git a/contrib/wpa/wpa_supplicant/wpas_glue.c b/contrib/wpa/wpa_supplicant/wpas_glue.c index fc72cb8..4af0cd0 100644 --- a/contrib/wpa/wpa_supplicant/wpas_glue.c +++ b/contrib/wpa/wpa_supplicant/wpas_glue.c @@ -16,18 +16,22 @@ #include "common.h" #include "eapol_supp/eapol_supp_sm.h" -#include "wpa.h" +#include "rsn_supp/wpa.h" #include "eloop.h" #include "config.h" #include "l2_packet/l2_packet.h" -#include "wpa_common.h" +#include "common/wpa_common.h" #include "wpa_supplicant_i.h" -#include "pmksa_cache.h" +#include "driver_i.h" +#include "rsn_supp/pmksa_cache.h" #include "mlme.h" -#include "ieee802_11_defs.h" -#include "wpa_ctrl.h" +#include "sme.h" +#include "common/ieee802_11_defs.h" +#include "common/wpa_ctrl.h" #include "wpas_glue.h" #include "wps_supplicant.h" +#include "bss.h" +#include "scan.h" #ifndef CONFIG_NO_CONFIG_BLOBS @@ -241,7 +245,7 @@ static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, int success, wpa_supplicant_req_auth_timeout(wpa_s, 2, 0); } - if (!success || !wpa_s->driver_4way_handshake) + if (!success || !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) return; if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) @@ -298,35 +302,29 @@ static void wpa_supplicant_notify_eapol_done(void *ctx) static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s) { - size_t i; int ret = 0; - struct wpa_scan_res *curr = NULL; + struct wpa_bss *curr = NULL, *bss; struct wpa_ssid *ssid = wpa_s->current_ssid; const u8 *ie; - if (wpa_s->scan_res == NULL) - return -1; - - for (i = 0; i < wpa_s->scan_res->num; i++) { - struct wpa_scan_res *r = wpa_s->scan_res->res[i]; - if (os_memcmp(r->bssid, wpa_s->bssid, ETH_ALEN) != 0) + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { + if (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) != 0) continue; - ie = wpa_scan_get_ie(r, WLAN_EID_SSID); if (ssid == NULL || - ((ie && ie[1] == ssid->ssid_len && - os_memcmp(ie + 2, ssid->ssid, ssid->ssid_len) == 0) || + ((bss->ssid_len == ssid->ssid_len && + os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) == 0) || ssid->ssid_len == 0)) { - curr = r; + curr = bss; break; } } if (curr) { - ie = wpa_scan_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE); if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) ret = -1; - ie = wpa_scan_get_ie(curr, WLAN_EID_RSN); + ie = wpa_bss_get_ie(curr, WLAN_EID_RSN); if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) ret = -1; } else { @@ -346,9 +344,8 @@ static int wpa_supplicant_get_beacon_ie(void *ctx) /* No WPA/RSN IE found in the cached scan results. Try to get updated * scan results from the driver. */ - if (wpa_supplicant_get_scan_results(wpa_s) < 0) { + if (wpa_supplicant_update_scan_results(wpa_s) < 0) return -1; - } return wpa_get_beacon_ie(wpa_s); } @@ -375,7 +372,7 @@ static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s) } -static void _wpa_supplicant_set_state(void *wpa_s, wpa_states state) +static void _wpa_supplicant_set_state(void *wpa_s, enum wpa_states state) { wpa_supplicant_set_state(wpa_s, state); } @@ -386,13 +383,13 @@ static void _wpa_supplicant_set_state(void *wpa_s, wpa_states state) * @wpa_s: Pointer to wpa_supplicant data * Returns: The current connection state (WPA_*) */ -static wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s) +static enum wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s) { return wpa_s->wpa_state; } -static wpa_states _wpa_supplicant_get_state(void *wpa_s) +static enum wpa_states _wpa_supplicant_get_state(void *wpa_s) { return wpa_supplicant_get_state(wpa_s); } @@ -423,7 +420,7 @@ static void * wpa_supplicant_get_network_ctx(void *wpa_s) static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid) { struct wpa_supplicant *wpa_s = ctx; - if (wpa_s->use_client_mlme) { + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) { os_memcpy(bssid, wpa_s->bssid, ETH_ALEN); return 0; } @@ -431,7 +428,7 @@ static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid) } -static int wpa_supplicant_set_key(void *_wpa_s, wpa_alg alg, +static int wpa_supplicant_set_key(void *_wpa_s, enum wpa_alg alg, const u8 *addr, int key_idx, int set_tx, const u8 *seq, size_t seq_len, const u8 *key, size_t key_len) @@ -474,8 +471,10 @@ static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md, const u8 *ies, size_t ies_len) { struct wpa_supplicant *wpa_s = ctx; - if (wpa_s->use_client_mlme) + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) return ieee80211_sta_update_ft_ies(wpa_s, md, ies, ies_len); + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) + return sme_update_ft_ies(wpa_s, md, ies, ies_len); return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len); } @@ -485,16 +484,41 @@ static int wpa_supplicant_send_ft_action(void *ctx, u8 action, const u8 *ies, size_t ies_len) { struct wpa_supplicant *wpa_s = ctx; - if (wpa_s->use_client_mlme) + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) return ieee80211_sta_send_ft_action(wpa_s, action, target_ap, ies, ies_len); return wpa_drv_send_ft_action(wpa_s, action, target_ap, ies, ies_len); } + + +static int wpa_supplicant_mark_authenticated(void *ctx, const u8 *target_ap) +{ + struct wpa_supplicant *wpa_s = ctx; + struct wpa_driver_auth_params params; + struct wpa_bss *bss; + + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) + return -1; + + bss = wpa_bss_get_bssid(wpa_s, target_ap); + if (bss == NULL) + return -1; + + os_memset(¶ms, 0, sizeof(params)); + params.bssid = target_ap; + params.freq = bss->freq; + params.ssid = bss->ssid; + params.ssid_len = bss->ssid_len; + params.auth_alg = WPA_AUTH_ALG_FT; + params.local_state_change = 1; + return wpa_drv_authenticate(wpa_s, ¶ms); +} #endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_NO_WPA */ +#ifdef IEEE8021X_EAPOL #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) static void wpa_supplicant_eap_param_needed(void *ctx, const char *field, const char *txt) @@ -533,6 +557,24 @@ static void wpa_supplicant_eap_param_needed(void *ctx, const char *field, #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ +static void wpa_supplicant_port_cb(void *ctx, int authorized) +{ + struct wpa_supplicant *wpa_s = ctx; +#ifdef CONFIG_AP + if (wpa_s->ap_iface) { + wpa_printf(MSG_DEBUG, "AP mode active - skip EAPOL Supplicant " + "port status: %s", + authorized ? "Authorized" : "Unauthorized"); + return; + } +#endif /* CONFIG_AP */ + wpa_printf(MSG_DEBUG, "EAPOL: Supplicant port status: %s", + authorized ? "Authorized" : "Unauthorized"); + wpa_drv_set_supp_port(wpa_s, authorized); +} +#endif /* IEEE8021X_EAPOL */ + + int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s) { #ifdef IEEE8021X_EAPOL @@ -553,13 +595,12 @@ int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s) ctx->set_config_blob = wpa_supplicant_set_config_blob; ctx->get_config_blob = wpa_supplicant_get_config_blob; ctx->aborted_cached = wpa_supplicant_aborted_cached; -#ifdef EAP_TLS_OPENSSL ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; -#endif /* EAP_TLS_OPENSSL */ ctx->wps = wpa_s->wps; ctx->eap_param_needed = wpa_supplicant_eap_param_needed; + ctx->port_cb = wpa_supplicant_port_cb; ctx->cb = wpa_supplicant_eapol_cb; ctx->cb_ctx = wpa_s; wpa_s->eapol = eapol_sm_init(ctx); @@ -586,6 +627,7 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) } ctx->ctx = wpa_s; + ctx->msg_ctx = wpa_s; ctx->set_state = _wpa_supplicant_set_state; ctx->get_state = _wpa_supplicant_get_state; ctx->deauthenticate = _wpa_supplicant_deauthenticate; @@ -607,6 +649,7 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) #ifdef CONFIG_IEEE80211R ctx->update_ft_ies = wpa_supplicant_update_ft_ies; ctx->send_ft_action = wpa_supplicant_send_ft_action; + ctx->mark_authenticated = wpa_supplicant_mark_authenticated; #endif /* CONFIG_IEEE80211R */ wpa_s->wpa = wpa_sm_init(ctx); diff --git a/contrib/wpa/wpa_supplicant/wps_supplicant.c b/contrib/wpa/wpa_supplicant/wps_supplicant.c index 9422b1b..ba94d33 100644 --- a/contrib/wpa/wpa_supplicant/wps_supplicant.c +++ b/contrib/wpa/wpa_supplicant/wps_supplicant.c @@ -1,6 +1,6 @@ /* * wpa_supplicant / WPS integration - * Copyright (c) 2008, Jouni Malinen <j@w1.fi> + * Copyright (c) 2008-2010, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,18 +15,23 @@ #include "includes.h" #include "common.h" -#include "ieee802_11_defs.h" -#include "wpa_common.h" -#include "config.h" -#include "eap_peer/eap.h" -#include "wpa_supplicant_i.h" #include "eloop.h" #include "uuid.h" -#include "wpa_ctrl.h" -#include "ctrl_iface_dbus.h" +#include "crypto/dh_group5.h" +#include "common/ieee802_11_defs.h" +#include "common/ieee802_11_common.h" +#include "common/wpa_common.h" +#include "common/wpa_ctrl.h" #include "eap_common/eap_wsc_common.h" +#include "eap_peer/eap.h" +#include "rsn_supp/wpa.h" +#include "config.h" +#include "wpa_supplicant_i.h" +#include "driver_i.h" +#include "notify.h" #include "blacklist.h" -#include "wpa.h" +#include "bss.h" +#include "scan.h" #include "wps_supplicant.h" @@ -67,6 +72,8 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s) "try to associate with the received credential"); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); + wpa_s->after_wps = 5; + wpa_s->wps_freq = wpa_s->assoc_freq; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); return 1; @@ -90,8 +97,7 @@ static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) { struct wpa_driver_capa capa; - size_t i; - struct wpa_scan_res *bss; + struct wpa_bss *bss; const u8 *ie; struct wpa_ie_data adv; int wpa2 = 0, ccmp = 0; @@ -107,38 +113,22 @@ static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s, if (wpa_drv_get_capa(wpa_s, &capa)) return; /* Unknown what driver supports */ - if (wpa_supplicant_get_scan_results(wpa_s) || wpa_s->scan_res == NULL) - return; /* Could not get scan results for checking advertised - * parameters */ - - for (i = 0; i < wpa_s->scan_res->num; i++) { - bss = wpa_s->scan_res->res[i]; - if (os_memcmp(bss->bssid, cred->mac_addr, ETH_ALEN) != 0) - continue; - ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); - if (ie == NULL) - continue; - if (ie[1] != ssid->ssid_len || ssid->ssid == NULL || - os_memcmp(ie + 2, ssid->ssid, ssid->ssid_len) != 0) - continue; - - wpa_printf(MSG_DEBUG, "WPS: AP found from scan results"); - break; - } - - if (i == wpa_s->scan_res->num) { - wpa_printf(MSG_DEBUG, "WPS: The AP was not found from scan " - "results - use credential as-is"); + bss = wpa_bss_get(wpa_s, cred->mac_addr, ssid->ssid, ssid->ssid_len); + if (bss == NULL) { + wpa_printf(MSG_DEBUG, "WPS: The AP was not found from BSS " + "table - use credential as-is"); return; } - ie = wpa_scan_get_ie(bss, WLAN_EID_RSN); + wpa_printf(MSG_DEBUG, "WPS: AP found from BSS table"); + + ie = wpa_bss_get_ie(bss, WLAN_EID_RSN); if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0) { wpa2 = 1; if (adv.pairwise_cipher & WPA_CIPHER_CCMP) ccmp = 1; } else { - ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0 && adv.pairwise_cipher & WPA_CIPHER_CCMP) ccmp = 1; @@ -200,7 +190,8 @@ static int wpa_supplicant_wps_cred(void *ctx, WPS_EVENT_CRED_RECEIVED, buf); os_free(buf); } - wpa_supplicant_dbus_notify_wps_cred(wpa_s, cred); + + wpas_notify_wps_credential(wpa_s, cred); } else wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CRED_RECEIVED); @@ -253,6 +244,7 @@ static int wpa_supplicant_wps_cred(void *ctx, ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) return -1; + wpas_notify_network_added(wpa_s, ssid); } wpa_config_set_network_defaults(ssid); @@ -385,6 +377,7 @@ static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s, wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_M2D "dev_password_id=%d config_error=%d", m2d->dev_password_id, m2d->config_error); + wpas_notify_wps_event_m2d(wpa_s, m2d); } @@ -393,6 +386,7 @@ static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s, { wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL "msg=%d", fail->msg); wpas_clear_wps(wpa_s); + wpas_notify_wps_event_fail(wpa_s, fail); } @@ -400,6 +394,77 @@ static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s) { wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_SUCCESS); wpa_s->wps_success = 1; + wpas_notify_wps_event_success(wpa_s); +} + + +static void wpa_supplicant_wps_event_er_ap_add(struct wpa_supplicant *wpa_s, + struct wps_event_er_ap *ap) +{ + char uuid_str[100]; + char dev_type[WPS_DEV_TYPE_BUFSIZE]; + + uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str)); + if (ap->pri_dev_type) + wps_dev_type_bin2str(ap->pri_dev_type, dev_type, + sizeof(dev_type)); + else + dev_type[0] = '\0'; + + wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_ADD "%s " MACSTR + " pri_dev_type=%s wps_state=%d |%s|%s|%s|%s|%s|%s|", + uuid_str, MAC2STR(ap->mac_addr), dev_type, ap->wps_state, + ap->friendly_name ? ap->friendly_name : "", + ap->manufacturer ? ap->manufacturer : "", + ap->model_description ? ap->model_description : "", + ap->model_name ? ap->model_name : "", + ap->manufacturer_url ? ap->manufacturer_url : "", + ap->model_url ? ap->model_url : ""); +} + + +static void wpa_supplicant_wps_event_er_ap_remove(struct wpa_supplicant *wpa_s, + struct wps_event_er_ap *ap) +{ + char uuid_str[100]; + uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str)); + wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_REMOVE "%s", uuid_str); +} + + +static void wpa_supplicant_wps_event_er_enrollee_add( + struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee) +{ + char uuid_str[100]; + char dev_type[WPS_DEV_TYPE_BUFSIZE]; + + uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str)); + if (enrollee->pri_dev_type) + wps_dev_type_bin2str(enrollee->pri_dev_type, dev_type, + sizeof(dev_type)); + else + dev_type[0] = '\0'; + + wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_ADD "%s " MACSTR + " M1=%d config_methods=0x%x dev_passwd_id=%d pri_dev_type=%s " + "|%s|%s|%s|%s|%s|", + uuid_str, MAC2STR(enrollee->mac_addr), enrollee->m1_received, + enrollee->config_methods, enrollee->dev_passwd_id, dev_type, + enrollee->dev_name ? enrollee->dev_name : "", + enrollee->manufacturer ? enrollee->manufacturer : "", + enrollee->model_name ? enrollee->model_name : "", + enrollee->model_number ? enrollee->model_number : "", + enrollee->serial_number ? enrollee->serial_number : ""); +} + + +static void wpa_supplicant_wps_event_er_enrollee_remove( + struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee) +{ + char uuid_str[100]; + uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str)); + wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_REMOVE "%s " MACSTR, + uuid_str, MAC2STR(enrollee->mac_addr)); } @@ -423,6 +488,20 @@ static void wpa_supplicant_wps_event(void *ctx, enum wps_event event, break; case WPS_EV_PBC_TIMEOUT: break; + case WPS_EV_ER_AP_ADD: + wpa_supplicant_wps_event_er_ap_add(wpa_s, &data->ap); + break; + case WPS_EV_ER_AP_REMOVE: + wpa_supplicant_wps_event_er_ap_remove(wpa_s, &data->ap); + break; + case WPS_EV_ER_ENROLLEE_ADD: + wpa_supplicant_wps_event_er_enrollee_add(wpa_s, + &data->enrollee); + break; + case WPS_EV_ER_ENROLLEE_REMOVE: + wpa_supplicant_wps_event_er_enrollee_remove(wpa_s, + &data->enrollee); + break; } } @@ -440,7 +519,7 @@ enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid) static void wpas_clear_wps(struct wpa_supplicant *wpa_s) { int id; - struct wpa_ssid *ssid; + struct wpa_ssid *ssid, *remove_ssid = NULL; eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL); @@ -448,14 +527,20 @@ static void wpas_clear_wps(struct wpa_supplicant *wpa_s) ssid = wpa_s->conf->ssid; while (ssid) { if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) { - if (ssid == wpa_s->current_ssid) + if (ssid == wpa_s->current_ssid) { wpa_s->current_ssid = NULL; + if (ssid != NULL) + wpas_notify_network_changed(wpa_s); + } id = ssid->id; + remove_ssid = ssid; } else id = -1; ssid = ssid->next; - if (id >= 0) + if (id >= 0) { + wpas_notify_network_removed(wpa_s, remove_ssid); wpa_config_remove_network(wpa_s->conf, id); + } } } @@ -477,45 +562,35 @@ static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s, ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) return NULL; + wpas_notify_network_added(wpa_s, ssid); wpa_config_set_network_defaults(ssid); if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 || wpa_config_set(ssid, "eap", "WSC", 0) < 0 || wpa_config_set(ssid, "identity", registrar ? "\"" WSC_ID_REGISTRAR "\"" : "\"" WSC_ID_ENROLLEE "\"", 0) < 0) { + wpas_notify_network_removed(wpa_s, ssid); wpa_config_remove_network(wpa_s->conf, ssid->id); return NULL; } if (bssid) { - size_t i; + struct wpa_bss *bss; int count = 0; os_memcpy(ssid->bssid, bssid, ETH_ALEN); ssid->bssid_set = 1; - /* Try to get SSID from scan results */ - if (wpa_s->scan_res == NULL && - wpa_supplicant_get_scan_results(wpa_s) < 0) - return ssid; /* Could not find any scan results */ - - for (i = 0; i < wpa_s->scan_res->num; i++) { - const u8 *ie; - struct wpa_scan_res *res; - - res = wpa_s->scan_res->res[i]; - if (os_memcmp(bssid, res->bssid, ETH_ALEN) != 0) + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { + if (os_memcmp(bssid, bss->bssid, ETH_ALEN) != 0) continue; - ie = wpa_scan_get_ie(res, WLAN_EID_SSID); - if (ie == NULL) - break; os_free(ssid->ssid); - ssid->ssid = os_malloc(ie[1]); + ssid->ssid = os_malloc(bss->ssid_len); if (ssid->ssid == NULL) break; - os_memcpy(ssid->ssid, ie + 2, ie[1]); - ssid->ssid_len = ie[1]; + os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len); + ssid->ssid_len = bss->ssid_len; wpa_hexdump_ascii(MSG_DEBUG, "WPS: Picked SSID from " "scan results", ssid->ssid, ssid->ssid_len); @@ -543,7 +618,10 @@ static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s, /* Mark all other networks disabled and trigger reassociation */ ssid = wpa_s->conf->ssid; while (ssid) { + int was_disabled = ssid->disabled; ssid->disabled = ssid != selected; + if (was_disabled != ssid->disabled) + wpas_notify_network_enabled_changed(wpa_s, ssid); ssid = ssid->next; } wpa_s->disconnected = 0; @@ -574,7 +652,7 @@ int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *pin) { struct wpa_ssid *ssid; - char val[30]; + char val[128]; unsigned int rpin = 0; wpas_clear_wps(wpa_s); @@ -595,11 +673,63 @@ int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, } +#ifdef CONFIG_WPS_OOB +int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, + char *path, char *method, char *name) +{ + struct wps_context *wps = wpa_s->wps; + struct oob_device_data *oob_dev; + + oob_dev = wps_get_oob_device(device_type); + if (oob_dev == NULL) + return -1; + oob_dev->device_path = path; + oob_dev->device_name = name; + wps->oob_conf.oob_method = wps_get_oob_method(method); + + if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E) { + /* + * Use pre-configured DH keys in order to be able to write the + * key hash into the OOB file. + */ + wpabuf_free(wps->dh_pubkey); + wpabuf_free(wps->dh_privkey); + wps->dh_privkey = NULL; + wps->dh_pubkey = NULL; + dh5_free(wps->dh_ctx); + wps->dh_ctx = dh5_init(&wps->dh_privkey, &wps->dh_pubkey); + wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192); + if (wps->dh_ctx == NULL || wps->dh_pubkey == NULL) { + wpa_printf(MSG_ERROR, "WPS: Failed to initialize " + "Diffie-Hellman handshake"); + return -1; + } + } + + if (wps->oob_conf.oob_method == OOB_METHOD_CRED) + wpas_clear_wps(wpa_s); + + if (wps_process_oob(wps, oob_dev, 0) < 0) + return -1; + + if ((wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E || + wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) && + wpas_wps_start_pin(wpa_s, NULL, + wpabuf_head(wps->oob_conf.dev_password)) < 0) + return -1; + + return 0; +} +#endif /* CONFIG_WPS_OOB */ + + int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid, - const char *pin) + const char *pin, struct wps_new_ap_settings *settings) { struct wpa_ssid *ssid; - char val[30]; + char val[200]; + char *pos, *end; + int res; if (!pin) return -1; @@ -607,7 +737,24 @@ int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid, ssid = wpas_wps_add_network(wpa_s, 1, bssid); if (ssid == NULL) return -1; - os_snprintf(val, sizeof(val), "\"pin=%s\"", pin); + pos = val; + end = pos + sizeof(val); + res = os_snprintf(pos, end - pos, "\"pin=%s", pin); + if (res < 0 || res >= end - pos) + return -1; + pos += res; + if (settings) { + res = os_snprintf(pos, end - pos, " new_ssid=%s new_auth=%s " + "new_encr=%s new_key=%s", + settings->ssid_hex, settings->auth, + settings->encr, settings->key_hex); + if (res < 0 || res >= end - pos) + return -1; + pos += res; + } + res = os_snprintf(pos, end - pos, "\""); + if (res < 0 || res >= end - pos) + return -1; wpa_config_set(ssid, "phase1", val, 0); eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout, wpa_s, NULL); @@ -634,20 +781,36 @@ static void wpas_wps_pin_needed_cb(void *ctx, const u8 *uuid_e, { char uuid[40], txt[400]; int len; + char devtype[WPS_DEV_TYPE_BUFSIZE]; if (uuid_bin2str(uuid_e, uuid, sizeof(uuid))) return; wpa_printf(MSG_DEBUG, "WPS: PIN needed for UUID-E %s", uuid); len = os_snprintf(txt, sizeof(txt), "WPS-EVENT-PIN-NEEDED %s " MACSTR - " [%s|%s|%s|%s|%s|%d-%08X-%d]", + " [%s|%s|%s|%s|%s|%s]", uuid, MAC2STR(dev->mac_addr), dev->device_name, dev->manufacturer, dev->model_name, dev->model_number, dev->serial_number, - dev->categ, dev->oui, dev->sub_categ); + wps_dev_type_bin2str(dev->pri_dev_type, devtype, + sizeof(devtype))); if (len > 0 && len < (int) sizeof(txt)) wpa_printf(MSG_INFO, "%s", txt); } +static void wpas_wps_set_sel_reg_cb(void *ctx, int sel_reg, u16 dev_passwd_id, + u16 sel_reg_config_methods) +{ +#ifdef CONFIG_WPS_ER + struct wpa_supplicant *wpa_s = ctx; + + if (wpa_s->wps_er == NULL) + return; + wps_er_set_sel_reg(wpa_s->wps_er, sel_reg, dev_passwd_id, + sel_reg_config_methods); +#endif /* CONFIG_WPS_ER */ +} + + int wpas_wps_init(struct wpa_supplicant *wpa_s) { struct wps_context *wps; @@ -666,32 +829,14 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s) wps->dev.model_name = wpa_s->conf->model_name; wps->dev.model_number = wpa_s->conf->model_number; wps->dev.serial_number = wpa_s->conf->serial_number; - if (wpa_s->conf->device_type) { - char *pos; - u8 oui[4]; - /* <categ>-<OUI>-<subcateg> */ - wps->dev.categ = atoi(wpa_s->conf->device_type); - pos = os_strchr(wpa_s->conf->device_type, '-'); - if (pos == NULL) { - wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); - os_free(wps); - return -1; - } - pos++; - if (hexstr2bin(pos, oui, 4)) { - wpa_printf(MSG_ERROR, "WPS: Invalid device_type OUI"); - os_free(wps); - return -1; - } - wps->dev.oui = WPA_GET_BE32(oui); - pos = os_strchr(pos, '-'); - if (pos == NULL) { - wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); - os_free(wps); - return -1; - } - pos++; - wps->dev.sub_categ = atoi(pos); + wps->config_methods = + wps_config_methods_str2bin(wpa_s->conf->config_methods); + if (wpa_s->conf->device_type && + wps_dev_type_str2bin(wpa_s->conf->device_type, + wps->dev.pri_dev_type) < 0) { + wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); + os_free(wps); + return -1; } wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version); wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */ @@ -709,6 +854,7 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s) os_memset(&rcfg, 0, sizeof(rcfg)); rcfg.new_psk_cb = wpas_wps_new_psk_cb; rcfg.pin_needed_cb = wpas_wps_pin_needed_cb; + rcfg.set_sel_reg_cb = wpas_wps_set_sel_reg_cb; rcfg.cb_ctx = wpa_s; wps->registrar = wps_registrar_init(wps, &rcfg); @@ -731,7 +877,16 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s) if (wpa_s->wps == NULL) return; +#ifdef CONFIG_WPS_ER + wps_er_deinit(wpa_s->wps_er, NULL, NULL); + wpa_s->wps_er = NULL; +#endif /* CONFIG_WPS_ER */ + wps_registrar_deinit(wpa_s->wps->registrar); + wpabuf_free(wpa_s->wps->dh_pubkey); + wpabuf_free(wpa_s->wps->dh_privkey); + wpabuf_free(wpa_s->wps->oob_conf.pubkey_hash); + wpabuf_free(wpa_s->wps->oob_conf.dev_password); os_free(wpa_s->wps->network_key); os_free(wpa_s->wps); wpa_s->wps = NULL; @@ -841,30 +996,28 @@ int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s, int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *selected, - struct wpa_ssid *ssid) + struct wpa_bss *selected, struct wpa_ssid *ssid) { const u8 *sel_uuid, *uuid; - size_t i; struct wpabuf *wps_ie; int ret = 0; + struct wpa_bss *bss; if (!eap_is_wps_pbc_enrollee(&ssid->eap)) return 0; /* Make sure that only one AP is in active PBC mode */ - wps_ie = wpa_scan_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE); + wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE); if (wps_ie) sel_uuid = wps_get_uuid_e(wps_ie); else sel_uuid = NULL; - for (i = 0; i < wpa_s->scan_res->num; i++) { - struct wpa_scan_res *bss = wpa_s->scan_res->res[i]; + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { struct wpabuf *ie; if (bss == selected) continue; - ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (!ie) continue; if (!wps_is_selected_pbc_registrar(ie)) { @@ -892,23 +1045,25 @@ int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s, void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s) { - size_t i; + struct wpa_bss *bss; if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED) return; - for (i = 0; i < wpa_s->scan_res->num; i++) { - struct wpa_scan_res *bss = wpa_s->scan_res->res[i]; + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { struct wpabuf *ie; - ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (!ie) continue; if (wps_is_selected_pbc_registrar(ie)) - wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC); + wpa_msg_ctrl(wpa_s, MSG_INFO, + WPS_EVENT_AP_AVAILABLE_PBC); else if (wps_is_selected_pin_registrar(ie)) - wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN); + wpa_msg_ctrl(wpa_s, MSG_INFO, + WPS_EVENT_AP_AVAILABLE_PIN); else - wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE); + wpa_msg_ctrl(wpa_s, MSG_INFO, + WPS_EVENT_AP_AVAILABLE); wpabuf_free(ie); break; } @@ -926,3 +1081,105 @@ int wpas_wps_searching(struct wpa_supplicant *wpa_s) return 0; } + + +int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *buf, + char *end) +{ + struct wpabuf *wps_ie; + int ret; + + wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len, WPS_DEV_OUI_WFA); + if (wps_ie == NULL) + return 0; + + ret = wps_attr_text(wps_ie, buf, end); + wpabuf_free(wps_ie); + return ret; +} + + +int wpas_wps_er_start(struct wpa_supplicant *wpa_s) +{ +#ifdef CONFIG_WPS_ER + if (wpa_s->wps_er) { + wps_er_refresh(wpa_s->wps_er); + return 0; + } + wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname); + if (wpa_s->wps_er == NULL) + return -1; + return 0; +#else /* CONFIG_WPS_ER */ + return 0; +#endif /* CONFIG_WPS_ER */ +} + + +int wpas_wps_er_stop(struct wpa_supplicant *wpa_s) +{ +#ifdef CONFIG_WPS_ER + wps_er_deinit(wpa_s->wps_er, NULL, NULL); + wpa_s->wps_er = NULL; +#endif /* CONFIG_WPS_ER */ + return 0; +} + + +#ifdef CONFIG_WPS_ER +int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const char *uuid, + const char *pin) +{ + u8 u[UUID_LEN]; + int any = 0; + + if (os_strcmp(uuid, "any") == 0) + any = 1; + else if (uuid_str2bin(uuid, u)) + return -1; + return wps_registrar_add_pin(wpa_s->wps->registrar, any ? NULL : u, + (const u8 *) pin, os_strlen(pin), 300); +} + + +int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid) +{ + u8 u[UUID_LEN]; + + if (uuid_str2bin(uuid, u)) + return -1; + return wps_er_pbc(wpa_s->wps_er, u); +} + + +int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid, + const char *pin) +{ + u8 u[UUID_LEN]; + + if (uuid_str2bin(uuid, u)) + return -1; + return wps_er_learn(wpa_s->wps_er, u, (const u8 *) pin, + os_strlen(pin)); +} + + +static void wpas_wps_terminate_cb(void *ctx) +{ + wpa_printf(MSG_DEBUG, "WPS ER: Terminated"); + eloop_terminate(); +} +#endif /* CONFIG_WPS_ER */ + + +int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s) +{ +#ifdef CONFIG_WPS_ER + if (wpa_s->wps_er) { + wps_er_deinit(wpa_s->wps_er, wpas_wps_terminate_cb, wpa_s); + wpa_s->wps_er = NULL; + return 1; + } +#endif /* CONFIG_WPS_ER */ + return 0; +} diff --git a/contrib/wpa/wpa_supplicant/wps_supplicant.h b/contrib/wpa/wpa_supplicant/wps_supplicant.h index 8f81dc4..ba2fb16 100644 --- a/contrib/wpa/wpa_supplicant/wps_supplicant.h +++ b/contrib/wpa/wpa_supplicant/wps_supplicant.h @@ -1,6 +1,6 @@ /* * wpa_supplicant / WPS integration - * Copyright (c) 2008, Jouni Malinen <j@w1.fi> + * Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,11 +15,22 @@ #ifndef WPS_SUPPLICANT_H #define WPS_SUPPLICANT_H +struct wpa_scan_res; + #ifdef CONFIG_WPS #include "wps/wps.h" #include "wps/wps_defs.h" +struct wpa_bss; + +struct wps_new_ap_settings { + const char *ssid_hex; + const char *auth; + const char *encr; + const char *key_hex; +}; + int wpas_wps_init(struct wpa_supplicant *wpa_s); void wpas_wps_deinit(struct wpa_supplicant *wpa_s); int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s); @@ -27,17 +38,28 @@ 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 wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *pin); +int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, + char *path, char *method, char *name); int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid, - const char *pin); + const char *pin, struct wps_new_ap_settings *settings); int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_scan_res *bss); int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_scan_res *bss); int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *selected, - struct wpa_ssid *ssid); + struct wpa_bss *selected, struct wpa_ssid *ssid); void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s); int wpas_wps_searching(struct wpa_supplicant *wpa_s); +int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *pos, + char *end); +int wpas_wps_er_start(struct wpa_supplicant *wpa_s); +int wpas_wps_er_stop(struct wpa_supplicant *wpa_s); +int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const char *uuid, + const char *pin); +int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid); +int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid, + const char *pin); +int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s); #else /* CONFIG_WPS */ @@ -75,7 +97,7 @@ static inline int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s, } static inline int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *selected, + struct wpa_bss *selected, struct wpa_ssid *ssid) { return 0; diff --git a/contrib/wpa/wpa_supplicant/xcode/wpa_supplicant.xcodeproj/project.pbxproj b/contrib/wpa/wpa_supplicant/xcode/wpa_supplicant.xcodeproj/project.pbxproj new file mode 100644 index 0000000..6fea81b --- /dev/null +++ b/contrib/wpa/wpa_supplicant/xcode/wpa_supplicant.xcodeproj/project.pbxproj @@ -0,0 +1,513 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 881EED0F10DC14EF009E449F /* eap_register.c in Sources */ = {isa = PBXBuildFile; fileRef = 881EED0E10DC14EF009E449F /* eap_register.c */; }; + 8853CB17109F385C00358CEF /* libpcap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8853CB16109F385C00358CEF /* libpcap.dylib */; }; + 8853CB1B109F389800358CEF /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8853CB1A109F389800358CEF /* libcrypto.dylib */; }; + 8853CB1F109F38BD00358CEF /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8853CB1E109F38BD00358CEF /* CoreFoundation.framework */; }; + 8853CB2E109F3A3900358CEF /* scan_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CB2D109F3A3900358CEF /* scan_helpers.c */; }; + 8853CB32109F3A9400358CEF /* wpa_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CB31109F3A9400358CEF /* wpa_common.c */; }; + 8853CB36109F3AC700358CEF /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CB35109F3AC700358CEF /* md5.c */; }; + 8853CB3C109F3B5800358CEF /* Apple80211.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8853CB3B109F3B5800358CEF /* Apple80211.framework */; }; + 8853CBFB109F4C6E00358CEF /* eap_gtc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBEC109F4C6E00358CEF /* eap_gtc.c */; }; + 8853CBFC109F4C6E00358CEF /* eap_leap.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBED109F4C6E00358CEF /* eap_leap.c */; }; + 8853CBFD109F4C6E00358CEF /* eap_md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBEE109F4C6E00358CEF /* eap_md5.c */; }; + 8853CBFE109F4C6E00358CEF /* eap_methods.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBEF109F4C6E00358CEF /* eap_methods.c */; }; + 8853CBFF109F4C6E00358CEF /* eap_mschapv2.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF0109F4C6E00358CEF /* eap_mschapv2.c */; }; + 8853CC00109F4C6E00358CEF /* eap_otp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF1109F4C6E00358CEF /* eap_otp.c */; }; + 8853CC01109F4C6E00358CEF /* eap_peap.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF2109F4C6E00358CEF /* eap_peap.c */; }; + 8853CC02109F4C6E00358CEF /* eap_tls_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF3109F4C6E00358CEF /* eap_tls_common.c */; }; + 8853CC03109F4C6E00358CEF /* eap_tls.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF4109F4C6E00358CEF /* eap_tls.c */; }; + 8853CC04109F4C6E00358CEF /* eap_tnc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF5109F4C6E00358CEF /* eap_tnc.c */; }; + 8853CC05109F4C6E00358CEF /* eap_ttls.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF6109F4C6E00358CEF /* eap_ttls.c */; }; + 8853CC06109F4C6E00358CEF /* eap_wsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF7109F4C6E00358CEF /* eap_wsc.c */; }; + 8853CC07109F4C6E00358CEF /* eap.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF8109F4C6E00358CEF /* eap.c */; }; + 8853CC08109F4C6E00358CEF /* mschapv2.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBF9109F4C6E00358CEF /* mschapv2.c */; }; + 8853CC09109F4C6E00358CEF /* tncc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CBFA109F4C6E00358CEF /* tncc.c */; }; + 8853CC0E109F4CA100358CEF /* ctrl_iface_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC0C109F4CA100358CEF /* ctrl_iface_unix.c */; }; + 8853CC0F109F4CA100358CEF /* ctrl_iface.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC0D109F4CA100358CEF /* ctrl_iface.c */; }; + 8853CC11109F4CC800358CEF /* eapol_supp_sm.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC10109F4CC800358CEF /* eapol_supp_sm.c */; }; + 8853CC18109F4D0800358CEF /* chap.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC14109F4D0800358CEF /* chap.c */; }; + 8853CC19109F4D0800358CEF /* eap_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC15109F4D0800358CEF /* eap_common.c */; }; + 8853CC1A109F4D0800358CEF /* eap_peap_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC16109F4D0800358CEF /* eap_peap_common.c */; }; + 8853CC1B109F4D0800358CEF /* eap_wsc_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC17109F4D0800358CEF /* eap_wsc_common.c */; }; + 8853CC26109F4D3500358CEF /* wps_attr_build.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC1E109F4D3500358CEF /* wps_attr_build.c */; }; + 8853CC27109F4D3500358CEF /* wps_attr_parse.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC1F109F4D3500358CEF /* wps_attr_parse.c */; }; + 8853CC28109F4D3500358CEF /* wps_attr_process.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC20109F4D3500358CEF /* wps_attr_process.c */; }; + 8853CC29109F4D3500358CEF /* wps_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC21109F4D3500358CEF /* wps_common.c */; }; + 8853CC2A109F4D3500358CEF /* wps_dev_attr.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC22109F4D3500358CEF /* wps_dev_attr.c */; }; + 8853CC2B109F4D3500358CEF /* wps_enrollee.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC23109F4D3500358CEF /* wps_enrollee.c */; }; + 8853CC2C109F4D3500358CEF /* wps_registrar.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC24109F4D3500358CEF /* wps_registrar.c */; }; + 8853CC2D109F4D3500358CEF /* wps.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC25109F4D3500358CEF /* wps.c */; }; + 8853CC34109F4DE200358CEF /* ms_funcs.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC32109F4DE200358CEF /* ms_funcs.c */; }; + 8853CC35109F4DE200358CEF /* tls_openssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC33109F4DE200358CEF /* tls_openssl.c */; }; + 8853CC3C109F4E1D00358CEF /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8853CC3B109F4E1D00358CEF /* libssl.dylib */; }; + 8853CC40109F4E3A00358CEF /* wps_supplicant.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC3F109F4E3A00358CEF /* wps_supplicant.c */; }; + 8853CC44109F4E6200358CEF /* uuid.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC43109F4E6200358CEF /* uuid.c */; }; + 8853CC48109F4E8700358CEF /* ieee802_11_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC47109F4E8700358CEF /* ieee802_11_common.c */; }; + 8853CC4E109F4ED500358CEF /* sha256.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC4C109F4ED500358CEF /* sha256.c */; }; + 8853CC53109F4F3500358CEF /* aes-cbc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC51109F4F3500358CEF /* aes-cbc.c */; }; + 8853CC54109F4F3500358CEF /* sha1-tlsprf.c in Sources */ = {isa = PBXBuildFile; fileRef = 8853CC52109F4F3500358CEF /* sha1-tlsprf.c */; }; + 88950831109F2FAB004FB35D /* blacklist.c in Sources */ = {isa = PBXBuildFile; fileRef = 88950828109F2FAB004FB35D /* blacklist.c */; }; + 88950832109F2FAB004FB35D /* config_file.c in Sources */ = {isa = PBXBuildFile; fileRef = 88950829109F2FAB004FB35D /* config_file.c */; }; + 88950833109F2FAB004FB35D /* config.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895082A109F2FAB004FB35D /* config.c */; }; + 88950834109F2FAB004FB35D /* events.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895082B109F2FAB004FB35D /* events.c */; }; + 88950835109F2FAB004FB35D /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895082C109F2FAB004FB35D /* main.c */; }; + 88950836109F2FAB004FB35D /* notify.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895082D109F2FAB004FB35D /* notify.c */; }; + 88950837109F2FAB004FB35D /* scan.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895082E109F2FAB004FB35D /* scan.c */; }; + 88950838109F2FAB004FB35D /* wpa_supplicant.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895082F109F2FAB004FB35D /* wpa_supplicant.c */; }; + 88950839109F2FAB004FB35D /* wpas_glue.c in Sources */ = {isa = PBXBuildFile; fileRef = 88950830109F2FAB004FB35D /* wpas_glue.c */; }; + 88950840109F301A004FB35D /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895083A109F301A004FB35D /* base64.c */; }; + 88950841109F301A004FB35D /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895083B109F301A004FB35D /* common.c */; }; + 88950842109F301A004FB35D /* eloop.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895083C109F301A004FB35D /* eloop.c */; }; + 88950843109F301A004FB35D /* os_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895083D109F301A004FB35D /* os_unix.c */; }; + 88950844109F301A004FB35D /* wpa_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895083E109F301A004FB35D /* wpa_debug.c */; }; + 88950845109F301A004FB35D /* wpabuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895083F109F301A004FB35D /* wpabuf.c */; }; + 88950864109F32D1004FB35D /* peerkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895085F109F32D1004FB35D /* peerkey.c */; }; + 88950865109F32D1004FB35D /* pmksa_cache.c in Sources */ = {isa = PBXBuildFile; fileRef = 88950860109F32D1004FB35D /* pmksa_cache.c */; }; + 88950866109F32D1004FB35D /* preauth.c in Sources */ = {isa = PBXBuildFile; fileRef = 88950861109F32D1004FB35D /* preauth.c */; }; + 88950867109F32D1004FB35D /* wpa_ie.c in Sources */ = {isa = PBXBuildFile; fileRef = 88950862109F32D1004FB35D /* wpa_ie.c */; }; + 88950868109F32D1004FB35D /* wpa.c in Sources */ = {isa = PBXBuildFile; fileRef = 88950863109F32D1004FB35D /* wpa.c */; }; + 8895086C109F3316004FB35D /* l2_packet_freebsd.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895086B109F3316004FB35D /* l2_packet_freebsd.c */; }; + 88950871109F3367004FB35D /* aes-unwrap.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895086D109F3367004FB35D /* aes-unwrap.c */; }; + 88950872109F3367004FB35D /* crypto_openssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895086E109F3367004FB35D /* crypto_openssl.c */; }; + 88950873109F3367004FB35D /* sha1-pbkdf2.c in Sources */ = {isa = PBXBuildFile; fileRef = 8895086F109F3367004FB35D /* sha1-pbkdf2.c */; }; + 88950874109F3367004FB35D /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 88950870109F3367004FB35D /* sha1.c */; }; + 88950885109F3538004FB35D /* driver_osx.m in Sources */ = {isa = PBXBuildFile; fileRef = 88950883109F3538004FB35D /* driver_osx.m */; }; + 88950886109F3538004FB35D /* drivers.c in Sources */ = {isa = PBXBuildFile; fileRef = 88950884109F3538004FB35D /* drivers.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 8DD76FAF0486AB0100D96B5E /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 881EED0E10DC14EF009E449F /* eap_register.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_register.c; path = ../eap_register.c; sourceTree = SOURCE_ROOT; }; + 8853CB16109F385C00358CEF /* libpcap.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpcap.dylib; path = usr/lib/libpcap.dylib; sourceTree = SDKROOT; }; + 8853CB1A109F389800358CEF /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = usr/lib/libcrypto.dylib; sourceTree = SDKROOT; }; + 8853CB1E109F38BD00358CEF /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; + 8853CB2D109F3A3900358CEF /* scan_helpers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scan_helpers.c; path = ../../src/drivers/scan_helpers.c; sourceTree = SOURCE_ROOT; }; + 8853CB31109F3A9400358CEF /* wpa_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wpa_common.c; path = ../../src/common/wpa_common.c; sourceTree = SOURCE_ROOT; }; + 8853CB35109F3AC700358CEF /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = md5.c; path = ../../src/crypto/md5.c; sourceTree = SOURCE_ROOT; }; + 8853CB3B109F3B5800358CEF /* Apple80211.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Apple80211.framework; path = /System/Library/PrivateFrameworks/Apple80211.framework; sourceTree = "<absolute>"; }; + 8853CBEC109F4C6E00358CEF /* eap_gtc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_gtc.c; path = ../../src/eap_peer/eap_gtc.c; sourceTree = SOURCE_ROOT; }; + 8853CBED109F4C6E00358CEF /* eap_leap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_leap.c; path = ../../src/eap_peer/eap_leap.c; sourceTree = SOURCE_ROOT; }; + 8853CBEE109F4C6E00358CEF /* eap_md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_md5.c; path = ../../src/eap_peer/eap_md5.c; sourceTree = SOURCE_ROOT; }; + 8853CBEF109F4C6E00358CEF /* eap_methods.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_methods.c; path = ../../src/eap_peer/eap_methods.c; sourceTree = SOURCE_ROOT; }; + 8853CBF0109F4C6E00358CEF /* eap_mschapv2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_mschapv2.c; path = ../../src/eap_peer/eap_mschapv2.c; sourceTree = SOURCE_ROOT; }; + 8853CBF1109F4C6E00358CEF /* eap_otp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_otp.c; path = ../../src/eap_peer/eap_otp.c; sourceTree = SOURCE_ROOT; }; + 8853CBF2109F4C6E00358CEF /* eap_peap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_peap.c; path = ../../src/eap_peer/eap_peap.c; sourceTree = SOURCE_ROOT; }; + 8853CBF3109F4C6E00358CEF /* eap_tls_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_tls_common.c; path = ../../src/eap_peer/eap_tls_common.c; sourceTree = SOURCE_ROOT; }; + 8853CBF4109F4C6E00358CEF /* eap_tls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_tls.c; path = ../../src/eap_peer/eap_tls.c; sourceTree = SOURCE_ROOT; }; + 8853CBF5109F4C6E00358CEF /* eap_tnc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_tnc.c; path = ../../src/eap_peer/eap_tnc.c; sourceTree = SOURCE_ROOT; }; + 8853CBF6109F4C6E00358CEF /* eap_ttls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_ttls.c; path = ../../src/eap_peer/eap_ttls.c; sourceTree = SOURCE_ROOT; }; + 8853CBF7109F4C6E00358CEF /* eap_wsc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_wsc.c; path = ../../src/eap_peer/eap_wsc.c; sourceTree = SOURCE_ROOT; }; + 8853CBF8109F4C6E00358CEF /* eap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap.c; path = ../../src/eap_peer/eap.c; sourceTree = SOURCE_ROOT; }; + 8853CBF9109F4C6E00358CEF /* mschapv2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mschapv2.c; path = ../../src/eap_peer/mschapv2.c; sourceTree = SOURCE_ROOT; }; + 8853CBFA109F4C6E00358CEF /* tncc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tncc.c; path = ../../src/eap_peer/tncc.c; sourceTree = SOURCE_ROOT; }; + 8853CC0C109F4CA100358CEF /* ctrl_iface_unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ctrl_iface_unix.c; path = ../ctrl_iface_unix.c; sourceTree = SOURCE_ROOT; }; + 8853CC0D109F4CA100358CEF /* ctrl_iface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ctrl_iface.c; path = ../ctrl_iface.c; sourceTree = SOURCE_ROOT; }; + 8853CC10109F4CC800358CEF /* eapol_supp_sm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eapol_supp_sm.c; path = ../../src/eapol_supp/eapol_supp_sm.c; sourceTree = SOURCE_ROOT; }; + 8853CC14109F4D0800358CEF /* chap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = chap.c; path = ../../src/eap_common/chap.c; sourceTree = SOURCE_ROOT; }; + 8853CC15109F4D0800358CEF /* eap_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_common.c; path = ../../src/eap_common/eap_common.c; sourceTree = SOURCE_ROOT; }; + 8853CC16109F4D0800358CEF /* eap_peap_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_peap_common.c; path = ../../src/eap_common/eap_peap_common.c; sourceTree = SOURCE_ROOT; }; + 8853CC17109F4D0800358CEF /* eap_wsc_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eap_wsc_common.c; path = ../../src/eap_common/eap_wsc_common.c; sourceTree = SOURCE_ROOT; }; + 8853CC1E109F4D3500358CEF /* wps_attr_build.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wps_attr_build.c; path = ../../src/wps/wps_attr_build.c; sourceTree = SOURCE_ROOT; }; + 8853CC1F109F4D3500358CEF /* wps_attr_parse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wps_attr_parse.c; path = ../../src/wps/wps_attr_parse.c; sourceTree = SOURCE_ROOT; }; + 8853CC20109F4D3500358CEF /* wps_attr_process.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wps_attr_process.c; path = ../../src/wps/wps_attr_process.c; sourceTree = SOURCE_ROOT; }; + 8853CC21109F4D3500358CEF /* wps_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wps_common.c; path = ../../src/wps/wps_common.c; sourceTree = SOURCE_ROOT; }; + 8853CC22109F4D3500358CEF /* wps_dev_attr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wps_dev_attr.c; path = ../../src/wps/wps_dev_attr.c; sourceTree = SOURCE_ROOT; }; + 8853CC23109F4D3500358CEF /* wps_enrollee.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wps_enrollee.c; path = ../../src/wps/wps_enrollee.c; sourceTree = SOURCE_ROOT; }; + 8853CC24109F4D3500358CEF /* wps_registrar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wps_registrar.c; path = ../../src/wps/wps_registrar.c; sourceTree = SOURCE_ROOT; }; + 8853CC25109F4D3500358CEF /* wps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wps.c; path = ../../src/wps/wps.c; sourceTree = SOURCE_ROOT; }; + 8853CC32109F4DE200358CEF /* ms_funcs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ms_funcs.c; path = ../../src/crypto/ms_funcs.c; sourceTree = SOURCE_ROOT; }; + 8853CC33109F4DE200358CEF /* tls_openssl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tls_openssl.c; path = ../../src/crypto/tls_openssl.c; sourceTree = SOURCE_ROOT; }; + 8853CC3B109F4E1D00358CEF /* libssl.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libssl.dylib; path = usr/lib/libssl.dylib; sourceTree = SDKROOT; }; + 8853CC3F109F4E3A00358CEF /* wps_supplicant.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wps_supplicant.c; path = ../wps_supplicant.c; sourceTree = SOURCE_ROOT; }; + 8853CC43109F4E6200358CEF /* uuid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = uuid.c; path = ../../src/utils/uuid.c; sourceTree = SOURCE_ROOT; }; + 8853CC47109F4E8700358CEF /* ieee802_11_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ieee802_11_common.c; path = ../../src/common/ieee802_11_common.c; sourceTree = SOURCE_ROOT; }; + 8853CC4C109F4ED500358CEF /* sha256.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sha256.c; path = ../../src/crypto/sha256.c; sourceTree = SOURCE_ROOT; }; + 8853CC51109F4F3500358CEF /* aes-cbc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "aes-cbc.c"; path = "../../src/crypto/aes-cbc.c"; sourceTree = SOURCE_ROOT; }; + 8853CC52109F4F3500358CEF /* sha1-tlsprf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "sha1-tlsprf.c"; path = "../../src/crypto/sha1-tlsprf.c"; sourceTree = SOURCE_ROOT; }; + 88950828109F2FAB004FB35D /* blacklist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = blacklist.c; path = ../../wpa_supplicant/blacklist.c; sourceTree = SOURCE_ROOT; }; + 88950829109F2FAB004FB35D /* config_file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = config_file.c; path = ../../wpa_supplicant/config_file.c; sourceTree = SOURCE_ROOT; }; + 8895082A109F2FAB004FB35D /* config.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = config.c; path = ../../wpa_supplicant/config.c; sourceTree = SOURCE_ROOT; }; + 8895082B109F2FAB004FB35D /* events.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = events.c; path = ../../wpa_supplicant/events.c; sourceTree = SOURCE_ROOT; }; + 8895082C109F2FAB004FB35D /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = main.c; path = ../../wpa_supplicant/main.c; sourceTree = SOURCE_ROOT; }; + 8895082D109F2FAB004FB35D /* notify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = notify.c; path = ../../wpa_supplicant/notify.c; sourceTree = SOURCE_ROOT; }; + 8895082E109F2FAB004FB35D /* scan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scan.c; path = ../../wpa_supplicant/scan.c; sourceTree = SOURCE_ROOT; }; + 8895082F109F2FAB004FB35D /* wpa_supplicant.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wpa_supplicant.c; path = ../../wpa_supplicant/wpa_supplicant.c; sourceTree = SOURCE_ROOT; }; + 88950830109F2FAB004FB35D /* wpas_glue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wpas_glue.c; path = ../../wpa_supplicant/wpas_glue.c; sourceTree = SOURCE_ROOT; }; + 8895083A109F301A004FB35D /* base64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = base64.c; path = ../../src/utils/base64.c; sourceTree = SOURCE_ROOT; }; + 8895083B109F301A004FB35D /* common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = common.c; path = ../../src/utils/common.c; sourceTree = SOURCE_ROOT; }; + 8895083C109F301A004FB35D /* eloop.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eloop.c; path = ../../src/utils/eloop.c; sourceTree = SOURCE_ROOT; }; + 8895083D109F301A004FB35D /* os_unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = os_unix.c; path = ../../src/utils/os_unix.c; sourceTree = SOURCE_ROOT; }; + 8895083E109F301A004FB35D /* wpa_debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wpa_debug.c; path = ../../src/utils/wpa_debug.c; sourceTree = SOURCE_ROOT; }; + 8895083F109F301A004FB35D /* wpabuf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wpabuf.c; path = ../../src/utils/wpabuf.c; sourceTree = SOURCE_ROOT; }; + 8895085F109F32D1004FB35D /* peerkey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = peerkey.c; path = ../../src/rsn_supp/peerkey.c; sourceTree = SOURCE_ROOT; }; + 88950860109F32D1004FB35D /* pmksa_cache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pmksa_cache.c; path = ../../src/rsn_supp/pmksa_cache.c; sourceTree = SOURCE_ROOT; }; + 88950861109F32D1004FB35D /* preauth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = preauth.c; path = ../../src/rsn_supp/preauth.c; sourceTree = SOURCE_ROOT; }; + 88950862109F32D1004FB35D /* wpa_ie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wpa_ie.c; path = ../../src/rsn_supp/wpa_ie.c; sourceTree = SOURCE_ROOT; }; + 88950863109F32D1004FB35D /* wpa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wpa.c; path = ../../src/rsn_supp/wpa.c; sourceTree = SOURCE_ROOT; }; + 8895086B109F3316004FB35D /* l2_packet_freebsd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = l2_packet_freebsd.c; path = ../../src/l2_packet/l2_packet_freebsd.c; sourceTree = SOURCE_ROOT; }; + 8895086D109F3367004FB35D /* aes-unwrap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "aes-unwrap.c"; path = "../../src/crypto/aes-unwrap.c"; sourceTree = SOURCE_ROOT; }; + 8895086E109F3367004FB35D /* crypto_openssl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crypto_openssl.c; path = ../../src/crypto/crypto_openssl.c; sourceTree = SOURCE_ROOT; }; + 8895086F109F3367004FB35D /* sha1-pbkdf2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "sha1-pbkdf2.c"; path = "../../src/crypto/sha1-pbkdf2.c"; sourceTree = SOURCE_ROOT; }; + 88950870109F3367004FB35D /* sha1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sha1.c; path = ../../src/crypto/sha1.c; sourceTree = SOURCE_ROOT; }; + 88950883109F3538004FB35D /* driver_osx.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = driver_osx.m; path = ../../src/drivers/driver_osx.m; sourceTree = SOURCE_ROOT; }; + 88950884109F3538004FB35D /* drivers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = drivers.c; path = ../../src/drivers/drivers.c; sourceTree = SOURCE_ROOT; }; + 8DD76FB20486AB0100D96B5E /* wpa_supplicant */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = wpa_supplicant; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8DD76FAD0486AB0100D96B5E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8853CB17109F385C00358CEF /* libpcap.dylib in Frameworks */, + 8853CB1B109F389800358CEF /* libcrypto.dylib in Frameworks */, + 8853CB1F109F38BD00358CEF /* CoreFoundation.framework in Frameworks */, + 8853CB3C109F3B5800358CEF /* Apple80211.framework in Frameworks */, + 8853CC3C109F4E1D00358CEF /* libssl.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* wpa_supplicant */ = { + isa = PBXGroup; + children = ( + 08FB7795FE84155DC02AAC07 /* Source */, + C6A0FF2B0290797F04C91782 /* Documentation */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + 8853CB16109F385C00358CEF /* libpcap.dylib */, + 8853CB1A109F389800358CEF /* libcrypto.dylib */, + 8853CB1E109F38BD00358CEF /* CoreFoundation.framework */, + 8853CB3B109F3B5800358CEF /* Apple80211.framework */, + 8853CC3B109F4E1D00358CEF /* libssl.dylib */, + ); + name = wpa_supplicant; + sourceTree = "<group>"; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 881EED0E10DC14EF009E449F /* eap_register.c */, + 8853CC51109F4F3500358CEF /* aes-cbc.c */, + 8853CC52109F4F3500358CEF /* sha1-tlsprf.c */, + 8853CC4C109F4ED500358CEF /* sha256.c */, + 8853CC47109F4E8700358CEF /* ieee802_11_common.c */, + 8853CC43109F4E6200358CEF /* uuid.c */, + 8853CC3F109F4E3A00358CEF /* wps_supplicant.c */, + 8853CC32109F4DE200358CEF /* ms_funcs.c */, + 8853CC33109F4DE200358CEF /* tls_openssl.c */, + 8853CC1E109F4D3500358CEF /* wps_attr_build.c */, + 8853CC1F109F4D3500358CEF /* wps_attr_parse.c */, + 8853CC20109F4D3500358CEF /* wps_attr_process.c */, + 8853CC21109F4D3500358CEF /* wps_common.c */, + 8853CC22109F4D3500358CEF /* wps_dev_attr.c */, + 8853CC23109F4D3500358CEF /* wps_enrollee.c */, + 8853CC24109F4D3500358CEF /* wps_registrar.c */, + 8853CC25109F4D3500358CEF /* wps.c */, + 8853CC14109F4D0800358CEF /* chap.c */, + 8853CC15109F4D0800358CEF /* eap_common.c */, + 8853CC16109F4D0800358CEF /* eap_peap_common.c */, + 8853CC17109F4D0800358CEF /* eap_wsc_common.c */, + 8853CC10109F4CC800358CEF /* eapol_supp_sm.c */, + 8853CC0C109F4CA100358CEF /* ctrl_iface_unix.c */, + 8853CC0D109F4CA100358CEF /* ctrl_iface.c */, + 8853CBEC109F4C6E00358CEF /* eap_gtc.c */, + 8853CBED109F4C6E00358CEF /* eap_leap.c */, + 8853CBEE109F4C6E00358CEF /* eap_md5.c */, + 8853CBEF109F4C6E00358CEF /* eap_methods.c */, + 8853CBF0109F4C6E00358CEF /* eap_mschapv2.c */, + 8853CBF1109F4C6E00358CEF /* eap_otp.c */, + 8853CBF2109F4C6E00358CEF /* eap_peap.c */, + 8853CBF3109F4C6E00358CEF /* eap_tls_common.c */, + 8853CBF4109F4C6E00358CEF /* eap_tls.c */, + 8853CBF5109F4C6E00358CEF /* eap_tnc.c */, + 8853CBF6109F4C6E00358CEF /* eap_ttls.c */, + 8853CBF7109F4C6E00358CEF /* eap_wsc.c */, + 8853CBF8109F4C6E00358CEF /* eap.c */, + 8853CBF9109F4C6E00358CEF /* mschapv2.c */, + 8853CBFA109F4C6E00358CEF /* tncc.c */, + 8853CB35109F3AC700358CEF /* md5.c */, + 8853CB31109F3A9400358CEF /* wpa_common.c */, + 8853CB2D109F3A3900358CEF /* scan_helpers.c */, + 88950883109F3538004FB35D /* driver_osx.m */, + 88950884109F3538004FB35D /* drivers.c */, + 8895086D109F3367004FB35D /* aes-unwrap.c */, + 8895086E109F3367004FB35D /* crypto_openssl.c */, + 8895086F109F3367004FB35D /* sha1-pbkdf2.c */, + 88950870109F3367004FB35D /* sha1.c */, + 8895086B109F3316004FB35D /* l2_packet_freebsd.c */, + 8895085F109F32D1004FB35D /* peerkey.c */, + 88950860109F32D1004FB35D /* pmksa_cache.c */, + 88950861109F32D1004FB35D /* preauth.c */, + 88950862109F32D1004FB35D /* wpa_ie.c */, + 88950863109F32D1004FB35D /* wpa.c */, + 8895083A109F301A004FB35D /* base64.c */, + 8895083B109F301A004FB35D /* common.c */, + 8895083C109F301A004FB35D /* eloop.c */, + 8895083D109F301A004FB35D /* os_unix.c */, + 8895083E109F301A004FB35D /* wpa_debug.c */, + 8895083F109F301A004FB35D /* wpabuf.c */, + 88950828109F2FAB004FB35D /* blacklist.c */, + 88950829109F2FAB004FB35D /* config_file.c */, + 8895082A109F2FAB004FB35D /* config.c */, + 8895082B109F2FAB004FB35D /* events.c */, + 8895082C109F2FAB004FB35D /* main.c */, + 8895082D109F2FAB004FB35D /* notify.c */, + 8895082E109F2FAB004FB35D /* scan.c */, + 8895082F109F2FAB004FB35D /* wpa_supplicant.c */, + 88950830109F2FAB004FB35D /* wpas_glue.c */, + ); + name = Source; + sourceTree = "<group>"; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8DD76FB20486AB0100D96B5E /* wpa_supplicant */, + ); + name = Products; + sourceTree = "<group>"; + }; + C6A0FF2B0290797F04C91782 /* Documentation */ = { + isa = PBXGroup; + children = ( + ); + name = Documentation; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8DD76FA90486AB0100D96B5E /* wpa_supplicant */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "wpa_supplicant" */; + buildPhases = ( + 8DD76FAB0486AB0100D96B5E /* Sources */, + 8DD76FAD0486AB0100D96B5E /* Frameworks */, + 8DD76FAF0486AB0100D96B5E /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = wpa_supplicant; + productInstallPath = "$(HOME)/bin"; + productName = wpa_supplicant; + productReference = 8DD76FB20486AB0100D96B5E /* wpa_supplicant */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "wpa_supplicant" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 08FB7794FE84155DC02AAC07 /* wpa_supplicant */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8DD76FA90486AB0100D96B5E /* wpa_supplicant */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 8DD76FAB0486AB0100D96B5E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 88950831109F2FAB004FB35D /* blacklist.c in Sources */, + 88950832109F2FAB004FB35D /* config_file.c in Sources */, + 88950833109F2FAB004FB35D /* config.c in Sources */, + 88950834109F2FAB004FB35D /* events.c in Sources */, + 88950835109F2FAB004FB35D /* main.c in Sources */, + 88950836109F2FAB004FB35D /* notify.c in Sources */, + 88950837109F2FAB004FB35D /* scan.c in Sources */, + 88950838109F2FAB004FB35D /* wpa_supplicant.c in Sources */, + 88950839109F2FAB004FB35D /* wpas_glue.c in Sources */, + 88950840109F301A004FB35D /* base64.c in Sources */, + 88950841109F301A004FB35D /* common.c in Sources */, + 88950842109F301A004FB35D /* eloop.c in Sources */, + 88950843109F301A004FB35D /* os_unix.c in Sources */, + 88950844109F301A004FB35D /* wpa_debug.c in Sources */, + 88950845109F301A004FB35D /* wpabuf.c in Sources */, + 88950864109F32D1004FB35D /* peerkey.c in Sources */, + 88950865109F32D1004FB35D /* pmksa_cache.c in Sources */, + 88950866109F32D1004FB35D /* preauth.c in Sources */, + 88950867109F32D1004FB35D /* wpa_ie.c in Sources */, + 88950868109F32D1004FB35D /* wpa.c in Sources */, + 8895086C109F3316004FB35D /* l2_packet_freebsd.c in Sources */, + 88950871109F3367004FB35D /* aes-unwrap.c in Sources */, + 88950872109F3367004FB35D /* crypto_openssl.c in Sources */, + 88950873109F3367004FB35D /* sha1-pbkdf2.c in Sources */, + 88950874109F3367004FB35D /* sha1.c in Sources */, + 88950885109F3538004FB35D /* driver_osx.m in Sources */, + 88950886109F3538004FB35D /* drivers.c in Sources */, + 8853CB2E109F3A3900358CEF /* scan_helpers.c in Sources */, + 8853CB32109F3A9400358CEF /* wpa_common.c in Sources */, + 8853CB36109F3AC700358CEF /* md5.c in Sources */, + 8853CBFB109F4C6E00358CEF /* eap_gtc.c in Sources */, + 8853CBFC109F4C6E00358CEF /* eap_leap.c in Sources */, + 8853CBFD109F4C6E00358CEF /* eap_md5.c in Sources */, + 8853CBFE109F4C6E00358CEF /* eap_methods.c in Sources */, + 8853CBFF109F4C6E00358CEF /* eap_mschapv2.c in Sources */, + 8853CC00109F4C6E00358CEF /* eap_otp.c in Sources */, + 8853CC01109F4C6E00358CEF /* eap_peap.c in Sources */, + 8853CC02109F4C6E00358CEF /* eap_tls_common.c in Sources */, + 8853CC03109F4C6E00358CEF /* eap_tls.c in Sources */, + 8853CC04109F4C6E00358CEF /* eap_tnc.c in Sources */, + 8853CC05109F4C6E00358CEF /* eap_ttls.c in Sources */, + 8853CC06109F4C6E00358CEF /* eap_wsc.c in Sources */, + 8853CC07109F4C6E00358CEF /* eap.c in Sources */, + 8853CC08109F4C6E00358CEF /* mschapv2.c in Sources */, + 8853CC09109F4C6E00358CEF /* tncc.c in Sources */, + 8853CC0E109F4CA100358CEF /* ctrl_iface_unix.c in Sources */, + 8853CC0F109F4CA100358CEF /* ctrl_iface.c in Sources */, + 8853CC11109F4CC800358CEF /* eapol_supp_sm.c in Sources */, + 8853CC18109F4D0800358CEF /* chap.c in Sources */, + 8853CC19109F4D0800358CEF /* eap_common.c in Sources */, + 8853CC1A109F4D0800358CEF /* eap_peap_common.c in Sources */, + 8853CC1B109F4D0800358CEF /* eap_wsc_common.c in Sources */, + 8853CC26109F4D3500358CEF /* wps_attr_build.c in Sources */, + 8853CC27109F4D3500358CEF /* wps_attr_parse.c in Sources */, + 8853CC28109F4D3500358CEF /* wps_attr_process.c in Sources */, + 8853CC29109F4D3500358CEF /* wps_common.c in Sources */, + 8853CC2A109F4D3500358CEF /* wps_dev_attr.c in Sources */, + 8853CC2B109F4D3500358CEF /* wps_enrollee.c in Sources */, + 8853CC2C109F4D3500358CEF /* wps_registrar.c in Sources */, + 8853CC2D109F4D3500358CEF /* wps.c in Sources */, + 8853CC34109F4DE200358CEF /* ms_funcs.c in Sources */, + 8853CC35109F4DE200358CEF /* tls_openssl.c in Sources */, + 8853CC40109F4E3A00358CEF /* wps_supplicant.c in Sources */, + 8853CC44109F4E6200358CEF /* uuid.c in Sources */, + 8853CC48109F4E8700358CEF /* ieee802_11_common.c in Sources */, + 8853CC4E109F4ED500358CEF /* sha256.c in Sources */, + 8853CC53109F4F3500358CEF /* aes-cbc.c in Sources */, + 8853CC54109F4F3500358CEF /* sha1-tlsprf.c in Sources */, + 881EED0F10DC14EF009E449F /* eap_register.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1DEB928608733DD80010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = /usr/local/bin; + PRODUCT_NAME = wpa_supplicant; + }; + name = Debug; + }; + 1DEB928708733DD80010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + ); + GCC_MODEL_TUNING = G5; + INSTALL_PATH = /usr/local/bin; + PRODUCT_NAME = wpa_supplicant; + }; + name = Release; + }; + 1DEB928A08733DD80010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + FRAMEWORK_SEARCH_PATHS = /System/Library/PrivateFrameworks; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + ../../src, + ../../src/utils, + ); + ONLY_ACTIVE_ARCH = YES; + OTHER_CFLAGS = "-DCONFIG_XCODE_DEFAULTS"; + PREBINDING = NO; + PRELINK_LIBS = ""; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = macosx10.6; + }; + name = Debug; + }; + 1DEB928B08733DD80010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + FRAMEWORK_SEARCH_PATHS = /System/Library/PrivateFrameworks; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + ../../src, + ../../src/utils, + ); + OTHER_CFLAGS = "-DCONFIG_XCODE_DEFAULTS"; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "wpa_supplicant" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB928608733DD80010E9CD /* Debug */, + 1DEB928708733DD80010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "wpa_supplicant" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB928A08733DD80010E9CD /* Debug */, + 1DEB928B08733DD80010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} |