Build and send the FT Authentication Request frame, the initial Fast
Transition message.
In this version the assumption is that once we start a transition attempt
there's no going back so the old handshake_state, scan_bss, etc. can be
replaced by the new objects immediately and there's no point at which both
the old and the new connection states are needed. Also the disconnect
event for the old connection is implicit. At netdev level the state
during a transition is almost the same with a new connection setup.
The first disconnect event on the netlink socket after the FT Authenticate
is assumed to be the one generated by the kernel for the old connection.
The disconnect event doesn't contain the AP bssid (unlike the
deauthenticate event preceding it), otherwise we could check to see if
the bssid is the one we are interested in or could check connect_cmd_id
assuming a disconnect doesn't happen before the connect command finishes.
This adds support for iwd.conf 'ManagementFrameProtection' setting.
This setting has the following semantics, with '1' being the default:
0 - MFP off, even if hardware is capable
1 - Use MFP if available
2 - MFP required. If the hardware is not capable, no connections will
be possible. Use at your own risk.
Despite RFC3748 mandating MSKs to be at least 256 bits some EAP methods
return shorter MSKs. Since we call handshake_failed when the MSK is too
short, EAP methods have to be careful with their calls to set_key_material
because it may result in a call to the method's .remove method.
EAP-TLS and EAP-TTLS can't handle that currently and would be difficult to
adapt because of the TLS internals but they always set msk_len to 64 so
handshake_failed will not be called.
Make sure that eap_set_key_material can free the whole EAP method and
EAP state machine before returning, by calling that function last. This
relies on eap_mschapv2_handle_success being the last call in about 5
stack frames above it too.
Action Frames are sent by nl80211 as unicast data. We're not receiving
any other unicast packets in iwd at this time so let netdev directly
handle all unicast data on the genl socket.
Add a version of scan_active that accepts a struct with the scan
parameters so we can more easily add new parameters. Since the genl
message is now built within scan_active_start the extra_ie memory
can be freed by the caller at any time.
clang complains about enum as var_arg type
because of the argument standard conversion.
In a small test I did neither clang nor gcc can
properly warn about out of range values, so it's
purely for documentation either way.
There are situations when a CMD_DISCONNECT or deauthenticate will be
issued locally because of an error detected locally where netdev would
not be able to emit a event to the device object. The CMD_DISCONNECT
handler can only send an event if the disconnect is triggered by the AP
because we don't have an enum value defined for other diconnects. We
have these values defined for the connect callback but those errors may
happen when the connect callback is already NULL because a connection
has been estabilshed. So add an event type for local errors.
These situations may occur in a transition negotiation or in an eapol
handshake failure during rekeying resulting in a call to
netdev_handshake_failed.
The kernel parses NL80211_ATTR_USE_MFP to mean an enumeration
nl80211_mfp. So instead of using a boolean, we should be using the
value NL80211_MFP_REQUIRED.
Make the use of EAPOL-Start the default and send it when configured for
8021x and either we receive no EAPOL-EAP from from the AP before
timeout, or if the AP tries to start a 4-Way Handshake.
On certain routers, the 4-Way handshake message 3 of 4 contains a key iv
field which is not zero as it is supposed to. This causes us to fail
the handshake.
Since the iv field is not utilized in this particular case, it is safe
to simply warn rather than fail the handshake outright.
Use the NLMSG_ALIGN macro on the family header size (struct ifinfomsg in
this case). The ascii graphics in include/net/netlink.h show that both
the netlink header and the family header should be padded. The netlink
header (nlmsghdr) is already padded in ell. To "document" this
requirementin ell what we could do is take two buffers, one for the
family header and one for the attributes.
This doesn't change anything for most people because ifinfomsg is
already 16-byte long on the usual architectures.
Remove the keys and other data from struct eapol_sm, update device.c,
netdev.c and wsc.c to use the handshake_state object instead of
eapol_sm. This also gets rid of eapol_cancel and the ifindex parameter
in some of the eapol functions where sm->handshake->ifindex can be
used instead.
struct handshake_state is an object that stores all the key data and other
authentication state and does the low level operations on the keys. Together
with the next patch this mostly just splits eapol.c into two layers
so that the key operations can also be used in Fast Transitions which don't
use eapol.
If device_select_akm_suite selects Fast Transition association then pass
the MD IE and other bits needed for eapol and netdev to do an FT
association and 4-Way Handshake.
If an MD IE is supplied to netdev_connect, pass that MD IE in the
associate request, then validate and handle the MD IE and FT IE in the
associate response from AP.
Add space in the eapol_sm struct for the pieces of information required
for the FT 4-Way Handshake and add setters for device.c and netdev.c to
be able to provide the data.
Don't decide on the AKM suite to use when the bss entries are received
and processed, instead select the suite when the connection is triggered
using a new function device_select_akm_suite, similar to
wiphy_select_cipher(). Describing the AKM suite through flags will be
more difficult when more than 2 suites per security type are supported.
Also handle the wiphy_select_cipher 0 return value when no cipher can be
selected.
The len parameter was only used so it could be validated against ie[1],
but since it was not checked to be > 2, it must have been validated
already, the check was redundant. In any case all users directly
passed ie[1] as len anyway. This makes it consistent with the ie
parsers and builders which didn't require a length.
In many cases the pairwise and group cipher information is not the only
information needed from the BSS RSN/WPA elements in order to make a
decision. For example, th MFPC/MFPR bits might be needed, or
pre-authentication capability bits, group management ciphers, etc.
This patch refactors bss_get_supported_ciphers into the more general
scan_bss_get_rsn_info function
Split eapol_start into two calls, one to register the state machine so
that the PAE read handler knows not to discard frames for that ifindex,
and eapol_start to actually start processing the frames. This is needed
because, as per the comment in netdev.c, due to scheduling the PAE
socket read handler may trigger before the CMD_CONNECT event handler,
which needs to parse the FTE from the Associate Response frame and
supply it to the eapol SM before it can do anything with the message 1
of 4 of the FT handshake.
Another issue is that depending on the driver or timing, the underlying
link might not be marked as 'ready' by the kernel. In this case, our
response to Message 1 of the 4-way Handshake is written and accepted by
the kernel, but gets dropped on the floor internally. Which leads to
timeouts if the AP doesn't retransmit.
This function takes an Operating Channel and a Country String to convert
it into a band. Using scan_oper_class_to_band and scan_channel_to_freq,
an Operating Channel, a Country String and a Channel Number together can
be converted into an actual frequency. EU and US country codes based on
wpa_supplicant's tables.
It doesn't matter for crypto_derive_pairwise_ptk in non-SHA256 mode
but in the FT PTK derivation function, as well as in SHA256 mode all
bytes of the output do actually change with the PTK size.
Fix autoconnect trying to connect to networks never used before as found
by Tim Kourt. Update the comments to be consistent with the use of the
is_known field and the docs, in that a Known Network is any network that
has a config file in the iwd storage, and an autoconnect candidate is a
network that has been connected to before.
If the handshake fails, we trigger a deauthentication prior to reporting
NETDEV_RESULT_HANDSHAKE_FAILED. If a netdev_disconnect is invoked in
the meantime, then the caller will receive -ENOTCONN. This is
incorrect, since we are in fact logically connected until the connect_cb
is notified.
Tweak the behavior to keep the connected variable as true, but check
whether disconnect_cmd_id has been issued in the netdev_disconnect_event
callback.
If the device is currently connected, we will initiate a disconnection
(or wait for the disconnection to complete) prior to starting the
WSC-EAP association.
Use the org.freedesktop.DBus.Properties interfaces on objects with
properties and drop the old style GetProperty/SetProperty methods on
individual interfaces. Agent and KnownNetworks have no properties at
this time so don't add org.freedesktop.DBus.Properties interfaces.
We send the scan results where we obtained a PushButton target over to
device object. If EAP-WSC transaction is successful, then the scan
results are searched to find a network/bss combination found in the
credentials obtained. If found, the network is connected to
automatically.
This also fixes a potential buffer overflow since the ssid was cast to a
string inside network_create. However, ssid is a buffer of 32 bytes,
and would not be null-terminated in the case of a 32-byte SSID.
==5362== Conditional jump or move depends on uninitialised value(s)
==5362== at 0x419B62: wsc_wfa_ext_iter_next (wscutil.c:52)
==5362== by 0x41B869: wsc_parse_probe_response (wscutil.c:1016)
==5362== by 0x41FD77: scan_results (wsc.c:218)
==5362== by 0x415669: get_scan_done (scan.c:892)
==5362== by 0x432932: destroy_request (genl.c:134)
==5362== by 0x433245: process_unicast (genl.c:394)
==5362== by 0x43361A: received_data (genl.c:506)
==5362== by 0x42FDC2: io_callback (io.c:120)
==5362== by 0x42EABE: l_main_run (main.c:381)
==5362== by 0x402F90: main (main.c:234)