Since the property Autoconnect was renamed to AutoConnect, change the
Autoconnect setting to match.
For now we still allow the legacy name to be used here, but a warning is
printed to remind users to update.
Relax the pre-check for local user certificate. Before we used to check
that the CA provided (if any) was used to verify both the peer identity
and the local certificate chain. However, there seem to be networks
that use different CAs to sign AP/Radius certificates and certificates
issued to users.
Drop the ca_certs argument from l_certchain_verify, but keep the call
there to make sure the certificate chain is indeed a chain as a sanity
check.
The commit/confirm processing was incorrectly subtracting 2 from
the length when they should be subtracting 6. As with the other
similar change, the length is validated with mpdu_validate so
subtracting 6 will not cause an overflow.
This function was returning a boolean and the expected return was
a signed integer. Since this function actually returned false in
all cases the check for a success (0) return always worked.
The comment about the 'standard code path' was removed as this is
no longer valid.
If an authentication frame of length <= 5 is sent sae will overflow an
integer. The original cause of this was due to incorrectly using the
sizeof(struct mmpdu_header). The header can be either 24 or 28 bytes
depending on fc.order. sizeof does not account for this so 28 is always
the calculated length.
This, in addition to hostapd not including a group number when rejecting,
cause this erroneous length calculation to be worked around as seen in
the removed comment. The comment is still valid (and described again
in another location) but the actual check for len == 4 is not correct.
To fix this we now rely on mpdu_validate to check that the authentication
frame is valid, and then subtract the actual header length using
mmpdu_header_len rather than sizeof. Doing this lets us also remove the
length check since it was validated previously.
A recent change checked the return value of ie_parse_rsne_from_data
inside the ptk 1/4 handler. This seemed safe, but actually caused
the eapol unit test to fail.
The reason was because eapol was parsing the IEs assuming they were
an RSN, when they could be a WPA IE (WPA1 not WPA2). The WPA case
does not end up using the rsn_info at all, so having rsn_info
uninitialized did not pose a problem. After adding the return value
check it was found this fails every time for WPA1.
Since the rsn_info is not needed for WPA1 we can only do the RSN
parse for WPA2 and leave rsn_info uninitialized.
The intent here was to validate that the frequency is a multiple of 5
and lies in a certain range. Somehow the channel was checked for being
a multiple of 5 instead.
The logic here intended to check whether all required attributes were
available. However, it set the parse_error to true instead of
have_required to false as intended.
Replace uses of strcpy by the safer l_strlcpy. Note that both of these
functions can only be called with a buffer of max 253 bytes (the
identity string), so this is purely a precautionary measure.
Technically there's no problem here as l_queue_remove does not
dereference the pointer. Still, it confuses certain static analysis
tools in the current form. Reordering this will not change the behavior
at all.
This was refactored to set the mtu via __eap_set_config rather than
passing the MTU into eap_init. This makes eap work in a similar fashion
as eapol (i.e. __eapol_set_config).
If __eap_set_config is not used, the MTU will be set to 1020, which is
the same as previously passing 0 to eap_init.
Since iwd_modules_init is now defered until nl80211_appeared, we can
assume the nl80211 object is available. This removes the need for
netdev_set_nl80211 completely.
In preparation for integrating IWD_MODULE into modules which require
nl80211 we move the module init into the nl80211_appeared callback.
This will guarentee that the nl80211 is available during module init
and allow modules to get their own copy of nl80211 rather than needing
a set function (e.g. netdev_set_nl80211).
Since the dbus name request callback happens before this as well any
dbus module can also use IWD_MODULE and simply assume the dbus object
is ready.
plugin_init was also deferred to nl80211_appeared since some plugins
depend on modules being initialized.
Converts agent into an IWD module. This removes the dbus dependency
on agent. Since dbus is initialized very early we can assume
dbus_get_bus is going to return a valid object.
Previously, station state 'connected' used to identify an interface associated
with AP. With the introduction of netconfig, an interface is assumed to be
connected after the IP addresses have been assigned to it. If netconfig is
disabled, the behavior remains unchanged.
Refactoring was required to allow for embedded certs. The existing
eap_tls_state object was changed to hold the cert types (l_queue,
l_certchain, l_key) rather than the file path, since there may not
actually be separate PEM files.
Care was taken to properly manage the memory of these objects.
Since the TLS object takes ownership when setting auth data or the
CA certs all error cases must be handled properly to free these
objects after they are loaded and in addition they must be set to
NULL so that the cleanup doesn't double free them.
If everything goes to plan, we load all the PEMs in settings_load,
provide these objects to the TLS APIs, and then NULL out the
pointers (TLS now owns this memory). If anything fails between
settings_load and l_tls_start we must free these objects.
A special format must be used to indicate that a PEM is embedded
inside the settings file. First, the l_settings format should be
followed for the PEM itself, e.g.
[@pem@my_ca_cert]
<CA Cert data>
This PEM can then be referenced by "embed:my_ca_cert", e.g.
EAP-TLS-CACert=embed:my_ca_cert
Any other value not starting with "embed:" will be treated as a file
path.
The IPv6 default route needs to be explicitly revoked. Unlike in IPv4,
there is no SRC address associated with the route and it will not be
removed on address removal.
The network configuration options for IPv6 are grouped under [IPv6]
and include the following:
ip= ADDRESS/PREFIX
gateway=ADDRESS
dns=ADDRESS
The placeholders for DHCPv6 are placed along the way and marked
as TODO items.
Previously, netconfig_ipv4_select_and_install was used to install
addresses on initial connection to a network and after we have roamed.
Now for the after roaming connection scenario we have
netconfig_reconfigure. Remove roaming related code from
netconfig_ipv4_select_and_install
As part of the de-coupling from station object, switch all of
the network settings inquiries to use active_settings. active_settings
are set with netconfig_configure by the owner of netconfig object
and removed with netconfig_reset once network disconnects.
Instead of relying on station state changed signal, netconfig
introduces three new API calls to configure, re-configure and
reset the network configurations. The owner of netconfig object
is responsible for initiating the re-configuration of the device
depending on its state.
As a first step to enable the usage of netconfig in ead and
prospective transition to be a part of ell, the public API for
creation and destruction of the netconfig objects has been
renamed and changed. Instead of hiding the netconfig objects inside
of netconfig module, the object is now passed back to the caller.
The internal queue of netconfig objects remains untouched, due
to limitations in ell’s implementation of rtnl. After the proper
changes are done to ell, netconfig_list is expected to be removed
from netconfig module.
A NEW_WIPHY event may not always contain all the information about a
given phy, but GET_WIPHY will. In order to get everything we must
mimic the behavior done during initalization and dump both wiphy
and interfaces when a NEW_WIPHY comes in.
Now, any NEW_WIPHY event will initialize a wiphy, but then do a
GET_WIPHY/GET_INTERFACE to obtain all the information. Because of
this we can ignore any NEW_INTERFACE notifications since we are
dumping the interface anyways.
Once some kernel changes get merged we wont need to do this anymore
so long as the 'full' NEW_WIPHY feature is supported.
If the AP sent us the plain passphrase we can now store that rather
than generating the PSK. This will allow WPA3 to work properly when
WPA3 + WSC is implemented.
This lets other modules (like WSC) to set a plain text passphrase
as opposed to only allowing a PSK to be set. network_get_psk was
also updated to generate a PSK on-the-fly if required. Since WPA3
requires the raw passphrase to work, it makes sense to just store
the passphrase if we have it.
If neighbor reports are unavailable, or the report yielded no
results we can quickly scan for only known frequencies. This
changes the original behavior where we would do a full scan
in this case.
This password key was deprecated in favor of the common EAP-Password
key. Its been about a year so we are now removing support entirely
for EAP-PWD-Password.
Gets a newly created scan_freq_set containing the most recent
frequencies for the network. The currently connected BSS frequency
(passed as a parameters) will not be included in the set.
Since the UUID was being generated purely on the file path, it
would never change for a given network (unless the SSID/name changed).
In the future we would like to use this unique UUID to generate a
MAC per-SSID, and if that network is forgotten we also want the UUID
to change next time the network is connected to.
Rather than only using the file path, the mtime can also be fed into
the UUID generation. Since the mtime would be changed after forgetting
and re-adding a known network we will get a new UUID.
Now, whenever a known network is removed, we lookup the UUID we have
in network_info and remove that entry in the settings file and
sync the frequency file.
The UUID was being generated every time we synced which is wasteful.
Instead we can track the UUID inside network_info and only generate
it once when needed.
Two new network_info APIs were added:
network_info_set_uuid
network_info_get_uuid
The setter is used when the frequency file is loaded. If a valid UUID
is found in the frequency file this UUID is set and used.
network_info_get_uuid will not just get the UUID, but actually generate
it if one has not been set yet. This will allow other modules to
get/generate the UUID if one has no been loaded from the frequency
file.
The QoS Map can come in either as a management frame or via the
Associate Response. In either case this IE simply needs to be
forwarded back to the kernel.
The extended capability bits were not being set properly inside
wiphy. Since we build the IE after the wiphy dump the first 2
bytes are the IE type and length. The way we were setting the bits
did not take this into account and were actually setting the
completely wrong bits.
The known frequency file was being loaded at the end of the known
networks initialization routine. This allowed all known networks
to be properly loaded, but since hotspot depends on known networks,
its initalization would be run afterwards meaning the frequency
loading would not have been finding any hotspot networks.
To fix this a new module was added inside known networks which
depends on hotspot. This means that first known networks will
initialize, then hotspot, then the frequency file would be loaded.
The current format for the .known_networks.freq file had a hidden
limitation of not being able to handle SSID's with some special
characters. Since the provisioning file path was used as the
group name the filename was limited to only characters supported
by l_settings groups, which conflicted with allowable SSID
characters.
Instead we can generate a unique UUID for each network and use
this as the group. For this particular case the group does not
really matter, so long as its unique. But we can utilize this unique
UUID for other purposes, including using it as a seed for changing
the MAC address per-connection in the future.
The .known_networks.freq file will now have the following format:
[<UUID>]
name=/path/to/provisioning/file
list= XXXX YYYY ZZZZ
The existing frequency syncing was done when IWD closes. Instead we
can sync as networks are connected to or promoted to known which
will keep the FS more up to date. This also allows hotspot networks
to use the known frequency file.
This API will sync the known frequencies of a network_info object
to disk. This will allow network to sync known frequencies as
known networks are added, rather that when IWD closes.
Since this will result in more frequent syncing that before, the
known_freqs settings pointer was moved globally in knownnetworks.c
as to only parse the file one time rather than on every sync.
Some of the EAP-PEAP server implementations seem to require a
cleartext ACK for the tunneled EAP-Success message similar to EAP-TLS
specification, instead of simply shutting down the tunnel like
EAP-PEAPv1 requires.
ACKing the tunneled EAP-Success seems also to work for implementations
which were relying on the tunnel close event.
create_dirs was dependent on the path ending in '/' to create the
full path. The hotspot code did not include a '/' at the end so
it was not getting created, which prevented the hotspot module
from initializing.
Station was building up the HS20 elements manually. Now we can
use this new API and let network take care of the complexity
of building network specific vendor IEs.
This op builds up the vendor IEs required for hotspot 2.0. The
version, and optionally the RC are provided in order to correctly
build the HS20 Indication Element and RC Selection element.
The HS20 module had its own getter for returning the matched roaming
consortium. Since we already have the network_info op for matching
we might as well return the matched RC rather than just a bool. This
allows the RC to be included in (Re)Association without the need for
a specific getter.
When performing a fast transition to another OPEN network the RSN
element won't be there and therefore the bss->rsne is gonna be NULL.
Fix crash by not accessing the rsne member when performing a fast
transition to an AP that doe snot advertise any RSN IE.
Crash caught with gdb:
src/station.c:station_transition_start() 186, target 34:8f:27:2f:b8:fc
Program received signal SIGSEGV, Segmentation fault.
handshake_state_set_authenticator_ie (s=0x555555626eb0, ie=0x0) at src/handshake.c:163
163 s->authenticator_ie = l_memdup(ie, ie[1] + 2u);
(gdb) bt
#0 handshake_state_set_authenticator_ie (s=0x555555626eb0, ie=0x0) at src/handshake.c:163
#1 0x0000555555561a98 in fast_transition (netdev=0x55555562fbe0, target_bss=0x55555561f4a0,
over_air=over_air@entry=true, cb=0x55555556d5b0 <station_fast_transition_cb>) at src/netdev.c:3164
#2 0x0000555555565dfd in netdev_fast_transition (netdev=<optimized out>, target_bss=<optimized out>,
cb=<optimized out>) at src/netdev.c:3232
#3 0x000055555556ccbd in station_transition_start (bss=0x55555561f4a0, station=0x555555617da0)
at src/station.c:1261
#4 station_roam_scan_notify (err=<optimized out>, bss_list=<optimized out>, userdata=0x555555617da0)
at src/station.c:1444
#5 0x0000555555579560 in scan_finished (sc=0x55555562bf80, err=err@entry=0, bss_list=0x55555561bd90,
sr=0x555555626b30, wiphy=<optimized out>) at src/scan.c:1234
#6 0x0000555555579620 in get_scan_done (user=0x555555618920) at src/scan.c:1264
#7 0x00005555555abd23 in destroy_request (data=0x55555561b000) at ell/genl.c:673
#8 0x00005555555ac129 in process_unicast (nlmsg=0x7fffffffc310, genl=0x55555560b7a0) at ell/genl.c:940
#9 received_data (io=<optimized out>, user_data=0x55555560b7a0) at ell/genl.c:1039
#10 0x00005555555a8aa3 in io_callback (fd=<optimized out>, events=1, user_data=0x55555560b840)
at ell/io.c:126
#11 0x00005555555a7ccd in l_main_iterate (timeout=<optimized out>) at ell/main.c:473
#12 0x00005555555a7d9c in l_main_run () at ell/main.c:520
#13 l_main_run () at ell/main.c:502
#14 0x00005555555a7fac in l_main_run_with_signal (callback=<optimized out>, user_data=0x0)
at ell/main.c:642
#15 0x000055555555e5b8 in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:519
After wsc_store_credentials, wsc_try_credentials is called which
sets the PSK obtained via the protocol. After the known network
refactor network_settings_load was changed to depend on the
network_info->open() call. Since there is no known network for
this initial WSC connection this always fails and the PSK is not
set into the network object (and the connection is failed).
In this case if network_settings_load fails we can just create
an empty settings object to be filled later.
known_network_update was being used to both update and create known
networks as they appeared on the file system. Hotspot needs updating
capabilities so known_network_update was exposed and updated with
one major difference; it no longer can be used to create new known
networks. For creation, a new API was added (known_network_new)
which will create and add to the queue.
Since hotspot networks may require ANQP the autoconnect loop needed to
be delayed until after the ANQP results came back and the network
objects were updated. If there are hotspot networks in range ANQP will
be performed and once complete autoconnect will begin for all networks
including hotspots. If no hotspots are in range autoconnect will
proceed as it always has.
Note: Assuming hotspots are in range this will introduce some delay
in autoconnecting to any network since ANQP must come back. The full
plan is to intellegently decide when and when not to do ANQP in order
to minimize delays but since ANQP is disabled by default the behavior
introduced with this patch is acceptable.
The remove op was being called inside known_networks_remove, which only
gets called from L_DIR_WATCH events. In this case the actual provisioning
has already been removed. Calling remove() again causes the op
implementation to then try and remove the file that no longer exists.
Valgrind does not like uninitialized bytes used in a syscall. In this
case the buffer is an out buffer but since valgrind doesn't know that
it complains. Initializing to zero fixes the warning:
Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
at 0x5162C4D: send (send.c:28)
by 0x457AF4: l_checksum_update (checksum.c:319)
by 0x43C03C: eap_wsc_handle_m2 (eap-wsc.c:842)
by 0x43CD33: eap_wsc_handle_request (eap-wsc.c:1048)
by 0x43A3A7: __eap_handle_request.part.0 (eap.c:266)
by 0x41A426: eapol_rx_packet.part.12 (eapol.c:2262)
by 0x41B536: __eapol_rx_packet (eapol.c:2650)
by 0x407C80: netdev_control_port_frame_event (netdev.c:3542)
by 0x407C80: netdev_unicast_notify (netdev.c:3684)
by 0x4598C5: dispatch_unicast_watches (genl.c:899)
by 0x4598C5: process_unicast (genl.c:918)
by 0x4598C5: received_data (genl.c:1039)
by 0x456452: io_callback (io.c:126)
by 0x45569D: l_main_iterate (main.c:473)
by 0x45576B: l_main_run (main.c:520)
Address 0x1ffeffe290 is on thread 1's stack
in frame #2, created by eap_wsc_handle_m2 (eap-wsc.c:797)
We were not using or taking into account the noencrypt flag obtained
from the kernel via CONTROL_PORT events. For the most part this still
worked as the kernel would never include NO_ENCRYPT flag (due to a bug).
However, this was actually incorrect and led to loss of synchronization
between the AP and STA 4-Way handshake state machines when certain
packets were lost and had to be re-transmitted.
Allow users to provide a glob string that the contents of the server
certificate's subject DN should be matched against as a primitive
protection against rogue APs using certificates purchased from
commercial CAs trusted by the client. If the network uses an AP
certificate emitted by a commerical CA and the clients are configured
to trust those CAs so that the client configurations don't have to be
updated when the AP renews its certificate, this new option can be used
to check if the CN in the AP certificate's DN matches the known domain
name. This logic assumes that the commercial CAs provide enough
assurance that only the owner of the domain can buy a certificate with
that domain in the CN field.
The format of this option is similar to apple's TLSTrustedServerNames
and wpa_supplicant's domain_match/domain_suffix_match format, the exact
syntax is documented in ell/tls.c.
Some capability bits are required by the spec to be set for
probe requests for certain features (HS20, FILS, FT). Currently
these features work as-is, but depending on the hardware we may
be in violation of the spec if we assume the correct bits are
set when we get the wiphy dump.
Just to be safe we can explicity set these capability bits.
There are also two ways the kernel exposes these capabilities.
Per-type or globally. The hardware may expose one, or both of
these capability arrays. To combat this we are now always
creating a per-type capability array for stations. If the
wiphy dump has not produced a per-type capability array we
now create one based off the global capability array. That
way we can always assume there is a capability array for a
station iftype.
This will be seen in Probe Requests. More IEs can and should
be added here depending on the support in IWD. E.g. HS20 indication,
Interworking, HT/VHT IE's etc.
In order to implement get_name/get_type we need some value for the name
of the hotspot network. For simplicity we now require a 'Name' value
be provided inside the hotspot provisioning file. Eventually this may
change (e.g. obtained via ANQP).
Rather than using timespec directly, ELL has a convenient API
to get the elapsed microseconds as a uint64_t. This can then
be used with the other l_time_ APIs for comparison.
This patch removes timespec from network_info and updates
to use l_time_* API's for sorting.
These operations will allow the hotspot module to implement
matching HESSID, Roaming Consortium, and NAI realms. This offloads
the matching details into the hotspot module.
This way resolve_remove can be called once per interface and
remove IPv4 and IPv6 addresses at once.
In addition, this allows to remove the IP addresses and DNS
servers within the same main loop cycle. This will allow iwd
to make an attempt to remove the DNS servers on shutdown of iwd.
These two API's have been added to allow hotspot to add its
own networks to the known network list. This will allow any
added networks to behave exactly like they do now, including
all the dbus and watchlist functionality.
The known network APIs all revolved around the ssid/security matching
to do any operations on the provisioning file. In the near future
hotspot provisioning files (managed by hotspot.c) will be incorporated
into the known network list. Since these hotspot files do not use the
ssid as the file name hotspot.c will need other ways of matching.
This patch adds network_info_ops to the network object. This ops
structure will hold function pointers which operate on network_info
rather than ssid/security. This will allow hotspot and known networks
to both register their own operation routines.
For now open, touch, sync, remove, free, and get_path were added.
Wrappers were added for accessing these operations outside of
knownnetworks.c.
Isolate the known_frequency queue management to a function and place
that function in knownnetworks.c where it now belongs. Since we no
longer have network_info objects for unknown networks, only frequencies
for known networks are tracked
networks queue was intended to share basic network information between
multiple adapters running simultaneously. The network_info object was
also serving double duty to carry known network information. This made
things overly complicated and really didn't result in much savings.
This setup also made managing hotspot networks challenging as we would
have ended up with multiple network_info objects for each known hotspot
network.
So get rid of the networks queue and the is_known bit from the
network_info structure.
network_find_rank_index was used to find the offset of the selected
network_info among known networks so as to compute a modifier based on
the rankmod table. Instead of using known_networks_foreach for this,
moove it to knownnetworks.c where it can be coded and optimized
separately.
For now provide a simple for loop implementation.
Previously, the option PrivateDevices=true disabled access to
/dev/rfkill, which lead to:
'iwctl adapter phy0 set-property Powered {off|on}'
to fail.
This patch explicitly allows access to /dev/rfkill
src/rtnlutil.c: In function ‘rtnl_route_add’:
./ell/util.h:248:2: error: ‘rtmmsg’ may be used uninitialized in
this function [-Werror=maybe-uninitialized]
Instead of using a flag ipv4_static, just store the value of the rtm
protocol directly inside netconfig object. This allows us to simplify
the logic quite significantly and avoid repeating the conditional
expression needlessly
The routes are installed as a result of a successful installation
of the IP addresses. The gateway is fetched with netconfig_ipv4_get_gateway
helper function according to the origin of the installed IP address.
The route priority offset can be set in main.conf. The default value
of 300 is used if the offset isn’t set.
The API allows to add connected and gateway routes to the main
routing table.
rtnl_route_ipv4_add_gateway() is equivalent to the following
example 'ip route' command:
ip route add default via 10.0.0.1 dev wlan0 proto dhcp src 10.0.0.2 metric 339
rtnl_route_ipv4_add_connected() is equivalent to the following
example 'ip route' command:
sudo ip route add 10.0.0.0/24 dev wlan0 proto dhcp src 10.0.0.2 scope link
The 'ip route' output from the above commands looks as follows:
rtnl_route_ipv4_add_connected():
10.0.0.0/24 dev wlan0 proto dhcp scope link src 10.0.0.2
rtnl_route_ipv4_add_gateway():
default via 10.0.0.1 dev wlan0 proto dhcp src 10.0.0.2 metric 339
The DNS addresses are installed as a result of a successful
installation of the IP addresses. The DNS lists are fetched
with netconfig_ipv4_get_dns helper function according to the
origin of the installed IP address.
iwd reconfigures the wireless interfaces with respective
connection events. Each supported network protocol is
reconfigured. The address for each protocol is
selected as static or dynamic based on availability.
netconfig_ipv4_get_ifaddr helper function allows to fetch IPv4
addresses from static or dynamic sources. The origin of the addresses
is noted in 'ipv4_is_static' flag.
For (Re)Association the HS20 indication element was passed exactly as
it was found in the scan results. The spec defines what bits can be
set and what cannot when this IE is used in (Re)Association. Instead
of assuming the AP's IE conforms to the spec, we now parse the IE and
re-build it for use with (Re)Association.
Since the full IE is no longer used, it was removed from scan_bss, and
replaced with a bit for HS20 support (hs20_capable). This member is
now used the same as hs20_ie was.
The version parsed during scan results is now used when building the
(Re)Association IE.
The parser fully parses the IE and returns the version, Domain ID,
and PPS MO ID. This is meant to be used with an IE in scan results.
The builder only takes the version number, and assumes DGAF disabled,
and no Domain ID or PPS MO ID.
Previously, iwd used to throw net.connman.iwd.Busy when connection
attempt was made while connected. The new behavior allows iwd to
seamlessly disconnect from the connected network and attempt a new
connection.
Since NAI realms, Roaming Consortium and HESSID are defined in 802.11,
they are not a guarentee that the network is Hotspot 2.0. The indication
element in addition to these IE's gives a better idea of Hotspot 2.0
support. Now, when a BSS is added this is_hs20 boolean will get set to
true if the HS20 IE was found in the BSS.
Now, if is_hs20 is set AND one of NAI realms, roaming consortium, or
HESSID is set we know this is a hotspot 2.0 network.
It is possible for a zero-length anti-clogging token payload to cause
IWD to abort. If the length passed into sae_process_anti_clogging was
1, l_memdup would be called with a size of -1. This will cause malloc
to abort.
Fix this by checking for a minimum packet length and dropping the
packet if the length is too small.
The HS20 indication element should always be included during
(Re)Association per the spec. This removes the need for a
dedicated boolean, and now the hs20_ie can be used instead.
The hotspot spec specifically mentions the roaming consortium OI be
3 or 5 bytes long. This requirement also prevents potential buffer
overflows if the user were to configure a long roaming consortium OI.
If the scan was triggered and later aborted, make sure to reset the
triggered value when the CMD_NEW_SCAN_RESULTS event comes in.
src/station.c:station_enter_state() Old State: disconnected, new state: connecting
src/scan.c:scan_notify() Scan notification 33
src/station.c:station_netdev_event() Associating
src/scan.c:scan_notify() Scan notification 34
Aborting (signal 11) [/home/denkenz/iwd-master/src/iwd]
++++++++ backtrace ++++++++
#0 0x7efd4d6a2ef0 in /lib64/libc.so.6
#1 0x42b20d in scan_notify() at src/scan.c:1383
In the same fashion as the WSC WFA OUI, ie.[ch] will now expose the
other vendor OUIs to avoid duplication across multiple files in IWD
as well as used in iwmon.
P2P probe requests are to be sent at min 6.0 Mb/s using OFDM,
specifically the 802.11b rates are prohibited (section 2.4.1 in Wi-Fi
P2p Technical Spec v1.7), some of which use CCK modulation. This is
already the default for 5G but for 2.4G the drivers generally do this
if we set the NL80211_ATTR_TX_NO_CCK_RATE flags with
NL80211_CMD_TRIGGER_SCAN.
The length check was incorrectly assuming that PPS MO ID or
ANQP Domain ID would be present in the IE. Both these are optional
and without then the minimum length is 5 bytes, not 7.
Per the hotspot 2.0 spec, if a matching roaming consortium OI is
found it should be added to the (Re)Association request. vendor_ies
can now be provided to netdev_connect, which get appended to the IE
attribute.
This API will attempt to find a matching roaming consortium OI
if present in the config file. A single matching OI is returned
or NULL if one was not found.
Hotspot 2.0 network providers allow 'roaming' between a users home
network and other providers networks, assuming they are part of the
same roaming consortium. The roaming consortium is advertised as an
IE in beacon/probe frames.
In terms of the hotspot config files this is similar to HESSID, where
if the AP advertises the roaming consortium IE, and the config file
matches we do not need to do ANQP in order to connect.
This is duplicated when the first scan_bss is added to a network
object that contains the IE. Any future BSS's added will not re-add
the IE. Its assumed that all BSS's under a network will contain the
same roaming consortium OIs.
Parses up to 3 (the max) roaming consortium OIs out of the roaming
consortium IE. If more OIs are available via ANQP the 'num_anqp_out'
value will be set to indicate how many more OIs are available.
Builds according to the hotspot 2.0 spec using the vendor specific
IE.
Declare structures to hold the parsed contents of the P2P IEs and WSC
IEs in P2P-related frames and add functions to free memory used by
those structures.
Define structs and types for most P2P attributes and p2p_parse_attrs
similar to wsc_parse_attrs -- a generic parser for attributes in a P2P
IE payload. This parser may write into the provided buffer even on
error but it's private to p2putil.c. The local callers will take care
of keeping the user-provided buffers untouched on error.
Add a utility for building the simplified WSC IEs used in P2P action
frames and public action frames. Only three types of WSC attributes are
mandatory in those frames (but different subsets are needed by different
frame types) so add a single utility for building those IEs. We may
need to add some more optional attributes to those IEs later.
The ifindex is used to index the netdevs in the system (wlan, ethernet,
etc.) but we can also do wifi scanning on interfaces that have no
corresponding netdev object, like the P2P-device virtual interfaces.
Use the wdev id's to reference interfaces, the nl80211 api doesn't care
whether we use a NL80211_ATTR_IFINDEX or NL80211_ATTR_WDEV. Only
wireless interfaces have a wdev id.
Save the actual cmd_id returned from l_genl_family_dump and zero it in
the get_scan_done. There's no need to zero it in scan_cancel because
get_scan_done gets called automatically.
Store the scan_context pointer in scan_results directly instead of
storing the ifindex. We now cancel ongoing GET_SCAN commands when the
scan_context is being freed so there's no point going through the extra
step of looking up the scan_context by ifindex inside the command
callback to guard against non-existent scan_contexts.
method.ops is NULL, which causes method.ops->exit to crash. This
adds a check that method.ops is not NULL before dereferencing.
Fixes:
Aborting (signal 11) [/home/jprestwo/iwd/src/iwd]
++++++++ backtrace ++++++++
0 0x7f016b59cf20 in /lib/x86_64-linux-gnu/libc.so.6
1 0x432057 in resolve_exit() at /home/jprestwo/iwd/src/resolve.c:295
2 0x403b61 in iwd_modules_exit() at /home/jprestwo/iwd/src/main.c:195
3 0x7f016b57fb97 in /lib/x86_64-linux-gnu/libc.so.6
+++++++++++++++++++++++++++
The original idea was to allow the provisioning file to include HESSID
without the NAIRealmNames. Configuring this way would allow for ANQP
to be skipped completely, assuming the AP advertises its HESSID.
The way the code was written still required NAIRealmNames to be
provided in the provisioning file.
The framework enables the service specific implementations
to provide its own variations for the DNS installation tasks.
The selection of the address resolution service can be done
through dns_resolve_method setting.
The module is responsible for the configuration of the address
resolution services. It will consist of the multiple service
specific plugins such as: systemd-resolved plugin, dnsmasq
plugin, etc.
If supported by the driver, we can create an interface directly with a
random MAC if configured to do so. If the driver does not have this
capability, then tell netdev to perform the necessary logic as part of
the interface initialization procedure.
#0 0x7f5e25e71930 in /lib64/libc.so.6
#1 0x446faa in hs20_config_free() at src/hotspot.c:63
#2 0x469542 in l_queue_clear() at ell/queue.c:109
#3 0x4694e7 in l_queue_destroy() at ell/queue.c:83
#4 0x4475c1 in hotspot_exit() at src/hotspot.c:273
#5 0x403170 in iwd_modules_exit() at src/main.c:195
#6 0x404085 in main() at src/main.c:531
#7 0x7f5e25e5cbde in /lib64/libc.so.6
Regulatory domain management is now completely handled by the kernel, so
iwd doesn't really need to query or be aware of changes to this. This
may change in the future, but for now this code has not been used and
can be safely gotten rid of.
After a scan, station can now pause future scans and start ANQP requests
to discover Hotspot's NAI realm. This lets us check if the AP's NAI realm
matches any stored hotspot configuration files. If so we can connect to
this network. If the network provides an HESSID and a matching one is
found in a hotspot provisioning file we can skip ANQP and directly connect
as this is expected to be our 'home network'
The actual ANQP request was handled by netdev, but in the case of P2P
their may be no netdev. For this reason all functionality needed for
an ANQP request has been moved into anqp.c. There are still a few netdev
references, which need to be removed when P2P is introduced. Leaving them
in for now as its still going to work as a first pass implementation
The initial ANQP parser design did not work well with how the hotspot
implementation was turning out. For one, much care was taken into parsing
the EAP credentials which are not really required. The assumption is
that any hotspot network will already be provisioned, so checking that
the EAP parameters match is a bit overkill. Instead only the NAI Realms
will be checked. This greatly simplifies the NAI realm parser, as now it
can just return a string list of realms instead of the full EAP
credential info.
This module will be in charge of managing Hotspot provisioning files
stored under the .hotspot/ directory. This includes a dir watch to
handle file changes/removal as well as an API to match a network
object to a hotspot provisioning file.
Hotspot networks are supposed to include an HESSID in the scan
results. This is more or less an identifier for the overall
network. In addition, the NAI Realms can be obtained via ANQP
and should be the same for each BSS. Since both HESSID and NAI
realms should be the same for a given network in range we can
store these values in the network object itself. This also allows
us to easily find hotspot configuration files by looking at
the HESSID/NAI Realms directly in the network object as opposed
to individual scan_bss's.
In order to do ANQP efficiently IWD needs the ability to suspend scanning
temporarily. This is because both scanning and ANQP go offchannel and must
remain off channel for some amount of time. This cannot be done
simultaneously and if e.g. ANQP is requested after a scan is already
pending, the kernel will wait till that scan finishes before sending out
the frame.
Use memset instead. explicit_bzero should only be used when we're
wiping a secret just prior to the encopassing storage being freed. The
compiler would usually optimize away the memset, leaving the secrets
around.
In rtnlutil we're simply zeroing the structure prior to filling it, so
the use of explicit_bzero is not needed and brings confusion to the
reader since no secrets are being wiped.
netconfig is interested in three station states: connected,
disconnected and connected after it has roamed. On connected
it tries to obtain a new DHCP lease, on disconnected it stops
the DHCP client and discards all addresses from interface, on
connected after roaming it will try to request a previously
issued address.
iwd keeps track of the addresses assigned to the managed
interfaces. The list of assigned IPv4/IPv6 addresses is stored
in ifaddr_list inside of netconfig. The tracking of the IP
addresses will help to remove them from an interface once they
are no longer valid.
netconfig module will be responsible for the orchestration
of the network configuration with the IP addresses.
iwd creates one netconfig structure per interface index.
The purpose of this struct is to hold all of the interface
related addressing states such as: assigned dhcp
clients, known addresses, routes, etc.
A not-yet-merged kernel patch will enable the FRAME_WAIT_CANCEL
event to be emitted when a CMD_FRAME duration expires. This can
shortcut the ridiculously long timeout that is required making
GAS requests with no response drastically quicker to handle.
This adds a new API netdev_anqp_request which will send out a GAS
request, parses the GAS portion of the response and forwards the
ANQP response to the callers callback.
This IE tells us what Advertisement Protocols the AP supports. This
is only here to look for ANQP support, so all this does is iterate
through all other Advertisement Protocol tuples looking for ANQP.
If found, anqp_capable is set in the scan_bss
Currently these are geared to support the WiFi Alliance Hotspot 2.0
ANQP elements, which all fall under the vendor specific ANQP element.
anqp_iter_next behaves similar to the genl parsers, where the id, length
and data will be returned as out parameters. Currently there is only
vendor support for Hotspot 2.0. anqp_iter_is_hs20 can be used to setup
the subtype, length, and data pointer to parse any Hotspot 2.0 ANQP
elements. From here the subtype can be checked and a vendor specific
parser for that subtype can be used to parse the data, e.g.
hs20_parse_osu_provider_nai.
The vendor specific IE was being parsed only to check if the AP supported
WPA, which used a Microsoft OUI. Hotspot/OSEN uses neither WPA or RSN
(although its nearly identical to RSN) so the we also need to check for
this Wifi-Alliance OUI and set bss->osen (new) if found.
The OSEN AKM uses the vendor specific IE, so when finding the RSNE
element we need to handle it specially to ensure that its both
a vendor specific element and it matches the WFA OUI since other
vendor specific elements may be included.
The OSEN AKM is nearly identical to the RSN IE, but differs slightly.
For one, OSEN is encapsulated into the vendor specific IE, and includes
the WFA OUI before the 'normal' RSN elements. OSEN also does not include
a WPA version, since its not technically WPA/WPA2.
Some of the RSN parsing was made common so both RSN/OSEN parsing could
use it.
The handshake object had 4 setters for authenticator/supplicant IE.
Since the IE ultimately gets put into the same buffer, there really
only needs to be a single setter for authenticator/supplicant. The
handshake object can deal with parsing to decide what kind of IE it
is (WPA or RSN).
The Hotspot 2.0 spec introduces 'Anonymous EAP-TLS' as a new EAP method
to be used with OSEN/Hotspot. The protocol details of this aren't
relevant to this patch, but one major difference is that it uses the
expanded EAP type rather than the TLS type. Since the common TLS code
was written with only EAP_TYPE_TLS in mind the vendor ID/type cause the
EAP packet to be malformed when using the expanded EAP type.
To handle this the common TLS code now checks the EAP type, and if its
expanded we shift the payload 7 bytes further to account for the extra
header data.
802.11 defines GAS (generic advertisement service) which can be used
to query supported advertisement protocols from an AP before
authentication/association. Hotspot/OSEN only care about the ANQP
protocol, but the way the IE is structured potentially requires
iterating through several tuples before you reach the ANQP protocol
identifier. Because of this we define all protocol identifiers.