3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2025-08-02 17:37:22 +02:00

Compare commits

..

No commits in common. "master" and "1.22" have entirely different histories.
master ... 1.22

369 changed files with 9437 additions and 30567 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

13
.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
@ -42,8 +37,6 @@ wired/ead.service
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 +59,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 +67,3 @@ unit/*.log
unit/*.trs
test-suite.log
src/builtin.h
autotests/*/__pycache__
iwd-coverage.info
gcov

View File

@ -34,10 +34,3 @@ Matt Oberle <matt.r.oberle@gmail.com>
Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
Torsten Schmitz <noreply.torsten@gmail.com>
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>

234
ChangeLog
View File

@ -1,237 +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.
Add support for DeviceProvisioning API properties.
ver 1.28:
Fix issue with handling invalid EAPoL frames.
Fix issue with handling unexpectedly unencrypted EAP frames.
Fix issue with handling AlwaysRandomizeAddress/AddressOverride.
Fix issue with handling initial signal level notification.
Fix issue with handling sorting of scan requests.
Fix issue with handling frame type check in FT.
ver 1.27:
Fix issue with hidden networks on connection error.
Fix issue with directed roams if already trying to roam.
Fix issue with checking for connected in FT frame event.
ver 1.26:
Fix issue with handling BSS that changed frequency.
Fix issue with handling frequencies in neighbor report.
Fix issue with operating classes for 802.11ax standard.
Fix issue with enforcing of MFPR for 6 GHz frequencies.
Add support for band defined in the WiFi 6E amendment.
Add support for scanning while in AP mode.
ver 1.25:
Fix issue with handling abort of periodic scans.
Fix issue with handling connection when link goes down.
Fix issue with handling operating channel information.
Add support for encrypted network profile storage.
Add support for DPP initiating as a configurator.
ver 1.24:
Fix issue with handshake and missing rekeying support.
Fix issue with BSS ranking and zero signal strength.
Fix issue with setting OWE IE length correctly.
ver 1.23:
Fix issue with handling handshake offloading.
Fix issue with at_console and D-Bus policy.
ver 1.22:
Fix issue with handling periodic scanning.
Fix issue with handling scanning completion.

View File

@ -5,7 +5,7 @@ If you fixed a bug or you want to add support for something, patches are
welcome! The preferred method of submitting the patches to the project is by
email to the iwd mailing list:
iwd@lists.linux.dev
iwd@lists.01.org
In order to ease the inclusion of your patch, it's important to follow
some rules, otherwise it will likely be rejected by maintainers.

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 \
@ -92,7 +86,6 @@ ell_sources = ell/private.h \
ell/netlink-private.h \
ell/netlink.c \
ell/genl.c \
ell/rtnl-private.h \
ell/rtnl.c \
ell/dbus-private.h \
ell/dbus.c \
@ -147,25 +140,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 +199,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 +234,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 +251,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 +300,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,8 +362,7 @@ man_MANS += wired/ead.8
endif
endif
if DAEMON
noinst_PROGRAMS += tools/probe-req tools/iwd-decrypt-profile
noinst_PROGRAMS += tools/probe-req
tools_probe_req_SOURCES = tools/probe-req.c src/mpdu.h src/mpdu.c \
src/ie.h src/ie.c \
@ -400,13 +372,6 @@ tools_probe_req_SOURCES = tools/probe-req.c src/mpdu.h src/mpdu.c \
src/band.h src/band.c
tools_probe_req_LDADD = $(ell_ldadd)
tools_iwd_decrypt_profile_SOURCES = tools/iwd-decrypt-profile.c \
src/common.h src/common.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
@ -416,9 +381,7 @@ tools_hwsim_SOURCES = tools/hwsim.c src/mpdu.h \
src/nl80211util.h src/nl80211util.c \
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
src/band.h src/band.c
tools_hwsim_LDADD = $(ell_ldadd)
if DBUS_POLICY
@ -430,19 +393,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 +410,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 +417,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 +432,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 +458,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 +477,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 +507,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 +520,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 +562,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 +572,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 +679,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 +722,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,14 +58,10 @@ 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"
fi
fi
if (test "$CC" = "clang"); then
CFLAGS+=" -Wno-unknown-warning-option"
CFLAGS+=" -Wno-unknown-pragmas"
fi
])

View File

@ -20,8 +20,3 @@
"ttls-mschapv2-phase2@example.com" TTLS-MSCHAPV2 "Password" [2]
"ttls-pap-phase2@example.com" TTLS-PAP "Password" [2]
"112345678@phonesim.org" SIM [2]
# TODO: Hostapd is broken with phase1 lookups for reauthentication.
# Allowing a wildcard phase1 for PEAP/TTLS is a stop gap until
# hostapd is actually fixed.
* PEAP,TTLS

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,76 +1,105 @@
#! /usr/bin/python3
import unittest
import os
import sys, os
import iwd
from iwd import IWD
from config import ctx
from validation import validate, client_connect
from iwd import PSKAgent
from iwd import NetworkType
from hostapd import HostapdCLI
import testutil
class Test(unittest.TestCase):
def test_connection_success(self):
IWD.copy_to_storage('TestAP1.psk')
def client_connect(self, wd, dev):
hostapd = HostapdCLI(config='psk-ccmp.conf')
ordered_network = dev.get_ordered_network('TestAP1')
self.assertEqual(ordered_network.type, NetworkType.psk)
psk_agent = PSKAgent('Password1')
wd.register_psk_agent(psk_agent)
ordered_network.network_object.connect()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(dev, condition)
wd.unregister_psk_agent(psk_agent)
testutil.test_iface_operstate(dev.name)
testutil.test_ifaces_connected(hostapd.ifname, dev.name)
dev.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
def test_connection_success(self):
wd = IWD(True)
dev1, dev2 = wd.list_devices(2)
client_connect(wd, dev1, 'TestAP1')
self.client_connect(wd, dev1)
dev1.start_ap('TestAP2', 'Password2')
validate(wd, dev2, dev1, 'TestAP2', 'Password2')
try:
condition = 'not obj.scanning'
wd.wait_for_object_condition(dev2, condition)
dev2.scan()
condition = 'obj.scanning'
wd.wait_for_object_condition(dev2, condition)
condition = 'not obj.scanning'
wd.wait_for_object_condition(dev2, condition)
networks = {}
networks['TestAP1'] = dev2.get_ordered_network('TestAP1')
networks['TestAP2'] = dev2.get_ordered_network('TestAP2', full_scan=True)
self.assertEqual(networks['TestAP1'].type, NetworkType.psk)
self.assertEqual(networks['TestAP2'].type, NetworkType.psk)
psk_agent = PSKAgent('Password2')
wd.register_psk_agent(psk_agent)
try:
dev2.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(dev2, condition)
except:
pass
networks['TestAP2'].network_object.connect()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(dev2, condition)
testutil.test_iface_operstate(dev2.name)
testutil.test_ifaces_connected(dev1.name, dev2.name, group=False)
wd.unregister_psk_agent(psk_agent)
dev2.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(networks['TestAP2'].network_object,
condition)
finally:
dev1.stop_ap()
# Finally test dev1 can go to client mode and connect again
client_connect(wd, dev1, 'TestAP1')
self.client_connect(wd, dev1)
def test_client_start_ap(self):
@classmethod
def setUpClass(cls):
IWD.copy_to_storage('TestAP1.psk')
wd = IWD(True)
dev1, dev2 = wd.list_devices(2)
ctx.start_process(['iwctl', 'device', dev1.name, 'set-property', 'Mode', 'ap'], check=True)
ctx.start_process(['iwctl', 'ap', dev1.name, 'start', 'TestAP2', 'Password2'], check=True)
iwctl = ctx.start_process(['iwctl', 'ap', 'list'], check=True)
self.assertIn(dev1.name, iwctl.out)
iwctl = ctx.start_process(['iwctl', 'ap', dev1.name, 'show'], check=True)
self.assertIn('TestAP2', iwctl.out)
validate(wd, dev2, dev1, 'TestAP2', 'Password2')
def test_valid_ciphers(self):
ciphers = ['TKIP', 'CCMP-128', 'GCMP-128', 'CCMP-256', 'GCMP-256']
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,10 +1,14 @@
#! /usr/bin/python3
import unittest
import sys, os
import iwd
from iwd import IWD
from iwd import PSKAgent
from iwd import NetworkType
from config import ctx
from validation import validate
import testutil
class Test(unittest.TestCase):
def test_connection_success(self):
@ -24,8 +28,55 @@ class Test(unittest.TestCase):
dev1.start_ap('APConfig')
validate(wd, dev2, dev1, 'APConfig', 'password123',
sta_ip_info=('192.168.1.3', ctx), ap_ip_info=('192.168.1.1', ns0))
try:
condition = 'not obj.scanning'
wd.wait_for_object_condition(dev2, condition)
dev2.scan()
condition = 'obj.scanning'
wd.wait_for_object_condition(dev2, condition)
condition = 'not obj.scanning'
wd.wait_for_object_condition(dev2, condition)
networks = {}
networks['APConfig'] = dev2.get_ordered_network('APConfig', full_scan=True)
self.assertEqual(networks['APConfig'].type, NetworkType.psk)
psk_agent = PSKAgent('password123')
wd.register_psk_agent(psk_agent)
try:
dev2.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(dev2, condition)
except:
pass
networks['APConfig'].network_object.connect()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(dev2, condition)
testutil.test_iface_operstate(dev2.name)
#
# TODO: cannot yet check the AP interface IP since its in a
# different namespace.
#
testutil.test_ip_address_match(dev2.name, "192.168.1.3")
testutil.test_ip_connected(('192.168.1.3', ctx), ('192.168.1.1', ns0))
wd.unregister_psk_agent(psk_agent)
dev2.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(networks['APConfig'].network_object,
condition)
finally:
dev1.stop_ap()
@classmethod
def setUpClass(cls):

View File

@ -10,8 +10,6 @@ from iwd import NetworkType
from config import ctx
import testutil
from validation import validate
class Test(unittest.TestCase):
def test_connection_success(self):
wd = IWD(True, '/tmp/dhcp')
@ -27,36 +25,67 @@ class Test(unittest.TestCase):
with self.assertRaises(iwd.AlreadyExistsEx):
dev4.start_ap('TestAP4', 'Password4')
validate(wd, dev2, dev1, 'TestAP2', 'Password2', ip_checks=False)
network = dev2.get_ordered_network('TestAP2', full_scan=True)
try:
testutil.test_ip_address_match(dev1.name, "192.168.80.1")
testutil.test_ip_address_match(dev2.name, "192.168.80.2")
ip = "192.168.80.1"
except:
testutil.test_ip_address_match(dev1.name, "192.168.80.17")
testutil.test_ip_address_match(dev2.name, "192.168.80.18")
ip = "192.168.80.17"
condition = 'not obj.scanning'
wd.wait_for_object_condition(dev2, condition)
dev2.scan()
condition = 'obj.scanning'
wd.wait_for_object_condition(dev2, condition)
condition = 'not obj.scanning'
wd.wait_for_object_condition(dev2, condition)
dev2.disconnect()
networks = {}
networks['TestAP2'] = dev2.get_ordered_network('TestAP2', full_scan=True)
condition = 'not obj.connected'
wd.wait_for_object_condition(network.network_object, condition)
self.assertEqual(networks['TestAP2'].type, NetworkType.psk)
# This should release the IP */
dev1.stop_ap()
psk_agent = PSKAgent('Password2')
wd.register_psk_agent(psk_agent)
# This should now succeed and the IP should match the old IP dev1
# got initially.
dev4.start_ap('TestAP4', 'Password4')
try:
dev2.disconnect()
testutil.test_ip_address_match(dev4.name, ip)
condition = 'not obj.connected'
wd.wait_for_object_condition(dev2, condition)
except:
pass
dev1.stop_ap()
dev3.stop_ap()
dev4.stop_ap()
networks['TestAP2'].network_object.connect()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(dev2, condition)
testutil.test_iface_operstate(dev2.name)
testutil.test_ifaces_connected(dev1.name, dev2.name, group=False)
try:
testutil.test_ip_address_match(dev1.name, "192.168.80.1")
testutil.test_ip_address_match(dev2.name, "192.168.80.2")
ip = "192.168.80.1"
except:
testutil.test_ip_address_match(dev1.name, "192.168.80.17")
testutil.test_ip_address_match(dev2.name, "192.168.80.18")
ip = "192.168.80.17"
wd.unregister_psk_agent(psk_agent)
dev2.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(networks['TestAP2'].network_object,
condition)
# This should release the IP */
dev1.stop_ap()
# This should now succeed and the IP should match the old IP dev1
# got initially.
dev4.start_ap('TestAP4', 'Password4')
testutil.test_ip_address_match(dev4.name, ip)
finally:
dev1.stop_ap()
@classmethod
def setUpClass(cls):

View File

@ -48,8 +48,16 @@ class Test(unittest.TestCase):
dev1.start_ap('TestAP2', 'Password2')
try:
condition = 'not obj.scanning'
wd.wait_for_object_condition(dev2, condition)
dev2.scan()
condition = 'obj.scanning'
wd.wait_for_object_condition(dev2, condition)
condition = 'not obj.scanning'
wd.wait_for_object_condition(dev2, condition)
networks = {}
networks['TestAP1'] = dev2.get_ordered_network('TestAP1', full_scan=True)
networks['TestAP1'] = dev2.get_ordered_network('TestAP1')
networks['TestAP2'] = dev2.get_ordered_network('TestAP2', full_scan=True)
self.assertEqual(networks['TestAP1'].type, NetworkType.psk)

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

@ -1,71 +0,0 @@
from iwd import PSKAgent
from iwd import NetworkType
from hostapd import HostapdCLI
import testutil
def validate(wd, sta_dev, ap_dev, ssid, passphrase,
sta_ip_info=None, ap_ip_info=None, ip_checks=True):
try:
network = sta_dev.get_ordered_network(ssid, full_scan=True)
if network.type != NetworkType.psk:
raise Exception("Network type mismatch")
psk_agent = PSKAgent(passphrase)
wd.register_psk_agent(psk_agent)
network.network_object.connect()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(sta_dev, condition)
testutil.test_iface_operstate(sta_dev.name)
# This implies separate namespaces so the iface names won't exist
if not sta_ip_info or not ap_ip_info:
testutil.test_ifaces_connected(ap_dev.name, sta_dev.name, group=False)
if not ip_checks:
return
if sta_ip_info:
testutil.test_ip_address_match(sta_dev.name, sta_ip_info[0])
if sta_ip_info and ap_ip_info:
testutil.test_ip_connected(sta_ip_info, ap_ip_info)
wd.unregister_psk_agent(psk_agent)
sta_dev.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(network.network_object, condition)
finally:
if ip_checks:
ap_dev.stop_ap()
def client_connect(wd, dev, ssid):
hostapd = HostapdCLI(config='psk-ccmp.conf')
ordered_network = dev.get_ordered_network(ssid)
if ordered_network.type != NetworkType.psk:
raise Exception("Network type mismatch")
psk_agent = PSKAgent('Password1')
wd.register_psk_agent(psk_agent)
ordered_network.network_object.connect()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(dev, condition)
wd.unregister_psk_agent(psk_agent)
testutil.test_iface_operstate(dev.name)
testutil.test_ifaces_connected(hostapd.ifname, dev.name)
dev.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)

View File

@ -11,71 +11,57 @@ 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.assertTrue(bss_hostapd[0].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)
self.assertEqual(device.state, iwd.DeviceState.connected)
self.assertTrue(bss_hostapd[1].list_sta())
device.disconnect()
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
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

@ -2,16 +2,16 @@
import unittest
import sys
import time
sys.path.append('../util')
import iwd
from iwd import IWD
from iwd import AdHocDevice
from config import ctx
import testutil
class Test(unittest.TestCase):
def validate_connection(self, wd, client=False):
def validate_connection(self, wd):
dev1, dev2 = wd.list_devices(2)
self.assertIsNotNone(dev1)
@ -22,14 +22,7 @@ class Test(unittest.TestCase):
condition = 'obj.started == True'
wd.wait_for_object_condition(adhoc1, condition)
if not client:
adhoc2 = dev2.start_adhoc("AdHocNetwork", "secret123")
else:
ctx.start_process(['iwctl', 'device', dev2.name, 'set-property',
'Mode', 'ad-hoc'], check=True)
ctx.start_process(['iwctl', 'ad-hoc', dev2.name, 'start',
'AdHocNetwork', 'secret123'], check=True)
adhoc2 = AdHocDevice(dev2.device_path)
adhoc2 = dev2.start_adhoc("AdHocNetwork", "secret123")
condition = 'obj.started == True'
wd.wait_for_object_condition(adhoc1, condition)
@ -49,10 +42,6 @@ class Test(unittest.TestCase):
self.validate_connection(wd)
def test_client_adhoc(self):
wd = IWD(True)
self.validate_connection(wd, client=True)
@classmethod
def setUpClass(cls):
pass

View File

@ -46,7 +46,7 @@ class Test(unittest.TestCase):
perm_addr = device.address
# 1. Test per-network deterministic MAC generation
IWD.copy_to_storage('pernetwork.psk', name='ssidCCMP.psk')
os.system('cat pernetwork.psk > /tmp/iwd/ssidCCMP.psk')
new_addr = self.try_connection(wd)
self.assertNotEqual(perm_addr, new_addr)
# try again to ensure the generation was deterministic
@ -54,7 +54,7 @@ class Test(unittest.TestCase):
self.assertEqual(new_addr, new_addr2)
# 2. Test FullAddressRandomization
IWD.copy_to_storage('full_random.psk', name='ssidCCMP.psk')
os.system('cat full_random.psk > /tmp/iwd/ssidCCMP.psk')
new_addr = self.try_connection(wd)
self.assertNotEqual(perm_addr, new_addr)
# try again to make sure the generation was random
@ -62,7 +62,7 @@ class Test(unittest.TestCase):
self.assertNotEqual(new_addr, new_addr2)
# 3. Test AddressOverride
IWD.copy_to_storage('override.psk', name='ssidCCMP.psk')
os.system('cat override.psk > /tmp/iwd/ssidCCMP.psk')
new_addr = self.try_connection(wd)
self.assertEqual(new_addr, 'e6:f6:38:a9:02:02')

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

@ -2,7 +2,6 @@
import unittest
import sys
import dbus
sys.path.append('../util')
import iwd
@ -56,19 +55,36 @@ class Test(unittest.TestCase):
IWD.clear_storage()
def test_connection_use_first_from_multiple_registered(self):
def test_connection_with_other_agent(self):
wd = IWD()
psk_agent = PSKAgent("secret_ssid1")
wd.register_psk_agent(psk_agent)
iwctl = ctx.start_process(['iwctl', '-P', 'secret_ssid2'])
# Let iwctl to start and register its agent.
wd.wait(2)
psk_agent = PSKAgent("secret_ssid2")
self.check_connection(wd, 'ssid2')
iwctl.kill()
IWD.clear_storage()
def test_connection_use_own_agent_from_multiple_registered(self):
wd = IWD()
iwctl = ctx.start_process(['iwctl', '-P', 'secret_ssid2'])
# Let iwctl to start and register its agent.
wd.wait(2)
psk_agent = PSKAgent("secret_ssid1")
wd.register_psk_agent(psk_agent)
self.check_connection(wd, 'ssid1')
wd.unregister_psk_agent(psk_agent)
iwctl.kill()
IWD.clear_storage()
@classmethod

View File

@ -33,7 +33,7 @@ class Test(unittest.TestCase):
dev1, dev2 = wd.list_devices(2)
ordered_network = dev1.get_ordered_network("TestBlacklist", full_scan=True)
ordered_network = dev1.get_ordered_network("TestBlacklist")
self.assertEqual(ordered_network.type, NetworkType.psk)
@ -45,12 +45,12 @@ class Test(unittest.TestCase):
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(dev1, condition)
bss_hostapd[2].wait_for_event('AP-STA-CONNECTED %s' % dev1.address)
self.assertIn(dev1.address, bss_hostapd[2].list_sta())
# dev1 now connected, this should max out the first AP, causing the next
# connection to fail to this AP.
ordered_network = dev2.get_ordered_network("TestBlacklist", full_scan=True)
ordered_network = dev2.get_ordered_network("TestBlacklist")
self.assertEqual(ordered_network.type, NetworkType.psk)
@ -64,7 +64,7 @@ class Test(unittest.TestCase):
# We should have temporarily blacklisted the first BSS, and connected
# to this one.
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % dev2.address)
self.assertIn(dev2.address, bss_hostapd[1].list_sta())
# Now check that the first BSS is still not blacklisted. We can
# disconnect dev1, opening up the AP for more connections
@ -83,7 +83,7 @@ class Test(unittest.TestCase):
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(dev2, condition)
bss_hostapd[2].wait_for_event('AP-STA-CONNECTED %s' % dev2.address)
self.assertIn(dev2.address, bss_hostapd[2].list_sta())
wd.unregister_psk_agent(psk_agent)
@ -101,7 +101,7 @@ class Test(unittest.TestCase):
devices = wd.list_devices(1)
device = devices[0]
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
ordered_network = device.get_ordered_network("TestBlacklist")
self.assertEqual(ordered_network.type, NetworkType.psk)
@ -110,11 +110,11 @@ class Test(unittest.TestCase):
# Have both APs drop all packets, both should get blacklisted
rule0.drop = True
rule0.enabled = True
rule0.enable = True
rule1.drop = True
rule1.enabled = True
rule1.enable = True
rule2.drop = True
rule2.enabled = True
rule2.enable = True
with self.assertRaises(iwd.FailedEx):
ordered_network.network_object.connect()
@ -134,7 +134,7 @@ class Test(unittest.TestCase):
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
self.assertIn(device.address, bss_hostapd[0].list_sta())
wd.unregister_psk_agent(psk_agent)
@ -148,7 +148,7 @@ class Test(unittest.TestCase):
devices = wd.list_devices(1)
device = devices[0]
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
ordered_network = device.get_ordered_network("TestBlacklist")
self.assertEqual(ordered_network.type, NetworkType.psk)
@ -188,7 +188,7 @@ class Test(unittest.TestCase):
devices[1].disconnect()
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
ordered_network = device.get_ordered_network("TestBlacklist")
self.assertEqual(ordered_network.type, NetworkType.psk)
@ -214,7 +214,7 @@ class Test(unittest.TestCase):
# should automatically try the next BSS in the list, which is
# bss_hostapd[1]
self.assertNotIn(device.address, bss_hostapd[0].list_sta())
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
self.assertIn(device.address, bss_hostapd[1].list_sta())
rule0.drop = False
@ -234,7 +234,7 @@ class Test(unittest.TestCase):
# Same as before, make sure we didn't connect to the blacklisted AP.
self.assertNotIn(device.address, bss_hostapd[0].list_sta())
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
self.assertIn(device.address, bss_hostapd[1].list_sta())
# Wait for the blacklist to expire (10 seconds)
elapsed = time.time() - start
@ -244,7 +244,15 @@ class Test(unittest.TestCase):
device.disconnect()
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
condition = 'not obj.scanning'
wd.wait_for_object_condition(device, condition)
device.scan()
condition = 'not obj.scanning'
wd.wait_for_object_condition(device, condition)
ordered_network = device.get_ordered_network("TestBlacklist")
self.assertEqual(ordered_network.type, NetworkType.psk)
@ -256,73 +264,16 @@ class Test(unittest.TestCase):
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
self.assertIn(device.address, bss_hostapd[0].list_sta())
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=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,9 +11,13 @@ import subprocess
from config import ctx
class Test(unittest.TestCase):
def check_connection_success(self, ssid):
device = self.wd.list_devices(1)[0]
condition = 'not obj.scanning'
self.wd.wait_for_object_condition(device, condition)
ordered_network = device.get_ordered_network(ssid)
condition = 'obj.state == DeviceState.connected'
@ -24,14 +28,9 @@ class Test(unittest.TestCase):
condition = 'not obj.connected'
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
def establish_network(self, ssid):
device = self.wd.list_devices(1)[0]
device.get_ordered_network(ssid)
def test_connection_with_passphrase(self):
ssid = 'ssidPassphrase'
self.establish_network(ssid)
device = self.wd.list_devices(1)[0]
# Use --dontaks cmd-line option
@ -46,7 +45,6 @@ class Test(unittest.TestCase):
def test_connection_with_username_and_password(self):
ssid = 'ssidUNameAndPWord'
self.establish_network(ssid)
device = self.wd.list_devices(1)[0]
ctx.start_process(['iwctl', '-u', 'user', '-p', 'password', 'station', \
@ -56,7 +54,6 @@ class Test(unittest.TestCase):
def test_connection_with_password(self):
ssid = 'ssidPWord'
self.establish_network(ssid)
device = self.wd.list_devices(1)[0]
ctx.start_process(['iwctl', '-p', 'password', 'station', device.name, 'connect', ssid],
@ -67,7 +64,6 @@ class Test(unittest.TestCase):
def test_connection_failure(self):
ssid = 'ssidPassphrase'
self.establish_network(ssid)
device = self.wd.list_devices(1)[0]
with self.assertRaises(subprocess.CalledProcessError):
@ -77,13 +73,14 @@ class Test(unittest.TestCase):
def test_invalid_command_line_option(self):
ssid = 'ssidPassphrase'
self.establish_network(ssid)
device = self.wd.list_devices(1)[0]
with self.assertRaises(subprocess.CalledProcessError):
ctx.start_process(['iwctl', '-z', 'station', device.name, 'connect', ssid], check=True)
def test_invalid_command(self):
device = self.wd.list_devices(1)[0]
with self.assertRaises(subprocess.CalledProcessError):
ctx.start_process(['iwctl', 'inexistent', 'command'], check=True)
@ -94,6 +91,19 @@ class Test(unittest.TestCase):
cls.wd = IWD()
device = cls.wd.list_devices(1)[0]
condition = 'not obj.scanning'
cls.wd.wait_for_object_condition(device, condition)
device.scan()
condition = 'obj.scanning'
cls.wd.wait_for_object_condition(device, condition)
condition = 'not obj.scanning'
cls.wd.wait_for_object_condition(device, condition)
@classmethod
def tearDownClass(cls):
IWD.clear_storage()

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

@ -5,11 +5,9 @@ import sys
sys.path.append('../util')
from iwd import IWD
from iwd import DeviceProvisioning
from wpas import Wpas
from hostapd import HostapdCLI
from hwsim import Hwsim
from config import ctx
class Test(unittest.TestCase):
def test_iwd_as_enrollee(self):
@ -38,18 +36,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)
@ -80,60 +80,12 @@ class Test(unittest.TestCase):
self.wpas.dpp_enrollee_start(uri)
self.wpas.wait_for_event('DPP-CONF-RECEIVED', timeout=30)
def test_iwd_as_configurator_initiator(self):
self.hapd.reload()
self.hapd.wait_for_event('AP-ENABLED')
IWD.copy_to_storage('ssidCCMP.psk')
self.device.autoconnect = True
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device, condition)
uri = self.wpas.dpp_enrollee_start(oper_and_channel='81/2')
self.device.dpp_start_configurator(uri)
self.wpas.wait_for_event('DPP-CONF-RECEIVED', timeout=30)
def test_client_as_configurator(self):
self.hapd.reload()
self.hapd.wait_for_event('AP-ENABLED')
IWD.copy_to_storage('ssidCCMP.psk')
self.device.autoconnect = True
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device, condition)
ctx.start_process(['iwctl', 'dpp', self.device.name, 'start-configurator'], check=True)
dpp = DeviceProvisioning(self.device.device_path)
self.wpas.dpp_enrollee_start(dpp.uri)
self.wpas.wait_for_event('DPP-CONF-RECEIVED', timeout=30)
def test_client_as_enrollee(self):
self.device.autoconnect = True
self.hapd.reload()
ctx.start_process(['iwctl', 'dpp', self.device.name, 'start-enrollee'], check=True)
dpp = DeviceProvisioning(self.device.device_path)
self.wpas.dpp_configurator_create(dpp.uri)
self.wpas.dpp_configurator_start('ssidCCMP', 'secret123')
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device, condition)
self.hapd.wait_for_event('AP-STA-CONNECTED 42:00:00:00:00:00')
def setUp(self):
self.wpas = Wpas('wpas.conf')
self.wd = IWD(True)
self.device = self.wd.list_devices(1)[0]
self.wpas = Wpas('wpas.conf')
self.hapd = HostapdCLI('hostapd.conf')
self.hapd.disable()
self.hwsim = Hwsim()
@ -146,15 +98,10 @@ 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
print("calling Disconnect()")
self.device.disconnect()
self.device.dpp_stop()
self.wpas.dpp_configurator_remove()
self.wpas.clean_up()
self.wd = None
self.device = None

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

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

View File

@ -21,7 +21,12 @@ class Test(unittest.TestCase):
hostapd = HostapdCLI(config='ssidOpen.conf')
ordered_network = device.get_ordered_network('ssidOpen', full_scan=True)
device.scan()
condition = 'not obj.scanning'
wd.wait_for_object_condition(device, condition)
ordered_network = device.get_ordered_network('ssidOpen')
ordered_network.network_object.connect()

View File

@ -37,6 +37,9 @@ class Test(unittest.TestCase):
hostapd.eapol_reauth(device.address)
hostapd.wait_for_event('CTRL-EVENT-EAP-STARTED')
hostapd.wait_for_event('CTRL-EVENT-EAP-SUCCESS')
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)

View File

@ -4,23 +4,22 @@ import unittest
import sys
sys.path.append('../util')
import iwd
from iwd import IWD
from iwd import DeviceState
from hostapd import HostapdCLI
from config import ctx
class Test(unittest.TestCase):
def four_digit_pin_success(self, wd, client=False):
def four_digit_pin_success(self, wd):
devices = wd.list_devices(1)
device = devices[0]
pin = '1234'
self.hostapd.wps_pin(pin)
if not client:
device.wps_start_pin(pin)
else:
ctx.start_process(['iwctl', 'wsc', device.name, 'start-user-pin', pin], check=True)
device.wps_start_pin(pin)
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
@ -37,11 +36,6 @@ class Test(unittest.TestCase):
self.four_digit_pin_success(wd)
def test_client_four_digit_pin(self):
wd = IWD(True)
self.four_digit_pin_success(wd, client=True)
@classmethod
def setUpClass(cls):
cls.hostapd = HostapdCLI(config='ssidWPS.conf')

View File

@ -4,22 +4,20 @@ import unittest
import sys
sys.path.append('../util')
import iwd
from iwd import IWD
from hostapd import HostapdCLI
from config import ctx
from iwd import DeviceState
from hostapd import HostapdCLI
class Test(unittest.TestCase):
def push_button_success(self, wd, client=False):
def push_button_success(self, wd):
self.hostapd.wps_push_button()
devices = wd.list_devices(1)
device = devices[0]
if not client:
device.wps_push_button()
else:
ctx.start_process(['iwctl', 'wsc', device.name, 'push-button'], check=True)
device.wps_push_button()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
@ -36,11 +34,6 @@ class Test(unittest.TestCase):
self.push_button_success(wd)
def test_client_push_button(self):
wd = IWD(True)
self.push_button_success(wd, client=True)
@classmethod
def setUpClass(cls):
cls.hostapd = HostapdCLI(config='ssidWPS.conf')

View File

@ -11,8 +11,6 @@ from iwd import PSKAgent
from hlrauc import AuthCenter
from ofono import Ofono
from config import ctx
from hostapd import HostapdCLI
import testutil
import traceback
@ -52,8 +50,6 @@ class Test(unittest.TestCase):
testutil.test_iface_operstate()
testutil.test_ifaces_connected()
self.hostapd.eapol_reauth(device.address)
if secrets:
wd.unregister_psk_agent(psk_agent)
@ -255,7 +251,6 @@ class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.wd = IWD()
cls.hostapd = HostapdCLI()
@classmethod
def tearDownClass(cls):

View File

@ -1,77 +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 hwsim import Hwsim
from hostapd import HostapdCLI
from time import sleep
class Test(unittest.TestCase):
def test_connection_success(self):
hwsim = Hwsim()
hostapd = HostapdCLI(config='ssidCCMP.conf')
radio = hwsim.get_radio('rad0')
wd = IWD()
psk_agent = PSKAgent("secret123")
wd.register_psk_agent(psk_agent)
devices = wd.list_devices(1)
device = devices[0]
ordered_network = device.get_ordered_network('ssidCCMP')
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
ordered_network.network_object.connect()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
# Ensure IWD is not scanning. This causes problems with mac80211_hwsim
# where CMD_FRAME will fail during a scan. This is due to the frame not
# having the same frequency as the radio (since hwsim is off-channel)
if device.scanning:
condition = 'not obj.scanning'
wd.wait_for_object_condition(device, condition)
hwsim.spoof_eap_fail(radio, hostapd.frequency, device.address)
hwsim.spoof_invalid_ptk_1_of_4(radio, hostapd.frequency, device.address)
with self.assertRaises(TimeoutError):
condition = 'obj.state == DeviceState.disconnected'
wd.wait_for_object_condition(device, condition, 4)
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
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):
pass
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -1,6 +0,0 @@
[SETUP]
num_radios=2
hwsim_medium=yes
[HOSTAPD]
rad0=ssidCCMP.conf

View File

@ -1,12 +0,0 @@
hw_mode=g
channel=1
ssid=ssidCCMP
wpa=2
wpa_pairwise=CCMP
wpa_passphrase=secret123
ieee80211w=2
wpa_key_mgmt=WPA-PSK-SHA256
beacon_int=10
ocv=1

View File

@ -1,163 +0,0 @@
#!/usr/bin/python3
import unittest
import sys
sys.path.append('../util')
import iwd
import os
from time import sleep
from iwd import IWD
from iwd import NetworkType
from iwd import PSKAgent
class Test(unittest.TestCase):
def profile_is_encrypted(self, profile):
with open('/tmp/iwd/' + profile) as f:
contents = f.read()
if 'Passphrase' in contents:
return False
return True
def validate(self, wd):
devices = wd.list_devices(1)
device = devices[0]
ordered_network = device.get_ordered_network('ssidCCMP')
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
ordered_network.network_object.connect()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
device.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
# Tests that an existing plaintext profile gets encrypted
def test_new_profile(self):
IWD.copy_to_storage('ssidCCMP.psk')
mtime = os.path.getmtime('/tmp/iwd/' + 'ssidCCMP.psk')
self.assertFalse(self.profile_is_encrypted('ssidCCMP.psk'))
sleep(1)
wd = IWD(True)
# Make sure profile was accepted
condition = 'len(obj.list_known_networks()) == 1'
wd.wait_for_object_condition(wd, condition)
# Check the file was modified (should be encrypted now)
self.assertNotEqual(mtime, os.path.getmtime('/tmp/iwd/' + 'ssidCCMP.psk'))
self.validate(wd)
self.assertTrue(self.profile_is_encrypted('ssidCCMP.psk'))
# Tests that a new connection with agent gets written to an encrypted profile
def test_agent_profile(self):
wd = IWD(True)
psk_agent = PSKAgent("secret123")
wd.register_psk_agent(psk_agent)
with self.assertRaises(FileNotFoundError):
self.profile_is_encrypted('ssidCCMP.psk')
self.validate(wd)
self.assertTrue(self.profile_is_encrypted('ssidCCMP.psk'))
wd.unregister_psk_agent(psk_agent)
# Tests that an invalid profile gets re-written after an agent request
def test_invalid_profile_rewritten(self):
bad_config = '[Security]\nPassphrase=incorrect\n'
os.system('echo "%s" > /tmp/iwd/ssidCCMP.psk' % bad_config)
wd = IWD(True)
condition = 'len(obj.list_known_networks()) == 1'
wd.wait_for_object_condition(wd, condition)
# IWD should still encrypt the profile automatically
self.assertTrue(self.profile_is_encrypted('ssidCCMP.psk'))
# This should fail
with self.assertRaises(iwd.FailedEx):
self.validate(wd)
psk_agent = PSKAgent("secret123")
wd.register_psk_agent(psk_agent)
self.validate(wd)
self.assertTrue(self.profile_is_encrypted('ssidCCMP.psk'))
# Tests that a profile that doesn't decrypt won't become a known network
def test_decryption_failure(self):
bad_config = \
'''
[Security]
EncryptedSalt=000102030405060708090a0b0c0d0e0f
EncryptedSecurity=aabbccddeeff00112233445566778899
'''
os.system('echo "%s" > /tmp/iwd/ssidCCMP.psk' % bad_config)
wd = IWD(True)
self.assertEqual(wd.list_known_networks(), [])
# This test starts and stops IWD so quickly the DBus utilities don't
# even have a chance to set up the Device interface object which causes
# exceptions on the next test as the InterfaceAdded signals arrive. This
# allows the device interface to get set up before ending the test.
wd.list_devices(1)
def test_runtime_profile(self):
wd = IWD(True)
self.assertEqual(wd.list_known_networks(), [])
# Add profile after IWD starts
IWD.copy_to_storage('ssidCCMP.psk')
self.validate(wd)
# Should now be encrypted
self.assertTrue(self.profile_is_encrypted('ssidCCMP.psk'))
with open('/tmp/iwd/ssidCCMP.psk') as f:
profile = f.read()
# Edit the profile, corrupting it
profile.replace('EncryptedSecurity=', 'EncryptedSecurity=00')
devices = wd.list_devices(1)
device = devices[0]
condition = 'obj.state == DeviceState.disconnected'
wd.wait_for_object_condition(device, condition)
def tearDown(self):
IWD.clear_storage()
@classmethod
def setUpClass(cls):
os.environ['CREDENTIALS_DIRECTORY'] = '/tmp'
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -1,6 +0,0 @@
[SETUP]
num_radios=2
start_iwd=0
[HOSTAPD]
rad0=ssidCCMP.conf

View File

@ -1 +0,0 @@
secret123

View File

@ -1,2 +0,0 @@
[General]
SystemdEncrypt=iwd-secret

View File

@ -1,5 +0,0 @@
[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

@ -27,7 +27,7 @@ class Test(unittest.TestCase):
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)
self.assertTrue(self.bss_hostapd[0].list_sta())
self.assertFalse(self.bss_hostapd[1].list_sta())
testutil.test_iface_operstate(device.name)
@ -37,13 +37,16 @@ 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'
to_condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_change(device, from_condition, to_condition)
self.bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
self.assertTrue(self.bss_hostapd[1].list_sta())
testutil.test_iface_operstate(device.name)
testutil.test_ifaces_connected(self.bss_hostapd[1].ifname, device.name)
@ -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

@ -13,10 +13,21 @@ class Test(unittest.TestCase):
def validate_connection(self, wd):
device = wd.list_devices(1)[0]
condition = 'not obj.scanning'
wd.wait_for_object_condition(device, condition)
# Scanning is unavoidable in this case since both FILS-SHA256 and
# FILS-SHA384 are tested. Without a new scan the cached scan results
# would cause IWD to choose an incorrect AKM for the second test.
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
device.scan()
condition = 'obj.scanning'
wd.wait_for_object_condition(device, condition)
condition = 'not obj.scanning'
wd.wait_for_object_condition(device, condition)
ordered_network = device.get_ordered_network('TestFT')
self.assertEqual(ordered_network.type, NetworkType.eap)
@ -28,8 +39,7 @@ class Test(unittest.TestCase):
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)
self.assertTrue(self.bss_hostapd[0].list_sta())
self.assertFalse(self.bss_hostapd[1].list_sta())
testutil.test_iface_operstate(device.name)
@ -52,8 +62,7 @@ class Test(unittest.TestCase):
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)
self.assertTrue(self.bss_hostapd[0].list_sta())
self.assertFalse(self.bss_hostapd[1].list_sta())
testutil.test_iface_operstate(device.name)
@ -70,13 +79,16 @@ 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'
to_condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_change(device, from_condition, to_condition)
self.bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
self.assertTrue(self.bss_hostapd[1].list_sta())
testutil.test_iface_operstate(device.name)
testutil.test_ifaces_connected(self.bss_hostapd[1].ifname, device.name)
@ -119,15 +131,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

@ -14,11 +14,22 @@ from hostapd import HostapdCLI
class Test(unittest.TestCase):
def do_connect(self, wd, device, hostapd):
condition = 'not obj.scanning'
wd.wait_for_object_condition(device, condition)
device.scan()
condition = 'obj.scanning'
wd.wait_for_object_condition(device, condition)
condition = 'not obj.scanning'
wd.wait_for_object_condition(device, condition)
#
# Scanning must be explicitly done to get updated RSSI values. Therefore
# full_scan is set.
# scan_if_needed is set false because of the previous scan.
#
ordered_network = device.get_ordered_network('testSSID', full_scan=True)
ordered_network = device.get_ordered_network('testSSID', scan_if_needed=False)
self.assertEqual(ordered_network.type, NetworkType.psk)

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

@ -6,13 +6,12 @@ import sys
sys.path.append('../util')
import iwd
import validation
from validation import TestHiddenNetworks
from validation import TestConnectAutoConnect
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:
@ -24,7 +23,7 @@ class TestWpaNetwork(unittest.TestCase):
'''
def test_wpa(self):
tca = TestHiddenNetworks()
tca = TestConnectAutoConnect()
tca.validate('UnExistingNetwork', False, iwd.NotFoundEx)
tca.validate('ssidOverlap', False, iwd.ServiceSetOverlapEx)
@ -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

@ -6,13 +6,12 @@ import sys
sys.path.append('../util')
import iwd
import validation
from validation import TestHiddenNetworks
from validation import TestConnectAutoConnect
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:
@ -21,26 +20,13 @@ class TestOpenNetwork(unittest.TestCase):
True True Connection succeeds
'''
def test_open(self):
tca = TestHiddenNetworks()
tca = TestConnectAutoConnect()
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

@ -9,7 +9,7 @@ from iwd import IWD
from iwd import PSKAgent
from iwd import NetworkType
class TestHiddenNetworks(unittest.TestCase):
class TestConnectAutoConnect(unittest.TestCase):
def check_connect_hidden_network(self, wd, device, ssid, throws):
if not throws is None:

View File

@ -6,13 +6,12 @@ import sys
sys.path.append('../util')
import iwd
import validation
from validation import TestHiddenNetworks
from validation import TestConnectAutoConnect
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:
@ -22,27 +21,13 @@ class TestWpaNetwork(unittest.TestCase):
'''
def test_wpa(self):
tca = TestHiddenNetworks()
tca = TestConnectAutoConnect()
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

@ -2,11 +2,10 @@
import unittest
import sys
import subprocess
sys.path.append('../util')
import iwd
from iwd import IWD
from config import ctx
class Test(unittest.TestCase):
@ -71,26 +70,8 @@ class Test(unittest.TestCase):
self.list_removal_and_addition(wd)
def test_client_known_networks(self):
networks = ['Hotspot Network', 'ssidOpen', 'ssidTKIP', 'ssidEAP-TLS']
wd = IWD(True)
iwctl = ctx.start_process(['iwctl', 'known-networks', 'list'], check=True)
for n in networks:
self.assertIn(n, iwctl.out)
for n in networks:
ctx.start_process(['iwctl', 'known-networks', n, 'show'], check=True)
networks.remove('ssidOpen')
ctx.start_process(['iwctl', 'known-networks', 'ssidOpen', 'forget'], check=True)
with self.assertRaises(subprocess.CalledProcessError):
ctx.start_process(['iwctl', 'known-networks', 'ssidOpen', 'show'], check=True)
@classmethod
def setUp(self):
def setUpClass(cls):
IWD.copy_to_storage('known_networks/ssidOpen.open')
IWD.copy_to_storage('known_networks/ssidTKIP.psk')
IWD.copy_to_storage('known_networks/ssidEAP-TLS.8021x')

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,7 +0,0 @@
hw_mode=g
channel=1
ssid=ap-main
wpa=1
wpa_pairwise=TKIP
wpa_passphrase=secret123

View File

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

View File

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

View File

@ -11,33 +11,11 @@ from iwd import NetworkType
from hostapd import HostapdCLI
import testutil
from config import ctx
import os
import socket
import datetime, time
import os, time
class Test(unittest.TestCase):
def test_connection_success(self):
def check_addr(device):
try:
# DHCPv6 addresses always have a prefix length of 128 bits, the actual
# subnet's prefix length is in the route.
testutil.test_ip_address_match(device.name, '3ffe:501:ffff:100::1', 128, 112)
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
os.system("hostname test-sta")
IWD.copy_to_storage('auto.psk', name='ap-ns1.psk')
wd = IWD(True)
psk_agent = PSKAgent("secret123")
@ -46,7 +24,7 @@ class Test(unittest.TestCase):
devices = wd.list_devices(1)
device = devices[0]
ordered_network = device.get_ordered_network('ap-ns1')
ordered_network = device.get_ordered_network('ssidTKIP')
self.assertEqual(ordered_network.type, NetworkType.psk)
@ -57,120 +35,13 @@ class Test(unittest.TestCase):
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
connect_time = time.time()
testutil.test_iface_operstate()
testutil.test_ifaces_connected()
testutil.test_ip_address_match(device.name, '192.168.1.10', 17, 24)
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)
# Since we're in an isolated VM with freshly created interfaces we know any routes
# will have been created by IWD and we don't have to allow for pre-existing routes
# in the table.
# Flags: 1=RTF_UP, 2=RTF_GATEWAY
expected_routes4 = {
testutil.RouteInfo(gw=socket.inet_pton(socket.AF_INET, '192.168.1.1'),
flags=3, ifname=ifname),
testutil.RouteInfo(dst=socket.inet_pton(socket.AF_INET, '192.168.0.0'), plen=17,
flags=1, ifname=ifname)
}
expected_routes6 = {
# Default router
testutil.RouteInfo(gw=router_ll_addr, flags=3, ifname=ifname),
# On-link prefix
testutil.RouteInfo(dst=socket.inet_pton(socket.AF_INET6, '3ffe:501:ffff:100::'), plen=72,
flags=1, ifname=ifname),
# Router for an off-link prefix, medium preference
testutil.RouteInfo(dst=socket.inet_pton(socket.AF_INET6, '3ffe:501:ffff:300::'), plen=64,
gw=router_ll_addr, flags=3, ifname=ifname),
# Router for an off-link prefix, high preference
testutil.RouteInfo(dst=socket.inet_pton(socket.AF_INET6, '3ffe:501:ffff:400::'), plen=65,
gw=router_ll_addr, flags=3, ifname=ifname),
# Router for an off-link prefix, low preference
testutil.RouteInfo(dst=socket.inet_pton(socket.AF_INET6, '3ffe:501:ffff:500::'), plen=66,
gw=router_ll_addr, flags=3, ifname=ifname)
}
self.maxDiff = None
self.assertEqual(expected_routes4, set(testutil.get_routes4(ifname)))
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']
# Every real resolvconf -a run overwrites the previous settings. Check the last three lines
# of our log since we care about the end result here.
self.assertEqual(expected_rclog, entries[-3:])
leases_file = self.parse_lease_file('/tmp/dhcpd.leases', socket.AF_INET)
lease = leases_file['leases'][socket.inet_pton(socket.AF_INET, '192.168.1.10')]
self.assertEqual(lease['state'], 'active')
self.assertEqual(lease['client-hostname'], 'test-sta')
self.assertTrue(lease['starts'] < connect_time)
self.assertTrue(lease['ends'] > connect_time)
# The T1 is 15 seconds per dhcpd.conf. This is the approximate interval between lease
# renewals we should see from the client (+/- 1 second + some jitter). Wait a little
# less than twice that time (25s) so that we can expect the lease was renewed strictly
# once (not 0 or 2 times) by that time, check that the lease timestamps have changed by
# at least 10s so as to leave a lot of margin.
renew_time = lease['starts'] + 15
now = time.time()
ctx.non_block_wait(lambda: False, renew_time + 10 - now, exception=False)
leases_file = self.parse_lease_file('/tmp/dhcpd.leases', socket.AF_INET)
new_lease = leases_file['leases'][socket.inet_pton(socket.AF_INET, '192.168.1.10')]
self.assertEqual(new_lease['state'], 'active')
self.assertEqual(new_lease['client-hostname'], 'test-sta')
self.assertTrue(new_lease['starts'] > lease['starts'] + 10)
self.assertTrue(new_lease['starts'] < lease['starts'] + 25)
self.assertTrue(new_lease['ends'] > lease['ends'] + 10)
self.assertTrue(new_lease['ends'] < lease['ends'] + 25)
# Now wait another T1 seconds but don't let our DHCP client get its REQUEST out this
# time so as to test renew timeouts and resends. The retry interval is 60 seconds
# 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.
# 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.
#
# We can't use hswim to block the frames from reaching the AP because we'd lose
# beacons and get disconnected. We also can't drop our subnet route or IP address
# because IWD's sendto() call would synchronously error out and the DHCP client
# would just give up. Add a false route to break routing to 192.168.1.1 and delete
# it afterwards.
os.system('ip route add 192.168.1.1/32 dev ' + ifname + ' via 192.168.1.100 preference 0')
lease = new_lease
renew_time = lease['starts'] + 15
now = time.time()
ctx.non_block_wait(lambda: False, renew_time + 10 - now, exception=False)
leases_file = self.parse_lease_file('/tmp/dhcpd.leases', socket.AF_INET)
new_lease = leases_file['leases'][socket.inet_pton(socket.AF_INET, '192.168.1.10')]
self.assertEqual(new_lease['starts'], lease['starts'])
os.system('ip route del 192.168.1.1/32 dev ' + ifname + ' via 192.168.1.100 preference 0')
retry_time = lease['starts'] + 75
now = time.time()
ctx.non_block_wait(lambda: False, retry_time + 10 - now, exception=False)
leases_file = self.parse_lease_file('/tmp/dhcpd.leases', socket.AF_INET)
new_lease = leases_file['leases'][socket.inet_pton(socket.AF_INET, '192.168.1.10')]
self.assertEqual(new_lease['state'], 'active')
self.assertEqual(lease['client-hostname'], 'test-sta')
self.assertTrue(new_lease['starts'] > lease['starts'] + 70)
self.assertTrue(new_lease['starts'] < lease['starts'] + 85)
self.assertTrue(new_lease['ends'] > lease['ends'] + 70)
self.assertTrue(new_lease['ends'] < lease['ends'] + 85)
time.sleep(2)
ret = os.system('ip addr show ' + device.name + ' | grep \'inet6 3ffe:501:ffff:100::\'')
self.assertEqual(os.waitstatus_to_exitcode(ret), 0)
device.disconnect()
@ -194,130 +65,40 @@ class Test(unittest.TestCase):
except:
pass
cls.ns1 = ctx.get_namespace('ns1')
cls.hapd = HostapdCLI('ap-ns1.conf')
hapd = HostapdCLI()
# TODO: This could be moved into test-runner itself if other tests ever
# require this functionality (p2p, FILS, etc.). Since its simple
# enough it can stay here for now.
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)
ctx.start_process(['ip', 'addr','add','dev', hapd.ifname,
'192.168.1.1/255.255.255.0']).wait()
ctx.start_process(['touch', '/tmp/dhcpd.leases']).wait()
cls.dhcpd_pid = ctx.start_process(['dhcpd', '-f', '-cf', '/tmp/dhcpd.conf',
'-lf', '/tmp/dhcpd.leases',
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()
# Send out Router Advertisements telling clients to use DHCPv6.
# Note trying to send the RAs from the router's global IPv6 address by adding a
# "AdvRASrcAddress { 3ffe:501:ffff:100::1; };" line will fail because the client
# and the router interfaces are in the same namespace and Linux won't allow routes
# with a non-link-local gateway address that is present on another interface in the
# same namespace.
ctx.start_process(['ip', 'addr', 'add', 'dev', hapd.ifname,
'3ffe:501:ffff:100::1/64']).wait()
ctx.start_process(['touch', '/tmp/dhcpd6.leases']).wait()
cls.dhcpd6_pid = ctx.start_process(['dhcpd', '-6', '-f', '-cf', '/tmp/dhcpd-v6.conf',
'-lf', '/tmp/dhcpd6.leases',
hapd.ifname], cleanup=remove_lease6)
ctx.start_process(['sysctl', 'net.ipv6.conf.' + hapd.ifname + '.forwarding=1']).wait()
# Tell clients to use DHCPv6
config = open('/tmp/radvd.conf', 'w')
config.write('interface ' + cls.hapd.ifname + ''' {
AdvSendAdvert on;
AdvManagedFlag on;
prefix 3ffe:501:ffff:100::/72 { AdvAutonomous off; };
route 3ffe:501:ffff:300::/64 {};
route 3ffe:501:ffff:400::/65 { AdvRoutePreference low; };
route 3ffe:501:ffff:500::/66 { AdvRoutePreference high; };
};''')
config.write('interface ' + hapd.ifname + ' { AdvSendAdvert on; AdvManagedFlag on; };')
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')
cls.radvd_pid = ctx.start_process(['radvd', '-n', '-d5', '-p', '/tmp/radvd.pid', '-C', '/tmp/radvd.conf'])
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
cls.ns1.stop_process(cls.dhcpd_pid)
ctx.stop_process(cls.dhcpd_pid)
cls.dhcpd_pid = None
cls.ns1.stop_process(cls.dhcpd6_pid)
ctx.stop_process(cls.dhcpd6_pid)
cls.dhcpd6_pid = None
cls.ns1.stop_process(cls.radvd_pid)
ctx.stop_process(cls.radvd_pid)
cls.radvd_pid = None
os.system('rm -rf /tmp/radvd.conf /tmp/resolvconf.log /tmp/test-bin')
os.environ['PATH'] = cls.orig_path
@staticmethod
def parse_lease_file(path, family):
file = open(path, 'r')
lines = file.readlines()
file.close()
stack = [[]]
statement = []
token = ''
for line in lines:
whitespace = False
quote = False
for ch in line:
if not quote and ch in ' \t\r\n;{}=#':
if len(token):
statement.append(token)
token = ''
if not quote and ch in ';{}':
if len(statement):
stack[-1].append(statement)
statement = []
if ch == '"':
quote = not quote
elif quote or ch not in ' \t\r\n;{}#':
token += ch
if ch == '#':
continue
elif ch == '{':
stack.append([])
elif ch == '}':
statements = stack.pop()
stack[-1][-1].append(statements)
if len(token):
statement.append(token)
token = ''
if len(statement):
stack[-1].append(statement)
statements = stack.pop(0)
if len(stack):
raise Exception('Unclosed block(s)')
contents = {'leases':{}}
for s in statements:
if s[0] == 'lease':
ip = socket.inet_pton(family, s[1])
lease = {}
for param in s[2]:
if param[0] in ('starts', 'ends', 'tstp', 'tsfp', 'atsfp', 'cltt'):
weekday = param[1]
year, month, day = param[2].split('/')
hour, minute, second = param[3].split(':')
dt = datetime.datetime(
int(year), int(month), int(day),
int(hour), int(minute), int(second),
tzinfo=datetime.timezone.utc)
lease[param[0]] = dt.timestamp()
elif param[0:2] == ['binding', 'state']:
lease['state'] = param[2]
elif param[0:2] == ['hardware', 'ethernet']:
lease['hwaddr'] = bytes([int(v, 16) for v in param[2].split(':')])
elif param[0] in ('preferred-life', 'max-life'):
lease[param[0]] = int(param[1])
elif param[0] in ('client-hostname'):
lease[param[0]] = param[1]
contents['leases'][ip] = lease # New entries overwrite older ones
elif s[0] == 'server-duid':
contents[s[0]] = s[1]
return contents
os.remove('/tmp/radvd.conf')
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -1,6 +1,6 @@
subnet6 3ffe:501:ffff:100::/72
subnet6 3ffe:501:ffff:100::/64
{
option dhcp6.name-servers 3ffe:501:ffff:100::2;
option dhcp6.name-servers 3ffe:501:ffff:100::1;
range6 3ffe:501:ffff:100::10 3ffe:501:ffff:100::20;
range6 3ffe:501:ffff:100::100 3ffe:501:ffff:100::200;
}

View File

@ -1,25 +1,15 @@
default-lease-time 120; # 2 minutes
min-lease-time 120; # 2 minutes
max-lease-time 120; # 2 minutes
option dhcp-renewal-time 15; # 15 secs for T1
# We set a relatively low lease lifetime of 2 minutes but our renewal interval
# (T1) is still unproportionally low to speed the test up -- 12% instead of the
# default 50% lifetime value. We need a lifetime in the order of minutes
# because minimum lease renewal retry interval is 60s per spec. However by
# default dhcpd will not renew leases that are newer than 25% their lifetime.
# Set that threshold to 1% so that we can verify that the lease is renewed
# without waiting too long.
dhcp-cache-threshold 1;
default-lease-time 600; # 10 minutes
max-lease-time 7200; # 2 hours
option broadcast-address 192.168.127.255;
option broadcast-address 192.168.1.255;
option routers 192.168.1.254;
option subnet-mask 255.255.128.0;
option subnet-mask 255.255.255.0;
subnet 192.168.0.0 netmask 255.255.128.0
subnet 192.168.1.0 netmask 255.255.255.0
{
option routers 192.168.1.1;
option subnet-mask 255.255.128.0;
option domain-name-servers 192.168.1.2;
option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.1.1;
range 192.168.1.10 192.168.1.20;
range 192.168.1.100 192.168.1.200;
}

View File

@ -1,11 +1,9 @@
[SETUP]
num_radios=4
num_radios=3
start_iwd=0
[HOSTAPD]
rad2=ap-main.conf
rad3=ap-ns1.conf
rad0=ssidTKIP.conf
[NameSpaces]
ns0=rad0
ns1=rad3
ns0=rad2

View File

@ -3,4 +3,3 @@ EnableNetworkConfiguration=true
[Network]
EnableIPv6=true
NameResolvingService=resolvconf

Some files were not shown because too many files have changed in this diff Show More