This removes the need for duplicate code in AP/netdev for issuing
a DEL_STATION command. Now AP can issue a DEL_STATION with
netdev_del_station, and specify to either disassociate or deauth
depending on state.
If netdev fails to set the keys, there was no way for device/ap to
know. A new handshake event was added for this. The key setting
failure function was also fixed to support both AP/station iftypes.
It will now automatically send either a disconnect or del_station
depending on the interface type.
In similar manner, netdev_handshake_failed was also modified to
support both AP/station iftypes. Now, any handshake event listeners
should call netdev_handshake_failed upon a handshake failure
event, including AP.
If device is already disconnected or in autoconnect mode, don't return
an error if .Disconnect is called. Instead simply silently return
success after disabling autoconnect.
==1058== 231 (32 direct, 199 indirect) bytes in 1 blocks are definitely lost in loss record 10 of 10
==1058== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1058== by 0x452472: l_malloc (util.c:62)
==1058== by 0x456324: l_settings_new (settings.c:83)
==1058== by 0x427D45: storage_network_open (storage.c:262)
==1058== by 0x42806C: network_settings_load (network.c:75)
==1058== by 0x428C2F: network_autoconnect (network.c:490)
==1058== by 0x4104E9: device_autoconnect_next (device.c:194)
==1058== by 0x410E38: device_set_scan_results (device.c:393)
==1058== by 0x410EFA: new_scan_results (device.c:414)
==1058== by 0x424A6D: scan_finished (scan.c:1012)
==1058== by 0x424B88: get_scan_done (scan.c:1038)
==1058== by 0x45DC67: destroy_request (genl.c:134)
This is a fixup for the AP code merge. wsc.c never registered
for handshake events, so in case of failure it was never calling
netdev_handshake_failed, which caused a double free.
Many APs don't send properly zerod key_iv elements in EAPoL-Key frames.
In the past iwd has complained, but this broken behavior is so
prevalent, that it is likely a lost cause.
This patch takes out these warnings
Right now iwd uses Control Port over NL80211 feature if the kernel /
driver supports it. On some kernels this feature is still buggy, so add
an iwd.conf entry to allow the user to override id.
For now the default is to disable this feature until it is more stable.
Now, a user can setup an AP as follows:
- Set device "Mode" to ap (ap interface will appear on bus)
- call "Start()" on AP interface
Issuing "Stop()" on the AP interface will stop and cleanup
the internal AP structures, but the AP interface will remain
up. To shutdown completely the device Mode must be switched
back to station. If the AP interface is running, the Mode can
directly be switched to station without calling Stop; this
has the same effect and will take down the AP interface.
Some of the PEAP server implementation brake the protocol
and don’t set the M flag for the first packet during the
fragmented transmission. To stay compatible with such
devices, we relax this requirement in iwd.
This patch allows alternating between the passive and active
scans taking into consideration an existence of the known
hidden networks and previous observation of them in the scan
results, as well as an ability to randomize the MAC address.
The state of scan is split between the two variables sc->state
and sc->start_cmd_id. Not checking start_cmd_id used to cause
sending a scan request while periodic scan was just triggered
resulting in EBUSY.
Instead of manually sending a deauth/disassociate to a station
during an error or removal, the kernel can do it automatically
with DEL_STATION by including the MGMT_SUBTYPE attribute. This
removes the need for ap_error_deauth_sta and introduces
ap_deauthenticate_sta. Now AP can be explicit when it chooses
to deauth or disassociate.
All handshake packet handling has been removed from ap and
moved to eapol. After association, the AP registers a new
authenticator state machine which handles the AP side of
the handshake. AP will receive a handshake event once the
4-way handshake is complete.
Includes:
- support for handling ptk 2/4 and 4/4. Also sending 1/4 and 3/4.
- new API to register an authenticator SM. This automatically
sends 1/4 to kick off authentication with an sta.
These checks allow both a station and authenticator to use
the same netdev key install functions. For NEW_KEY and
SET_STATION, the iftype is checked and either handshake->aa
or ->spa is used as the station address for the KEY/STATION
commands. Also, in the failure cases, a disconnect command
is issued only if the iftype is station as this doesn't
apply to AP.
Handshake related netdev events were removed in favor of
handshake events. Now events will be emitted on the handshake
object related to the 4-way handshake and key settings. Events
are:
HANDSHAKE_EVENT_STARTED
HANDSHAKE_EVENT_SETTING_KEYS
HANDSHAKE_EVENT_COMPLETE
HANDSHAKE_EVENT_FAILED
Right now, since netdev only operates in station mode, nothing
listens for COMPLETE/FAILED, as device/wsc gets notified by the
connect_cb when the connection was successful. The COMPLETE/
FAILED were added in preperation for AP moving into eapol/netdev.
==1057== 32 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1057== at 0x4C2AF0F: malloc (vg_replace_malloc.c:299)
==1057== by 0x15E9A2: l_malloc (util.c:62)
==1057== by 0x15EA9D: l_memdup (util.c:121)
==1057== by 0x133D9A: network_set_psk (network.c:350)
==1057== by 0x13BD29: wsc_try_credentials (wsc.c:136)
==1057== by 0x13C121: wsc_connect_cb (wsc.c:220)
==1057== by 0x110FAF: netdev_connect_failed (netdev.c:525)
==1057== by 0x16AAF4: process_unicast (genl.c:390)
==1057== by 0x16AF03: received_data (genl.c:509)
==1057== by 0x166CB6: io_callback (io.c:123)
==1057== by 0x16580D: l_main_iterate (main.c:376)
==1057== by 0x16594B: l_main_run (main.c:423)
load_settings ensures that ttls->eap is correctly initialized. So this
code should be treated as an error condition.
We also do not support EAP chaining, so remove that logic as well
dbus_init() currently does not check for the g_dbus object being
properly initialized and this leads to crashes when dbus is not yet
running.
Ensure g_dbus is properly initialized and return false otherwise.
In this case the caller can understand that something went wrong and
stop the initialization procedure.
Program received signal SIGSEGV, Segmentation fault.
0x00005555555bc089 in l_dbus_add_service_watch (dbus=0x0,
name=0x5555555e5b0a "org.ofono",
connect_func=0x5555555aa81e <ofono_found>,
disconnect_func=0x5555555aa8e6 <ofono_disappeared>,
user_data=0x0, destroy=0x0) at ell/dbus.c:1621
1621 if (!dbus->name_cache)
(gdb) bt
name=0x5555555e5b0a "org.ofono",
connect_func=0x5555555aa81e <ofono_found>,
disconnect_func=0x5555555aa8e6 <ofono_disappeared>,
user_data=0x0, destroy=0x0) at ell/dbus.c:1621
user_data=0x0) at ell/plugin.c:115
function=0x5555555b40fd <plugin_start>,
user_data=0x0) at ell/queue.c:441
version=0x0) at ell/plugin.c:201
src/plugin.c:82
src/main.c:417
When the response structure is generated, not all of the memory was
initialized to 0.
==1045== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==1045== at 0x5134D52: send (in /lib64/libc-2.25.so)
==1045== by 0x168AB5: l_checksum_update (checksum.c:338)
==1045== by 0x186777: tls_write_mac (tls-record.c:58)
==1045== by 0x1869D1: tls_tx_record_plaintext (tls-record.c:120)
==1045== by 0x186DEA: tls_tx_record (tls-record.c:201)
==1045== by 0x185A3B: l_tls_write (tls.c:2064)
==1045== by 0x14584F: eap_ttls_eap_tx_packet (eap-ttls.c:321)
==1045== by 0x14236C: eap_send_response (eap.c:165)
==1045== by 0x147904: eap_mschapv2_send_response (eap-mschapv2.c:468)
==1045== by 0x147A10: eap_mschapv2_handle_challenge (eap-mschapv2.c:492)
==1045== by 0x147E9A: eap_mschapv2_handle_request (eap-mschapv2.c:615)
==1045== by 0x142693: __eap_handle_request (eap.c:240)
==1045== Address 0x1ffeffe7f9 is on thread 1's stack
==1045== in frame #4, created by tls_tx_record (tls-record.c:177)
==1045== Uninitialised value was created by a stack allocation
==1045== at 0x1477AE: eap_mschapv2_send_response (eap-mschapv2.c:443)
==1045==
==1045== Syscall param sendmsg(msg.msg_iov[0]) points to uninitialised byte(s)
==1045== at 0x5134E3B: sendmsg (in /lib64/libc-2.25.so)
==1045== by 0x17F691: operate_cipher (cipher.c:356)
==1045== by 0x17F9D8: l_cipher_encrypt (cipher.c:446)
==1045== by 0x186BAA: tls_tx_record_plaintext (tls-record.c:152)
==1045== by 0x186DEA: tls_tx_record (tls-record.c:201)
==1045== by 0x185A3B: l_tls_write (tls.c:2064)
==1045== by 0x14584F: eap_ttls_eap_tx_packet (eap-ttls.c:321)
==1045== by 0x14236C: eap_send_response (eap.c:165)
==1045== by 0x147904: eap_mschapv2_send_response (eap-mschapv2.c:468)
==1045== by 0x147A10: eap_mschapv2_handle_challenge (eap-mschapv2.c:492)
==1045== by 0x147E9A: eap_mschapv2_handle_request (eap-mschapv2.c:615)
==1045== by 0x142693: __eap_handle_request (eap.c:240)
==1045== Address 0x1ffeffe7f9 is on thread 1's stack
==1045== in frame #4, created by tls_tx_record (tls-record.c:177)
==1045== Uninitialised value was created by a stack allocation
==1045== at 0x1477AE: eap_mschapv2_send_response (eap-mschapv2.c:443)
==1045==
Since PEAP & TTLS expect to use eap_check_settings recursively, make
them use a private version of that API that does not perform cleanup and
can contain side-effects.
eap_check_settings itself will guarantee that no side effects happen on
error. It is meant to be used by code outside of the eap subsystem.
Missing secrets are freed by eap_send_agent_req() even in case of
failure, so it was erroneous to try to free them on error.
==1048== Invalid read of size 8
==1048== at 0x1603EC: l_queue_clear (queue.c:101)
==1048== by 0x1603B8: l_queue_destroy (queue.c:82)
==1048== by 0x135328: network_connect_8021x (network.c:943)
==1048== by 0x1354C4: network_connect (network.c:987)
==1048== by 0x178DD2: _dbus_object_tree_dispatch (dbus-service.c:1690)
==1048== by 0x16D32A: message_read_handler (dbus.c:285)
==1048== by 0x166EC3: io_callback (io.c:123)
==1048== by 0x165A1A: l_main_iterate (main.c:376)
==1048== by 0x165B58: l_main_run (main.c:423)
==1048== by 0x1102DA: main (main.c:458)
==1048== Address 0x5461850 is 0 bytes inside a block of size 24 free'd
==1048== at 0x4C2C13B: free (vg_replace_malloc.c:530)
==1048== by 0x15ED03: l_free (util.c:136)
==1048== by 0x1603C4: l_queue_destroy (queue.c:83)
==1048== by 0x134BD5: eap_secret_request_free (network.c:719)
==1048== by 0x134EF9: eap_send_agent_req (network.c:817)
==1048== by 0x1352F7: network_connect_8021x (network.c:936)
==1048== by 0x1354C4: network_connect (network.c:987)
==1048== by 0x178DD2: _dbus_object_tree_dispatch (dbus-service.c:1690)
==1048== by 0x16D32A: message_read_handler (dbus.c:285)
==1048== by 0x166EC3: io_callback (io.c:123)
==1048== by 0x165A1A: l_main_iterate (main.c:376)
==1048== by 0x165B58: l_main_run (main.c:423)
In eap_check_settings move the check for the EAP-Identity setting so
that the method's check_setting call back has a chance to request it
from the agent. Note the check can be also moved to the EAP methods
so that they are free to skip it if not NULL identity is ok.
Replace usages of l_settings_get_value with l_settings_get_string, which
will make sure the returned strings are unescaped but also allocates
memeory and forces us to use l_free on most of the strings. Some of
these strings we explicitly set with l_settings_set_string() in our code
so when we retrieved them with l_settings_get_value() we would receive a
different string if there were any escapable characters in the string.
I didn't replace any of the l_settings_get_value() uses where we're just
checking whether a setting is present, or those which are hexstrings or
EAP method names assuming that they can't have any special characters,
although this isn't future proof. I did use l_settings_get_string() for
file paths though.
Accept two setting IDs in eap_append_secret, first for the username and
second for the password in case of the EAP_SECRET_REMOTE_USER_PASSWORD
EAP secret type. In all other cases only the first setting is used.
Until now for EAP_SECRET_REMOTE_USER_PASSWORD secrets we'd generate the
two setting names by adding different suffixes to the ID parameter.
Using the two different setting names automatically fixes the issues
with using the EAP Identity returned by the agent in EAP-MSCHAPv2 and
EAP-PWD.
The WDS dbus property of a Device directly maps to the 4ADDR property
of a real netdevice. It can be activated or deactivated at any point
in time.
The name WDS comes from the fact that this feature allows a STA
interface to be bridged and thus create a Wireless Distribution
System (the same name is used in OpenWRT and hostapd).
To implement this feature, the 'powered callback' data structure has
been renamed and re-used.
When a wifi interface is added/removed to/from a bridge, a
RTM_NEW/DELLINK event is issued. This is the same event used to signal
when an interface is created/deleted.
For this reason the event generated by the bridge code has to be
properly distinguished and handled accordingly. Failing to do so will
result in inconsistencies in iwd which will think an interface has been
deleted when it was actually not.
Detect incoming NEW/DELLINK bridge events and reacts accordingly. For
now, this simply means printing a simple message, as there is no
special logic in iwd for this yet.
This is meant to reset the EAP state back to its original state without
affecting any state variables obtained through load_settings. This can
be useful for EAP Reauthentication triggered by the AP.
Instead use '-d' command line option. This option uses an optional
argument. Without an argument, '*' is assumed. Otherwise you can
specify a glob string to match. Any debug output that matches the glob
string will be printed. e.g.:
src/iwd -d '*eap*'
Some EAP servers might try to send us packets after the EAP connection
has been established. When EAP succeeds we destroy the EAP object. If
a new EAP request arrives we create a temporary EAP object to handle the
request (most likely to NAK it). However, if the packet is not destined
to a particular method (e.g. it is a notification) the current logic can
result in a crash.
src/netdev.c:netdev_set_gtk() 3
==4300== Invalid read of size 8
==4300== at 0x14204B: __eap_handle_request (eap.c:203)
==4300== by 0x142339: eap_rx_packet (eap.c:287)
==4300== by 0x12AEF9: eapol_rx_packet (eapol.c:1622)
==4300== by 0x12BBBC: __eapol_rx_packet (eapol.c:2018)
==4300== by 0x116D1E: netdev_pae_read (netdev.c:3121)
==4300== by 0x16672B: io_callback (io.c:123)
==4300== by 0x165239: l_main_iterate (main.c:376)
==4300== by 0x16537D: l_main_run (main.c:423)
==4300== by 0x10F95C: main (main.c:447)
==4300== Address 0x30 is not stack'd, malloc'd or (recently) free'd
==4300==
When the server sends an identity prompt or a notification, we were
trying to print from our local buffer, not from the actual packet. The
relevant valgrind trace is:
src/netdev.c:netdev_mlme_notify() MLME notification 64
==4300== Conditional jump or move depends on uninitialised value(s)
==4300== at 0x4C3006E: strnlen (vg_replace_strmem.c:425)
==4300== by 0x508C513: vfprintf (vfprintf.c:1643)
==4300== by 0x508EB75: buffered_vfprintf (vfprintf.c:2329)
==4300== by 0x508C1A1: vfprintf (vfprintf.c:1301)
==4300== by 0x167051: log_stderr (log.c:145)
==4300== by 0x16756E: l_log_with_location (log.c:293)
==4300== by 0x142173: __eap_handle_request (eap.c:235)
==4300== by 0x142339: eap_rx_packet (eap.c:287)
==4300== by 0x12AEF9: eapol_rx_packet (eapol.c:1622)
==4300== by 0x12BBBC: __eapol_rx_packet (eapol.c:2018)
==4300== by 0x116D1E: netdev_pae_read (netdev.c:3121)
==4300== by 0x16672B: io_callback (io.c:123)
==4300==
EAP identity prompt: ""
GLIBC is not necessarily the only library that provides execinfo.
With libexecinfo execinfo can be used also in other Libraries.
The patch lets the configure check the existence of the header
and the libexecinfo Library and uses them if avaible.
(also fixes compilation if execinfo is not avaible)
iwd was auto-connecting to the open networks despite having
Autoconnect=false flag set in the network configuration file.
This patch enables iwd to load the configuration files for the
open networks during the auto-connect attempt to take advantage
of the Autoconnect flag.
EAP-PWD was hard coded to only work on LE architectures. This
adds 2 conversion functions to go from network byte order (BE)
to any native architecture, and vise versa.
The file, src/ecc.c was taken from the bluez project:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/shared/ecc.c
There were minor changes made, e.g. changing some functions to globals
for access in EAP-PWD as well as removing some unneeded code. There was
also some code appended which allows for point addition, modulus inverse
as well as a function to compute a Y value given an X.
If Control Port over NL80211 is not supported, open up a PAE socket and
stuff it into an l_io on the netdev object. Install a read handler on
the l_io and call __eapol_rx_packet as needed.
With the introduction of Control Port Over NL80211 feature, the
transport details need to be moved out of eapol and into netdev.c.
Whether a given WiFi hardware supports transfer of Control Port packets
over NL80211 is Wiphy and kernel version related, so the transport
decisions need to be made elsewhere.
On connect add any secrets we've received through the agent to the
l_settings objects which the EAP methods will process in load_settings.
The settings object is modified but is never written to storage. If
this was to change because some settings need to be saved to storage,
a new l_settings object might be needed with the union of the settings
from the file and the secrets so as to avoid saving the sensitive data.
These EAP methods do not store the identity inside the settings file
since it is obtained from the SIM card, then provided to IWD via
get_identity method. If the get_identity method is implemented, do
not fail the settings check when EAP-Identity is missing.
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.
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.