If the request being cancelled by agent_request_cancel has already been
sent over dbus we need to reset pending_id, the timeout, call l_dbus_cancel
to avoid the agent_receive_reply callback (and crash) and perhaps start
the next request. Alternatively we could only reset the callback and not
free the request, then wait until the agent method to return before starting
the next request.
Move the cancelling of the eapol timeout from the end of step 1 to
step 3 to guard the whole handshake. At the end of step 1 stop the
EAPOL-Start timeout for the case of 802.1X authentication + a cached
PMKSA (not used yet.)
Some APs respond to Neighbor Report Requests with neighbor reports that
have a zero operating class value and a non-zero channel number. This
does not mean that the channel is in the same band that the reporting
AP operates in. Try to guess the band that the channel refers to out of
2.4 and 5GHz -- the bands supported by those APs.
wpa_supplicant also has this workaround in place.
SA Query procedure is used when an unprotected disassociate frame
is received (with frame protection enabled). There are two code
paths that can occur when this disassociate frame is received:
1. Send out SA Query and receive a response from the AP within a
timeout. This means that the disassociate frame was not sent
from the AP and can be ignored.
2. Send out SA Query and receive no response. In this case it is
assumed that the AP went down ungracefully and is now back up.
Since frame protection is enabled, you must re-associate with
the AP.
1. Enforce implementation of handle_request function
2. In case of unimplemented handle_retransmit try to use
handle_request instead and rely on method specific
mechanism to restart the conversation if necessary
3. Make method->free implementation unrequired
When we call scan_periodic_stop and a periodic scan is in progress (i.e.
the trigger callback has been called already) we get no new callback
from scan.c and the device Scanning property remains True forever so set
it to False.
The change from scan_periodic_stop to periodic_scan_stop looks silly but
it's consistent with our naming :)
This patch adds a watcher/parser for the frame event associated with
an AP directed BSS transition (AP roaming). When the AP sends a BSS
transition request, this will parse out the BSS candidate list
(neighbor report) and initiate a roam scan. After this point the
existing roaming code path is reused.
The identity retrieved from simauth was required to include the
prefix for SIM/AKA/AKA', but in reality a real SIM would not
include that prefix in the IMSI. Now the correct prefix is
prepended onto the identity depending on the EAP method.
If the SQN in AUTN is incorrect the simauth module will return
the AUTS parameter, which is sent back to the server and the
servers SQN number is updated.
Forcing a plugin to create and register simauth at once is sometimes
inconvenient. This patch separates the creation and registration
into two API's, and also adds several others to add the required simauth
data incrementally (identity, driver data, sim/aka support). This also
allows for the driver to unregister the auth provider without freeing
up the simauth object itself e.g. if the driver temporarily becomes
unavailable, but will come back sometime in the future.
The simauth watch API's were also renamed. Watchers will now get a
callback when the provider has been unregistered, so they have been
renamed to sim_auth_unregistered_watch_[add|remove].
src/simauth.c:163:6: error: no previous declaration for ‘sim_auth_cancel_request’ [-Werror=missing-declarations]
void sim_auth_cancel_request(struct iwd_sim_auth *auth, int id)
^~~~~~~~~~~~~~~~~~~~~~~
iwd now supports plugin loading, whitelisting and blacklisting. Both
the whitelist and the blacklist support multiple patterns separated by a
',' character.
Make sure device->autoconnect is set when entering the autoconnect state
after netdev UP event. Otherwise the next time
device_set_autoconnect(device, false) is called it will exit early seeing
that device->autoconnect is false and not switch the device state.
This is the core module that takes care of registering
authentication drivers. EAP-SIM/AKA will be able to acquire
a driver that supports the required algorithms. The driver
implementation (hardcoded/ofono etc.) is isolated into
separate plugin modules.
EAP-SIM/AKA/AKA' retrieve the EAP-Identity off the SIM card
not from the settings file. This adds a new EAP method API
which can optionally be implemented to retrieve the identity.
If get_identity is implemented, the EAP layer will use it to
retrieve the identity rather than looking in the settings file.
network_settings_load expects NULL value to be returned
on failed attempts to read the settings files inside of
storage_network_open. At the same time storage_network_open
used to always return an initialized l_settings
structure despite the outcome of the read operations,
indicating a success.
When the 4-Way Handshake is done eapol.c calls netdev_set_tk, then
optionally netdev_set_gtk and netdev_set_igtk. To support the no group
key option send the final SET STATION enabling the controlled port
inside the callback for the netdev_set_tk operation which always means
the end of a 4-Way Handshake rather than in the netdev_set_gtk callback.
The spec says exactly that the controlled port is enabled at the end of
the 4-Way Handshake.
The netlink operations will still be queued in the same order because
the netdev_set_tk/netdev_set_gtk/netdev_set_igtk calls happen in one
main loop iteration but even if the order changed it wouldn't matter.
On failure of any of the three operations netdev_setting_keys_failed
gets called and the remaining operations are cancelled.
Track the contents and size of the GTK and IGTK and if the Authenticator
(or an adversary) tries to set the same GTK/IGTK, process the packet
normally but do not resubmit the GTK/IGTK to the kernel.
GTK KDE was being checked for being a minimum of 6 bytes. Not quite
sure why since the minimum GTK key length is 16 bytes for CCMP.
Similarly make sure that the maximum length is not more than 32, which
is currently the largest key size (TKIP)
This is a bizarre case since MIC calculation succeeded for the incoming
packet. But just in case MIC calculation fails for the outgoing packet,
kill the handshake.
The comments quoted sections of the specification that indicated STA
behavior for verifying Message 3 of 4 or GTK 1 of 2. But in reality the
code directly below simply calculated the MIC for Message 4 of 4 or GTK
2 of 2.
Use eapol_frame_watch_add/eapol_frame_watch_remove in eapol_sm, while
there simplify the early_frame logic and confirm sender address for
received frames.
Set all the new field values into struct sta_state only after all the
error checks for better readabilty and fixing a possible issue if we
did "sta->rates = rates" and then detected en error and freed "rates".
Also update a comment which I think used the wording from 802.11-2012
instead of 802.11-2016.
DEL_KEY is not needed and will return errors right after NEW_STATION or
right after DEL_STATION. In both cases the kernel makes sure there are
no old keys for the station already.
As a temporary DBus API to switch between Station and Access Point
modes, add two methods on the Device interface. Add a new state
DEVICE_STATE_ACCESS_POINT which is in effect from the moment
StartAccessPoint is received (even before it returns) until
StopAccessPoint returns, there are no intermediate states when the
methods run for simplicity. Add checks across device.c to make sure
Station related functionality is disabled when in Access Point mode.
Add a utility to append a KDE to the key_data field in an EAPoL frame.
The KDE types enum is actually added to handshake.h because we've got
the utilities for finding those KDEs in a buffer there. The new
function is specific to EAPoL-Key frames though and perhaps to simple to
be split across handshake.c and eapol.c. Also it didn't seem useful to
use the ie_tlv_builder here.
Parse Association Request frames and send Association Responses, handle
Disassociation. With this we should be able to receive uncontrolled
port data frames since we register the STAs with the kernel.
In this version I don't register for Reassociation frames.