mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-08-05 20:47:24 +02:00
Compare commits
No commits in common. "master" and "1.29" have entirely different histories.
@ -1,3 +0,0 @@
|
||||
[codespell]
|
||||
ignore-words-list = fils, FILS, SME, assertIn, OCE, clen, aci, ELL, sav, ths
|
||||
skip = build-aux, linux, autom4te.cache, aclocal.m4, AUTHORS, libtool, configure*, *.5, ell
|
12
.gitignore
vendored
12
.gitignore
vendored
@ -1,14 +1,9 @@
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
*.gcno
|
||||
*.gcda
|
||||
.libs
|
||||
.deps
|
||||
.dirstamp
|
||||
.cache
|
||||
.ccls-cache
|
||||
compile_commands.json
|
||||
tags
|
||||
cscope.*
|
||||
Makefile
|
||||
@ -43,7 +38,6 @@ tools/hwsim
|
||||
tools/hwsim.1
|
||||
tools/probe-req
|
||||
tools/iwd-decrypt-profile
|
||||
tools/iwd-psk
|
||||
unit/test-cmac-aes
|
||||
unit/test-arc4
|
||||
unit/test-hmac-md5
|
||||
@ -66,9 +60,6 @@ unit/test-p2p
|
||||
unit/test-band
|
||||
unit/test-dpp
|
||||
unit/test-json
|
||||
unit/test-nl80211util
|
||||
unit/test-pmksa
|
||||
unit/test-storage
|
||||
unit/cert-*.pem
|
||||
unit/cert-*.csr
|
||||
unit/cert-*.srl
|
||||
@ -77,6 +68,3 @@ unit/*.log
|
||||
unit/*.trs
|
||||
test-suite.log
|
||||
src/builtin.h
|
||||
autotests/*/__pycache__
|
||||
iwd-coverage.info
|
||||
gcov
|
||||
|
4
AUTHORS
4
AUTHORS
@ -37,7 +37,3 @@ Diederik de Haas <didi.debian@cknow.org>
|
||||
Vladimír Dudr <vladimir@tango-dj.cz>
|
||||
Emmanuel VAUTRIN <Emmanuel.VAUTRIN@cpexterne.org>
|
||||
Jesse Lentz <jesse@twosheds.org>
|
||||
Pinghao Wu <xdavidwuph@gmail.com>
|
||||
Neehar Vijay <env252525@gmail.com>
|
||||
Jiajie Chen <c@jia.je>
|
||||
Ronan Pigott <ronan@rjp.ie>
|
||||
|
192
ChangeLog
192
ChangeLog
@ -1,195 +1,3 @@
|
||||
ver 3.9:
|
||||
Fix issue with Access Point mode and frequency unlocking.
|
||||
Fix issue with network configuration and BSS retry logic.
|
||||
Fix issue with handling busy notification from Access Point.
|
||||
Fix issue with handling P-192, P-224 and P-521 for SAE.
|
||||
|
||||
ver 3.8:
|
||||
Fix issue with handling unit tests and missing kernel features.
|
||||
|
||||
ver 3.7:
|
||||
Fix issue with handling length of EncryptedSecurity.
|
||||
Fix issue with handling empty affinities lists.
|
||||
Fix issue with handling survey scanning results.
|
||||
Fix issue with handling duplicate values in DPP URI.
|
||||
|
||||
ver 3.6:
|
||||
Fix issue with handling blacklisting and roaming requests.
|
||||
Fix issue with handling CQM thresholds for FullMAC devices.
|
||||
Add support for PMKSA when using FullMAC devices.
|
||||
|
||||
ver 3.5:
|
||||
Add support for option to disable blacklist handling.
|
||||
Add support for option to disable SAE for broken drivers.
|
||||
|
||||
ver 3.4:
|
||||
Add support for the Test Anything Protocol.
|
||||
|
||||
ver 3.3:
|
||||
Fix issue with handling External Authentication.
|
||||
|
||||
ver 3.2:
|
||||
Fix issue with GCC 15 and -std=c23 build errors.
|
||||
Add support for using PMKSA over SAE if available.
|
||||
Add support for HighUtilization/StationCount thresholds.
|
||||
Add support for disabling Multicast RX option.
|
||||
|
||||
ver 3.1:
|
||||
Fix issue with handling OWE transition BSS selection.
|
||||
Fix issue with handling oper class 136 starting frequency.
|
||||
|
||||
ver 3.0:
|
||||
Fix issue with handling alpha2 code for United Kingdom.
|
||||
Fix issue with handling empty TX/RX bitrate attributes.
|
||||
Fix issue with handling RSSI polling fallback workaround.
|
||||
Fix issue with handling harmless cloned information elements.
|
||||
Add experimental support for External Authentication feature.
|
||||
|
||||
ver 2.22:
|
||||
Fix issue with handling the Affinities property.
|
||||
Fix issue with handling ConnectedAccessPoint signal when roaming.
|
||||
|
||||
ver 2.21:
|
||||
Fix issue with pending scan requests after regdom update.
|
||||
Fix issue with handling the rearming of the roaming timeout.
|
||||
Fix issue with survey request and externally triggered scans.
|
||||
Fix issue with RSSI fallback when setting CQM threshold fails.
|
||||
Fix issue with FT-over-Air without offchannel support.
|
||||
Add support for per station Affinities property.
|
||||
|
||||
ver 2.20:
|
||||
Fix issue with PKEX timeout and number of frequencies used.
|
||||
Fix issue with handling logic for handshake failures.
|
||||
Fix issue with handling ConnectedAccessPoint signal.
|
||||
|
||||
ver 2.19:
|
||||
Fix issue with handling flush flag for external scans.
|
||||
Fix issue with handling SNR calculation in ranking.
|
||||
|
||||
ver 2.18:
|
||||
Fix issue with handling BSS with invalid HE capabilities.
|
||||
Fix issue with neighbor reports with invalid country codes.
|
||||
Fix issue with EAP-TTLS Start packets with L flag set.
|
||||
Add support for enabling SAE for AP mode operation.
|
||||
|
||||
ver 2.17:
|
||||
Fix issue with handling deauthenticate on disconnect.
|
||||
Fix issue with handling of rate estimation errors.
|
||||
Fix issue with handling EAPOL frame listeners.
|
||||
|
||||
ver 2.16:
|
||||
Fix issue with uninitialized variable and DPP encrypt.
|
||||
Fix issue with Access Point mode and ATTR_MAC validation.
|
||||
Fix issue with Access Point mode and frequency attributes.
|
||||
Fix issue with P2P and handling client info description.
|
||||
Fix issue with P2P and handling parsing of service info.
|
||||
Fix issue with netconfig and handling domain list.
|
||||
Add support for forcing a default ECC group.
|
||||
|
||||
ver 2.15:
|
||||
Fix issue with notice events for connection timeouts.
|
||||
Fix issue with reason code and deauthenticate event.
|
||||
Fix issue with handling basename() functionality.
|
||||
|
||||
ver 2.14:
|
||||
Fix issue with accepting PTK 4/4 after receiving PTK 2/4.
|
||||
Fix issue with frequency limit for quick scans.
|
||||
Fix issue with limiting DHCPv4 attempts.
|
||||
|
||||
ver 2.13:
|
||||
Fix issue with handling netconfig and roaming conditions.
|
||||
Fix issue with logging requirement for CMD_EXTERNAL_AUTH.
|
||||
Fix issue with using OpenSSL 3.2 installations.
|
||||
|
||||
ver 2.12:
|
||||
Fix issue with DPP extra settings not being used.
|
||||
Fix issue with DPP and PRF+ handling on AARCH64.
|
||||
Add support for SAE password identifiers.
|
||||
|
||||
ver 2.11:
|
||||
Fix issue with handling iovecs with multiple IEs.
|
||||
Fix issue with handling SAE password identifiers.
|
||||
Fix issue with handling agent release method call.
|
||||
|
||||
ver 2.10:
|
||||
Fix issue with buffer overflow for 32 byte SSIDs.
|
||||
Fix issue with deauthentication before FT work completes.
|
||||
Fix issue with power save disabling procedure.
|
||||
|
||||
ver 2.9:
|
||||
Fix issue with handling certain FT failures.
|
||||
Fix issue with handling user-disabled bands.
|
||||
Fix issue with handling roam on beacon loss event.
|
||||
Add support for PKEX configurator.
|
||||
Add support for PKEX enrollee.
|
||||
|
||||
ver 2.8:
|
||||
Fix issue with handling OWE AKM in association reply.
|
||||
|
||||
ver 2.7:
|
||||
Fix issue with handling FT-8021X and SHA256 PMKID derivation.
|
||||
|
||||
ver 2.6:
|
||||
Add support for setting driver specific quirks.
|
||||
Add support for disabling power saving mode.
|
||||
|
||||
ver 2.5:
|
||||
Fix issue with HT40+/- checks when creating chandef.
|
||||
Fix issue with handling support for FT-8021X-SHA384.
|
||||
Fix issue with handling secure bit check in handshake 1/4.
|
||||
Fix issue with allowing roaming before netconfig finishes.
|
||||
Fix issue with double free when disconnecting during FT.
|
||||
|
||||
ver 2.4:
|
||||
Fix issue with FT-over-Air and same channel operation.
|
||||
Fix issue with AP mode and missing support for GTK.
|
||||
Fix issue with AP mode and channel switch event.
|
||||
Fix issue with SSID string conversion handling.
|
||||
|
||||
ver 2.3:
|
||||
Fix issue with length calculation for WMM IE.
|
||||
Fix issue with channel number allocation off-by-one.
|
||||
Fix issue with cached session when TLS phase2 fails.
|
||||
Add support for FastReauthentication setting for EAP-TLS.
|
||||
|
||||
ver 2.2:
|
||||
Fix issue with handling FT and multiple roaming scans.
|
||||
Fix issue with handling multiple wiphy registrations.
|
||||
Fix issue with with EAP-PEAP session resumption.
|
||||
Add support for using PTK rekeying in AP mode.
|
||||
Add support for setting country IE in AP mode.
|
||||
Add support for setting WMM parameter IE in AP mode.
|
||||
|
||||
ver 2.1:
|
||||
Fix issue with handling FT-over-DS action.
|
||||
Fix issue with handling scan and 6 GHz support check.
|
||||
Fix issue with handling when periodic scans get aborted.
|
||||
Add support for using 5 GHz frequencies in AP mode.
|
||||
|
||||
ver 2.0:
|
||||
Fix issue with handling P2P and limiting ciphers to CCMP.
|
||||
Fix issue with scanning before forced roaming action.
|
||||
Fix issue with provided scan frequencies from RRM.
|
||||
Fix issue with handling Michael MIC failure message.
|
||||
Fix issue with handling timestamp size in MPDU frames.
|
||||
Fix issue with handling enablement of OCVC for FT AKMs.
|
||||
Fix issue with handling FT work as highest priority.
|
||||
Fix issue with handling roaming events and Multi-BSS.
|
||||
Add support for utilizing roaming candidates list.
|
||||
Add support for utilizing TLS session caching.
|
||||
Add support for ciphers with 256 bits key size.
|
||||
Add support for Access Point mode with legacy TKIP.
|
||||
Add support for MAC address changes while powered.
|
||||
Add support for IPv4 and IPv6 network configuration.
|
||||
|
||||
ver 1.30:
|
||||
Fix issue with handling OWE if buggy AP is detected.
|
||||
Fix issue with handling quick scan and enabling 6GHz.
|
||||
Fix issue with handling tags for extended IEs.
|
||||
Add support for handling HE capabilities.
|
||||
Add support for handling regulatory domain changes.
|
||||
Add support for handling netdev packet loss events.
|
||||
|
||||
ver 1.29:
|
||||
Fix issue with handling EAP-Success message.
|
||||
Fix issue with handling secure setting and EAPoL.
|
||||
|
127
Makefile.am
127
Makefile.am
@ -62,18 +62,12 @@ ell_headers = ell/util.h \
|
||||
ell/icmp6.h \
|
||||
ell/dhcp6.h \
|
||||
ell/acd.h \
|
||||
ell/cleanup.h \
|
||||
ell/netconfig.h \
|
||||
ell/sysctl.h \
|
||||
ell/notifylist.h \
|
||||
ell/minheap.h
|
||||
ell/cleanup.h
|
||||
|
||||
ell_sources = ell/private.h \
|
||||
ell/missing.h \
|
||||
ell/util.c \
|
||||
ell/test-private.h \
|
||||
ell/test.c \
|
||||
ell/test-dbus.c \
|
||||
ell/strv.c \
|
||||
ell/utf8.c \
|
||||
ell/queue.c \
|
||||
@ -147,25 +141,13 @@ ell_sources = ell/private.h \
|
||||
ell/icmp6-private.h \
|
||||
ell/dhcp6-lease.c \
|
||||
ell/dhcp6-transport.c \
|
||||
ell/acd.c \
|
||||
ell/netconfig.c \
|
||||
ell/sysctl.c \
|
||||
ell/notifylist.c \
|
||||
ell/minheap.c
|
||||
ell/acd.c
|
||||
|
||||
ell_shared = ell/useful.h ell/asn1-private.h
|
||||
|
||||
ell_libell_internal_la_SOURCES = $(ell_headers) $(ell_sources) $(ell_shared)
|
||||
endif
|
||||
|
||||
if LIBEDIT
|
||||
client_cflags = $(LIBEDIT_CFLAGS)
|
||||
client_ldadd = $(LIBEDIT_LIBS)
|
||||
else
|
||||
client_cflags =
|
||||
client_ldadd = $(READLINE_LIBS)
|
||||
endif
|
||||
|
||||
bin_PROGRAMS =
|
||||
libexec_PROGRAMS =
|
||||
noinst_PROGRAMS =
|
||||
@ -218,8 +200,7 @@ eap_sources = src/eap.c src/eap.h src/eap-private.h \
|
||||
if DAEMON
|
||||
libexec_PROGRAMS += src/iwd
|
||||
|
||||
src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
|
||||
src/missing.h src/defs.h \
|
||||
src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h src/missing.h \
|
||||
src/netdev.h src/netdev.c \
|
||||
src/wiphy.h src/wiphy.c \
|
||||
src/device.c \
|
||||
@ -254,8 +235,7 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
|
||||
src/anqp.h src/anqp.c \
|
||||
src/anqputil.h src/anqputil.c \
|
||||
src/netconfig.h src/netconfig.c\
|
||||
src/netconfig-commit.c \
|
||||
src/resolve.h src/resolve.c \
|
||||
src/resolve.h src/resolve.c\
|
||||
src/hotspot.c \
|
||||
src/p2p.h src/p2p.c \
|
||||
src/p2putil.h src/p2putil.c \
|
||||
@ -272,8 +252,6 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
|
||||
src/dpp-util.h src/dpp-util.c \
|
||||
src/json.h src/json.c \
|
||||
src/dpp.c \
|
||||
src/udev.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
$(eap_sources) \
|
||||
$(builtin_sources)
|
||||
|
||||
@ -323,13 +301,9 @@ client_iwctl_SOURCES = client/main.c \
|
||||
client/wsc.c client/station.c \
|
||||
client/diagnostic.c client/diagnostic.h \
|
||||
client/daemon.c client/daemon.h \
|
||||
client/dpp.c client/dpp-pkex.c \
|
||||
client/station-debug.c \
|
||||
client/bss.c \
|
||||
src/util.c src/util.h \
|
||||
src/band.c src/band.h
|
||||
client/dpp.c
|
||||
|
||||
client_iwctl_LDADD = $(ell_ldadd) $(client_ldadd)
|
||||
client_iwctl_LDADD = $(ell_ldadd) $(READLINE_LIBS)
|
||||
|
||||
if MANUAL_PAGES
|
||||
man_MANS += client/iwctl.1
|
||||
@ -389,7 +363,6 @@ man_MANS += wired/ead.8
|
||||
endif
|
||||
endif
|
||||
|
||||
if DAEMON
|
||||
noinst_PROGRAMS += tools/probe-req tools/iwd-decrypt-profile
|
||||
|
||||
tools_probe_req_SOURCES = tools/probe-req.c src/mpdu.h src/mpdu.c \
|
||||
@ -405,7 +378,6 @@ tools_iwd_decrypt_profile_SOURCES = tools/iwd-decrypt-profile.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/storage.h src/storage.c
|
||||
tools_iwd_decrypt_profile_LDADD = ${ell_ldadd}
|
||||
endif
|
||||
|
||||
if HWSIM
|
||||
bin_PROGRAMS += tools/hwsim
|
||||
@ -417,7 +389,6 @@ tools_hwsim_SOURCES = tools/hwsim.c src/mpdu.h \
|
||||
src/storage.h src/storage.c \
|
||||
src/common.h src/common.c \
|
||||
src/band.h src/band.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/crypto.h src/crypto.c
|
||||
tools_hwsim_LDADD = $(ell_ldadd)
|
||||
|
||||
@ -430,19 +401,14 @@ man_MANS += tools/hwsim.1
|
||||
endif
|
||||
endif
|
||||
|
||||
unit_tests =
|
||||
|
||||
if DAEMON
|
||||
unit_tests += unit/test-cmac-aes \
|
||||
unit_tests = unit/test-cmac-aes \
|
||||
unit/test-hmac-md5 unit/test-hmac-sha1 unit/test-hmac-sha256 \
|
||||
unit/test-prf-sha1 unit/test-kdf-sha256 \
|
||||
unit/test-crypto unit/test-eapol unit/test-mpdu \
|
||||
unit/test-ie unit/test-util unit/test-ssid-security \
|
||||
unit/test-arc4 unit/test-wsc unit/test-eap-mschapv2 \
|
||||
unit/test-eap-sim unit/test-sae unit/test-p2p unit/test-band \
|
||||
unit/test-dpp unit/test-json unit/test-nl80211util \
|
||||
unit/test-pmksa unit/test-storage
|
||||
endif
|
||||
unit/test-dpp unit/test-json
|
||||
|
||||
if CLIENT
|
||||
unit_tests += unit/test-client
|
||||
@ -452,7 +418,6 @@ if MAINTAINER_MODE
|
||||
noinst_PROGRAMS += $(unit_tests)
|
||||
endif
|
||||
|
||||
if DAEMON
|
||||
unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
|
||||
src/crypto.h src/crypto.c src/simutil.h src/simutil.c \
|
||||
src/ie.h src/ie.c \
|
||||
@ -460,13 +425,13 @@ unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/eap.h src/eap.c src/eap-private.h \
|
||||
src/util.h src/util.c \
|
||||
src/simauth.h src/simauth.c \
|
||||
src/erp.h src/erp.c \
|
||||
src/band.h src/band.c \
|
||||
src/eap-sim.c
|
||||
|
||||
unit_test_eap_sim_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_cmac_aes_SOURCES = unit/test-cmac-aes.c \
|
||||
@ -475,6 +440,7 @@ unit_test_cmac_aes_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_arc4_SOURCES = unit/test-arc4.c \
|
||||
src/crypto.h src/crypto.c
|
||||
|
||||
unit_test_arc4_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_hmac_md5_SOURCES = unit/test-hmac-md5.c \
|
||||
@ -500,8 +466,7 @@ unit_test_kdf_sha256_LDADD = $(ell_ldadd)
|
||||
unit_test_ie_SOURCES = unit/test-ie.c src/ie.h src/ie.c
|
||||
unit_test_ie_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_band_SOURCES = unit/test-band.c src/band.h src/band.c src/netdev.h \
|
||||
src/ie.h src/ie.c
|
||||
unit_test_band_SOURCES = unit/test-band.c src/band.h src/band.c
|
||||
unit_test_band_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_crypto_SOURCES = unit/test-crypto.c \
|
||||
@ -520,7 +485,6 @@ unit_test_eapol_SOURCES = unit/test-eapol.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/eap.h src/eap.c src/eap-private.h \
|
||||
src/eap-tls.c src/eap-ttls.c \
|
||||
src/eap-md5.c src/util.c \
|
||||
@ -551,7 +515,6 @@ unit_test_wsc_SOURCES = unit/test-wsc.c src/wscutil.h src/wscutil.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/eap.h src/eap.c src/eap-private.h \
|
||||
src/util.h src/util.c \
|
||||
src/erp.h src/erp.c \
|
||||
@ -565,12 +528,24 @@ unit_test_eap_mschapv2_SOURCES = src/eap-mschapv2.h src/eap-mschapv2.c \
|
||||
unit/test-eap-mschapv2.c
|
||||
unit_test_eap_mschapv2_LDADD = $(ell_ldadd)
|
||||
|
||||
if CLIENT
|
||||
unit_test_client_SOURCES = unit/test-client.c \
|
||||
client/adapter.c \
|
||||
client/agent.h client/agent.c \
|
||||
client/agent-manager.h client/agent-manager.c \
|
||||
client/command.h client/command.c \
|
||||
client/dbus-proxy.h client/dbus-proxy.c \
|
||||
client/display.h client/display.c \
|
||||
client/network.h client/network.c \
|
||||
client/properties.h client/properties.c
|
||||
unit_test_client_LDADD = $(ell_ldadd) $(READLINE_LIBS)
|
||||
endif
|
||||
|
||||
unit_test_sae_SOURCES = unit/test-sae.c \
|
||||
src/sae.h src/sae.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/erp.h src/erp.c \
|
||||
src/band.h src/band.c \
|
||||
src/util.h src/util.c \
|
||||
@ -595,39 +570,6 @@ unit_test_dpp_LDADD = $(ell_ldadd)
|
||||
unit_test_json_SOURCES = unit/test-json.c src/json.h src/json.c shared/jsmn.h
|
||||
unit_test_json_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_nl80211util_SOURCES = unit/test-nl80211util.c \
|
||||
src/nl80211util.h src/nl80211util.c \
|
||||
src/band.h src/band.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/util.h src/util.c
|
||||
unit_test_nl80211util_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_pmksa_SOURCES = unit/test-pmksa.c src/pmksa.c src/pmksa.h \
|
||||
src/module.h src/util.h
|
||||
unit_test_pmksa_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_storage_SOURCES = unit/test-storage.c src/storage.c src/storage.h \
|
||||
src/crypto.c src/crypto.h \
|
||||
src/common.c src/common.h
|
||||
unit_test_storage_LDADD = $(ell_ldadd)
|
||||
endif
|
||||
|
||||
if CLIENT
|
||||
unit_test_client_SOURCES = unit/test-client.c \
|
||||
client/adapter.c \
|
||||
client/agent.h client/agent.c \
|
||||
client/agent-manager.h client/agent-manager.c \
|
||||
client/command.h client/command.c \
|
||||
client/dbus-proxy.h client/dbus-proxy.c \
|
||||
client/display.h client/display.c \
|
||||
client/network.h client/network.c \
|
||||
client/properties.h client/properties.c
|
||||
unit_test_client_LDADD = $(ell_ldadd) $(client_ldadd)
|
||||
endif
|
||||
|
||||
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
|
||||
$(top_srcdir)/build-aux/tap-driver.sh
|
||||
|
||||
TESTS = $(unit_tests)
|
||||
|
||||
EXTRA_DIST = src/genbuiltin src/iwd.service.in src/net.connman.iwd.service \
|
||||
@ -638,9 +580,10 @@ EXTRA_DIST = src/genbuiltin src/iwd.service.in src/net.connman.iwd.service \
|
||||
$(patsubst %.5,%.rst, \
|
||||
$(patsubst %.8,%.rst,$(manual_pages))))
|
||||
|
||||
AM_CFLAGS = $(ell_cflags) $(client_cflags) -fvisibility=hidden \
|
||||
AM_CFLAGS = $(ell_cflags) -fvisibility=hidden \
|
||||
-DUNITDIR=\""$(top_srcdir)/unit/"\" \
|
||||
-DCERTDIR=\""$(top_builddir)/unit/"\"
|
||||
-DCERTDIR=\""$(top_builddir)/unit/"\" \
|
||||
-DJSMN_PARENT_LINKS -DJSMN_STRICT
|
||||
|
||||
if MAINTAINER_MODE
|
||||
AM_CFLAGS += -DHAVE_PKCS8_SUPPORT
|
||||
@ -744,7 +687,6 @@ ell/internal: Makefile
|
||||
done > $@
|
||||
|
||||
ell/ell.h: Makefile
|
||||
$(AM_V_at)$(MKDIR_P) ell
|
||||
$(AM_V_at)echo -n > $@
|
||||
$(AM_V_GEN)for f in $(ell_headers) ; do \
|
||||
echo "#include <$$f>" >> $@ ; \
|
||||
@ -788,25 +730,12 @@ if WIRED
|
||||
endif
|
||||
endif
|
||||
|
||||
gcov-clean:
|
||||
if GCOV
|
||||
-$(LCOV) --quiet --directory $(builddir) -z
|
||||
-rm -rf "$(builddir)/iwd-coverage.info" "$(builddir)/gcov"
|
||||
-find . -name "*.gcda" -o -name "*.gcov" -o -name "*.gcno" -delete
|
||||
endif
|
||||
|
||||
clean-local: gcov-clean
|
||||
clean-local:
|
||||
-rm -f unit/cert-*.pem unit/cert-*.csr unit/cert-*.srl unit/*-settings.8021x
|
||||
|
||||
maintainer-clean-local:
|
||||
-rm -rf build-aux ell
|
||||
|
||||
gcov-report:
|
||||
if GCOV
|
||||
$(LCOV) --quiet --directory $(builddir) --capture --output-file "iwd-coverage.info"
|
||||
LANG=C $(GENHTML) --quiet --prefix $(builddir) --output-directory "$(builddir)/gcov" --title "iwd Code Coverage" --legend "$(builddir)/iwd-coverage.info"
|
||||
endif
|
||||
|
||||
src/builtin.h: src/genbuiltin config.status
|
||||
$(AM_V_at)$(MKDIR_P) $(@D)
|
||||
$(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_modules) > $@
|
||||
|
3
README
3
README
@ -268,8 +268,7 @@ Information
|
||||
===========
|
||||
|
||||
Mailing list:
|
||||
https://lists.linux.dev/
|
||||
https://lore.kernel.org/iwd/
|
||||
https://lists.01.org/postorius/lists/iwd.lists.01.org/
|
||||
|
||||
IRC:
|
||||
irc://irc.oftc.net/#iwd
|
||||
|
6
TODO
6
TODO
@ -110,7 +110,7 @@ Wireless monitor
|
||||
|
||||
- Subscribe to all nl80211 multicast groups at startup
|
||||
|
||||
It seems the nlmon packets are limited to actual subscribed multicast
|
||||
It seems the nlmon packets are limited to actual subscribed mutlicast
|
||||
groups. To get a complete picture of all the nl80211 commands and
|
||||
events, it is required that iwmon adds membership to all multicast
|
||||
groups that the nl80211 lists.
|
||||
@ -234,7 +234,7 @@ Wireless daemon
|
||||
|
||||
- Implement Enrollee Session Overlap Detection after WSC Protocol Run
|
||||
|
||||
WSC Best Practices v2.0.1, Section 3.15 describes an enhancement to detect
|
||||
WSC Best Practices v2.0.1, Section 3.15 describes an enhacement to detect
|
||||
PBC session overlaps. The Enrollee is asked to perform an extra scan without
|
||||
the PBC request in the ProbeRequest frames after EAP-WSC completes
|
||||
successfully. If another AP in PBC mode is found, then a SessionOverlap
|
||||
@ -286,7 +286,7 @@ Wireless daemon
|
||||
- Support OCE mutually non-overlapping channels optimization.
|
||||
|
||||
OCE Section 3.10 mandates that the STA should scan channels 1, 6 and 11 in
|
||||
the 2.4GHz band first, unless it expects to find an AP on a different
|
||||
the 2.4Ghz band first, unless it expects to find an AP on a different
|
||||
channel.
|
||||
|
||||
Priority: Low
|
||||
|
25
acinclude.m4
25
acinclude.m4
@ -46,30 +46,10 @@ AC_DEFUN([AC_PROG_CC_UBSAN], [
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_PROG_CC_GCOV], [
|
||||
AC_CACHE_CHECK([whether ${CC-cc} accepts -fprofile-arcs], ac_cv_prog_cc_profile_arcs, [
|
||||
echo 'void f(){}' > conftest.c
|
||||
if test -z "`${CC-cc} -fprofile-arcs -c conftest.c 2>&1`"; then
|
||||
ac_cv_prog_cc_profile_arcs=yes
|
||||
else
|
||||
ac_cv_prog_cc_profile_arcs=no
|
||||
fi
|
||||
rm -rf conftest*
|
||||
])
|
||||
AC_CACHE_CHECK([whether ${CC-cc} accepts -ftest_coverage], ac_cv_prog_cc_test_coverage, [
|
||||
echo 'void f(){}' > conftest.c
|
||||
if test -z "`${CC-cc} -ftest-coverage -c conftest.c 2>&1`"; then
|
||||
ac_cv_prog_cc_test_coverage=yes
|
||||
else
|
||||
ac_cv_prog_cc_test_coverage=no
|
||||
fi
|
||||
rm -rf conftest*
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([COMPILER_FLAGS], [
|
||||
if (test "${CFLAGS}" = ""); then
|
||||
CFLAGS="-Wall -fsigned-char -fno-exceptions"
|
||||
CFLAGS="-Wall -O2 -fsigned-char -fno-exceptions"
|
||||
CFLAGS+=" -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2"
|
||||
fi
|
||||
if (test "$USE_MAINTAINER_MODE" = "yes"); then
|
||||
CFLAGS+=" -Werror -Wextra"
|
||||
@ -78,6 +58,7 @@ AC_DEFUN([COMPILER_FLAGS], [
|
||||
CFLAGS+=" -Wdeclaration-after-statement"
|
||||
CFLAGS+=" -Wmissing-declarations"
|
||||
CFLAGS+=" -Wredundant-decls"
|
||||
CFALGS+=" -Wvariadic-macros"
|
||||
CFLAGS+=" -Wformat -Wformat-security"
|
||||
if ( $CC -v 2>/dev/null | grep "gcc version" ); then
|
||||
CFLAGS+=" -Wcast-align"
|
||||
|
@ -1,3 +0,0 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
||||
PairwiseCiphers=CCMP
|
@ -5,58 +5,20 @@ import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD, NetworkType, PSKAgent
|
||||
from iwd import IWD
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_no_ap_mode(self):
|
||||
wd = IWD(True)
|
||||
def test_connection_success(self):
|
||||
wd = IWD()
|
||||
|
||||
dev = wd.list_devices(1)[0]
|
||||
|
||||
with self.assertRaises(iwd.NotSupportedEx):
|
||||
dev.start_ap('TestAP2', 'Password2')
|
||||
|
||||
def test_only_tkip_support(self):
|
||||
wd = IWD(True)
|
||||
|
||||
devices = wd.list_devices(2)
|
||||
|
||||
dev_sta = devices[0]
|
||||
dev_ap = devices[1]
|
||||
|
||||
dev_ap.start_ap('TestAP2', 'Password2')
|
||||
|
||||
self.assertTrue(dev_ap.group_cipher == 'TKIP')
|
||||
self.assertIn('TKIP', dev_ap.pairwise_ciphers)
|
||||
|
||||
ordered_network = dev_sta.get_ordered_network('TestAP2')
|
||||
|
||||
if ordered_network.type != NetworkType.psk:
|
||||
raise Exception("Network type mismatch")
|
||||
|
||||
psk_agent = PSKAgent('Password2')
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(dev_sta, condition)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
def test_no_ccmp_support(self):
|
||||
wd = IWD(True)
|
||||
|
||||
dev = wd.list_devices(2)[1]
|
||||
|
||||
# Should fail to start since the radio doesn't support CCMP but the
|
||||
# profile only lists CCMP as allowed.
|
||||
with self.assertRaises(iwd.NotSupportedEx):
|
||||
dev.start_ap('TestAP2')
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_ap('TestAP2.ap')
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
@ -1,9 +1,6 @@
|
||||
[SETUP]
|
||||
num_radios=2
|
||||
start_iwd=0
|
||||
num_radios=1
|
||||
radio_confs=rad0
|
||||
|
||||
[rad0]
|
||||
iftype_disable=ap
|
||||
|
||||
[rad1]
|
||||
cipher_disable=ccmp,bip_cmac,gcmp,gcmp_256,ccmp_256,bip_gmac,bip_gmac_256,bip_cmac_256
|
||||
|
@ -1,2 +0,0 @@
|
||||
[Security]
|
||||
Passphrase=Password2
|
@ -1,7 +1,6 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import os
|
||||
|
||||
from iwd import IWD
|
||||
from config import ctx
|
||||
@ -9,8 +8,6 @@ from validation import validate, client_connect
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_connection_success(self):
|
||||
IWD.copy_to_storage('TestAP1.psk')
|
||||
|
||||
wd = IWD(True)
|
||||
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
@ -25,8 +22,6 @@ class Test(unittest.TestCase):
|
||||
client_connect(wd, dev1, 'TestAP1')
|
||||
|
||||
def test_client_start_ap(self):
|
||||
IWD.copy_to_storage('TestAP1.psk')
|
||||
|
||||
wd = IWD(True)
|
||||
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
@ -44,33 +39,12 @@ class Test(unittest.TestCase):
|
||||
|
||||
validate(wd, dev2, dev1, 'TestAP2', 'Password2')
|
||||
|
||||
def test_valid_ciphers(self):
|
||||
ciphers = ['TKIP', 'CCMP-128', 'GCMP-128', 'CCMP-256', 'GCMP-256']
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('TestAP1.psk')
|
||||
|
||||
for group in ciphers:
|
||||
for pairwise in ciphers:
|
||||
IWD.copy_to_ap('TestAP2.ap')
|
||||
os.system('echo "PairwiseCiphers=%s" >> /tmp/iwd/ap/TestAP2.ap' % pairwise)
|
||||
os.system('echo "GroupCipher=%s" >> /tmp/iwd/ap/TestAP2.ap' % group)
|
||||
|
||||
wd = IWD(True)
|
||||
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
|
||||
dev1.start_ap('TestAP2')
|
||||
|
||||
self.assertTrue(dev1.group_cipher == group)
|
||||
self.assertIn(pairwise, dev1.pairwise_ciphers)
|
||||
|
||||
try:
|
||||
validate(wd, dev2, dev1, 'TestAP2', 'Password2', ip_checks=False)
|
||||
except:
|
||||
raise Exception("Failed with pairwise=%s group=%s" % (pairwise, group))
|
||||
finally:
|
||||
IWD.clear_storage()
|
||||
del wd
|
||||
|
||||
def tearDown(self):
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,20 +0,0 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
|
||||
from iwd import IWD
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_ap_scan(self):
|
||||
wd = IWD(True)
|
||||
|
||||
dev = wd.list_devices(1)[0]
|
||||
|
||||
dev.start_ap('TestAP2', 'Password2')
|
||||
|
||||
dev.scan()
|
||||
|
||||
networks = dev.get_ordered_networks()
|
||||
|
||||
self.assertTrue(len(networks) == 1)
|
||||
self.assertTrue(networks[0]['Name'] == 'TestAP1')
|
@ -11,71 +11,56 @@ from iwd import NetworkType
|
||||
from hostapd import HostapdCLI
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def initial_connection(self):
|
||||
ordered_network = self.device.get_ordered_network('TestAPRoam')
|
||||
|
||||
def test_connection_success(self):
|
||||
bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
|
||||
wd = IWD()
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
ordered_network = device.get_ordered_network('TestAPRoam')
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
self.device.connect_bssid(self.bss_hostapd[0].bssid)
|
||||
device.connect_bssid(bss_hostapd[0].bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED')
|
||||
bss_hostapd[0].wait_for_event('AP-STA-CONNECTED')
|
||||
|
||||
self.assertFalse(self.bss_hostapd[1].list_sta())
|
||||
self.assertFalse(bss_hostapd[1].list_sta())
|
||||
|
||||
def validate_roam(self, from_bss, to_bss, expect_roam=True):
|
||||
from_bss.send_bss_transition(self.device.address,
|
||||
self.neighbor_list,
|
||||
disassoc_imminent=expect_roam)
|
||||
bss_hostapd[0].send_bss_transition(device.address,
|
||||
[(bss_hostapd[1].bssid, '8f0000005102060603000000')])
|
||||
|
||||
if expect_roam:
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
|
||||
condition = 'obj.state == DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
to_bss.wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
|
||||
else:
|
||||
self.device.wait_for_event("no-roam-candidates")
|
||||
condition = 'obj.state != DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def test_disassoc_imminent(self):
|
||||
self.initial_connection()
|
||||
self.validate_roam(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def test_no_candidates(self):
|
||||
self.initial_connection()
|
||||
# We now have BSS0 roam blacklisted
|
||||
self.validate_roam(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
# Try and trigger another roam back, which shouldn't happen since now
|
||||
# both BSS's are roam blacklisted
|
||||
self.validate_roam(self.bss_hostapd[1], self.bss_hostapd[0], expect_roam=False)
|
||||
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
device.disconnect()
|
||||
|
||||
devices = self.wd.list_devices(1)
|
||||
self.device = devices[0]
|
||||
|
||||
def tearDown(self):
|
||||
self.wd = None
|
||||
self.device = None
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('TestAPRoam.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
cls.neighbor_list = [
|
||||
(cls.bss_hostapd[0].bssid, "8f0000005101060603000000"),
|
||||
(cls.bss_hostapd[1].bssid, "8f0000005102060603000000"),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
@ -1,7 +1,5 @@
|
||||
[SETUP]
|
||||
num_radios=4
|
||||
hwsim_medium=true
|
||||
start_iwd=false
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssid1.conf
|
||||
|
@ -1,6 +0,0 @@
|
||||
[General]
|
||||
RoamThreshold=-72
|
||||
CriticalRoamThreshold=-72
|
||||
|
||||
[Blacklist]
|
||||
InitialAccessPointBusyTimeout=20
|
@ -1,183 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD, IWD_CONFIG_DIR
|
||||
from iwd import NetworkType
|
||||
|
||||
from hostapd import HostapdCLI
|
||||
from hwsim import Hwsim
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def validate_connected(self, hostapd):
|
||||
ordered_network = self.device.get_ordered_network('TestAPRoam')
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
self.device.connect_bssid(hostapd.bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
hostapd.wait_for_event('AP-STA-CONNECTED')
|
||||
|
||||
def validate_ap_roamed(self, from_hostapd, to_hostapd):
|
||||
from_hostapd.send_bss_transition(
|
||||
self.device.address, self.neighbor_list, disassoc_imminent=True
|
||||
)
|
||||
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
|
||||
|
||||
to_hostapd.wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
|
||||
|
||||
self.device.wait_for_event("ap-roam-blacklist-added")
|
||||
|
||||
def test_roam_to_optimal_candidates(self):
|
||||
# In this test IWD will naturally transition down the list after each
|
||||
# BSS gets roam blacklisted. All BSS's are above the RSSI thresholds.
|
||||
self.rule_ssid1.signal = -5000
|
||||
self.rule_ssid2.signal = -6500
|
||||
self.rule_ssid3.signal = -6900
|
||||
|
||||
# Connect to BSS0
|
||||
self.validate_connected(self.bss_hostapd[0])
|
||||
|
||||
# AP directed roam to BSS1
|
||||
self.validate_ap_roamed(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
|
||||
# AP directed roam to BSS2
|
||||
self.validate_ap_roamed(self.bss_hostapd[1], self.bss_hostapd[2])
|
||||
|
||||
def test_avoiding_under_threshold_bss(self):
|
||||
# In this test IWD will blacklist BSS0, then roam the BSS1. BSS1 will
|
||||
# then tell IWD to roam, but it should go back to BSS0 since the only
|
||||
# non-blacklisted BSS is under the roam threshold.
|
||||
self.rule_ssid1.signal = -5000
|
||||
self.rule_ssid2.signal = -6500
|
||||
self.rule_ssid3.signal = -7300
|
||||
|
||||
# Connect to BSS0
|
||||
self.validate_connected(self.bss_hostapd[0])
|
||||
|
||||
# AP directed roam to BSS1
|
||||
self.validate_ap_roamed(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
|
||||
# AP directed roam, but IWD should choose BSS0 since BSS2 is -73dB
|
||||
self.validate_ap_roamed(self.bss_hostapd[1], self.bss_hostapd[0])
|
||||
|
||||
def test_connect_to_roam_blacklisted_bss(self):
|
||||
# In this test a BSS will be roam blacklisted, but all other options are
|
||||
# below the RSSI threshold so IWD should roam back to the blacklisted
|
||||
# BSS.
|
||||
self.rule_ssid1.signal = -5000
|
||||
self.rule_ssid2.signal = -8000
|
||||
self.rule_ssid3.signal = -8500
|
||||
|
||||
# Connect to BSS0
|
||||
self.validate_connected(self.bss_hostapd[0])
|
||||
|
||||
# AP directed roam, should connect to BSS1 as its the next best
|
||||
self.validate_ap_roamed(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
|
||||
# Connected to BSS1, but the signal is bad, so IWD should try to roam
|
||||
# again. BSS0 is still blacklisted, but its the only reasonable option
|
||||
# since both BSS1 and BSS2 are below the set RSSI threshold (-72dB)
|
||||
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
|
||||
|
||||
# IWD should have connected to BSS0, even though its roam blacklisted
|
||||
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
|
||||
|
||||
def test_blacklist_during_roam_scan(self):
|
||||
# Tests that an AP roam request mid-roam results in the AP still being
|
||||
# blacklisted even though the request itself doesn't directly trigger
|
||||
# a roam.
|
||||
self.rule_ssid1.signal = -7300
|
||||
self.rule_ssid2.signal = -7500
|
||||
self.rule_ssid3.signal = -8500
|
||||
|
||||
# Connect to BSS0 under the roam threshold so IWD will immediately try
|
||||
# roaming elsewhere
|
||||
self.validate_connected(self.bss_hostapd[0])
|
||||
|
||||
self.device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
self.bss_hostapd[0].send_bss_transition(
|
||||
self.device.address, self.neighbor_list, disassoc_imminent=True
|
||||
)
|
||||
self.device.wait_for_event("ap-roam-blacklist-added")
|
||||
|
||||
# BSS0 should have gotten blacklisted even though IWD was mid-roam,
|
||||
# causing IWD to choose BSS1 when it gets is results.
|
||||
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
|
||||
|
||||
self.bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
|
||||
devices = self.wd.list_devices(1)
|
||||
self.device = devices[0]
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
self.wd = None
|
||||
self.device = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage("main.conf.roaming", IWD_CONFIG_DIR, "main.conf")
|
||||
IWD.copy_to_storage('TestAPRoam.psk')
|
||||
hwsim = Hwsim()
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
|
||||
rad0 = hwsim.get_radio('rad0')
|
||||
rad1 = hwsim.get_radio('rad1')
|
||||
rad2 = hwsim.get_radio('rad2')
|
||||
|
||||
cls.neighbor_list = [
|
||||
(cls.bss_hostapd[0].bssid, "8f0000005101060603000000"),
|
||||
(cls.bss_hostapd[1].bssid, "8f0000005102060603000000"),
|
||||
(cls.bss_hostapd[2].bssid, "8f0000005103060603000000"),
|
||||
]
|
||||
|
||||
|
||||
cls.rule_ssid1 = hwsim.rules.create()
|
||||
cls.rule_ssid1.source = rad0.addresses[0]
|
||||
cls.rule_ssid1.bidirectional = True
|
||||
cls.rule_ssid1.enabled = True
|
||||
|
||||
cls.rule_ssid2 = hwsim.rules.create()
|
||||
cls.rule_ssid2.source = rad1.addresses[0]
|
||||
cls.rule_ssid2.bidirectional = True
|
||||
cls.rule_ssid2.enabled = True
|
||||
|
||||
cls.rule_ssid3 = hwsim.rules.create()
|
||||
cls.rule_ssid3.source = rad2.addresses[0]
|
||||
cls.rule_ssid3.bidirectional = True
|
||||
cls.rule_ssid3.enabled = True
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,2 +0,0 @@
|
||||
[Security]
|
||||
Passphrase=EasilyGuessedPassword
|
@ -1,41 +0,0 @@
|
||||
hw_mode=g
|
||||
channel=1
|
||||
ssid=TestFT
|
||||
utf8_ssid=1
|
||||
ctrl_interface=/var/run/hostapd
|
||||
|
||||
r1_key_holder=120000000001
|
||||
nas_identifier=dummy1
|
||||
|
||||
wpa=2
|
||||
# Can support WPA-PSK and FT-PSK (space separated list) and/or EAP at the same
|
||||
# time but we want to force FT
|
||||
wpa_key_mgmt=FT-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=EasilyGuessedPassword
|
||||
ieee80211w=0
|
||||
rsn_preauth=1
|
||||
rsn_preauth_interfaces=lo
|
||||
disable_pmksa_caching=0
|
||||
# Allow PMK cache to be shared opportunistically among configured interfaces
|
||||
# and BSSes (i.e., all configurations within a single hostapd process).
|
||||
okc=1
|
||||
mobility_domain=1234
|
||||
reassociation_deadline=60000
|
||||
r0kh=12:00:00:00:00:01 dummy1 000102030405060708090a0b0c0d0e0f
|
||||
r0kh=12:00:00:00:00:02 dummy2 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:01 00:00:00:00:00:01 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:02 00:00:00:00:00:02 000102030405060708090a0b0c0d0e0f
|
||||
# Push mode only needed for 8021x, not PSK mode since msk already known
|
||||
pmk_r1_push=0
|
||||
# Allow locally generated FT response so we don't have to configure push/pull
|
||||
# between BSSes running as separate hostapd processes as in the test-runner
|
||||
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
|
||||
# CONFIG_BRIDGE enabled in the kernel.
|
||||
ft_psk_generate_local=1
|
||||
rkh_pull_timeout=50
|
||||
ft_over_ds=0
|
||||
ap_table_expiration_time=36000
|
||||
ap_table_max_size=10
|
||||
rrm_neighbor_report=1
|
||||
ocv=1
|
@ -1,41 +0,0 @@
|
||||
hw_mode=g
|
||||
channel=2
|
||||
ssid=TestFT
|
||||
utf8_ssid=1
|
||||
ctrl_interface=/var/run/hostapd
|
||||
|
||||
r1_key_holder=120000000002
|
||||
nas_identifier=dummy2
|
||||
|
||||
wpa=2
|
||||
# Can support WPA-PSK and FT-PSK (space separated list) and/or EAP at the same
|
||||
# time but we want to force FT
|
||||
wpa_key_mgmt=FT-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=EasilyGuessedPassword
|
||||
ieee80211w=0
|
||||
rsn_preauth=1
|
||||
rsn_preauth_interfaces=lo
|
||||
disable_pmksa_caching=0
|
||||
# Allow PMK cache to be shared opportunistically among configured interfaces
|
||||
# and BSSes (i.e., all configurations within a single hostapd process).
|
||||
okc=1
|
||||
mobility_domain=1234
|
||||
reassociation_deadline=60000
|
||||
r0kh=12:00:00:00:00:01 dummy1 000102030405060708090a0b0c0d0e0f
|
||||
r0kh=12:00:00:00:00:02 dummy2 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:01 00:00:00:00:00:01 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:02 00:00:00:00:00:02 000102030405060708090a0b0c0d0e0f
|
||||
# Push mode only needed for 8021x, not PSK mode since msk already known
|
||||
pmk_r1_push=0
|
||||
# Allow locally generated FT response so we don't have to configure push/pull
|
||||
# between BSSes running as separate hostapd processes as in the test-runner
|
||||
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
|
||||
# CONFIG_BRIDGE enabled in the kernel.
|
||||
ft_psk_generate_local=1
|
||||
rkh_pull_timeout=50
|
||||
ft_over_ds=0
|
||||
ap_table_expiration_time=36000
|
||||
ap_table_max_size=10
|
||||
rrm_neighbor_report=1
|
||||
ocv=1
|
@ -1,8 +0,0 @@
|
||||
[SETUP]
|
||||
num_radios=3
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ft-psk-ccmp-1.conf
|
||||
rad1=ft-psk-ccmp-2.conf
|
@ -1,5 +0,0 @@
|
||||
[Scan]
|
||||
DisableMacAddressRandomization=true
|
||||
|
||||
[General]
|
||||
RoamRetryInterval=1
|
@ -1,216 +0,0 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys, os
|
||||
import dbus
|
||||
|
||||
sys.path.append('../util')
|
||||
from config import ctx
|
||||
import iwd
|
||||
from iwd import IWD, IWDDBusAbstract
|
||||
from iwd import NetworkType
|
||||
from hwsim import Hwsim
|
||||
from hostapd import HostapdCLI
|
||||
|
||||
#
|
||||
# Separate client used to test DBus disconnects so we don't bring down the
|
||||
# entire IWD python library
|
||||
#
|
||||
class AffinityClient(IWDDBusAbstract):
|
||||
def __init__(self, device_path):
|
||||
self._bus = dbus.bus.BusConnection(address_or_type=ctx.dbus_address)
|
||||
self._station_prop_if = dbus.Interface(
|
||||
self._bus.get_object(iwd.IWD_SERVICE, device_path),
|
||||
iwd.DBUS_PROPERTIES)
|
||||
|
||||
def set(self, values):
|
||||
self._station_prop_if.Set(iwd.IWD_STATION_INTERFACE, 'Affinities', dbus.Array([dbus.ObjectPath(v) for v in values], signature="o"))
|
||||
|
||||
def close(self):
|
||||
self._bus.close()
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def connect(self, device, hapd):
|
||||
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
device.connect_bssid(hapd.bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def test_set_affinity(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
print(device.connected_bss)
|
||||
|
||||
device.affinities = [device.connected_bss]
|
||||
|
||||
# IWD should not attempt to roam
|
||||
with self.assertRaises(TimeoutError):
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
device.affinities = []
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
def test_roam_below_critical(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
device.affinities = [device.connected_bss]
|
||||
|
||||
# IWD should not attempt to roam
|
||||
with self.assertRaises(TimeoutError):
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
# Lower signal past critical level
|
||||
self.bss0_rule.signal = -9000
|
||||
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
def test_error_conditions(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
# Calling set while disconnected should fail
|
||||
with self.assertRaises(iwd.NotConnectedEx):
|
||||
device.affinities = ["/some/path"]
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
device.affinities = [device.connected_bss]
|
||||
|
||||
# An invalid path should fail
|
||||
with self.assertRaises(iwd.InvalidArgumentsEx):
|
||||
device.affinities = [device.connected_bss, "/an/invalid/path"]
|
||||
|
||||
def test_affinity_client_disconnect(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
client = AffinityClient(device.device_path)
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
client.set([device.connected_bss])
|
||||
|
||||
with self.assertRaises(TimeoutError):
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
client._bus.close()
|
||||
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
def test_affinity_client_reconnect_during_roam(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
client = AffinityClient(device.device_path)
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
client.set([device.connected_bss])
|
||||
|
||||
# Lower signal past critical level
|
||||
self.bss0_rule.signal = -9000
|
||||
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
client.close()
|
||||
del client
|
||||
client = AffinityClient(device.device_path)
|
||||
# setting here should get cleared after connecting
|
||||
client.set([device.connected_bss])
|
||||
|
||||
device.wait_for_event("ft-authenticating")
|
||||
device.wait_for_event("associating")
|
||||
device.wait_for_event("connected")
|
||||
|
||||
# Affinity should be reset, and IWD should be trying to roam
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
def test_cleanup_with_connected_client(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
client = AffinityClient(device.device_path)
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
client.set([device.connected_bss])
|
||||
self.wd.stop()
|
||||
|
||||
def test_affinity_removed_after_roam(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
device.affinities = [device.connected_bss]
|
||||
|
||||
# Lower signal past critical level
|
||||
self.bss0_rule.signal = -9000
|
||||
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
device.wait_for_event("ft-authenticating")
|
||||
device.wait_for_event("associating")
|
||||
device.wait_for_event("connected")
|
||||
|
||||
self.assertEqual(device.affinities, [])
|
||||
|
||||
def tearDown(self):
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
|
||||
|
||||
self.wd.stop()
|
||||
self.wd = None
|
||||
|
||||
def setUp(self):
|
||||
self.bss0_rule.signal = -8000
|
||||
self.bss1_rule.signal = -8000
|
||||
|
||||
self.wd = IWD(True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hwsim = Hwsim()
|
||||
|
||||
IWD.copy_to_storage('TestFT.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
|
||||
HostapdCLI(config='ft-psk-ccmp-2.conf') ]
|
||||
|
||||
rad0 = hwsim.get_radio('rad0')
|
||||
rad1 = hwsim.get_radio('rad1')
|
||||
|
||||
cls.bss0_rule = hwsim.rules.create()
|
||||
cls.bss0_rule.source = rad0.addresses[0]
|
||||
cls.bss0_rule.bidirectional = True
|
||||
cls.bss0_rule.signal = -8000
|
||||
cls.bss0_rule.enabled = True
|
||||
|
||||
cls.bss1_rule = hwsim.rules.create()
|
||||
cls.bss1_rule.source = rad1.addresses[0]
|
||||
cls.bss1_rule.bidirectional = True
|
||||
cls.bss1_rule.signal = -8000
|
||||
cls.bss1_rule.enabled = True
|
||||
|
||||
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
|
||||
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
|
||||
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.bss_hostapd = None
|
||||
cls.bss0_rule.remove()
|
||||
cls.bss1_rule.remove()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -260,69 +260,12 @@ class Test(unittest.TestCase):
|
||||
|
||||
self.wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
def test_blacklist_disabled(self):
|
||||
wd = self.wd
|
||||
bss_hostapd = self.bss_hostapd
|
||||
|
||||
rule0 = self.rule0
|
||||
rule1 = self.rule1
|
||||
rule2 = self.rule2
|
||||
|
||||
psk_agent = PSKAgent(["secret123", 'secret123'])
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
rule0.drop = True
|
||||
rule0.enabled = True
|
||||
|
||||
device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
# The first BSS should fail, and we should connect to the second. This
|
||||
# should not result in a connection blacklist though since its disabled.
|
||||
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
device.disconnect()
|
||||
|
||||
rule0.drop = False
|
||||
device.autoconnect = True
|
||||
|
||||
# Verify the first BSS wasn't blacklisted.
|
||||
bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
def setUp(self):
|
||||
_, _, name = self.id().split(".")
|
||||
|
||||
# TODO: If we have this pattern elsewhere it might be nice to turn this
|
||||
# into a decorator e.g.
|
||||
#
|
||||
# @config("main.conf.disabled")
|
||||
# @profile("TestBlacklist.psk")
|
||||
# def test_blacklist_disabled(self)
|
||||
# ...
|
||||
#
|
||||
if name == "test_blacklist_disabled":
|
||||
IWD.copy_to_storage("main.conf.disabled", IWD_CONFIG_DIR, "main.conf")
|
||||
IWD.copy_to_storage("TestBlacklist.psk")
|
||||
else:
|
||||
IWD.copy_to_storage("main.conf.default", IWD_CONFIG_DIR, "main.conf")
|
||||
|
||||
self.wd = IWD(True)
|
||||
|
||||
def tearDown(self):
|
||||
IWD.clear_storage()
|
||||
self.wd = None
|
||||
self.rule0.drop = False
|
||||
self.rule1.drop = False
|
||||
self.rule2.drop = False
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
@ -1,2 +0,0 @@
|
||||
[Blacklist]
|
||||
InitialTimeout=0
|
@ -1,98 +0,0 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys, os
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from hwsim import Hwsim
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_bss_unregister(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
ordered_network = device.get_ordered_network('ssidTKIP', full_scan=True)
|
||||
network = ordered_network.network_object
|
||||
|
||||
self.assertEqual(len(network.extended_service_set), 2)
|
||||
|
||||
ends = [parts.split('/')[-1] for parts in network.extended_service_set]
|
||||
|
||||
self.assertIn(self.bss_hostapd[0].bssid.replace(':', ''), ends)
|
||||
self.assertIn(self.bss_hostapd[1].bssid.replace(':', ''), ends)
|
||||
|
||||
self.rule_bss1.enabled = True
|
||||
|
||||
# Even with flushing, the kernel still seems to return the scan
|
||||
# results
|
||||
self.wd.wait(40)
|
||||
ordered_network = device.get_ordered_network('ssidTKIP', full_scan=True)
|
||||
network = ordered_network.network_object
|
||||
|
||||
ends = [parts.split('/')[-1] for parts in network.extended_service_set]
|
||||
|
||||
self.assertIn(self.bss_hostapd[0].bssid.replace(':', ''), ends)
|
||||
self.assertNotIn(self.bss_hostapd[1].bssid.replace(':', ''), ends)
|
||||
|
||||
self.rule_bss0.enabled = True
|
||||
|
||||
self.wd.wait(40)
|
||||
ordered_networks = device.get_ordered_networks('ssidTKIP', full_scan=True)
|
||||
self.assertIsNone(ordered_networks)
|
||||
|
||||
self.rule_bss0.enabled = False
|
||||
|
||||
ordered_networks = device.get_ordered_networks('ssidTKIP', full_scan=True)
|
||||
ends = [parts.split('/')[-1] for parts in network.extended_service_set]
|
||||
|
||||
self.assertIn(self.bss_hostapd[0].bssid.replace(':', ''), ends)
|
||||
self.assertNotIn(self.bss_hostapd[1].bssid.replace(':', ''), ends)
|
||||
|
||||
def tearDown(self):
|
||||
self.rule_bss0.enabled = False
|
||||
self.rule_bss1.enabled = False
|
||||
|
||||
self.wd.stop()
|
||||
self.wd.wait(10)
|
||||
self.wd = None
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hwsim = Hwsim()
|
||||
|
||||
IWD.copy_to_storage('ssidTKIP.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ssidTKIP-1.conf'),
|
||||
HostapdCLI(config='ssidTKIP-2.conf') ]
|
||||
|
||||
|
||||
rad0 = hwsim.get_radio('rad0')
|
||||
rad1 = hwsim.get_radio('rad1')
|
||||
|
||||
cls.rule_bss0 = hwsim.rules.create()
|
||||
cls.rule_bss0.source = rad0.addresses[0]
|
||||
cls.rule_bss0.bidirectional = True
|
||||
cls.rule_bss0.drop = True
|
||||
|
||||
cls.rule_bss1 = hwsim.rules.create()
|
||||
cls.rule_bss1.source = rad1.addresses[0]
|
||||
cls.rule_bss1.bidirectional = True
|
||||
cls.rule_bss1.drop = True
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.bss_hostapd = None
|
||||
cls.rule_bss0.remove()
|
||||
cls.rule_bss1.remove()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,8 +0,0 @@
|
||||
[SETUP]
|
||||
num_radios=3
|
||||
hwsim_medium=yes
|
||||
start_iwd=no
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssidTKIP-1.conf
|
||||
rad1=ssidTKIP-2.conf
|
@ -1,7 +0,0 @@
|
||||
hw_mode=g
|
||||
channel=1
|
||||
ssid=ssidTKIP
|
||||
|
||||
wpa=1
|
||||
wpa_pairwise=TKIP
|
||||
wpa_passphrase=secret123
|
@ -1,7 +0,0 @@
|
||||
hw_mode=g
|
||||
channel=2
|
||||
ssid=ssidTKIP
|
||||
|
||||
wpa=1
|
||||
wpa_pairwise=TKIP
|
||||
wpa_passphrase=secret123
|
@ -1,5 +0,0 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
||||
|
||||
[Settings]
|
||||
AutoConnect=False
|
@ -11,7 +11,7 @@ from iwd import IWD
|
||||
|
||||
class Test8021xNetwork(unittest.TestCase):
|
||||
'''
|
||||
The below test cases excesise the following connection scenarios:
|
||||
The bellow test cases excesise the following connection scenarios:
|
||||
|
||||
Network config is
|
||||
present at start time: Connect: AutoConnect: Result:
|
||||
|
@ -11,7 +11,7 @@ from iwd import IWD
|
||||
|
||||
class TestOpenNetwork(unittest.TestCase):
|
||||
'''
|
||||
The below test cases excesise the following connection scenarios:
|
||||
The bellow test cases excesise the following connection scenarios:
|
||||
|
||||
Network config is
|
||||
present at start time: Connect: AutoConnect: Result:
|
||||
|
@ -11,7 +11,7 @@ from iwd import IWD
|
||||
|
||||
class TestWpaNetwork(unittest.TestCase):
|
||||
'''
|
||||
The below test cases exercise the following connection scenarios:
|
||||
The bellow test cases exercise the following connection scenarios:
|
||||
|
||||
Network config is
|
||||
present at start time: Connect: AutoConnect: Result:
|
||||
|
@ -38,18 +38,20 @@ class Test(unittest.TestCase):
|
||||
|
||||
def test_iwd_as_enrollee_scan_after(self):
|
||||
self.wpas.disconnect()
|
||||
self.device.autoconnect = True
|
||||
uri = self.device.dpp_start_enrollee()
|
||||
|
||||
self.wpas.dpp_configurator_create(uri)
|
||||
self.wpas.dpp_configurator_start('ssidCCMP', 'secret123')
|
||||
|
||||
self.hapd.reload()
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
self.device.get_ordered_network('ssidCCMP', scan_if_needed=False)
|
||||
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
|
||||
self.device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
@ -146,13 +148,8 @@ class Test(unittest.TestCase):
|
||||
self.rule0.drop = True
|
||||
|
||||
def tearDown(self):
|
||||
# Tests end in various states, don't fail when tearing down.
|
||||
try:
|
||||
self.device.disconnect()
|
||||
self.device.dpp_stop()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.device.disconnect()
|
||||
self.device.dpp_stop()
|
||||
self.wpas.dpp_configurator_remove()
|
||||
self.wpas.clean_up()
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
[Security]
|
||||
Passphrase=IncorrectPassphrase
|
@ -1,5 +1,5 @@
|
||||
hw_mode=g
|
||||
channel=6
|
||||
channel=1
|
||||
ssid=ssidCCMP
|
||||
|
||||
wpa=2
|
||||
|
@ -1,5 +1,5 @@
|
||||
[SETUP]
|
||||
num_radios=5
|
||||
num_radios=3
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
@ -8,7 +8,3 @@ rad0=wpas.conf
|
||||
|
||||
[HOSTAPD]
|
||||
rad1=hostapd.conf
|
||||
rad2=ssidHidden.conf
|
||||
|
||||
[NameSpaces]
|
||||
ns0=rad3
|
||||
|
@ -1,336 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD, SharedCodeAgent, DeviceState
|
||||
from iwd import DeviceProvisioning
|
||||
from wpas import Wpas
|
||||
from hostapd import HostapdCLI
|
||||
from hwsim import Hwsim
|
||||
from config import ctx
|
||||
from time import time
|
||||
import os
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def start_wpas_pkex(self, code, curve=None, **kwargs):
|
||||
self.wpas.dpp_bootstrap_gen(type='pkex', curve=curve)
|
||||
self.wpas.dpp_pkex_add(code=code, **kwargs)
|
||||
if kwargs.get('role', 'configurator') == 'configurator':
|
||||
self.wpas.dpp_configurator_create()
|
||||
self.wpas.dpp_listen(2437)
|
||||
|
||||
def stop_wpas_pkex(self):
|
||||
self.wpas.dpp_pkex_remove()
|
||||
self.wpas.dpp_stop_listen()
|
||||
self.wpas.dpp_configurator_remove()
|
||||
|
||||
def start_iwd_pkex_configurator(self, device, agent=False, profile='ssidCCMP.psk'):
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
|
||||
IWD.copy_to_storage(profile)
|
||||
device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
if agent:
|
||||
self.agent = SharedCodeAgent(codes = {"test": "secret123"})
|
||||
|
||||
device.dpp_pkex_start_configurator(self.agent.path)
|
||||
else:
|
||||
device.dpp_pkex_configure_enrollee('secret123', identifier="test")
|
||||
|
||||
#
|
||||
# WPA Supplicant has awful handling of retransmissions and no-ACK
|
||||
# conditions. It only handles retransmitting the exchange request when
|
||||
# there is no-ACK, which makes zero sense since its a broadcast...
|
||||
#
|
||||
# So, really, testing against wpa_supplicant is fragile and dependent on
|
||||
# how the scheduling works out. If IWD doesn't ACK due to being on the
|
||||
# next frequency or in between offchannel requests wpa_supplicant gets
|
||||
# into a state where it thinks a PKEX session has been started (having
|
||||
# received the exchange request) but will only accept commit-reveal
|
||||
# frames. IWD is unaware because it never got a response so it keeps
|
||||
# sending exchange requests which are ignored.
|
||||
#
|
||||
# Nevertheless we should still test against wpa_supplicant for
|
||||
# compatibility so attempt to detect this case and restart the
|
||||
# wpa_supplicant configurator.
|
||||
#
|
||||
def restart_wpas_if_needed(self):
|
||||
i = 0
|
||||
|
||||
while i < 10:
|
||||
data = self.wpas.wait_for_event("DPP-RX")
|
||||
self.assertIn("type=7", data)
|
||||
|
||||
data = self.wpas.wait_for_event("DPP-TX")
|
||||
self.assertIn("type=8", data)
|
||||
|
||||
data = self.wpas.wait_for_event("DPP-TX-STATUS")
|
||||
if "result=no-ACK" in data:
|
||||
self.stop_wpas_pkex()
|
||||
self.start_wpas_pkex('secret123', identifier="test")
|
||||
else:
|
||||
return
|
||||
|
||||
i += 1
|
||||
|
||||
raise Exception("wpa_supplicant could not complete PKEX after 10 retries")
|
||||
|
||||
def test_pkex_iwd_as_enrollee(self):
|
||||
self.start_wpas_pkex('secret123', identifier="test")
|
||||
|
||||
self.device[0].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
self.restart_wpas_if_needed()
|
||||
|
||||
self.wpas.wait_for_event("DPP-AUTH-SUCCESS")
|
||||
|
||||
def test_pkex_iwd_as_enrollee_retransmit(self):
|
||||
self.rule_reveal_req.enabled = True
|
||||
|
||||
self.start_wpas_pkex('secret123', identifier="test")
|
||||
|
||||
self.device[0].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
self.restart_wpas_if_needed()
|
||||
|
||||
self.wpas.wait_for_event("DPP-AUTH-SUCCESS")
|
||||
|
||||
def test_pkex_unsupported_version(self):
|
||||
self.start_wpas_pkex('secret123', identifier="test", version=2)
|
||||
|
||||
now = time()
|
||||
self.device[0].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = "obj.started == False"
|
||||
self.wd.wait_for_object_condition(self.device[0]._sc_device_provisioning,
|
||||
condition, max_wait=125)
|
||||
|
||||
# Check the enrollee stopped after 2 minutes
|
||||
elapsed = time() - now
|
||||
self.assertLess(elapsed, 125)
|
||||
|
||||
def test_pkex_configurator_timeout(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
now = time()
|
||||
|
||||
condition = "obj.started == False"
|
||||
self.wd.wait_for_object_condition(self.device[0]._sc_device_provisioning,
|
||||
condition, max_wait=125)
|
||||
|
||||
# Check the enrollee stopped after 2 minutes
|
||||
elapsed = time() - now
|
||||
self.assertLess(elapsed, 125)
|
||||
|
||||
def test_pkex_iwd_as_configurator(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
self.start_wpas_pkex('secret123', identifier="test", initiator=True,
|
||||
role='enrollee')
|
||||
|
||||
self.wpas.wait_for_event("DPP-AUTH-SUCCESS")
|
||||
self.wpas.wait_for_event("DPP-CONF-RECEIVED")
|
||||
|
||||
def test_pkex_iwd_as_configurator_retransmit(self):
|
||||
self.rule_xchg_resp.enabled = True
|
||||
self.rule_reveal_resp.enabled = True
|
||||
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
self.start_wpas_pkex('secret123', identifier="test", initiator=True,
|
||||
role='enrollee')
|
||||
|
||||
self.wpas.wait_for_event("DPP-AUTH-SUCCESS")
|
||||
self.wpas.wait_for_event("DPP-CONF-RECEIVED")
|
||||
|
||||
def test_pkex_iwd_as_configurator_bad_group(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
self.start_wpas_pkex('secret123', identifier="test", initiator=True,
|
||||
role='enrollee', curve='P-384')
|
||||
|
||||
self.wpas.wait_for_event(f"DPP-RX src={self.device[0].address} freq=2437 type=8")
|
||||
self.wpas.wait_for_event("DPP-FAIL")
|
||||
|
||||
def test_pkex_iwd_to_iwd(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
self.device[1].autoconnect = True
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
# Check additional settings were carried over
|
||||
with open('/tmp/ns0/ssidCCMP.psk', 'r') as f:
|
||||
settings = f.read()
|
||||
|
||||
self.assertIn("SendHostname=true", settings)
|
||||
|
||||
def test_pkex_configurator_with_agent(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0], agent=True)
|
||||
self.device[1].autoconnect = True
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
self.agent = None
|
||||
|
||||
def test_existing_network(self):
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
IWD.copy_to_storage("existingProfile.psk", "/tmp/ns0/", "ssidCCMP.psk")
|
||||
|
||||
# Scan first so a network object exists, and its a known network
|
||||
self.device[1].scan()
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.scanning == True')
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.scanning == False')
|
||||
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
self.device[1].autoconnect = False
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
# Check additional settings were carried over
|
||||
with open('/tmp/ns0/ssidCCMP.psk', 'r') as f:
|
||||
settings = f.read()
|
||||
|
||||
self.assertIn("SendHostname=true", settings)
|
||||
|
||||
def test_existing_incorrect_profile(self):
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
IWD.copy_to_storage("existingProfile.psk", "/tmp/ns0/", "ssidCCMP.psk")
|
||||
|
||||
# Start connecting
|
||||
self.device[1].autoconnect = True
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.state == DeviceState.connecting')
|
||||
|
||||
# We should be able to start DPP despite the connecting state
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
self.assertEqual(self.device[1].state, DeviceState.disconnected)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
def test_existing_hidden_network(self):
|
||||
self.hapd_hidden.reload()
|
||||
self.hapd_hidden.wait_for_event('AP-ENABLED')
|
||||
IWD.copy_to_storage("existingProfile.psk", "/tmp/ns0/", "ssidHidden.psk")
|
||||
|
||||
# Scan first so a network object exists, and its a known network
|
||||
self.device[1].scan()
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.scanning == True')
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.scanning == False')
|
||||
|
||||
self.start_iwd_pkex_configurator(self.device[0], profile='ssidHidden.psk')
|
||||
|
||||
self.device[1].autoconnect = False
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
# Check additional settings were carried over
|
||||
with open('/tmp/ns0/ssidHidden.psk', 'r') as f:
|
||||
settings = f.read()
|
||||
|
||||
self.assertIn("Hidden=true", settings)
|
||||
|
||||
def test_hidden_network(self):
|
||||
self.hapd_hidden.reload()
|
||||
self.hapd_hidden.wait_for_event('AP-ENABLED')
|
||||
self.start_iwd_pkex_configurator(self.device[0], profile='ssidHidden.psk')
|
||||
|
||||
self.device[1].autoconnect = False
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
# Check additional settings were carried over
|
||||
with open('/tmp/ns0/ssidHidden.psk', 'r') as f:
|
||||
settings = f.read()
|
||||
|
||||
self.assertIn("Hidden=true", settings)
|
||||
|
||||
def setUp(self):
|
||||
ns0 = ctx.get_namespace('ns0')
|
||||
self.wpas = Wpas('wpas.conf')
|
||||
|
||||
self.wd = IWD(True)
|
||||
self.wd_ns0 = IWD(True, iwd_storage_dir='/tmp/ns0', namespace=ns0)
|
||||
self.device = []
|
||||
self.device.append(self.wd.list_devices(1)[0])
|
||||
self.device.append(self.wd_ns0.list_devices(1)[0])
|
||||
self.hapd = HostapdCLI('hostapd.conf')
|
||||
self.hapd.disable()
|
||||
self.hapd_hidden = HostapdCLI('ssidHidden.conf')
|
||||
self.hapd_hidden.disable()
|
||||
self.hwsim = Hwsim()
|
||||
|
||||
self.rule_xchg_resp = self.hwsim.rules.create()
|
||||
self.rule_xchg_resp.prefix = 'd0'
|
||||
self.rule_xchg_resp.match_offset = 24
|
||||
self.rule_xchg_resp.match = '04 09 50 6f 9a 1a 01 08'
|
||||
self.rule_xchg_resp.match_times = 1
|
||||
self.rule_xchg_resp.drop = True
|
||||
|
||||
self.rule_reveal_resp = self.hwsim.rules.create()
|
||||
self.rule_reveal_resp.prefix = 'd0'
|
||||
self.rule_reveal_resp.match_offset = 24
|
||||
self.rule_reveal_resp.match = '04 09 50 6f 9a 1a 01 0a'
|
||||
self.rule_reveal_resp.match_times = 1
|
||||
self.rule_reveal_resp.drop = True
|
||||
|
||||
self.rule_reveal_req = self.hwsim.rules.create()
|
||||
self.rule_reveal_req.prefix = 'd0'
|
||||
self.rule_reveal_req.match_offset = 24
|
||||
self.rule_reveal_req.match = '04 09 50 6f 9a 1a 01 09'
|
||||
self.rule_reveal_req.match_times = 1
|
||||
self.rule_reveal_req.drop = True
|
||||
|
||||
def tearDown(self):
|
||||
# Tests end in various states, don't fail when tearing down.
|
||||
try:
|
||||
self.device[0].disconnect()
|
||||
self.device[0].dpp_pkex_stop()
|
||||
self.device[1].disconnect()
|
||||
self.device[1].dpp_pkex_stop()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.wpas.dpp_configurator_remove()
|
||||
self.wpas.clean_up()
|
||||
|
||||
self.wd = None
|
||||
self.wd_ns0 = None
|
||||
self.device = None
|
||||
self.wpas = None
|
||||
self.hapd = None
|
||||
self.rule_xchg_resp = None
|
||||
IWD.clear_storage()
|
||||
IWD.clear_storage('/tmp/ns0')
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,5 +1,2 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
||||
|
||||
[IPv4]
|
||||
SendHostname=true
|
||||
|
@ -1,9 +0,0 @@
|
||||
hw_mode=g
|
||||
channel=6
|
||||
ssid=ssidHidden
|
||||
|
||||
wpa=1
|
||||
wpa_pairwise=TKIP
|
||||
wpa_passphrase=secret123
|
||||
|
||||
ignore_broadcast_ssid=1
|
@ -1,5 +0,0 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
||||
|
||||
[Settings]
|
||||
Hidden=true
|
@ -1,107 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD, SharedCodeAgent, DeviceState
|
||||
from iwd import DeviceProvisioning
|
||||
from wpas import Wpas
|
||||
from hostapd import HostapdCLI
|
||||
from hwsim import Hwsim
|
||||
from config import ctx
|
||||
from time import time
|
||||
import os
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def auto_connect(self):
|
||||
IWD.copy_to_storage('ssidCCMP.psk')
|
||||
self.device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
def test_configurator_stops_on_disconnect(self):
|
||||
self.auto_connect()
|
||||
|
||||
self.device.dpp_start_configurator()
|
||||
|
||||
self.device.disconnect()
|
||||
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
self.assertEqual(self.device._device_provisioning.started, False)
|
||||
|
||||
def test_enrollee_stops_on_connect(self):
|
||||
# Scan to get a list of networks
|
||||
self.device.scan()
|
||||
self.wd.wait_for_object_condition(self.device, 'obj.scanning == True')
|
||||
self.wd.wait_for_object_condition(self.device, 'obj.scanning == False')
|
||||
|
||||
self.device.dpp_start_enrollee()
|
||||
|
||||
network = self.device.get_ordered_network("ssidCCMP")
|
||||
network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
self.assertEqual(self.device._device_provisioning.started, False)
|
||||
|
||||
def test_enrollee_disconnects_automatically(self):
|
||||
self.auto_connect()
|
||||
|
||||
self.device.dpp_start_enrollee()
|
||||
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
def test_enrollee_autoconnect_stays_on(self):
|
||||
# Put in an autoconnecting state, no saved profile though
|
||||
self.device.autoconnect = True
|
||||
|
||||
self.device.dpp_start_enrollee()
|
||||
|
||||
# DPP should set autoconnect false, but then re-enable after it stops
|
||||
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == False")
|
||||
self.wd.wait_for_object_condition(self.device._device_provisioning, "obj.started == True")
|
||||
|
||||
# Stop DPP
|
||||
self.device.dpp_stop()
|
||||
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == True")
|
||||
|
||||
def test_enrollee_autoconnect_stays_off(self):
|
||||
# Autoconnect should be off by default
|
||||
|
||||
self.device.dpp_start_enrollee()
|
||||
|
||||
# DPP should set autoconnect false, but stay off after it stops
|
||||
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == False")
|
||||
self.wd.wait_for_object_condition(self.device._device_provisioning, "obj.started == True")
|
||||
|
||||
# Stop DPP
|
||||
self.device.dpp_stop()
|
||||
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == False")
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
self.device = self.wd.list_devices(1)[0]
|
||||
|
||||
def tearDown(self):
|
||||
self.wd.stop()
|
||||
self.wd = None
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hapd = HostapdCLI(config="hostapd.conf")
|
||||
hapd.reload()
|
||||
|
||||
hapd.wait_for_event("AP-ENABLED")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -3,4 +3,3 @@ ctrl_interface=/tmp/rad1-p2p-wpas
|
||||
update_config=0
|
||||
pmf=2
|
||||
dpp_config_processing=2
|
||||
p2p_disabled=1
|
||||
|
@ -104,7 +104,7 @@ class Test(unittest.TestCase):
|
||||
|
||||
self.assertTrue(self.profile_is_encrypted('ssidCCMP.psk'))
|
||||
|
||||
# Tests that a profile that doesn't decrypt won't become a known network
|
||||
# Tests that a profile that doesn't decrypt wont become a known network
|
||||
def test_decryption_failure(self):
|
||||
bad_config = \
|
||||
'''
|
||||
|
@ -1,5 +1,2 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
||||
|
||||
[General]
|
||||
AutoConnect=false
|
||||
|
@ -55,10 +55,6 @@ class Test(unittest.TestCase):
|
||||
testutil.test_iface_operstate()
|
||||
testutil.test_ifaces_connected(device.name, hapd.ifname)
|
||||
|
||||
#
|
||||
# TODO: If this is failing its likely due to an older hostapd version
|
||||
# not containing commit 7ee814201b72
|
||||
#
|
||||
hapd.rekey(device.address)
|
||||
|
||||
device.disconnect()
|
||||
@ -66,6 +62,8 @@ class Test(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('ssidFILS-256.8021x')
|
||||
os.system('ip link set lo up')
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
@ -55,10 +55,6 @@ class Test(unittest.TestCase):
|
||||
testutil.test_iface_operstate()
|
||||
testutil.test_ifaces_connected(device.name, hapd.ifname)
|
||||
|
||||
#
|
||||
# TODO: If this is failing its likely due to an older hostapd version
|
||||
# not containing commit 7ee814201b72
|
||||
#
|
||||
hapd.rekey(device.address)
|
||||
|
||||
device.disconnect()
|
||||
@ -66,6 +62,8 @@ class Test(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('ssidFILS-384.8021x')
|
||||
os.system('ip link set lo up')
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
@ -11,3 +11,5 @@ fils_realm=example.com
|
||||
disable_pmksa_caching=1
|
||||
|
||||
pwd_group=19
|
||||
wpa_group_rekey=30
|
||||
wpa_ptk_rekey=30
|
||||
|
@ -17,4 +17,6 @@ nas_identifier=nas.w1.fi
|
||||
fils_realm=example.com
|
||||
disable_pmksa_caching=1
|
||||
|
||||
wpa_group_rekey=30
|
||||
wpa_ptk_rekey=30
|
||||
ocv=1
|
||||
|
@ -17,4 +17,6 @@ nas_identifier=nas.w1.fi
|
||||
fils_realm=example.com
|
||||
disable_pmksa_caching=1
|
||||
|
||||
wpa_group_rekey=30
|
||||
wpa_ptk_rekey=30
|
||||
ocv=1
|
||||
|
@ -37,6 +37,9 @@ class Test(unittest.TestCase):
|
||||
|
||||
device.roam(self.bss_hostapd[1].bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# Check that iwd is on BSS 1 once out of roaming state and doesn't
|
||||
# go through 'disconnected', 'autoconnect', 'connecting' in between
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
@ -63,10 +66,28 @@ class Test(unittest.TestCase):
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ft-eap-ccmp-1.conf'),
|
||||
HostapdCLI(config='ft-eap-ccmp-2.conf') ]
|
||||
|
||||
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
|
||||
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
|
||||
# Set interface addresses to those expected by hostapd config files
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" down')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + \
|
||||
'" address 12:00:00:00:00:01 up')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" down')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + \
|
||||
'" address 12:00:00:00:00:02 up')
|
||||
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
cls.bss_hostapd[0].reload()
|
||||
cls.bss_hostapd[0].wait_for_event("AP-ENABLED")
|
||||
cls.bss_hostapd[1].reload()
|
||||
cls.bss_hostapd[1].wait_for_event("AP-ENABLED")
|
||||
|
||||
# Fill in the neighbor AP tables in both BSSes. By default each
|
||||
# instance knows only about current BSS, even inside one hostapd
|
||||
# process.
|
||||
# FT still works without the neighbor AP table but neighbor reports
|
||||
# have to be disabled in the .conf files
|
||||
cls.bss_hostapd[0].set_neighbor('12:00:00:00:00:02', 'TestFT',
|
||||
'1200000000028f0000005102060603000000')
|
||||
cls.bss_hostapd[1].set_neighbor('12:00:00:00:00:01', 'TestFT',
|
||||
'1200000000018f0000005101060603000000')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
@ -17,6 +17,8 @@ eap_user_file=/tmp/secrets/eap-user.text
|
||||
ca_cert=/tmp/certs/cert-ca.pem
|
||||
server_cert=/tmp/certs/cert-server.pem
|
||||
private_key=/tmp/certs/cert-server-key.pem
|
||||
wpa_ptk_rekey=30
|
||||
wpa_group_rekey=80
|
||||
ieee80211w=1
|
||||
rsn_preauth=1
|
||||
disable_pmksa_caching=0
|
||||
|
@ -17,6 +17,8 @@ eap_user_file=/tmp/secrets/eap-user.text
|
||||
ca_cert=/tmp/certs/cert-ca.pem
|
||||
server_cert=/tmp/certs/cert-server.pem
|
||||
private_key=/tmp/certs/cert-server-key.pem
|
||||
wpa_ptk_rekey=30
|
||||
wpa_group_rekey=80
|
||||
ieee80211w=1
|
||||
rsn_preauth=1
|
||||
disable_pmksa_caching=0
|
||||
|
@ -70,6 +70,9 @@ class Test(unittest.TestCase):
|
||||
#rule0.signal = -8000
|
||||
device.roam(self.bss_hostapd[1].bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# Check that iwd is on BSS 1 once out of roaming state and doesn't
|
||||
# go through 'disconnected', 'autoconnect', 'connecting' in between
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
@ -119,15 +122,32 @@ class Test(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
os.system('ip link set lo up')
|
||||
IWD.copy_to_storage('TestFT.8021x')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ft-eap-ccmp-1.conf'),
|
||||
HostapdCLI(config='ft-eap-ccmp-2.conf') ]
|
||||
|
||||
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
|
||||
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
|
||||
# Set interface addresses to those expected by hostapd config files
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" down')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" addr 12:00:00:00:00:01 up')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" down')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" addr 12:00:00:00:00:02 up')
|
||||
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
cls.bss_hostapd[0].reload()
|
||||
cls.bss_hostapd[0].wait_for_event("AP-ENABLED")
|
||||
cls.bss_hostapd[1].reload()
|
||||
cls.bss_hostapd[1].wait_for_event("AP-ENABLED")
|
||||
|
||||
# Fill in the neighbor AP tables in both BSSes. By default each
|
||||
# instance knows only about current BSS, even inside one hostapd
|
||||
# process.
|
||||
# FT still works without the neighbor AP table but neighbor reports
|
||||
# have to be disabled in the .conf files
|
||||
cls.bss_hostapd[0].set_neighbor('12:00:00:00:00:02', 'TestFT',
|
||||
'1200000000028f0000005102060603000000')
|
||||
cls.bss_hostapd[1].set_neighbor('12:00:00:00:00:01', 'TestFT',
|
||||
'1200000000018f0000005101060603000000')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
@ -15,6 +15,8 @@ ieee8021x=1
|
||||
|
||||
fils_realm=example.com
|
||||
|
||||
wpa_ptk_rekey=30
|
||||
wpa_group_rekey=80
|
||||
ieee80211w=1
|
||||
rsn_preauth=1
|
||||
disable_pmksa_caching=1
|
||||
|
@ -15,6 +15,8 @@ ieee8021x=1
|
||||
|
||||
fils_realm=example.com
|
||||
|
||||
wpa_ptk_rekey=30
|
||||
wpa_group_rekey=80
|
||||
ieee80211w=1
|
||||
rsn_preauth=1
|
||||
disable_pmksa_caching=1
|
||||
|
@ -11,3 +11,5 @@ fils_realm=example.com
|
||||
disable_pmksa_caching=1
|
||||
|
||||
pwd_group=19
|
||||
wpa_group_rekey=30
|
||||
wpa_ptk_rekey=30
|
||||
|
@ -1,76 +0,0 @@
|
||||
import unittest
|
||||
import sys
|
||||
import sys
|
||||
import os
|
||||
from scapy.layers.dot11 import *
|
||||
from scapy.arch import str2mac
|
||||
try:
|
||||
from scapy.arch import get_if_raw_hwaddr
|
||||
except:
|
||||
from scapy.arch.unix import get_if_raw_hwaddr
|
||||
from time import time, sleep
|
||||
from threading import Thread
|
||||
|
||||
def if_hwaddr(iff):
|
||||
return str2mac(get_if_raw_hwaddr(iff)[1])
|
||||
|
||||
def config_mon(iface, channel):
|
||||
"""set the interface in monitor mode and then change channel using iw"""
|
||||
os.system("ip link set dev %s down" % iface)
|
||||
os.system("iw dev %s set type monitor" % iface)
|
||||
os.system("ip link set dev %s up" % iface)
|
||||
os.system("iw dev %s set channel %d" % (iface, channel))
|
||||
|
||||
class AP:
|
||||
def __init__(self, ssid, psk, mac=None, mode="stdio", iface="wlan0", channel=1):
|
||||
self.channel = channel
|
||||
self.iface = iface
|
||||
self.mode = mode
|
||||
if self.mode == "iface":
|
||||
if not mac:
|
||||
mac = if_hwaddr(iface)
|
||||
config_mon(iface, channel)
|
||||
if not mac:
|
||||
raise Exception("Need a mac")
|
||||
else:
|
||||
self.mac = mac
|
||||
self.boottime = time()
|
||||
|
||||
def get_radiotap_header(self):
|
||||
return RadioTap()
|
||||
|
||||
def dot11_beacon(self, contents):
|
||||
evil_packet = (
|
||||
self.get_radiotap_header()
|
||||
/ Dot11(
|
||||
subtype=8, addr1="ff:ff:ff:ff:ff:ff", addr2=self.mac, addr3=self.mac
|
||||
)
|
||||
/ Dot11Beacon(cap=0x3101)
|
||||
/ contents
|
||||
)
|
||||
self.sendp(evil_packet)
|
||||
|
||||
def run(self, contents):
|
||||
interval = 0.05
|
||||
num_beacons = 100
|
||||
|
||||
while num_beacons:
|
||||
self.dot11_beacon(contents)
|
||||
sleep(interval)
|
||||
num_beacons -= 1
|
||||
|
||||
def start(self, contents):
|
||||
self.thread = Thread(target=self.run, args=(contents,))
|
||||
self.thread.start()
|
||||
|
||||
def stop(self):
|
||||
self.thread.join()
|
||||
|
||||
def sendp(self, packet, verbose=False):
|
||||
if self.mode == "stdio":
|
||||
x = packet.build()
|
||||
sys.stdout.buffer.write(struct.pack("<L", len(x)) + x)
|
||||
sys.stdout.buffer.flush()
|
||||
return
|
||||
assert self.mode == "iface"
|
||||
sendp(packet, iface=self.iface, verbose=False)
|
@ -1,7 +0,0 @@
|
||||
[SETUP]
|
||||
num_radios=2
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
[rad1]
|
||||
reserve=true
|
@ -1,37 +0,0 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import sys
|
||||
import os
|
||||
from fake_ap import AP
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD
|
||||
|
||||
# Probe frame that causes IWD to crash
|
||||
beacon=b'\xdd\nPo\x9a\t\x0e\x00\x00\x19\x10\x00\xdd/Po\x9a\t\x0c\x02\x00\x00\xdd\x05\x03\x03\x03Po\x9a\x10\x00\x0b\x05\x0e\x00\x00\x00\x00\x0b\x05\x00\x00\x00\xdd\x05\x00\x03\x03\x03\x03\x00\x00\x00\xdd\x05\x03\x03\x03\x03\x03'
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_beacon_crash(self):
|
||||
wd = IWD(True)
|
||||
|
||||
devs = wd.list_devices()
|
||||
|
||||
self.assertEqual(len(devs), 1)
|
||||
|
||||
devs[0].autoconnect = True
|
||||
|
||||
os.system("iw phy rad1 interface add wlan1 type managed")
|
||||
|
||||
ap = AP("evilAP", "password1234", mode="iface", iface="wlan1", channel=4)
|
||||
ap.start(beacon)
|
||||
|
||||
condition = "obj.scanning == True"
|
||||
wd.wait_for_object_condition(devs[0], condition)
|
||||
|
||||
condition = "obj.scanning == False"
|
||||
wd.wait_for_object_condition(devs[0], condition)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -7,7 +7,6 @@ sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
import time
|
||||
|
||||
@ -68,20 +67,11 @@ class TestConnectionAfterHiddenNetwork(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.disabled = [HostapdCLI('ssidHiddenOpen.conf'),
|
||||
HostapdCLI('ssidHiddenWPA.conf'),
|
||||
HostapdCLI('ssidOverlap1.conf'),
|
||||
HostapdCLI('ssidOverlap2.conf')]
|
||||
|
||||
for hapd in cls.disabled:
|
||||
hapd.disable()
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
for hapd in cls.disabled:
|
||||
hapd.reload()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
||||
|
@ -8,11 +8,10 @@ import iwd
|
||||
import validation
|
||||
from validation import TestHiddenNetworks
|
||||
from iwd import IWD
|
||||
from hostapd import HostapdCLI
|
||||
|
||||
class TestWpaNetwork(unittest.TestCase):
|
||||
'''
|
||||
The below test cases excesise the following connection scenarios:
|
||||
The bellow test cases excesise the following connection scenarios:
|
||||
|
||||
Network config is
|
||||
present at start time: Connect: AutoConnect: Result:
|
||||
@ -35,19 +34,9 @@ class TestWpaNetwork(unittest.TestCase):
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('ssidAlreadyKnown.open')
|
||||
|
||||
cls.disabled = [HostapdCLI('ssidHiddenOpen.conf'),
|
||||
HostapdCLI('ssidHiddenWPA.conf'),
|
||||
HostapdCLI('ssidSomeHidden.conf')]
|
||||
|
||||
for hapd in cls.disabled:
|
||||
hapd.disable()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
for hapd in cls.disabled:
|
||||
hapd.reload()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
||||
|
@ -8,11 +8,10 @@ import iwd
|
||||
import validation
|
||||
from validation import TestHiddenNetworks
|
||||
from iwd import IWD
|
||||
from hostapd import HostapdCLI
|
||||
|
||||
class TestOpenNetwork(unittest.TestCase):
|
||||
'''
|
||||
The below test cases excesise the following connection scenarios:
|
||||
The bellow test cases excesise the following connection scenarios:
|
||||
|
||||
Network config is
|
||||
present at start time: Connect: AutoConnect: Result:
|
||||
@ -25,22 +24,9 @@ class TestOpenNetwork(unittest.TestCase):
|
||||
tca.validate('ssidHiddenOpen', False)
|
||||
tca.validate('ssidHiddenOpen', True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.disabled = [HostapdCLI('ssidHiddenWPA.conf'),
|
||||
HostapdCLI('ssidOpen.conf'),
|
||||
HostapdCLI('ssidOverlap1.conf'),
|
||||
HostapdCLI('ssidOverlap2.conf'),
|
||||
HostapdCLI('ssidSomeHidden.conf')]
|
||||
for hapd in cls.disabled:
|
||||
hapd.disable()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
for hapd in cls.disabled:
|
||||
hapd.reload()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
||||
|
@ -8,11 +8,10 @@ import iwd
|
||||
import validation
|
||||
from validation import TestHiddenNetworks
|
||||
from iwd import IWD
|
||||
from hostapd import HostapdCLI
|
||||
|
||||
class TestWpaNetwork(unittest.TestCase):
|
||||
'''
|
||||
The below test cases excesise the following connection scenarios:
|
||||
The bellow test cases excesise the following connection scenarios:
|
||||
|
||||
Network config is
|
||||
present at start time: Connect: AutoConnect: Result:
|
||||
@ -26,23 +25,9 @@ class TestWpaNetwork(unittest.TestCase):
|
||||
tca.validate('ssidHiddenWPA', False, None, True)
|
||||
tca.validate('ssidHiddenWPA', True, None, True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.disabled = [HostapdCLI('ssidHiddenOpen.conf'),
|
||||
HostapdCLI('ssidOpen.conf'),
|
||||
HostapdCLI('ssidOverlap1.conf'),
|
||||
HostapdCLI('ssidOverlap2.conf'),
|
||||
HostapdCLI('ssidSomeHidden.conf')]
|
||||
|
||||
for hapd in cls.disabled:
|
||||
hapd.disable()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
for hapd in cls.disabled:
|
||||
hapd.reload()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
||||
|
@ -4,15 +4,17 @@ import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from hwsim import Hwsim
|
||||
from iwd import NetworkType
|
||||
import testutil
|
||||
import os
|
||||
from configparser import ConfigParser
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def connect_network(self, wd, device, network):
|
||||
ordered_network = device.get_ordered_network(network, full_scan=True)
|
||||
ordered_network = device.get_ordered_network(network)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
@ -28,7 +30,7 @@ class Test(unittest.TestCase):
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
def test_connection_success(self):
|
||||
wd = self.wd
|
||||
wd = IWD(True, '/tmp')
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
@ -36,11 +38,6 @@ class Test(unittest.TestCase):
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
|
||||
# Set the signals so that the 2.4GHz ranking will be higher
|
||||
self.ssidccmp_2g_rule.signal = -2000
|
||||
self.ssidccmp_5g_rule.signal = -8000
|
||||
|
||||
#
|
||||
# Connect to the PSK network, then Hotspot so IWD creates 2 entries in
|
||||
# the known frequency file.
|
||||
@ -78,10 +75,8 @@ class Test(unittest.TestCase):
|
||||
#
|
||||
self.assertIsNotNone(psk_freqs)
|
||||
self.assertIsNotNone(psk_uuid)
|
||||
|
||||
# The 2.4GHz frequency should come first, as it was ranked higher
|
||||
self.assertEqual('2412', psk_freqs[0])
|
||||
self.assertEqual('5180', psk_freqs[1])
|
||||
self.assertIn('5180', psk_freqs)
|
||||
self.assertIn('2412', psk_freqs)
|
||||
|
||||
self.assertIsNotNone(hs20_freqs)
|
||||
self.assertIsNotNone(hs20_uuid)
|
||||
@ -97,10 +92,6 @@ class Test(unittest.TestCase):
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
# Now set the signals so that the 5GHz ranking will be higher
|
||||
self.ssidccmp_2g_rule.signal = -8000
|
||||
self.ssidccmp_5g_rule.signal = -2000
|
||||
|
||||
#
|
||||
# Reconnect, this should generate a completely new UUID since we
|
||||
# previously forgot the network.
|
||||
@ -129,78 +120,8 @@ class Test(unittest.TestCase):
|
||||
self.assertIsNotNone(psk_freqs)
|
||||
self.assertIsNotNone(psk_uuid2)
|
||||
self.assertNotEqual(psk_uuid, psk_uuid2)
|
||||
# Now the 5GHz frequency should be first
|
||||
self.assertEqual('5180', psk_freqs[0])
|
||||
self.assertEqual('2412', psk_freqs[1])
|
||||
|
||||
def test_maximum_frequencies(self):
|
||||
psk_agent = PSKAgent("secret123")
|
||||
self.wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = self.wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
# Connect and generate a known frequencies file
|
||||
self.connect_network(self.wd, device, 'ssidCCMP')
|
||||
|
||||
self.wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
#
|
||||
# Rewrite the known frequencies file to move the valid network
|
||||
# frequencies to the end, past the maximum for a quick scan
|
||||
#
|
||||
config = ConfigParser()
|
||||
config.read('/tmp/iwd/.known_network.freq')
|
||||
for s in config.sections():
|
||||
if os.path.basename(config[s]['name']) == 'ssidCCMP.psk':
|
||||
config.set(s, 'list', "2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467 2472 2484 2412 5180")
|
||||
break
|
||||
|
||||
self.wd.stop()
|
||||
|
||||
with open('/tmp/iwd/.known_network.freq', 'w') as f:
|
||||
config.write(f)
|
||||
|
||||
self.wd = IWD(True)
|
||||
|
||||
devices = self.wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
device.autoconnect = True
|
||||
|
||||
device.wait_for_event("autoconnect_quick")
|
||||
|
||||
condition = "obj.scanning == True"
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
condition = "obj.scanning == False"
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
#
|
||||
# Check that the quick scan didn't return any results
|
||||
#
|
||||
with self.assertRaises(Exception):
|
||||
device.get_ordered_network("ssidCCMP", scan_if_needed=False)
|
||||
|
||||
device.wait_for_event("autoconnect_full")
|
||||
|
||||
condition = "obj.scanning == True"
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
condition = "obj.scanning == False"
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
#
|
||||
# The full scan should now see the network
|
||||
#
|
||||
device.get_ordered_network("ssidCCMP", scan_if_needed=False)
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
|
||||
def tearDown(self):
|
||||
self.wd.stop()
|
||||
self.wd = None
|
||||
self.assertIn('5180', psk_freqs)
|
||||
self.assertIn('2412', psk_freqs)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@ -208,23 +129,10 @@ class Test(unittest.TestCase):
|
||||
conf = '[General]\nDisableANQP=0\n'
|
||||
os.system('echo "%s" > /tmp/main.conf' % conf)
|
||||
|
||||
hwsim = Hwsim()
|
||||
|
||||
cls.ssidccmp_2g_rule = hwsim.rules.create()
|
||||
cls.ssidccmp_2g_rule.source = hwsim.get_radio('rad1').addresses[0]
|
||||
cls.ssidccmp_2g_rule.enabled = True
|
||||
|
||||
cls.ssidccmp_5g_rule = hwsim.rules.create()
|
||||
cls.ssidccmp_5g_rule.source = hwsim.get_radio('rad2').addresses[0]
|
||||
cls.ssidccmp_5g_rule.enabled = True
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
os.remove('/tmp/main.conf')
|
||||
|
||||
cls.ssidccmp_2g_rule.remove()
|
||||
cls.ssidccmp_5g_rule.remove()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
||||
|
@ -2,7 +2,6 @@
|
||||
num_radios=5
|
||||
start_iwd=0
|
||||
reg_domain=US
|
||||
hwsim_medium=yes
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssidNew.conf
|
||||
|
@ -11,7 +11,7 @@ from iwd import NetworkType
|
||||
|
||||
class TestMFP(unittest.TestCase):
|
||||
'''
|
||||
The below test cases excesise the following MFP option setting scenarios:
|
||||
The bellow test cases excesise the following MFP option setting scenarios:
|
||||
|
||||
IWD_MFP: AP_MFP: Result:
|
||||
0 0 No MFP, connection succeeds
|
||||
|
@ -1,2 +0,0 @@
|
||||
[IPv4]
|
||||
SendHostname=true
|
@ -137,7 +137,7 @@ class Test(unittest.TestCase):
|
||||
# since (T2 - T1) / 2 is shorter than 60s. It is now about 10s since the last
|
||||
# renewal or 5s before the next DHCPREQUEST frame that is going to be lost. We'll
|
||||
# wait T1 seconds, so until about 10s after the failed attempt, we'll check that
|
||||
# there was no renewal by that time, just in case, and we'll re-enable frame delivery.
|
||||
# there was no renewal by that time, just in case, and we'll reenable frame delivery.
|
||||
# We'll then wait another 60s and we should see the lease has been successfully
|
||||
# renewed some 10 seconds earlier on the 1st DHCPREQUEST retransmission.
|
||||
#
|
||||
@ -276,7 +276,7 @@ class Test(unittest.TestCase):
|
||||
elif quote or ch not in ' \t\r\n;{}#':
|
||||
token += ch
|
||||
if ch == '#':
|
||||
continue
|
||||
break
|
||||
elif ch == '{':
|
||||
stack.append([])
|
||||
elif ch == '}':
|
||||
|
@ -1,161 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
from config import ctx
|
||||
import os
|
||||
import socket
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_connection_success(self):
|
||||
def check_addr(device):
|
||||
try:
|
||||
testutil.test_ip_address_match(device.name, '3ffe:501:ffff:200::', 128, 64)
|
||||
except:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def get_ll_addrs6(ns, ifname):
|
||||
show_ip = ns.start_process(['ip', 'addr', 'show', ifname])
|
||||
show_ip.wait()
|
||||
for l in show_ip.out.split('\n'):
|
||||
if 'inet6 fe80::' in l:
|
||||
return socket.inet_pton(socket.AF_INET6, l.split(None, 1)[1].split('/', 1)[0])
|
||||
return None
|
||||
|
||||
IWD.copy_to_storage('auto.psk', name='ap-ns1.psk')
|
||||
wd = IWD(True)
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
ordered_network = device.get_ordered_network('ap-ns1')
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
# Give the AP's interface time to set up addresses so that radvd can
|
||||
# reply to our Router Solicitation immediately.
|
||||
ctx.non_block_wait(lambda: False, 3, exception=False)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
testutil.test_iface_operstate()
|
||||
|
||||
ctx.non_block_wait(check_addr, 10, device,
|
||||
exception=Exception("IPv6 address was not set"))
|
||||
|
||||
# Cannot use test_ifaces_connected() across namespaces (implementation details)
|
||||
testutil.test_ip_connected(('192.168.1.10', ctx), ('192.168.1.1', self.ns1))
|
||||
|
||||
ifname = str(device.name)
|
||||
router_ll_addr = get_ll_addrs6(self.ns1, self.hapd.ifname)
|
||||
expected_routes6 = {
|
||||
# Default router
|
||||
testutil.RouteInfo(gw=router_ll_addr, flags=3, ifname=ifname),
|
||||
# On-link prefixes
|
||||
testutil.RouteInfo(dst=socket.inet_pton(socket.AF_INET6, '3ffe:501:ffff:100::'), plen=64,
|
||||
flags=1, ifname=ifname),
|
||||
testutil.RouteInfo(dst=socket.inet_pton(socket.AF_INET6, '3ffe:501:ffff:200::'), plen=64,
|
||||
flags=1, ifname=ifname),
|
||||
}
|
||||
self.maxDiff = None
|
||||
self.assertEqual(expected_routes6, set(testutil.get_routes6(ifname)))
|
||||
|
||||
rclog = open('/tmp/resolvconf.log', 'r')
|
||||
entries = [l.strip() for l in rclog.readlines()[-7:]]
|
||||
rclog.close()
|
||||
expected_rclog = [
|
||||
'-a %s.dns' % (ifname,),
|
||||
'nameserver 192.168.1.2',
|
||||
'nameserver 3ffe:501:ffff:100::10',
|
||||
'nameserver 3ffe:501:ffff:100::50',
|
||||
'-a %s.domain' % (ifname,),
|
||||
'search test1',
|
||||
'search test2'
|
||||
]
|
||||
|
||||
for line in expected_rclog:
|
||||
self.assertIn(line, entries)
|
||||
expected_rclog.remove(line)
|
||||
|
||||
device.disconnect()
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
def remove_lease4():
|
||||
try:
|
||||
os.remove('/tmp/dhcpd.leases')
|
||||
os.remove('/tmp/dhcpd.leases~')
|
||||
except:
|
||||
pass
|
||||
cls.ns1 = ctx.get_namespace('ns1')
|
||||
cls.hapd = HostapdCLI('ap-ns1.conf')
|
||||
cls.ns1.start_process(['ip', 'addr','add', '192.168.1.1/17',
|
||||
'dev', cls.hapd.ifname]).wait()
|
||||
cls.ns1.start_process(['touch', '/tmp/dhcpd.leases']).wait()
|
||||
cls.dhcpd_pid = cls.ns1.start_process(['dhcpd', '-f', '-d', '-cf', '/tmp/dhcpd.conf',
|
||||
'-lf', '/tmp/dhcpd.leases',
|
||||
cls.hapd.ifname], cleanup=remove_lease4)
|
||||
|
||||
cls.ns1.start_process(['ip', 'addr', 'add', '3ffe:501:ffff:100::1/72',
|
||||
'dev', cls.hapd.ifname]).wait()
|
||||
cls.ns1.start_process(['sysctl',
|
||||
'net.ipv6.conf.' + cls.hapd.ifname + '.forwarding=1']).wait()
|
||||
config = open('/tmp/radvd.conf', 'w')
|
||||
config.write('interface ' + cls.hapd.ifname + ''' {
|
||||
AdvSendAdvert on;
|
||||
# Trick radvd to accept MinDelayBetweenRAs values less than 3 seconds.
|
||||
AdvHomeAgentFlag on;
|
||||
# Don't throttle so we can test solicited RA reception before link-local addr DAD done.
|
||||
# radvd may have sent an unsolicited RA just before our RS and would complain -- the
|
||||
# test should succeed regardless but will take some extra seconds.
|
||||
MinDelayBetweenRAs 0.05;
|
||||
AdvManagedFlag off;
|
||||
# Test that the prefix with longer lifetime is selected.
|
||||
prefix 3ffe:501:ffff:100::/64 { AdvAutonomous on; };
|
||||
prefix 3ffe:501:ffff:200::/64 { AdvAutonomous on; AdvPreferredLifetime infinity; AdvValidLifetime infinity; };
|
||||
RDNSS 3ffe:501:ffff:100::10 3ffe:501:ffff:100::50 { AdvRDNSSLifetime 3600; };
|
||||
DNSSL test1 test2 { AdvDNSSLLifetime 3600; };
|
||||
};''')
|
||||
config.close()
|
||||
cls.radvd_pid = cls.ns1.start_process(['radvd', '-n', '-d5',
|
||||
'-p', '/tmp/radvd.pid', '-C', '/tmp/radvd.conf'])
|
||||
|
||||
cls.orig_path = os.environ['PATH']
|
||||
os.environ['PATH'] = '/tmp/test-bin:' + os.environ['PATH']
|
||||
IWD.copy_to_storage('resolvconf', '/tmp/test-bin')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.ns1.stop_process(cls.dhcpd_pid)
|
||||
cls.dhcpd_pid = None
|
||||
cls.ns1.stop_process(cls.radvd_pid)
|
||||
cls.radvd_pid = None
|
||||
os.system('rm -rf /tmp/radvd.conf /tmp/test-bin')
|
||||
os.environ['PATH'] = cls.orig_path
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,162 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
from config import ctx
|
||||
import os
|
||||
import socket
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_connection_success(self):
|
||||
def check_addr(device):
|
||||
try:
|
||||
testutil.test_ip_address_match(device.name, '3ffe:501:ffff:100::', 128, 64)
|
||||
except:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def get_ll_addrs6(ns, ifname):
|
||||
show_ip = ns.start_process(['ip', 'addr', 'show', ifname])
|
||||
show_ip.wait()
|
||||
for l in show_ip.out.split('\n'):
|
||||
if 'inet6 fe80::' in l:
|
||||
return socket.inet_pton(socket.AF_INET6, l.split(None, 1)[1].split('/', 1)[0])
|
||||
return None
|
||||
|
||||
IWD.copy_to_storage('auto.psk', name='ap-ns1.psk')
|
||||
wd = IWD(True)
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
ordered_network = device.get_ordered_network('ap-ns1')
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
# Give the AP's interface time to set up addresses so that radvd can
|
||||
# reply to our Router Solicitation immediately.
|
||||
ctx.non_block_wait(lambda: False, 3, exception=False)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
testutil.test_iface_operstate()
|
||||
|
||||
ctx.non_block_wait(check_addr, 10, device,
|
||||
exception=Exception("IPv6 address was not set"))
|
||||
|
||||
# Cannot use test_ifaces_connected() across namespaces (implementation details)
|
||||
testutil.test_ip_connected(('192.168.1.10', ctx), ('192.168.1.1', self.ns1))
|
||||
|
||||
ifname = str(device.name)
|
||||
router_ll_addr = get_ll_addrs6(self.ns1, self.hapd.ifname)
|
||||
expected_routes6 = {
|
||||
# Default router
|
||||
testutil.RouteInfo(gw=router_ll_addr, flags=3, ifname=ifname),
|
||||
# On-link prefixes
|
||||
testutil.RouteInfo(dst=socket.inet_pton(socket.AF_INET6, '3ffe:501:ffff:100::'), plen=64,
|
||||
flags=1, ifname=ifname),
|
||||
testutil.RouteInfo(dst=socket.inet_pton(socket.AF_INET6, '3ffe:501:ffff:200::'), plen=64,
|
||||
flags=1, ifname=ifname),
|
||||
}
|
||||
self.maxDiff = None
|
||||
self.assertEqual(expected_routes6, set(testutil.get_routes6(ifname)))
|
||||
|
||||
rclog = open('/tmp/resolvconf.log', 'r')
|
||||
entries = rclog.readlines()
|
||||
rclog.close()
|
||||
expected_rclog = ['-a %s.dns\n' % (ifname,), 'nameserver 192.168.1.2\n',
|
||||
'nameserver 3ffe:501:ffff:100::2\n',
|
||||
'-a %s.domain\n' % (ifname,), 'search test1\n', 'search test2\n']
|
||||
# Every resolvconf -a run overwrites the previous settings. Check the last six lines
|
||||
# of our log since we care about the end result here.
|
||||
self.assertEqual(expected_rclog, entries[-6:])
|
||||
|
||||
device.disconnect()
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
def remove_lease4():
|
||||
try:
|
||||
os.remove('/tmp/dhcpd.leases')
|
||||
os.remove('/tmp/dhcpd.leases~')
|
||||
except:
|
||||
pass
|
||||
def remove_lease6():
|
||||
try:
|
||||
os.remove('/tmp/dhcpd6.leases')
|
||||
os.remove('/tmp/dhcpd6.leases~')
|
||||
except:
|
||||
pass
|
||||
|
||||
cls.ns1 = ctx.get_namespace('ns1')
|
||||
cls.hapd = HostapdCLI('ap-ns1.conf')
|
||||
cls.ns1.start_process(['ip', 'addr','add', '192.168.1.1/17',
|
||||
'dev', cls.hapd.ifname]).wait()
|
||||
cls.ns1.start_process(['touch', '/tmp/dhcpd.leases']).wait()
|
||||
cls.dhcpd_pid = cls.ns1.start_process(['dhcpd', '-f', '-d', '-cf', '/tmp/dhcpd.conf',
|
||||
'-lf', '/tmp/dhcpd.leases',
|
||||
cls.hapd.ifname], cleanup=remove_lease4)
|
||||
|
||||
cls.ns1.start_process(['ip', 'addr', 'add', '3ffe:501:ffff:100::1/72',
|
||||
'dev', cls.hapd.ifname]).wait()
|
||||
cls.ns1.start_process(['touch', '/tmp/dhcpd6.leases']).wait()
|
||||
cls.dhcpd6_pid = cls.ns1.start_process(['dhcpd', '-6', '-f', '-d',
|
||||
'-cf', '/tmp/dhcpd-v6.conf',
|
||||
'-lf', '/tmp/dhcpd6.leases',
|
||||
cls.hapd.ifname], cleanup=remove_lease6)
|
||||
cls.ns1.start_process(['sysctl',
|
||||
'net.ipv6.conf.' + cls.hapd.ifname + '.forwarding=1']).wait()
|
||||
config = open('/tmp/radvd.conf', 'w')
|
||||
config.write('interface ' + cls.hapd.ifname + ''' {
|
||||
AdvSendAdvert on;
|
||||
AdvManagedFlag off;
|
||||
AdvOtherConfigFlag on;
|
||||
# Test that the prefix with longer lifetime is selected.
|
||||
prefix 3ffe:501:ffff:100::/64 { AdvAutonomous on; AdvPreferredLifetime 3605; };
|
||||
prefix 3ffe:501:ffff:200::/64 { AdvAutonomous on; AdvPreferredLifetime 3600; };
|
||||
DNSSL test1 test2 { AdvDNSSLLifetime 3600; };
|
||||
};''')
|
||||
config.close()
|
||||
cls.radvd_pid = cls.ns1.start_process(['radvd', '-n', '-d5',
|
||||
'-p', '/tmp/radvd.pid', '-C', '/tmp/radvd.conf'])
|
||||
|
||||
cls.orig_path = os.environ['PATH']
|
||||
os.environ['PATH'] = '/tmp/test-bin:' + os.environ['PATH']
|
||||
IWD.copy_to_storage('resolvconf', '/tmp/test-bin')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.ns1.stop_process(cls.dhcpd_pid)
|
||||
cls.dhcpd_pid = None
|
||||
cls.ns1.stop_process(cls.dhcpd6_pid)
|
||||
cls.dhcpd6_pid = None
|
||||
cls.ns1.stop_process(cls.radvd_pid)
|
||||
cls.radvd_pid = None
|
||||
os.system('rm -rf /tmp/radvd.conf /tmp/test-bin')
|
||||
os.environ['PATH'] = cls.orig_path
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -13,28 +13,36 @@ import testutil
|
||||
from config import ctx
|
||||
import os
|
||||
import socket
|
||||
import gc
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_connection_success(self):
|
||||
# Use a non-default storage_dir for one of the instances, the default for the other one
|
||||
iwd_main = IWD(True, iwd_storage_dir='/tmp/storage-main')
|
||||
psk_agent_main = PSKAgent("secret123")
|
||||
iwd_main.register_psk_agent(psk_agent_main)
|
||||
dev1 = iwd_main.list_devices(1)[0]
|
||||
wd = IWD(True, iwd_storage_dir='/tmp/storage')
|
||||
|
||||
ns0 = ctx.get_namespace('ns0')
|
||||
|
||||
wd_ns0 = IWD(True, namespace=ns0)
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
psk_agent_ns0 = PSKAgent("secret123", namespace=ns0)
|
||||
wd.register_psk_agent(psk_agent)
|
||||
wd_ns0.register_psk_agent(psk_agent_ns0)
|
||||
|
||||
dev1 = wd.list_devices(1)[0]
|
||||
dev2 = wd_ns0.list_devices(1)[0]
|
||||
|
||||
ordered_network = dev1.get_ordered_network('ap-main')
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
iwd_main.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
iwd_main.wait_for_object_condition(dev1, condition)
|
||||
wd.wait_for_object_condition(dev1, condition)
|
||||
|
||||
testutil.test_iface_operstate()
|
||||
testutil.test_ifaces_connected()
|
||||
@ -72,68 +80,22 @@ class Test(unittest.TestCase):
|
||||
# of the log since we care about the end result here.
|
||||
self.assertEqual(expected_rclog, entries[-3:])
|
||||
|
||||
# Run our second client in a separate namespace to allow ACD (ARP) to
|
||||
# work, and also be able to set identical IPs on both interfaces for
|
||||
# the next part of this test.
|
||||
ns0 = ctx.get_namespace('ns0')
|
||||
|
||||
iwd_ns0_1 = IWD(True, namespace=ns0, iwd_storage_dir='/tmp/storage-ns0-1')
|
||||
psk_agent_ns0_1 = PSKAgent("secret123", namespace=ns0)
|
||||
iwd_ns0_1.register_psk_agent(psk_agent_ns0_1)
|
||||
dev2 = iwd_ns0_1.list_devices(1)[0]
|
||||
|
||||
ordered_network = dev2.get_ordered_network('ap-main')
|
||||
|
||||
condition = 'not obj.connected'
|
||||
iwd_ns0_1.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
wd_ns0.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
# Attempt a connection to the same AP that iwd_main is connected to
|
||||
# using the same static config. The new client's ACD client should
|
||||
# detect an IP conflict and not allow the device to reach the
|
||||
# "connected" state although the DBus .Connect call will succeed.
|
||||
with self.assertRaises(iwd.FailedEx):
|
||||
ordered_network.network_object.connect(timeout=500)
|
||||
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
iwd_ns0_1.wait_for_object_condition(dev2, condition, max_wait=21)
|
||||
|
||||
iwd_ns0_1.unregister_psk_agent(psk_agent_ns0_1)
|
||||
del dev2
|
||||
# Note: if any references to iwd_ns0_1 are left, the "del iwd_ns0_1"
|
||||
# will not kill the IWD process the iwd_ns0_2 initialization will raise
|
||||
# an exception. The iwd_ns0_1.wait_for_object_condition() above
|
||||
# creates a circular reference (which is not wrong in itself) and
|
||||
# gc.collect() gets rid of it. The actual solution is to eventually
|
||||
# avoid executing anything important in .__del__ (which is wrong.)
|
||||
gc.collect()
|
||||
del iwd_ns0_1
|
||||
|
||||
iwd_ns0_2 = IWD(True, namespace=ns0, iwd_storage_dir='/tmp/storage-ns0-2')
|
||||
psk_agent_ns0_2 = PSKAgent("secret123", namespace=ns0)
|
||||
iwd_ns0_2.register_psk_agent(psk_agent_ns0_2)
|
||||
dev2 = iwd_ns0_2.list_devices(1)[0]
|
||||
|
||||
ordered_network = dev2.get_ordered_network('ap-main')
|
||||
|
||||
condition = 'not obj.connected'
|
||||
iwd_ns0_2.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
# Connect to the same network from a dynamically configured client. We
|
||||
# block ICMP pings so that the DHCP server can't confirm that
|
||||
# 192.168.1.10 is in use by dev1 and if it assigns dev2 the lowest
|
||||
# available address, that's going to be 192.168.1.10. We also keep the
|
||||
# second client's netdev in a separate namespace so that the kernel
|
||||
# lets us assign the same IP. dev1's ACD implementation should then
|
||||
# stop using this address. Yes, a quite unrealistic scenario but this
|
||||
# lets us test our reaction to a conflict appearing after successful
|
||||
# initial setup.
|
||||
os.system("echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all")
|
||||
# Connect to the same network from a dynamically configured client. The
|
||||
# DHCP server doesn't know (even though dev1 announced itself) that
|
||||
# 192.168.1.10 is already in use and if it assigns dev2 the lowest
|
||||
# available address, that's going to be 192.168.1.10. dev1's ACD
|
||||
# implementation should then stop using this address.
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
iwd_ns0_2.wait_for_object_condition(dev2, condition)
|
||||
wd_ns0.wait_for_object_condition(dev2, condition)
|
||||
|
||||
iwd_main.wait(1)
|
||||
wd.wait(1)
|
||||
# Check dev1 is now disconnected or without its IPv4 address
|
||||
if dev1.state == iwd.DeviceState.connected:
|
||||
testutil.test_ip_address_match(dev1.name, None)
|
||||
@ -142,9 +104,9 @@ class Test(unittest.TestCase):
|
||||
dev2.disconnect()
|
||||
|
||||
condition = 'not obj.connected'
|
||||
iwd_main.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
iwd_main.unregister_psk_agent(psk_agent_main)
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@ -165,8 +127,7 @@ class Test(unittest.TestCase):
|
||||
cls.dhcpd_pid = ctx.start_process(['dhcpd', '-f', '-cf', '/tmp/dhcpd.conf',
|
||||
'-lf', '/tmp/dhcpd.leases',
|
||||
hapd.ifname], cleanup=remove_lease)
|
||||
IWD.copy_to_storage('static.psk', '/tmp/storage-main', 'ap-main.psk')
|
||||
IWD.copy_to_storage('static.psk', '/tmp/storage-ns0-1', 'ap-main.psk')
|
||||
IWD.copy_to_storage('static.psk', '/tmp/storage', 'ap-main.psk')
|
||||
|
||||
cls.orig_path = os.environ['PATH']
|
||||
os.environ['PATH'] = '/tmp/test-bin:' + os.environ['PATH']
|
||||
@ -175,7 +136,7 @@ class Test(unittest.TestCase):
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.dhcpd_pid.kill()
|
||||
os.system('rm -rf /tmp/resolvconf.log /tmp/test-bin /tmp/storage-*')
|
||||
os.system('rm -rf /tmp/resolvconf.log /tmp/test-bin /tmp/storage')
|
||||
os.environ['PATH'] = cls.orig_path
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,78 +0,0 @@
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def connect_failure(self, ex):
|
||||
self.failure_triggered = True
|
||||
|
||||
def test_netconfig_timeout(self):
|
||||
IWD.copy_to_storage('autoconnect.psk', name='ap-ns1.psk')
|
||||
|
||||
wd = IWD(True)
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
ordered_network = device.get_ordered_network('ap-ns1')
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
self.failure_triggered = False
|
||||
|
||||
# Set our error handler here so we can check if it fails
|
||||
ordered_network.network_object.connect(
|
||||
wait=False,
|
||||
timeout=1000,
|
||||
error_handler=self.connect_failure
|
||||
)
|
||||
|
||||
# IWD should attempt to try both BSS's with both failing netconfig.
|
||||
# Then the autoconnect list should be exhausted, and IWD should
|
||||
# transition to a disconnected state, then proceed to full autoconnect.
|
||||
device.wait_for_event("netconfig-failed", timeout=1000)
|
||||
device.wait_for_event("netconfig-failed", timeout=1000)
|
||||
device.wait_for_event("disconnected")
|
||||
|
||||
device.wait_for_event("autoconnect_full")
|
||||
|
||||
# The connect call should have failed
|
||||
self.assertTrue(self.failure_triggered)
|
||||
|
||||
condition = "obj.scanning"
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
condition = "not obj.scanning"
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# IWD should attempt to connect, but it will of course fail again.
|
||||
device.wait_for_event("netconfig-failed", timeout=1000)
|
||||
|
||||
device.disconnect()
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.orig_path = os.environ['PATH']
|
||||
os.environ['PATH'] = '/tmp/test-bin:' + os.environ['PATH']
|
||||
IWD.copy_to_storage('resolvconf', '/tmp/test-bin')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
os.system('rm -rf /tmp/radvd.conf /tmp/resolvconf.log /tmp/test-bin')
|
||||
os.environ['PATH'] = cls.orig_path
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,2 +0,0 @@
|
||||
[Security]
|
||||
Passphrase=EasilyGuessedPassword
|
@ -1,41 +0,0 @@
|
||||
hw_mode=g
|
||||
channel=1
|
||||
ssid=TestFT
|
||||
utf8_ssid=1
|
||||
ctrl_interface=/var/run/hostapd
|
||||
|
||||
r1_key_holder=120000000001
|
||||
nas_identifier=dummy1
|
||||
|
||||
wpa=2
|
||||
# Can support WPA-PSK and FT-PSK (space separated list) and/or EAP at the same
|
||||
# time but we want to force FT
|
||||
wpa_key_mgmt=FT-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=EasilyGuessedPassword
|
||||
ieee80211w=1
|
||||
rsn_preauth=1
|
||||
rsn_preauth_interfaces=lo
|
||||
disable_pmksa_caching=0
|
||||
# Allow PMK cache to be shared opportunistically among configured interfaces
|
||||
# and BSSes (i.e., all configurations within a single hostapd process).
|
||||
okc=1
|
||||
mobility_domain=1234
|
||||
reassociation_deadline=60000
|
||||
r0kh=12:00:00:00:00:01 dummy1 000102030405060708090a0b0c0d0e0f
|
||||
r0kh=12:00:00:00:00:02 dummy2 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:01 00:00:00:00:00:01 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:02 00:00:00:00:00:02 000102030405060708090a0b0c0d0e0f
|
||||
# Push mode only needed for 8021x, not PSK mode since msk already known
|
||||
pmk_r1_push=0
|
||||
# Allow locally generated FT response so we don't have to configure push/pull
|
||||
# between BSSes running as separate hostapd processes as in the test-runner
|
||||
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
|
||||
# CONFIG_BRIDGE enabled in the kernel.
|
||||
ft_psk_generate_local=1
|
||||
rkh_pull_timeout=50
|
||||
ft_over_ds=0
|
||||
ap_table_expiration_time=36000
|
||||
ap_table_max_size=10
|
||||
rrm_neighbor_report=1
|
||||
ocv=1
|
@ -1,41 +0,0 @@
|
||||
hw_mode=g
|
||||
channel=2
|
||||
ssid=TestFT
|
||||
utf8_ssid=1
|
||||
ctrl_interface=/var/run/hostapd
|
||||
|
||||
r1_key_holder=120000000002
|
||||
nas_identifier=dummy2
|
||||
|
||||
wpa=2
|
||||
# Can support WPA-PSK and FT-PSK (space separated list) and/or EAP at the same
|
||||
# time but we want to force FT
|
||||
wpa_key_mgmt=FT-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=EasilyGuessedPassword
|
||||
ieee80211w=1
|
||||
rsn_preauth=1
|
||||
rsn_preauth_interfaces=lo
|
||||
disable_pmksa_caching=0
|
||||
# Allow PMK cache to be shared opportunistically among configured interfaces
|
||||
# and BSSes (i.e., all configurations within a single hostapd process).
|
||||
okc=1
|
||||
mobility_domain=1234
|
||||
reassociation_deadline=60000
|
||||
r0kh=12:00:00:00:00:01 dummy1 000102030405060708090a0b0c0d0e0f
|
||||
r0kh=12:00:00:00:00:02 dummy2 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:01 00:00:00:00:00:01 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:02 00:00:00:00:00:02 000102030405060708090a0b0c0d0e0f
|
||||
# Push mode only needed for 8021x, not PSK mode since msk already known
|
||||
pmk_r1_push=0
|
||||
# Allow locally generated FT response so we don't have to configure push/pull
|
||||
# between BSSes running as separate hostapd processes as in the test-runner
|
||||
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
|
||||
# CONFIG_BRIDGE enabled in the kernel.
|
||||
ft_psk_generate_local=1
|
||||
rkh_pull_timeout=50
|
||||
ft_over_ds=0
|
||||
ap_table_expiration_time=36000
|
||||
ap_table_max_size=10
|
||||
rrm_neighbor_report=1
|
||||
ocv=1
|
@ -1,8 +0,0 @@
|
||||
[SETUP]
|
||||
num_radios=3
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ft-psk-ccmp-1.conf
|
||||
rad1=ft-psk-ccmp-2.conf
|
@ -1,3 +0,0 @@
|
||||
[General]
|
||||
EnableNetworkConfiguration=true
|
||||
RoamRetryInterval=1
|
@ -1,91 +0,0 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys, os
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from iwd import DeviceState
|
||||
from hwsim import Hwsim
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_roam_before_netconfig(self):
|
||||
wd = IWD(True)
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
device.get_ordered_network('TestFT', full_scan=True)
|
||||
device.connect_bssid(self.bss_hostapd[1].bssid, wait=False)
|
||||
|
||||
self.bss_hostapd[1].wait_for_event(f'AP-STA-CONNECTED {device.address}')
|
||||
device.wait_for_event("connecting (netconfig)")
|
||||
|
||||
roam_to = 0
|
||||
roam_from = 1
|
||||
|
||||
# Roam back and forth, ensuring that the state transitions between
|
||||
# roaming and connecting (netconfig).
|
||||
for _ in range(0, 5):
|
||||
self.rules[roam_to].signal = -2000
|
||||
self.rules[roam_from].signal = -8000
|
||||
|
||||
# Station should internally transition to roaming, but remain in a
|
||||
# connecting state on DBus
|
||||
device.wait_for_event("ft-roaming")
|
||||
self.assertEqual(device.state, DeviceState.connecting)
|
||||
|
||||
self.bss_hostapd[roam_to].wait_for_event(f'AP-STA-CONNECTED {device.address}')
|
||||
device.wait_for_event("connecting (netconfig)")
|
||||
|
||||
tmp = roam_from
|
||||
roam_from = roam_to
|
||||
roam_to = tmp
|
||||
|
||||
self.bss_hostapd[roam_from].deauthenticate(device.address)
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def tearDown(self):
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hwsim = Hwsim()
|
||||
|
||||
IWD.copy_to_storage('TestFT.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
|
||||
HostapdCLI(config='ft-psk-ccmp-2.conf') ]
|
||||
|
||||
rule0 = hwsim.rules.create()
|
||||
rule0.source = cls.bss_hostapd[0].bssid
|
||||
rule0.signal = -6000
|
||||
rule0.enabled = True
|
||||
|
||||
rule1 = hwsim.rules.create()
|
||||
rule1.source = cls.bss_hostapd[1].bssid
|
||||
rule1.signal = -2000
|
||||
rule1.enabled = True
|
||||
|
||||
cls.rules = [rule0, rule1]
|
||||
|
||||
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
|
||||
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
|
||||
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.bss_hostapd = None
|
||||
cls.rules = None
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -47,6 +47,11 @@ class Test(unittest.TestCase):
|
||||
|
||||
# Normal success case
|
||||
def test_owe_transition(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000f1000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
self.hapd_owe2.disable()
|
||||
self.hapd_open2.disable()
|
||||
|
||||
@ -54,8 +59,15 @@ class Test(unittest.TestCase):
|
||||
|
||||
# Normal success case
|
||||
def test_owe_transition_multi_network(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000f1000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
self.hapd_open2.set_value('vendor_elements', 'dd17506f9a1c02000000f1000c6f77652d68696464656e2d32')
|
||||
self.hapd_open2.set_value('ssid', 'transition-2')
|
||||
self.hapd_open2.reload()
|
||||
self.hapd_owe2.set_value('vendor_elements', 'dd17506f9a1c02000000f0000c7472616e736974696f6e2d32')
|
||||
self.hapd_owe2.set_value('ssid', 'owe-hidden-2')
|
||||
self.hapd_owe2.reload()
|
||||
|
||||
@ -63,6 +75,11 @@ class Test(unittest.TestCase):
|
||||
|
||||
# Two pairs of open/OWE BSS's (OWE BSS's have different SSIDs) */
|
||||
def test_owe_transition_multi_bss(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000f1000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
self.hapd_open2.set_value('vendor_elements', 'dd17506f9a1c02000000f3000c6f77652d68696464656e2d32')
|
||||
self.hapd_open2.set_value('ssid', 'transition')
|
||||
self.hapd_open2.reload()
|
||||
@ -74,6 +91,11 @@ class Test(unittest.TestCase):
|
||||
|
||||
# Two pairs of open/OWE BSS's (OWE BSS's have same SSID) */
|
||||
def test_owe_transition_multi_bss_same_ssid(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000f1000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
self.hapd_open2.set_value('vendor_elements', 'dd15506f9a1c02000000f3000a6f77652d68696464656e')
|
||||
self.hapd_open2.set_value('ssid', 'transition')
|
||||
self.hapd_open2.reload()
|
||||
@ -85,6 +107,11 @@ class Test(unittest.TestCase):
|
||||
|
||||
# Normal success autoconnect case
|
||||
def test_owe_transition_autoconnect(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000f1000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
self.hapd_owe2.disable()
|
||||
self.hapd_open2.disable()
|
||||
|
||||
@ -97,6 +124,8 @@ class Test(unittest.TestCase):
|
||||
def test_owe_transition_invalid_open_bssid(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000ff000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
self.hapd_owe2.disable()
|
||||
self.hapd_open2.disable()
|
||||
@ -106,6 +135,8 @@ class Test(unittest.TestCase):
|
||||
# OWE BSS has invalid BSSID in OWE transition element
|
||||
# Expected connection to Open BSS
|
||||
def test_owe_transition_invalid_owe_bssid(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000f1000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000ff000a7472616e736974696f6e')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
@ -117,6 +148,8 @@ class Test(unittest.TestCase):
|
||||
# No OWE hidden network exists
|
||||
# Expected connection to Open BSS
|
||||
def test_owe_transition_no_hidden_found(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000f1000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.disable()
|
||||
|
||||
self.hapd_owe2.disable()
|
||||
@ -127,6 +160,11 @@ class Test(unittest.TestCase):
|
||||
# Directly connect to valid OWE hidden network
|
||||
# Expected connection failure
|
||||
def test_owe_transition_connect_hidden_valid(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000f1000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
self.hapd_owe2.disable()
|
||||
self.hapd_open2.disable()
|
||||
|
||||
@ -151,6 +189,7 @@ class Test(unittest.TestCase):
|
||||
def test_owe_transition_band_info(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd17506f9a1c02000000f1000a6f77652d68696464656e5103')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.set_value('channel', '3')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
@ -162,6 +201,7 @@ class Test(unittest.TestCase):
|
||||
def test_owe_transition_wrong_band_info(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd17506f9a1c02000000f1000a6f77652d68696464656e5102')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.set_value('channel', '3')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
@ -172,6 +212,11 @@ class Test(unittest.TestCase):
|
||||
|
||||
# OWE Transition pair + additional open network with the same SSID
|
||||
def test_owe_transition_extra_open(self):
|
||||
self.hapd_open.set_value('vendor_elements', 'dd15506f9a1c02000000f1000a6f77652d68696464656e')
|
||||
self.hapd_open.reload()
|
||||
self.hapd_owe.set_value('vendor_elements', 'dd15506f9a1c02000000f0000a7472616e736974696f6e')
|
||||
self.hapd_owe.reload()
|
||||
|
||||
self.hapd_open2.set_value('ssid', 'transition')
|
||||
self.hapd_open2.reload()
|
||||
|
||||
@ -190,19 +235,17 @@ class Test(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
self.hapd_owe = HostapdCLI(config='ssidOWE.conf')
|
||||
self.hapd_owe.default()
|
||||
self.hapd_open = HostapdCLI(config='ssidOpen.conf')
|
||||
self.hapd_open.default()
|
||||
self.hapd_owe2 = HostapdCLI(config='ssidOWE-2.conf')
|
||||
self.hapd_owe2.default()
|
||||
self.hapd_open2 = HostapdCLI(config='ssidOpen-2.conf')
|
||||
self.hapd_open2.default()
|
||||
|
||||
self.hwsim = Hwsim()
|
||||
|
||||
def tearDown(self):
|
||||
IWD.clear_storage()
|
||||
|
||||
self.hapd_owe.set_value('channel', '1')
|
||||
|
||||
self.wd = None
|
||||
self.hapd_open = None
|
||||
self.hapd_owe = None
|
||||
|
@ -7,5 +7,3 @@ ieee80211w=1
|
||||
wpa=2
|
||||
wpa_key_mgmt=OWE
|
||||
rsn_pairwise=CCMP
|
||||
|
||||
vendor_elements=dd17506f9a1c02000000f0000c7472616e736974696f6e2d32
|
||||
|
@ -7,7 +7,6 @@ ieee80211w=1
|
||||
wpa=2
|
||||
wpa_key_mgmt=OWE
|
||||
rsn_pairwise=CCMP
|
||||
vendor_elements=dd15506f9a1c02000000f0000a7472616e736974696f6e
|
||||
|
||||
# You would conventionally use these options but hostapd does not include an
|
||||
# IE for the OWE network, hence vendor_elements must be used directly
|
||||
|
@ -1,4 +1,3 @@
|
||||
channel=1
|
||||
ssid=transition-2
|
||||
bssid=02:00:00:00:f2:00
|
||||
vendor_elements=dd17506f9a1c02000000f1000c6f77652d68696464656e2d32
|
||||
|
@ -1,7 +1,6 @@
|
||||
channel=1
|
||||
ssid=transition
|
||||
bssid=02:00:00:00:f0:00
|
||||
vendor_elements=dd15506f9a1c02000000f1000a6f77652d68696464656e
|
||||
|
||||
# You would conventionally use these options but hostapd does not include an
|
||||
# IE for the OWE network, hence vendor_elements must be used directly
|
||||
|
@ -53,6 +53,9 @@ class Test(unittest.TestCase):
|
||||
|
||||
device.roam(hapd1.bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_change(device, from_condition, to_condition)
|
||||
@ -64,39 +67,6 @@ class Test(unittest.TestCase):
|
||||
self.assertRaises(Exception, testutil.test_ifaces_connected,
|
||||
(hapd0.ifname, device.name, True, True))
|
||||
|
||||
def test_auto_default_group(self):
|
||||
wd = IWD()
|
||||
hapd = HostapdCLI(config='ssidOWE-1.conf')
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
device.get_ordered_network('ssidOWE')
|
||||
|
||||
device.connect_bssid(hapd.bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# Should have rejected group 20, but still connected on 19
|
||||
self.assertEqual(device.event_ocurred("ecc-group-rejected"), True)
|
||||
|
||||
testutil.test_iface_operstate()
|
||||
testutil.test_ifaces_connected(device.name, hapd.ifname)
|
||||
|
||||
device.disconnect()
|
||||
|
||||
device.connect_bssid(hapd.bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# IWD should have used the default group, no rejection
|
||||
self.assertEqual(device.event_ocurred("ecc-group-rejected"), False)
|
||||
|
||||
testutil.test_iface_operstate()
|
||||
testutil.test_ifaces_connected(device.name, hapd.ifname)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
@ -1,114 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def validate_connection(self, wd, ssid, hostapd, expected_group):
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
self.assertIsNotNone(devices)
|
||||
device = devices[0]
|
||||
|
||||
device.disconnect()
|
||||
|
||||
network = device.get_ordered_network(ssid, full_scan=True)
|
||||
|
||||
self.assertEqual(network.type, NetworkType.psk)
|
||||
|
||||
network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
wd.wait(2)
|
||||
|
||||
testutil.test_iface_operstate(intf=device.name)
|
||||
testutil.test_ifaces_connected(if0=device.name, if1=hostapd.ifname)
|
||||
|
||||
# Initial connection PMKSA should not be used. So we should see the
|
||||
# SAE group set.
|
||||
sta_status = hostapd.sta_status(device.address)
|
||||
self.assertEqual(int(sta_status["sae_group"]), expected_group)
|
||||
|
||||
device.disconnect()
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(network.network_object, condition)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
network.network_object.connect(wait=False)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
wd.wait(2)
|
||||
|
||||
testutil.test_iface_operstate(intf=device.name)
|
||||
testutil.test_ifaces_connected(if0=device.name, if1=hostapd.ifname)
|
||||
|
||||
# Having connected once prior we should have a PMKSA and SAE should not
|
||||
# have been used.
|
||||
sta_status = hostapd.sta_status(device.address)
|
||||
self.assertNotIn("sae_group", sta_status.keys())
|
||||
|
||||
device.disconnect()
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(network.network_object, condition)
|
||||
|
||||
hostapd.pmksa_flush()
|
||||
|
||||
wd.wait(5)
|
||||
|
||||
network.network_object.connect()
|
||||
|
||||
device.wait_for_event("pmksa-invalid-pmkid")
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
wd.wait(2)
|
||||
|
||||
testutil.test_iface_operstate(intf=device.name)
|
||||
testutil.test_ifaces_connected(if0=device.name, if1=hostapd.ifname)
|
||||
|
||||
# Manually flushing the PMKSA from the AP then reconnecting we should
|
||||
# have failed (INVALID_PMKID) then retried the same BSS with SAE, not
|
||||
# PMKSA.
|
||||
sta_status = hostapd.sta_status(device.address)
|
||||
self.assertEqual(int(sta_status["sae_group"]), expected_group)
|
||||
|
||||
def test_pmksa_sae(self):
|
||||
self.hostapd.wait_for_event("AP-ENABLED")
|
||||
self.validate_connection(self.wd, "ssidSAE", self.hostapd, 19)
|
||||
|
||||
def setUp(self):
|
||||
self.hostapd.default()
|
||||
self.wd = IWD(True)
|
||||
|
||||
def tearDown(self):
|
||||
self.wd.clear_storage()
|
||||
self.wd = None
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.hostapd = HostapdCLI(config='ssidSAE.conf')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,7 +0,0 @@
|
||||
[SETUP]
|
||||
num_radios=2
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssidSAE.conf
|
@ -1,12 +0,0 @@
|
||||
hw_mode=g
|
||||
channel=1
|
||||
ssid=ssidSAE
|
||||
|
||||
wpa=2
|
||||
wpa_key_mgmt=SAE
|
||||
wpa_pairwise=CCMP
|
||||
sae_password=secret123
|
||||
sae_groups=19
|
||||
ieee80211w=2
|
||||
sae_pwe=0
|
||||
rsn_preauth=1
|
@ -13,7 +13,7 @@ from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def validate_connection(self, wd, over_ds=False, pkt_loss=False):
|
||||
def validate_connection(self, wd, over_ds=False):
|
||||
device = wd.list_devices(1)[0]
|
||||
|
||||
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
|
||||
@ -41,16 +41,10 @@ class Test(unittest.TestCase):
|
||||
if over_ds:
|
||||
self.rule0.enabled = True
|
||||
|
||||
if pkt_loss:
|
||||
# Drop all data frames
|
||||
self.rule1.enabled = True
|
||||
# Set the current BSS signal lower so we have roam candidates
|
||||
self.rule2.enabled = True
|
||||
# Send 100 packets (to be dropped), should trigger beacon loss
|
||||
testutil.tx_packets(device.name, self.bss_hostapd[0].ifname, 100)
|
||||
device.wait_for_event('packet-loss-roam', timeout=60)
|
||||
else:
|
||||
device.roam(self.bss_hostapd[1].bssid)
|
||||
device.roam(self.bss_hostapd[1].bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# Check that iwd is on BSS 1 once out of roaming state and doesn't
|
||||
# go through 'disconnected', 'autoconnect', 'connecting' in between
|
||||
@ -58,10 +52,6 @@ class Test(unittest.TestCase):
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_change(device, from_condition, to_condition)
|
||||
|
||||
if pkt_loss:
|
||||
self.rule1.enabled = False
|
||||
self.rule2.enabled = False
|
||||
|
||||
self.bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
testutil.test_iface_operstate(device.name)
|
||||
@ -73,6 +63,9 @@ class Test(unittest.TestCase):
|
||||
|
||||
device.roam(self.bss_hostapd[0].bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# Check that iwd is on BSS 0 once out of roaming state and doesn't
|
||||
# go through 'disconnected', 'autoconnect', 'connecting' in between
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
@ -91,32 +84,53 @@ class Test(unittest.TestCase):
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def test_ft_psk(self):
|
||||
self.validate_connection(self.wd)
|
||||
wd = IWD(True)
|
||||
|
||||
def test_ft_psk_over_ds(self):
|
||||
self.bss_hostapd[0].set_value('ft_over_ds', '1')
|
||||
self.bss_hostapd[0].set_value('wpa_key_mgmt', 'FT-PSK')
|
||||
self.bss_hostapd[0].set_value('ft_over_ds', '0')
|
||||
self.bss_hostapd[0].set_value('ocv', '1')
|
||||
self.bss_hostapd[0].reload()
|
||||
self.bss_hostapd[0].wait_for_event("AP-ENABLED")
|
||||
|
||||
self.bss_hostapd[1].set_value('ft_over_ds', '1')
|
||||
self.bss_hostapd[1].set_value('wpa_key_mgmt', 'FT-PSK')
|
||||
self.bss_hostapd[1].set_value('ft_over_ds', '0')
|
||||
self.bss_hostapd[0].set_value('ocv', '1')
|
||||
self.bss_hostapd[1].reload()
|
||||
self.bss_hostapd[1].wait_for_event("AP-ENABLED")
|
||||
|
||||
self.validate_connection(self.wd, over_ds=True)
|
||||
self.validate_connection(wd)
|
||||
|
||||
def test_ft_psk_over_ds(self):
|
||||
wd = IWD(True)
|
||||
|
||||
self.bss_hostapd[0].set_value('wpa_key_mgmt', 'FT-PSK')
|
||||
self.bss_hostapd[0].set_value('ft_over_ds', '1')
|
||||
self.bss_hostapd[0].set_value('ocv', '1')
|
||||
self.bss_hostapd[0].reload()
|
||||
self.bss_hostapd[0].wait_for_event("AP-ENABLED")
|
||||
|
||||
self.bss_hostapd[1].set_value('wpa_key_mgmt', 'FT-PSK')
|
||||
self.bss_hostapd[1].set_value('ft_over_ds', '1')
|
||||
self.bss_hostapd[1].set_value('ocv', '1')
|
||||
self.bss_hostapd[1].reload()
|
||||
self.bss_hostapd[1].wait_for_event("AP-ENABLED")
|
||||
|
||||
self.validate_connection(wd, over_ds=True)
|
||||
|
||||
def test_reassociate_psk(self):
|
||||
wd = IWD(True)
|
||||
|
||||
self.bss_hostapd[0].set_value('wpa_key_mgmt', 'WPA-PSK')
|
||||
self.bss_hostapd[0].set_value('ft_over_ds', '0')
|
||||
self.bss_hostapd[0].reload()
|
||||
self.bss_hostapd[0].wait_for_event("AP-ENABLED")
|
||||
|
||||
self.bss_hostapd[1].set_value('wpa_key_mgmt', 'WPA-PSK')
|
||||
self.bss_hostapd[1].set_value('ft_over_ds', '0')
|
||||
self.bss_hostapd[1].reload()
|
||||
self.bss_hostapd[1].wait_for_event("AP-ENABLED")
|
||||
|
||||
self.validate_connection(self.wd)
|
||||
|
||||
def test_roam_packet_loss(self):
|
||||
self.validate_connection(self.wd, pkt_loss=True)
|
||||
self.validate_connection(wd)
|
||||
|
||||
def tearDown(self):
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
|
||||
@ -125,17 +139,6 @@ class Test(unittest.TestCase):
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
|
||||
|
||||
self.rule0.enabled = False
|
||||
self.rule1.enabled = False
|
||||
self.rule2.enabled = False
|
||||
|
||||
for hapd in self.bss_hostapd:
|
||||
hapd.default()
|
||||
|
||||
self.wd.stop()
|
||||
self.wd = None
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@ -145,41 +148,42 @@ class Test(unittest.TestCase):
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
|
||||
HostapdCLI(config='ft-psk-ccmp-2.conf') ]
|
||||
|
||||
unused = HostapdCLI(config='ft-psk-ccmp-3.conf')
|
||||
unused.disable()
|
||||
|
||||
rad0 = hwsim.get_radio('rad0')
|
||||
rad3 = hwsim.get_radio('rad3')
|
||||
rad2 = hwsim.get_radio('rad2')
|
||||
|
||||
cls.rule0 = hwsim.rules.create()
|
||||
cls.rule0.source = rad3.addresses[0]
|
||||
cls.rule0.source = rad2.addresses[0]
|
||||
cls.rule0.bidirectional = True
|
||||
cls.rule0.signal = -2000
|
||||
cls.rule0.prefix = 'b0'
|
||||
cls.rule0.drop = True
|
||||
|
||||
cls.rule1 = hwsim.rules.create()
|
||||
cls.rule1.source = rad3.addresses[0]
|
||||
cls.rule1.prefix = '08'
|
||||
cls.rule1.drop = True
|
||||
# Set interface addresses to those expected by hostapd config files
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" down')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" addr 12:00:00:00:00:01 up')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" down')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" addr 12:00:00:00:00:02 up')
|
||||
|
||||
cls.rule2 = hwsim.rules.create()
|
||||
cls.rule2.source = rad0.addresses[0]
|
||||
cls.rule2.signal = -7000
|
||||
cls.bss_hostapd[0].reload()
|
||||
cls.bss_hostapd[0].wait_for_event("AP-ENABLED")
|
||||
cls.bss_hostapd[1].reload()
|
||||
cls.bss_hostapd[1].wait_for_event("AP-ENABLED")
|
||||
|
||||
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
|
||||
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
|
||||
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
# Fill in the neighbor AP tables in both BSSes. By default each
|
||||
# instance knows only about current BSS, even inside one hostapd
|
||||
# process.
|
||||
# FT still works without the neighbor AP table but neighbor reports
|
||||
# have to be disabled in the .conf files
|
||||
cls.bss_hostapd[0].set_neighbor('12:00:00:00:00:02', 'TestFT',
|
||||
'1200000000028f0000005102060603000000')
|
||||
cls.bss_hostapd[1].set_neighbor('12:00:00:00:00:01', 'TestFT',
|
||||
'1200000000018f0000005101060603000000')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.bss_hostapd = None
|
||||
cls.rule0.enabled = False
|
||||
cls.rule0.remove()
|
||||
cls.rule1.remove()
|
||||
cls.rule2.remove()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
||||
|
@ -1,112 +0,0 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys, os
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from hwsim import Hwsim
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def validate_connection(self, wd):
|
||||
device = wd.list_devices(1)[0]
|
||||
|
||||
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
self.assertFalse(self.bss_hostapd[0].list_sta())
|
||||
self.assertFalse(self.bss_hostapd[1].list_sta())
|
||||
|
||||
device.connect_bssid(self.bss_hostapd[0].bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
testutil.test_iface_operstate(device.name)
|
||||
testutil.test_ifaces_connected(self.bss_hostapd[0].ifname, device.name)
|
||||
self.assertRaises(Exception, testutil.test_ifaces_connected,
|
||||
(self.bss_hostapd[1].ifname, device.name, True, True))
|
||||
|
||||
self.rule0.enabled = True
|
||||
|
||||
device.roam(self.bss_hostapd[1].bssid)
|
||||
|
||||
device.clear_events()
|
||||
device.wait_for_event("handshake-started")
|
||||
self.bss_hostapd[1].deauthenticate(device.address, reason=15, test=1)
|
||||
|
||||
# Check that iwd is on BSS 1 once out of roaming state and doesn't
|
||||
# go through 'disconnected', 'autoconnect', 'connecting' in between
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.disconnected'
|
||||
wd.wait_for_object_change(device, from_condition, to_condition)
|
||||
|
||||
def test_disconnect_during_handshake(self):
|
||||
self.bss_hostapd[0].set_value('wpa_key_mgmt', 'WPA-PSK')
|
||||
self.bss_hostapd[0].reload()
|
||||
self.bss_hostapd[0].wait_for_event("AP-ENABLED")
|
||||
|
||||
self.bss_hostapd[1].set_value('wpa_key_mgmt', 'WPA-PSK')
|
||||
self.bss_hostapd[1].reload()
|
||||
self.bss_hostapd[1].wait_for_event("AP-ENABLED")
|
||||
|
||||
self.validate_connection(self.wd)
|
||||
|
||||
def tearDown(self):
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
|
||||
|
||||
for hapd in self.bss_hostapd:
|
||||
hapd.default()
|
||||
|
||||
self.wd.stop()
|
||||
self.wd = None
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hwsim = Hwsim()
|
||||
|
||||
IWD.copy_to_storage('TestFT.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
|
||||
HostapdCLI(config='ft-psk-ccmp-2.conf') ]
|
||||
|
||||
unused = HostapdCLI(config='ft-psk-ccmp-3.conf')
|
||||
unused.disable()
|
||||
|
||||
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
|
||||
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
|
||||
|
||||
rad1 = hwsim.get_radio('rad1')
|
||||
|
||||
cls.rule0 = hwsim.rules.create()
|
||||
cls.rule0.destination = rad1.addresses[0]
|
||||
cls.rule0.prefix = '08'
|
||||
cls.rule0.drop = True
|
||||
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.bss_hostapd = None
|
||||
cls.rule0.remove()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,255 +0,0 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import os, sys
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD
|
||||
from iwd import NetworkType, DeviceState
|
||||
from hwsim import Hwsim
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def connect(self, wd, device, hostapd):
|
||||
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
device.connect_bssid(hostapd.bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
hostapd.wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
testutil.test_iface_operstate(device.name)
|
||||
testutil.test_ifaces_connected(hostapd.ifname, device.name)
|
||||
|
||||
def verify_roam(self, wd, device, prev, new):
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_change(device, from_condition, to_condition)
|
||||
|
||||
new.wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
testutil.test_iface_operstate(device.name)
|
||||
testutil.test_ifaces_connected(new.ifname, device.name)
|
||||
self.assertRaises(Exception, testutil.test_ifaces_connected,
|
||||
(prev.ifname, device.name, True, True))
|
||||
|
||||
# FT-over-Air failure, should stay connected
|
||||
def test_ft_over_air_failure(self):
|
||||
self.rule2.enabled = True
|
||||
self.rule3.enabled = True
|
||||
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(self.wd, device, self.bss_hostapd[0])
|
||||
|
||||
self.rule0.enabled = True
|
||||
|
||||
# IWD should connect, then attempt a roam to BSS 1, which should fail...
|
||||
device.wait_for_event('ft-roam-failed', timeout=60)
|
||||
# ... but IWD should remain connected
|
||||
self.assertTrue(device.state == DeviceState.connected)
|
||||
|
||||
self.rule0.enabled = False
|
||||
|
||||
# IWD should then try BSS 2, and succeed
|
||||
device.wait_for_event('ft-roaming', timeout=60)
|
||||
self.verify_roam(self.wd, device, self.bss_hostapd[0], self.bss_hostapd[2])
|
||||
|
||||
self.bss_hostapd[2].deauthenticate(device.address)
|
||||
|
||||
# Tests that an associate even should cause a disconnect
|
||||
def test_ft_over_air_assoc_timeout(self):
|
||||
self.rule2.enabled = True
|
||||
self.rule3.enabled = True
|
||||
self.assoc_rule.enabled = True
|
||||
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(self.wd, device, self.bss_hostapd[0])
|
||||
|
||||
device.wait_for_event('ft-roaming', timeout=60)
|
||||
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# FT-over-Air failure with Invalid PMKID, should reassociate
|
||||
def test_ft_over_air_fallback(self):
|
||||
self.rule_bss0.signal = -8000
|
||||
self.rule_bss0.enabled = True
|
||||
self.rule_bss1.signal = -7500
|
||||
self.rule_bss1.enabled = True
|
||||
self.rule_bss2.signal = -6000
|
||||
self.rule_bss2.enabled = True
|
||||
|
||||
# This will cause this BSS to reject any FT roams as its unable to
|
||||
# get keys from other APs
|
||||
self.bss_hostapd[2].set_value('ft_psk_generate_local', '0')
|
||||
self.bss_hostapd[2].reload()
|
||||
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(self.wd, device, self.bss_hostapd[0])
|
||||
|
||||
# IWD should connect, then attempt a roam to BSS 1, which should
|
||||
# fail and cause a fallback to reassociation
|
||||
device.wait_for_event('ft-fallback-to-reassoc', timeout=60)
|
||||
device.wait_for_event('roaming', timeout=60)
|
||||
|
||||
self.verify_roam(self.wd, device, self.bss_hostapd[0], self.bss_hostapd[2])
|
||||
|
||||
# Trigger another roam
|
||||
self.rule_bss2.signal = -8000
|
||||
|
||||
device.wait_for_event('ft-roaming', timeout=60)
|
||||
|
||||
# Ensure an FT roam back to a properly configured AP works.
|
||||
self.verify_roam(self.wd, device, self.bss_hostapd[2], self.bss_hostapd[1])
|
||||
|
||||
self.bss_hostapd[1].deauthenticate(device.address)
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# FT-over-Air failure with Invalid PMKID. The ranking is such that other
|
||||
# FT candidates are available so it should FT elsewhere rather than
|
||||
# retry with reassociation
|
||||
def test_ft_over_air_fallback_retry_ft(self):
|
||||
self.rule_bss0.signal = -8000
|
||||
self.rule_bss0.enabled = True
|
||||
self.rule_bss1.signal = -7300
|
||||
self.rule_bss1.enabled = True
|
||||
self.rule_bss2.signal = -7100
|
||||
self.rule_bss2.enabled = True
|
||||
|
||||
# This will cause this BSS to reject any FT roams as its unable to
|
||||
# get keys from other APs
|
||||
self.bss_hostapd[2].set_value('ft_psk_generate_local', '0')
|
||||
self.bss_hostapd[2].reload()
|
||||
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(self.wd, device, self.bss_hostapd[0])
|
||||
|
||||
# IWD should connect, then attempt a roam to BSS 1, which should
|
||||
# fail and cause the rank to be re-computed. This should then put
|
||||
# bss 1 as the next candidate (since the FT factor is removed)
|
||||
device.wait_for_event('ft-fallback-to-reassoc', timeout=60)
|
||||
device.wait_for_event('ft-roaming', timeout=60)
|
||||
|
||||
self.verify_roam(self.wd, device, self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
|
||||
self.bss_hostapd[1].deauthenticate(device.address)
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def test_ft_deauth_before_association(self):
|
||||
self.rule2.enabled = True
|
||||
self.rule3.enabled = True
|
||||
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(self.wd, device, self.bss_hostapd[0])
|
||||
|
||||
device.wait_for_event('ft-authenticating', timeout=60)
|
||||
|
||||
self.bss_hostapd[1].deauthenticate(device.address)
|
||||
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
|
||||
def tearDown(self):
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
|
||||
|
||||
self.rule0.enabled = False
|
||||
self.rule1.enabled = False
|
||||
self.rule2.enabled = False
|
||||
self.rule3.enabled = False
|
||||
self.rule_bss0.enabled = False
|
||||
self.rule_bss1.enabled = False
|
||||
self.rule_bss2.enabled = False
|
||||
self.assoc_rule.enabled = False
|
||||
|
||||
for hapd in self.bss_hostapd:
|
||||
hapd.default()
|
||||
|
||||
self.wd.stop()
|
||||
self.wd = None
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hwsim = Hwsim()
|
||||
|
||||
IWD.copy_to_storage('TestFT.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
|
||||
HostapdCLI(config='ft-psk-ccmp-2.conf'),
|
||||
HostapdCLI(config='ft-psk-ccmp-3.conf') ]
|
||||
|
||||
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
|
||||
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
|
||||
cls.bss_hostapd[2].set_address('12:00:00:00:00:03')
|
||||
|
||||
# Drop Authenticate frames
|
||||
cls.rule0 = hwsim.rules.create()
|
||||
cls.rule0.source = hwsim.get_radio('rad1').addresses[0]
|
||||
cls.rule0.prefix = 'b0'
|
||||
cls.rule0.drop = True
|
||||
|
||||
# Drop Associate frames
|
||||
cls.assoc_rule = hwsim.rules.create()
|
||||
cls.assoc_rule.prefix = '20'
|
||||
cls.assoc_rule.drop = True
|
||||
|
||||
# Drop Action frames
|
||||
cls.rule1 = hwsim.rules.create()
|
||||
cls.rule1.bidirectional = True
|
||||
cls.rule1.prefix = 'd0'
|
||||
cls.rule1.drop = True
|
||||
|
||||
# Causes IWD to immediately roam away from BSS 0
|
||||
cls.rule2 = hwsim.rules.create()
|
||||
cls.rule2.source = hwsim.get_radio('rad0').addresses[0]
|
||||
cls.rule2.signal = -8000
|
||||
|
||||
# Causes IWD to first prefer BSS 1 to roam, then BSS 2.
|
||||
cls.rule3 = hwsim.rules.create()
|
||||
cls.rule3.source = hwsim.get_radio('rad2').addresses[0]
|
||||
cls.rule3.signal = -7000
|
||||
|
||||
cls.rule_bss0 = hwsim.rules.create()
|
||||
cls.rule_bss0.source = hwsim.get_radio('rad0').addresses[0]
|
||||
cls.rule_bss1 = hwsim.rules.create()
|
||||
cls.rule_bss1.source = hwsim.get_radio('rad1').addresses[0]
|
||||
cls.rule_bss2 = hwsim.rules.create()
|
||||
cls.rule_bss2.source = hwsim.get_radio('rad2').addresses[0]
|
||||
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.bss_hostapd = None
|
||||
cls.rule0.remove()
|
||||
cls.rule1.remove()
|
||||
cls.rule2.remove()
|
||||
cls.rule3.remove()
|
||||
cls.assoc_rule.remove()
|
||||
cls.rule_bss0.remove()
|
||||
cls.rule_bss1.remove()
|
||||
cls.rule_bss2.remove()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -13,7 +13,9 @@ wpa=2
|
||||
wpa_key_mgmt=FT-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=EasilyGuessedPassword
|
||||
ieee80211w=0
|
||||
wpa_ptk_rekey=30
|
||||
wpa_group_rekey=80
|
||||
ieee80211w=1
|
||||
rsn_preauth=1
|
||||
rsn_preauth_interfaces=lo
|
||||
disable_pmksa_caching=0
|
||||
@ -33,9 +35,7 @@ pmk_r1_push=0
|
||||
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
|
||||
# CONFIG_BRIDGE enabled in the kernel.
|
||||
ft_psk_generate_local=1
|
||||
rkh_pull_timeout=50
|
||||
ft_over_ds=0
|
||||
ap_table_expiration_time=36000
|
||||
ap_table_max_size=10
|
||||
rrm_neighbor_report=1
|
||||
ocv=1
|
||||
|
@ -13,7 +13,9 @@ wpa=2
|
||||
wpa_key_mgmt=FT-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=EasilyGuessedPassword
|
||||
ieee80211w=0
|
||||
wpa_ptk_rekey=30
|
||||
wpa_group_rekey=80
|
||||
ieee80211w=1
|
||||
rsn_preauth=1
|
||||
rsn_preauth_interfaces=lo
|
||||
disable_pmksa_caching=0
|
||||
@ -33,9 +35,7 @@ pmk_r1_push=0
|
||||
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
|
||||
# CONFIG_BRIDGE enabled in the kernel.
|
||||
ft_psk_generate_local=1
|
||||
rkh_pull_timeout=50
|
||||
ft_over_ds=0
|
||||
ap_table_expiration_time=36000
|
||||
ap_table_max_size=10
|
||||
rrm_neighbor_report=1
|
||||
ocv=1
|
||||
|
@ -1,41 +0,0 @@
|
||||
hw_mode=g
|
||||
channel=2
|
||||
ssid=TestFT
|
||||
utf8_ssid=1
|
||||
ctrl_interface=/var/run/hostapd
|
||||
|
||||
r1_key_holder=120000000002
|
||||
nas_identifier=dummy2
|
||||
|
||||
wpa=2
|
||||
# Can support WPA-PSK and FT-PSK (space separated list) and/or EAP at the same
|
||||
# time but we want to force FT
|
||||
wpa_key_mgmt=FT-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=EasilyGuessedPassword
|
||||
ieee80211w=0
|
||||
rsn_preauth=1
|
||||
rsn_preauth_interfaces=lo
|
||||
disable_pmksa_caching=0
|
||||
# Allow PMK cache to be shared opportunistically among configured interfaces
|
||||
# and BSSes (i.e., all configurations within a single hostapd process).
|
||||
okc=1
|
||||
mobility_domain=1234
|
||||
reassociation_deadline=60000
|
||||
r0kh=12:00:00:00:00:01 dummy1 000102030405060708090a0b0c0d0e0f
|
||||
r0kh=12:00:00:00:00:02 dummy2 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:01 00:00:00:00:00:01 000102030405060708090a0b0c0d0e0f
|
||||
r1kh=12:00:00:00:00:02 00:00:00:00:00:02 000102030405060708090a0b0c0d0e0f
|
||||
# Push mode only needed for 8021x, not PSK mode since msk already known
|
||||
pmk_r1_push=0
|
||||
# Allow locally generated FT response so we don't have to configure push/pull
|
||||
# between BSSes running as separate hostapd processes as in the test-runner
|
||||
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
|
||||
# CONFIG_BRIDGE enabled in the kernel.
|
||||
ft_psk_generate_local=1
|
||||
rkh_pull_timeout=50
|
||||
ft_over_ds=0
|
||||
ap_table_expiration_time=36000
|
||||
ap_table_max_size=10
|
||||
rrm_neighbor_report=1
|
||||
ocv=1
|
@ -1,9 +1,8 @@
|
||||
[SETUP]
|
||||
num_radios=4
|
||||
num_radios=3
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ft-psk-ccmp-1.conf
|
||||
rad1=ft-psk-ccmp-2.conf
|
||||
rad2=ft-psk-ccmp-3.conf
|
||||
|
@ -3,6 +3,3 @@ DisableMacAddressRandomization=true
|
||||
|
||||
[General]
|
||||
RoamRetryInterval=1
|
||||
|
||||
# For disconnect_during_handshake_test
|
||||
ManagementFrameProtection=0
|
||||
|
@ -14,7 +14,8 @@ class Test(unittest.TestCase):
|
||||
# Tests a crash reported where multiple roam scans combined with an AP
|
||||
# disconnect result in a crash getting scan results.
|
||||
#
|
||||
def validate(self, wd):
|
||||
def validate(self):
|
||||
wd = IWD(True)
|
||||
device = wd.list_devices(1)[0]
|
||||
|
||||
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
|
||||
@ -32,7 +33,7 @@ class Test(unittest.TestCase):
|
||||
# Since both BSS's have low signal, the roam should fail and trigger
|
||||
# another roam scan.
|
||||
device.wait_for_event('roam-scan-triggered', timeout=30)
|
||||
device.wait_for_event('no-roam-candidates', timeout=60)
|
||||
device.wait_for_event('no-roam-candidates', timeout=30)
|
||||
|
||||
# Hostapd sends disconnect
|
||||
self.bss_hostapd[0].disable()
|
||||
@ -42,15 +43,17 @@ class Test(unittest.TestCase):
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def test_ap_disconnect_no_neighbors(self):
|
||||
self.validate(self.wd)
|
||||
self.validate()
|
||||
|
||||
def test_ap_disconnect_neighbors(self):
|
||||
HostapdCLI.group_neighbors(*self.bss_hostapd)
|
||||
self.bss_hostapd[0].set_neighbor('12:00:00:00:00:02', 'TestFT',
|
||||
'1200000000028f0000005102060603000000')
|
||||
self.bss_hostapd[1].set_neighbor('12:00:00:00:00:01', 'TestFT',
|
||||
'1200000000018f0000005101060603000000')
|
||||
|
||||
self.validate(self.wd)
|
||||
self.validate()
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
self.bss_hostapd[0].reload()
|
||||
self.bss_hostapd[0].wait_for_event("AP-ENABLED")
|
||||
|
||||
@ -63,9 +66,6 @@ class Test(unittest.TestCase):
|
||||
self.bss_hostapd[0].remove_neighbor(self.bss_hostapd[1].bssid)
|
||||
self.bss_hostapd[1].remove_neighbor(self.bss_hostapd[0].bssid)
|
||||
|
||||
self.wd.stop()
|
||||
self.wd = None
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hwsim = Hwsim()
|
||||
@ -73,38 +73,29 @@ class Test(unittest.TestCase):
|
||||
IWD.copy_to_storage('TestFT.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
|
||||
HostapdCLI(config='ft-psk-ccmp-2.conf'),
|
||||
HostapdCLI(config='ft-psk-ccmp-3.conf') ]
|
||||
HostapdCLI(config='ft-psk-ccmp-2.conf') ]
|
||||
cls.bss_hostapd[1].disable()
|
||||
cls.bss_hostapd[2].disable()
|
||||
|
||||
cls.bss_hostapd[0].set_value('ocv', '0')
|
||||
cls.bss_hostapd[0].set_value('ieee80211w', '0')
|
||||
|
||||
rad0 = hwsim.get_radio('rad0')
|
||||
rad1 = hwsim.get_radio('rad1')
|
||||
|
||||
cls.rule0 = hwsim.rules.create()
|
||||
cls.rule0.source = rad0.addresses[0]
|
||||
cls.rule0.source = 'any'
|
||||
cls.rule0.bidirectional = True
|
||||
cls.rule0.signal = -8000
|
||||
cls.rule0.enabled = True
|
||||
|
||||
cls.rule1 = hwsim.rules.create()
|
||||
cls.rule1.source = rad1.addresses[0]
|
||||
cls.rule1.bidirectional = True
|
||||
cls.rule1.signal = -8500
|
||||
cls.rule1.enabled = True
|
||||
|
||||
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
|
||||
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
|
||||
# Set interface addresses to those expected by hostapd config files
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" down')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" addr 12:00:00:00:00:01 up')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" down')
|
||||
os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" addr 12:00:00:00:00:02 up')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.bss_hostapd = None
|
||||
cls.rule0.remove()
|
||||
cls.rule1.remove()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
||||
|
@ -17,7 +17,18 @@ class Test(unittest.TestCase):
|
||||
bss0_addr = bss_hostapd[0].bssid
|
||||
bss1_addr = bss_hostapd[1].bssid
|
||||
|
||||
HostapdCLI.group_neighbors(*bss_hostapd)
|
||||
# Fill in the neighbor AP tables in both BSSes. By default each
|
||||
# instance knows only about current BSS, even inside one hostapd
|
||||
# process.
|
||||
# Roaming still works without the neighbor AP table but neighbor
|
||||
# reports have to be disabled in the .conf files
|
||||
bss0_nr = ''.join(bss0_addr.split(':')) + \
|
||||
'8f0000005101060603000000'
|
||||
bss1_nr = ''.join(bss1_addr.split(':')) + \
|
||||
'8f0000005102060603000000'
|
||||
|
||||
bss_hostapd[0].set_neighbor(bss1_addr, 'TestPreauth', bss1_nr)
|
||||
bss_hostapd[1].set_neighbor(bss0_addr, 'TestPreauth', bss0_nr)
|
||||
|
||||
wd = IWD(True)
|
||||
|
||||
@ -48,6 +59,9 @@ class Test(unittest.TestCase):
|
||||
|
||||
device.roam(bss1_addr)
|
||||
|
||||
condition = 'obj.state == DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# TODO: verify that the PMK from preauthentication was used
|
||||
|
||||
# Check that iwd is on BSS 1 once out of roaming state and doesn't
|
||||
@ -72,6 +86,8 @@ class Test(unittest.TestCase):
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('TestPreauth.8021x')
|
||||
|
||||
os.system('ip link set lo up')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user