Commit Graph

3668 Commits

Author SHA1 Message Date
James Prestwood cb76f219fb netdev: move ocvc setting to after connected check
We cannot check 'handshake' until first checking that IWD is
connected.
2022-04-05 13:30:30 -05:00
James Prestwood f7dc05969f netdev: check for connected in FT frame event
This frame could come unsolicited and cause a NULL dereference
if IWD is not connected.
2022-04-05 13:30:11 -05:00
Denis Kenzior dc7e12ac0c station: Ignore AP directed roams if already trying to roam 2022-04-05 11:41:03 -05:00
Denis Kenzior 92ef3da714 station: Sanitize AP directed roam addresses
Make sure the BSS Transition Management Request frames come from our
conected AP.  Ignore and print a message if the addresses do not match.
2022-04-05 11:36:39 -05:00
Denis Kenzior 3fad65e5df station: ignore AP directed roams if not connected 2022-04-05 10:09:08 -05:00
Emmanuel VAUTRIN 85d9d6461f network: Hide hidden networks on connection error
If a user connection fails on a freshly scanned psk or open hidden
network, during passphrase request or after, it shall be removed from
the network list.  Otherwise, it would be possible to directly connect
to that known network, which will appear as not hidden.
2022-04-05 09:31:44 -05:00
James Prestwood f59e69c6c4 rrm: use ULL for static values 2022-03-31 18:13:04 -05:00
Andrew Zaborowski ce94013bae p2p: Fix Device Address updates from Probe Requests
p2p_peer_update_existing may be called with a scan_bss struct built from
a Probe Request frame so it can't access bss->p2p_probe_resp_info even
if peer->bss was built from a Probe Response.  Check the source frame
type of the scan_bss struct before updating the Device Address.

This fixes one timing issue that would make the autotest fail often.
2022-03-30 14:43:37 -05:00
James Prestwood 6f7743426b eapol: zero entire buffer when creating frame
Since l_malloc is used the frame contents are not zero'ed automatically
which could result in random bytes being present in the frame which were
expected to be zero. This poses a problem when calculating the MIC as the
crypto operations are done on the entire frame with the expectation of
the MIC being zero.

Fixes: 83212f9b23 ("eapol: change eapol_create_common to support FILS")
2022-03-28 17:35:03 -05:00
Fabrice Fontaine d78950e039 storage: fix build with uclibc
explicit_bzero is used in src/storage.c since commit
01cd858760 but src/missing.h is not
included, as a result build with uclibc fails on:

/home/buildroot/autobuild/instance-0/output-1/host/lib/gcc/powerpc-buildroot-linux-uclibc/10.3.0/../../../../powerpc-buildroot-linux-uclibc/bin/ld: src/storage.o: in function `storage_init':
storage.c:(.text+0x13a4): undefined reference to `explicit_bzero'

Fixes:
 - http://autobuild.buildroot.org/results/2aff8d3d7c33c95e2c57f7c8a71e69939f0580a1
2022-03-28 12:39:51 -05:00
James Prestwood dbca7fcc02 dpp: set new_freq when configuring as initiator
This is used to hold the current BSS frequency which will be
used after IWD receives a presence announcement. Since this was
not being set, the logic was always thinking there was a channel
mismatch (0 != current_freq) and attempting to go offchannel to
'0' which resulted in -EINVAL, and ultimately protocol termination.
2022-03-28 12:38:15 -05:00
James Prestwood ad1e5252f3 dpp: fail if disconnected during DPP protocol
If the connected BSS is NULL IWD was disconnected and this should
trigger a protocol termination.
2022-03-28 12:38:15 -05:00
James Prestwood 9f6576be05 json: call va_end in error case
Caught by static analysis
2022-03-18 11:32:47 -05:00
James Prestwood ed81351f15 dpp-util: move up va_end before possible error case
This was caught by static analysis
2022-03-18 11:32:39 -05:00
James Prestwood 7bbcb67892 station: replace old BSS with 'best_bss' on roam scan
The logic here assumed any BSS's in the roam scan were identical to
ones in station's bss_list with the same address. Usually this is true
but, for example, if the BSS changed frequency the one in station's
list is invalid.

Instead when a match is found remove the old BSS and re-insert the new
one.
2022-03-08 11:37:25 -06:00
James Prestwood 1c5a2da046 knownnetworks: use band_freq_to_channel to verify known freqs
With the addition of 6GHz '6000' is no longer the maximum frequency
that could be in .known_network.freq. For more robustness
band_freq_to_channel is used to validate the frequency.
2022-03-03 13:58:45 -06:00
Denis Kenzior 778dacd262 wiphy: Use an inline function in favor of a macro 2022-03-02 13:57:00 -06:00
Denis Kenzior a8f3098115 wiphy: Use anonymous enum in favor of #defines 2022-03-02 13:55:26 -06:00
Denis Kenzior 86f34a394b ie: Use static inline functions in favor of macros 2022-03-02 13:51:56 -06:00
James Prestwood d4e9cda0c0 ap: add support for scanning while in AP mode
Scanning while in AP mode is somewhat of an edge case, but it does
have some usefulness specifically with onboarding new devices, i.e.
a new device starts an AP, a station connects and provides the new
device with network credentials, the new device switches to station
mode and connects to the desired network.

In addition this could be used later for ACS (though this is a bit
overkill for IWD's access point needs).

Since AP performance is basically non-existant while scanning this
feature is meant to be used in a limited scope.

Two DBus API's were added which mirror the station interface: Scan and
GetOrderedNetworks.

Scan is no different than the station variant, and will perform an active
scan on all channels.

GetOrderedNetworks diverges from station and simply returns an array of
dictionaries containing basic information about networks:

{
    Name: <ssid>
    SignalStrength: <mBm>
    Security: <psk, open, or 8021x>
}

Limitations:
 - Hidden networks are not supported. This isn't really possible since
   the SSID's are unknown from the AP perspective.

 - Sharing scan results with station is not supported. This would be a
   convenient improvement in the future with respect to onboarding new
   devices. The scan could be performed in AP mode, then switch to
   station and connect immediately without needing to rescan. A quick
   hack could better this situation by not flushing scan results in
   station (if the kernel retains these on an iftype change).
2022-02-28 13:23:01 -06:00
James Prestwood 70fc6ea262 scan: add support for scanning on AP interface type
This adds a new flag, force_ap to the scan parameters. When enabled
this will set NL80211_SCAN_FLAG_AP.
2022-02-28 13:22:54 -06:00
James Prestwood 1974a67b30 scan: check flush feature before using flag 2022-02-28 11:42:43 -06:00
James Prestwood 9224575a83 station: replace station_parse_bss_security
Replaces this with scan_bss_get_security
2022-02-28 11:42:26 -06:00
James Prestwood 27bf997545 scan: add scan_bss_get_security
This was already implemented in station but with no dependency on
that module at all. AP will need this for a scanning API so its
being moved into scan.c.
2022-02-28 11:42:07 -06:00
James Prestwood d38b7f2406 network: add 6GHz restrictions to network_can_connect_bss
The 802.11ax standards adds some restrictions for the 6GHz band. In short
stations must use SAE, OWE, or 8021x on this band and frame protection is
required.
2022-02-28 11:31:39 -06:00
James Prestwood 1024384ffd ie: add IE_AKM_IS_8021X 2022-02-25 17:54:33 -06:00
James Prestwood 6e660032c1 station: use IE_AKM_IS_FILS
Use this macro instead of manually checking
2022-02-25 17:54:27 -06:00
James Prestwood 44b3e7a8bb ie: update IE_AKM_IS_FILS to be bitwise
Currently nothing actually uses this macro, but switching it to a bitwise
comparison makes it more useful and consistent with the others.
2022-02-25 17:54:22 -06:00
James Prestwood 5627ef4141 ie: update IE_AKM_IS_SAE to bitwise comparison
All uses of this macro will work with a bitwise comparison which is
needed for 6GHz checks and somewhat more flexible since it can be
used to compare RSN info, not only single AKM values.
2022-02-25 17:54:09 -06:00
James Prestwood c20828f252 station: enforce MFPR=1 for 6GHz frequencies
This adds checks if MFP is set to 0 or 1:

0 - Always fail if the frequency is 6GHz
1 - Fail if MFPC=0 and the frequency is 6GHz.
    If HW is capable set MFPR=1 for 6GHz
2022-02-25 17:11:39 -06:00
James Prestwood 2f50038363 station: check supported frequencies in neighbor report
If the report has an unsupported frequency don't add it to the list.
2022-02-25 17:11:36 -06:00
James Prestwood 111e13cad6 band: keep 6GHz frequencies out of 40mhz special case
There is no 40MHz upper/lower concept for 6GHz so avoid this special
handling.
2022-02-25 13:10:45 -06:00
James Prestwood 7882621ca9 wiphy: add 6Ghz support 2022-02-25 13:04:33 -06:00
James Prestwood 5b6f1e3662 util: add 6GHz support to scan_freq_set* APIs
The 6GHz channels are stored and accessed identically to 5GHz,
just using a separate uintset object.
2022-02-25 13:01:20 -06:00
James Prestwood 1343cb928f band: add 6GHz support to {channel,freq}_to_{freq,channel}
Adds support for the channels and frequencies defined in the
802.11ax spec.
2022-02-25 13:00:26 -06:00
James Prestwood ff6961fbc4 band: add BAND_FREQ_6_GHZ
This is a new band defined in the WiFi 6E (ax) amendment. A completely
new value is needed due to channel reuse between 2.4/5 and 6GHz.

util.c needed minimal updating to prevent compile errors which will
be fixed later to actually handle this band. WSC also needed a case
added for 6GHz but the spec does not outline any RF Band value for
6GHz so the 5GHz value will be returned in this case.
2022-02-25 12:59:34 -06:00
James Prestwood 417b6fd022 band: remove unneeded line break
This fits within 80 characters
2022-02-25 12:59:27 -06:00
James Prestwood 650cac7979 band: add operating clases for 802.11ax
Obtained from the IEEE 802.11ax amendment, Table E-4
2022-02-25 12:57:45 -06:00
James Prestwood 6fce08c301 sae: define _GNU_SOURCE for reallocarray definition
sae.c was failing to build on some platforms:

error: implicit declaration of function 'reallocarray'; did you mean 'realloc'?
	[-Werror=implicit-function-declaration]
2022-02-24 12:14:46 -06:00
James Prestwood d3f7458e26 netdev: fail connection if the link goes down
In certain rare cases IWD gets a link down event before nl80211 ever sends
a disconnect event. Netdev notifies station of the link down which causes
station to be freed, but netdev remains in the same state. Then later the
disconnect event arrives and netdev still thinks its connected, calls into
(the now freed) station object and causes a crash.

To fix this netdev_connect_free() is now called on any link down events
which will reset the netdev object to a proper state.

src/netdev.c:netdev_link_notify() event 16 on ifindex 16
src/netdev.c:netdev_mlme_notify() MLME notification Del Station(20)
src/netdev.c:netdev_link_notify() event 16 on ifindex 16
src/netdev.c:netdev_mlme_notify() MLME notification Deauthenticate(39)
src/netdev.c:netdev_deauthenticate_event()
src/netdev.c:netdev_link_notify() event 16 on ifindex 16
src/station.c:station_free()
src/netconfig.c:netconfig_destroy()
src/resolve.c:resolve_systemd_revert() ifindex: 16
src/station.c:station_roam_state_clear() 16
src/netdev.c:netdev_mlme_notify() MLME notification Disconnect(48)
src/netdev.c:netdev_disconnect_event()
Received Deauthentication event, reason: 3, from_ap: false

0 0x472fa4 in station_disconnect_event src/station.c:2916
1 0x472fa4 in station_netdev_event src/station.c:2954
2 0x43a262 in netdev_disconnect_event src/netdev.c:1213
3 0x43a262 in netdev_mlme_notify src/netdev.c:5471
4 0x6706eb in process_multicast ell/genl.c:1029
5 0x6706eb in received_data ell/genl.c:1096
6 0x65e630 in io_callback ell/io.c:120
7 0x65a94e in l_main_iterate ell/main.c:478
8 0x65b0b3 in l_main_run ell/main.c:525
9 0x65b0b3 in l_main_run ell/main.c:507
10 0x65b5cc in l_main_run_with_signal ell/main.c:647
11 0x4124d7 in main src/main.c:532
2022-02-22 16:27:02 -06:00
James Prestwood 82b808cdfe dpp: add support for initiating as a configurator
The difference between the existing code is that IWD will send the
authentication request, making it the initiator.

This handles the use case where IWD is provided a peers URI containing
its bootstrapping key rather than IWD always providing its own URI.
A new DBus API was added, ConfigureEnrollee().

Using ConfigureEnrollee() IWD will act as a configurator but begin by
traversing a channel list (URI provided or default) and waiting for
presence announcements (with one caveat). When an announcement is
received IWD will send an authentication request to the peer, receive
its reply, and send an authentication confirm.

As with being a responder, IWD only supports configuration to the
currently connected BSS and will request the enrollee switch to this
BSS's frequency to preserve network performance.

The caveat here is that only one driver (ath9k) supports multicast frame
registration which prevents presence frame from being received. In this
case it will be required the the peer URI contains a MAC and channel
information. This is because IWD will jump right into sending auth
requests rather than waiting for a presence announcement.
2022-02-22 16:25:47 -06:00
James Prestwood de411818f0 dpp: manually register for some frame watches
The frame watch which covers the presence procedure (and most
frames for that matter) needs to support multicast frames for
presence to work. Doing this in frame-xchg seems like the right
choice but only ath9k supports multicast frame registration.
Because of this limited support DPP will register for these frames
manually.
2022-02-22 16:24:47 -06:00
James Prestwood f7f602e1b1 dpp-util: add URI parsing
Parses K (key), M (mac), C (class/channels), and V (version) tokens
into a new structure dpp_uri_info. H/I are not parsed since there
currently isn't any use for them.
2022-02-22 16:23:52 -06:00
James Prestwood c819903a7c dpp: check return of aes_siv_encrypt
This was caught by static analysis. As is common this should never
happen in the real world since the only way this can fail (apart from
extreme circumstances like OOM) is if the key size is incorrect, which
it will never be.
2022-02-18 14:45:45 -06:00
James Prestwood 5ca7948dfb main: remove unneeded stat call
Static analysis flagged that 'path' was never being checked (which
should not ever be NULL) but during that review I noticed stat()
was being called, then fstat afterwards.
2022-02-18 14:45:39 -06:00
James Prestwood 0fe054076f doc: Add warning to SystemdEncrypt as highly experimental 2022-02-16 16:11:01 -06:00
James Prestwood 1157e0a184 doc: document SystemdEncrypt 2022-02-15 17:44:20 -06:00
James Prestwood e8e9c68dea main: add SystemdEncrypt option, and initialize key
Recently systemd added the ability to pass secret credentials to
services via LoadCredentialEncrypted/SetCredentialEncrypted. Once
set up the service is able to read the decrypted credentials from
a file. The file path is found in the environment variable
CREDENTIALS_DIRECTORY + an identifier. The value of SystemdEncrypt
should be set to the systemd key ID used when the credential was
created.

When SystemdEncrypt is set IWD will attempt to read the decrypted
secret from systemd. If at any point this fails warnings will be
printed but IWD will continue normally. Its expected that any failures
will result in the inability to connect to any networks which have
previously encrypted the passphrase/PSK without re-entering
the passphrase manually. This could happen, for example, if the
systemd secret was changed.

Once the secret is read in it is set into storage to be used for
profile encryption/decryption.
2022-02-15 17:38:51 -06:00
James Prestwood 64f225df6e hotspot: implement hotspot profile encryption
Using storage_decrypt() hotspot can also support profile encyption.
The hotspot consortium name is used as the 'ssid' since this stays
consistent between hotspot networks for any profile.
2022-02-15 17:22:21 -06:00
James Prestwood 01cd858760 storage: implement network profile encryption
Some users don't like the idea of storing network credentials in
plaintext on the file system.  This patch implements an option to
encrypt such profiles using a secret key.  The origin of the key can in
theory be anything, but would typically be provided by systemd via
'LoadEncryptedCredential' setting in the iwd unit file.

The encryption operates on the entire [Security] group as well as all
embedded groups. Once encrypted the [Security] group will be replaced
with two key/values:

EncryptedSalt - A random string of bytes used for the encryption
EncryptedSecurity - A string of bytes containing the encrypted
                    [Security] group, as well as all embedded groups.

After the profile has been encrypted these values should not be
modified.  Note that any values added to [Security] after encryption
has no effect.  Once the profile is encrypted there is no way to modify
[Security] without manually decrypting first, or just re-creating it
entirely which effectively treated a 'new' profile.

The encryption/decryption is done using AES-SIV with a salt value and
the network SSID as the IV.

Once a key is set any profiles opened will automatically be encrypted
and re-written to disk.  Modules using network_storage_open will be
provided the decrypted profile, and will be unaware it was ever
encrypted in the first place.  Similarly when network_storage_sync is
called the profile will by automatically encrypted and written to disk
without the caller needing to do anything special.

A few private storage.c helpers were added to serve several purposes:

storage_init/exit():
This sets/cleans up the encryption key direct from systemd then uses
extract and expand to create a new fixed length key to perform
encryption/decryption.

__storage_decrypt():
Low level API to decrypt an l_settings object using a previously set
key and the SSID/name for the network.  This returns a 'changed' out
parameter signifying that the settings need to be encrypted and
re-written to disk.  The purpose of exposing this is for a standalone
decryption tool which does not re-write any settings.

storage_decrypt():
Wrapper around __storage_decrypt() that handles re-writing a new
profile to disk. This was exposed in order to support hotspot profiles.

__storage_encrypt():
Encrypts an l_settings object and returns the full profile as data
2022-02-15 17:19:33 -06:00