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.
We need to reset self._exception after _wait_for_async_op raises an
exception, otherwise _wait_for_async_op will report that exception for
every future operation (this wasn't an issue when an exception always
meant that the test was failing and objects were torn down anyway)
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.
Validate the IE order for some of the cases. For other cases, as with
the Disassociation, Deauthentication and Action frame types in section
9.3 it's not even clear from the spec the fields are expected to be IEs
(in fact for Action frame we know they aren't). For the Shared Key
authentication type drop the union with the contents as they can be
easier parsed as an IE sequence. For SAE we are not expecting an IE
sequence apparently so this is where the union could come useful but
let's leave that until we want to support SAE.
Check the IE order for each frame type where we'd just do the body
minimum length check until now (and not always correctly). We do not
try to validate the contents of any IEs (may be doable for some) or the
minimum mandatory IEs presence. This is because which IEs are required
depend on the contents of other fields in the frame, on the
authentication state and STA config and even contents of a request frame
which we're validating the response to. Frame handlers have to do this
work anyway.
Declare the two missing frame subtype enum values for Action frames,
assume Action frames are valid. Once we have specific validation code
for any Action frames elsewhere, we can move it to mpdu_validate, but
right don't try to validate the frame body as there are many subtypes
and we don't use any of them except Neighbor Reports which are actually
really simple.
Since we use the special 0xffff value in the builder code, check that
the tag is not 0xffff in ie_tlv_builder_finalize before writing the
header. This is for consistency, not for a specific use case.
Make parsing TLVs using Extended Element IDs easier by returning the
extended tag value as listed in enum ie_type instead of just the 255
value, and not returning the pointer to the extended tag as the IE data
and instead the pointer to the next byte after the extended ID.
Replace is_multicast_addr with util_is_broadcast_address usage.
is_multicast_addr seems to have been wrong, first because we're not
interested in just any multicast address (defined to be same as "group
address"), but rather specifically the broadcast address, as we don't
know of any specific address groups other than broadcast. And also
wrong because the "Individual/Group bit" is the LSB of byte 0, not the
MSB of byte 0 apparently.
The l_queue_find() to find other watches matching the new prefix
needs to be before the watchlist_link(), otherwise the prefix will
match itself and "registered" is always true.
In WATCHLIST_NOTIFY_MATCHES pass pointer to the item instead of
item->notify_data to free item->notify_data to be the final watch user's
user_data. This is also what netdev expects.
The EAP-method's .probe methods only checked the method name so do that
in eap.c instead and allocate method state in .load_settings. Rename
method's .remove method to .free to improve the naming.
This can be used to selectively notify watchlist items. The match
function is called for each watchlist_item and match_data is passed
along. If the match function returns true, then the watch_item is
notified. The match function signature and semantics are identical
to l_queue_match_func_t.