IE elements in various management frames are ordered. This ordering is
outlined in 802.11, Section 9.3.3. The ordering is actually different
depending on the frame type. Instead of trying to implement the order
manually, add a utility function that will sort the IEs in the order
expected by the particular management frame type.
Since we already have IE ordering look up tables in the various
management frame type validation functions, move them to global level
and re-use these lookup tables for the sorting utility.
This refactors some code to eliminate getting the ERP entry twice
by simply returning it from network_has_erp_identity (now renamed
to network_get_erp_cache). In addition this code was moved into
station_build_handshake_rsn and properly cleaned up in case there
was an error or if a FILS AKM was not chosen.
The authorized macs pointer was being set to either the wsc_beacon
or wsc_probe_response structures, which were initialized out of
scope to where 'amacs' was being used. This resulted in an out of
scope read, caught by address sanitizers.
One of these message buffers was overflowing due to padding not
being taken into account (caught by sanitizers). Wrapped the length
of all message buffers with EAP_SIM_ROUND as to account for any
padding that attributes may add.
The network_config was not being copied to network_info when
updated. This caused any new settings to be lost if the network
configuration file was updated during runtime.
The RoamThreshold5G was never honored because it was being
set prior to any connections. This caused the logic inside
netdev_cqm_rssi_update to always choose the 2GHz threshold
(RoamThreshold) due to netdev->frequency being zero at this time.
Instead call netdev_cqm_rssi_update in all connect/transition
calls after netdev->frequency is updated. This will allow both
the 2G and 5G thresholds to be used depending on what frequency
the new BSS is.
The call to netdev_cqm_rssi_update in netdev_setup_interface
was also removed since it serves no purpose, at least now
that there are two thresholds to consider.
Under certain conditions, access points with very low signal could be
detected. This signal is too low to estimate a data rate and causes
this L_WARN to fire. Fix this by returning a -ENETUNREACH error code in
case the signal is too low for any of the supported rates.
Transition Disable indications and information stored in the network
profile needs to be enforced. Since Transition Disable information is
now stored inside the network object, add a new method
'network_can_connect_bss' that will take this information into account.
wiphy_can_connect method is thus deprecated and removed.
Transition Disable can also result in certain AKMs and pairwise ciphers
being disabled, so wiphy_select_akm method's signature is changed and
takes the (possibly overriden) ie_rsn_info as input.
This indication can come in via EAPoL message 3 or during
FILS Association. It carries information as to whether certain
transition mode options should be disabled. See WPA3 Specification,
version 3 for more details.
Some network settings keys are set / parsed in multiple files. Add a
utility to parse all common network configuration settings in one place.
Also add some defines to make sure settings are always saved in the
expected group/key.
This returns the length of the actual contents, making the code a bit
easier to read and avoid the need to mask the KDE value which isn't
self-explanatory.
Instead of requiring each auth_proto to perform validation of the frames
received via rx_authenticate & rx_associate, have netdev itself perform
the mpdu validation. This is unlikely to happen anyway since the kernel
performs its own frame validation. Print a warning in case the
validation fails.
There's no reason why a change in groups would result in the
anti-clogging token becoming invalid. This might result in us needing
an extra round-trip if the peer is using countermeasures and our
requested group was deemed unsuitable.
We may receive multiple anti-clogging request messages. We memdup the
token every time, without checking whether memory for one has already
been allocated. Free the old token prior to allocating a new one.
The group was not checked at all. The specification doesn't
mention doing so specifically, but we are only likely to receive an Anti
Clogging Token Request message once we have sent our initial Commit. So
the group should be something we could have sent or might potentially be
able to use.
In case an exceptional condition occurs, handle this more consistently
by returning the following errors:
-ENOMSG -- If a message results in the retransmission timer t0 being
restarted without actually sending anything.
-EBADMSG -- If a received message is to be silently discarded without
affecting the t0 timer.
-ETIMEDOUT -- If SYNC_MAX has been exceeded
-EPROTO -- If a fatal protocol error occurred
Now that sae_verify_* methods no longer allow dropped frames though,
there's no reason to keep these checks. sae_process_commit and
sae_process_confirm will now always receive messages in their respective
state.
sae_verify_* functions were correctly marking frames to be dropped, but
were returning 0, which caused the to-be-dropped frames to be further
processed inside sae_rx_authenticate. Fix that by returning a proper
error.
Make sure to return -EAGAIN whenever a received frame from the peer
results in a retransmission. This also prevents the frame from being
mistakenly processed further in sae_rx_authenticate.
Do not try to transition to a new state from sae_send_commit /
sae_send_confirm since these methods can be called due to
retransmissions or other unexpected messages. Instead, transition to
the new state explicitly from sae_process_commit / sae_process_confirm.
SAE protocol is meant to authenticate peers simultaneously. Hence it
includes a tie-breaker provision in case both peers enter into the
Committed state and the Commit messages arrive at the respective peers
near simultaneously.
However, in the case of STA or Infrastructure mode, only one peer (STA)
would normally enter the Committed state (via Init) and the tie-breaker
provision is not needed. If this condition is detected, abort the
connection.
Also remove the uneeded group change check in process_commit.
sae_compute_pwe doesn't really depend on the state of sae_sm. Only the
curve to be used for the PWE calculation is needed. Rework the function
signature to reflect that and remove unneeded member of struct sae_sm.
ie_tlv_builder_init takes a size_t as input, yet for some reason
ie_tlv_builder_finalize takes an unsigned int argument as output. Fix
the latter to use size_t as well.