Use eap_check_settings directly from network.c before we start the
connection attempt at netdev.c level, to obtain all of the required
passwords/passphrases through the agent. This is in network.c because
here we can decide the policies for whether to call the agent in
autoconnect or only if we had a request from the user, also whether we
want to save any of that for later re-use (either password data or
kernel-side key serial), etc.
In this patch we save the credentials for the lifetime of the network
object in memory, and we skip the network if it requires any passphrases
we don't have while in autoconnect, same as with PSK networks where the
PSK isn't given in the settings. Note that NetworkManager does pop up
the password window for PSK or EAP passwords even in autoconnect.
If EAP needs multiple passwords we will call the agent sequentially for
each.
Confirm that the PEM file paths that we'll be passing to the l_tls
object are loading Ok and request/validate the private key passphrase
if needed. Then also call eap_check_settings to validate the inner
method's settings.
Confirm that the PEM file paths that we'll be passing to the l_tls
object are loading Ok and request/validate the private key passphrase
if needed. Then also call eap_check_settings to validate the inner
method's settings.
With the goal of requesting the required passwords/passphrases, such as
the TLS private key passphrase, from the agent, add a static method
eap_check_settings to validate the settings and calculate what passwords
are needed for those settings, if any. This is separate from
eap_load_settings because that can only be called later, once we've
got an eap state machine object. We need to get all the needed EAP
credentials from the user before we even start connecting.
While we do this, we also validate the settings and output any error
messages through l_error (this could be changed so the messages go
somewhere else in the future), so I removed the error messages from
eap_load_settings and that method now assumes that eap_check_settings
has been called before.
eap_check_settings calls the appropriate method's .check_settings method
if the settings are complete enough to contain the method name. The
policy is that any data can be provided inside the l_settings object
(from the network provisioning/config file), but some of the more
sensitive fields, like private key passwords, can be optionally omitted
and then the UI will ask for them and iwd will be careful with
caching them.
Within struct eap_secret_info, "id" is mainly for the EAP method to
locate the info in the list. "value" is the actual value returned
by agent. "parameter" is an optional string to be passed to the agent.
For a private key passphrase it may be the path to the key file, for a
password it may be the username for which the password is requested.
In agent_receive_reply we first call the callback for the pending
request (agent_finalize_pending) then try to send the next request
in the queue. Check that the next request has not been sent already
which could happen if it has been just queued by the callback.
The difference in the handlers was that in the
NETDEV_EVENT_DISCONNECT_BY_AP case we would make sure to reply
to a pending dbus Connect call. We also need to do that for
NETDEV_EVENT_DISCONNECT_BY_SME. This happens if another process
sends an nl80211 disconnect command while we're connecting.
The eapol handshake timeout can now be configured in main.conf
(/etc/iwd/main.conf) using the key eapol_handshake_timeout. This
allows the user to configure a long timeout if debugging.
If --gdb is used with test-runner, all the timeouts in the
IWD class must be turned off otherwise the test will fail.
Inside test-runner, a environment variable (IWD_TEST_TIMEOUTS)
is set to either 'on' or 'off'. Then the IWD class (and any
others) can handle the timeouts accordingly. Note that this
does not turn off dbus timeouts, rather it ignores timeout
failures. This does mean that ultimately the test will most
likely fail due to a dbus timeout, but it at least gives you
unlimited debugging time.
Without this subsequent tests may be affected by hwsim not being
restarted.
Additionally in 4.13 the kernel will not use the registered hwsim
wmedium for wiphys created after the HWSIM_CMD_REGISTER call and
there's no way to re-register it without disconnecting from netlink
which is a bit of work. It's a one line fix in 4.13, I've not yet
checked if this has changed in current git.
When running multiple BSSes in one ESS this solves the communication
between them (called RRB) for purposes like preauthentication,
FT key pull and push and FT-over-DS without complicated bridges. At the
same time we're unlikely to have a scenario where we need the
communication to fail so there's no need for this to be configurable.
The supporting code for multiple hostapd processes is left in place so
that configure_hostapd_instances can decide how many processes to run
based on hw.conf and policies. start_hostapd now uses "-i wln0,..."
which is no longer documented in hostapd manual page or usage() but
still supported in current git and required if interface names are not
provided in the config files (possibly unless -b is used which is also
undocumented.)
After an EAP exchange rsn_info would be uninitialized and in the FT case
we'd use it to generate the step 2 IEs which would cause an RSNE
mismatch during FT handshake.
Until now we'd save the second 32 bytes of the MSK as the PMK and use
that for the PMK-R0 as well as the PMKID calculation. The PMKID
actually uses the first 32 bytes of the PMK while the PMK-R0's XXKey
input maps to the second 32 bytes. Add a pmk_len parameter to
handshake_state_set_pmk to handle that. Update the eapol_eap_results_cb
802.11 quotes to the 2016 version.
handshake_state_install_ptk triggers a call to
netdev_set_pairwise_key_cb which calls netdev_connect_ok, so don't call
netdev_connect_ok after handshake_state_install_ptk. This doesn't fix
any specific problem though.
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.