3
0
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.
master ... 1.29

317 changed files with 6612 additions and 23449 deletions

View File

@ -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
View File

@ -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

View File

@ -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
View File

@ -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.

View File

@ -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
View File

@ -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
View File

@ -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

View File

@ -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"

View File

@ -1,3 +0,0 @@
[Security]
Passphrase=secret123
PairwiseCiphers=CCMP

View File

@ -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):

View File

@ -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

View File

@ -1,2 +0,0 @@
[Security]
Passphrase=Password2

View File

@ -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__':

View File

@ -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')

View File

@ -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()

View File

@ -1,7 +1,5 @@
[SETUP]
num_radios=4
hwsim_medium=true
start_iwd=false
[HOSTAPD]
rad0=ssid1.conf

View File

@ -1,6 +0,0 @@
[General]
RoamThreshold=-72
CriticalRoamThreshold=-72
[Blacklist]
InitialAccessPointBusyTimeout=20

View File

@ -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)

View File

@ -1,2 +0,0 @@
[Security]
Passphrase=EasilyGuessedPassword

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,5 +0,0 @@
[Scan]
DisableMacAddressRandomization=true
[General]
RoamRetryInterval=1

View File

@ -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)

View File

@ -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):

View File

@ -1,2 +0,0 @@
[Blacklist]
InitialTimeout=0

View File

@ -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)

View File

@ -1,8 +0,0 @@
[SETUP]
num_radios=3
hwsim_medium=yes
start_iwd=no
[HOSTAPD]
rad0=ssidTKIP-1.conf
rad1=ssidTKIP-2.conf

View File

@ -1,7 +0,0 @@
hw_mode=g
channel=1
ssid=ssidTKIP
wpa=1
wpa_pairwise=TKIP
wpa_passphrase=secret123

View File

@ -1,7 +0,0 @@
hw_mode=g
channel=2
ssid=ssidTKIP
wpa=1
wpa_pairwise=TKIP
wpa_passphrase=secret123

View File

@ -1,5 +0,0 @@
[Security]
Passphrase=secret123
[Settings]
AutoConnect=False

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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()

View File

@ -1,2 +0,0 @@
[Security]
Passphrase=IncorrectPassphrase

View File

@ -1,5 +1,5 @@
hw_mode=g
channel=6
channel=1
ssid=ssidCCMP
wpa=2

View File

@ -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

View File

@ -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)

View File

@ -1,5 +1,2 @@
[Security]
Passphrase=secret123
[IPv4]
SendHostname=true

View File

@ -1,9 +0,0 @@
hw_mode=g
channel=6
ssid=ssidHidden
wpa=1
wpa_pairwise=TKIP
wpa_passphrase=secret123
ignore_broadcast_ssid=1

View File

@ -1,5 +0,0 @@
[Security]
Passphrase=secret123
[Settings]
Hidden=true

View File

@ -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)

View File

@ -3,4 +3,3 @@ ctrl_interface=/tmp/rad1-p2p-wpas
update_config=0
pmf=2
dpp_config_processing=2
p2p_disabled=1

View File

@ -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 = \
'''

View File

@ -1,5 +1,2 @@
[Security]
Passphrase=secret123
[General]
AutoConnect=false

View File

@ -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):

View File

@ -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):

View File

@ -11,3 +11,5 @@ fils_realm=example.com
disable_pmksa_caching=1
pwd_group=19
wpa_group_rekey=30
wpa_ptk_rekey=30

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -11,3 +11,5 @@ fils_realm=example.com
disable_pmksa_caching=1
pwd_group=19
wpa_group_rekey=30
wpa_ptk_rekey=30

View File

@ -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)

View File

@ -1,7 +0,0 @@
[SETUP]
num_radios=2
start_iwd=0
hwsim_medium=yes
[rad1]
reserve=true

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -2,7 +2,6 @@
num_radios=5
start_iwd=0
reg_domain=US
hwsim_medium=yes
[HOSTAPD]
rad0=ssidNew.conf

View File

@ -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

View File

@ -1,2 +0,0 @@
[IPv4]
SendHostname=true

View File

@ -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 == '}':

View File

@ -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)

View File

@ -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)

View File

@ -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__':

View File

@ -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)

View File

@ -1,2 +0,0 @@
[Security]
Passphrase=EasilyGuessedPassword

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,3 +0,0 @@
[General]
EnableNetworkConfiguration=true
RoamRetryInterval=1

View File

@ -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)

View File

@ -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

View File

@ -7,5 +7,3 @@ ieee80211w=1
wpa=2
wpa_key_mgmt=OWE
rsn_pairwise=CCMP
vendor_elements=dd17506f9a1c02000000f0000c7472616e736974696f6e2d32

View File

@ -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

View File

@ -1,4 +1,3 @@
channel=1
ssid=transition-2
bssid=02:00:00:00:f2:00
vendor_elements=dd17506f9a1c02000000f1000c6f77652d68696464656e2d32

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -1,7 +0,0 @@
[SETUP]
num_radios=2
start_iwd=0
hwsim_medium=yes
[HOSTAPD]
rad0=ssidSAE.conf

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -3,6 +3,3 @@ DisableMacAddressRandomization=true
[General]
RoamRetryInterval=1
# For disconnect_during_handshake_test
ManagementFrameProtection=0

View File

@ -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)

View File

@ -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