From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.linux.dev
Cc: James Prestwood <prestwoj@gmail.com>
Subject: [RFC 3/4] dpp: fix non-scan connect path in DPP
Date: Wed, 13 Dec 2023 09:25:45 -0800 [thread overview]
Message-ID: <20231213172546.145998-4-prestwoj@gmail.com> (raw)
In-Reply-To: <20231213172546.145998-1-prestwoj@gmail.com>
When DPP completes it writes the network configuration to disk but
these changes aren't picked up by the network object until the
known networks dir watch. Currently the connection itself works
fine because the network object holds a copy of the passphrase/psk
but additional settings like Hidden/SendHostname are not updated
and not used for the connection through DPP.
In theory DPP could also watch for known networks events and wait
until the expected network is added but that is also fragile since
its not guaranteed that the DPP watch callback will happen _after_
the one in network (when the network_info) is set into the object.
Instead, DPP itself can handle the known network creation/update
itself. If a known network already exists update its config.
Otherwise create a new network_info object and set it into the
network object.
---
src/dpp.c | 89 ++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 62 insertions(+), 27 deletions(-)
diff --git a/src/dpp.c b/src/dpp.c
index 1ff4b99e..3b42541d 100644
--- a/src/dpp.c
+++ b/src/dpp.c
@@ -53,6 +53,7 @@
#include "src/network.h"
#include "src/handshake.h"
#include "src/nl80211util.h"
+#include "src/knownnetworks.h"
#define DPP_FRAME_MAX_RETRIES 5
#define DPP_FRAME_RETRY_TIMEOUT 1
@@ -814,6 +815,8 @@ static void dpp_write_config(struct dpp_configuration *config,
_auto_(l_free) char *path;
_auto_(l_free) uint8_t *psk = NULL;
size_t psk_len;
+ struct network_config network_config;
+ struct network_info *info;
path = storage_get_network_file_path(SECURITY_PSK, config->ssid);
@@ -822,22 +825,13 @@ static void dpp_write_config(struct dpp_configuration *config,
l_settings_remove_group(settings, "Security");
}
- if (config->passphrase) {
+ if (config->passphrase)
l_settings_set_string(settings, "Security", "Passphrase",
config->passphrase);
- if (network)
- network_set_passphrase(network, config->passphrase);
-
- } else if (config->psk) {
+ else if (config->psk)
l_settings_set_string(settings, "Security", "PreSharedKey",
config->psk);
- psk = l_util_from_hexstring(config->psk, &psk_len);
-
- if (network)
- network_set_psk(network, psk);
- }
-
if (config->send_hostname)
l_settings_set_bool(settings, "IPv4", "SendHostname", true);
@@ -847,6 +841,39 @@ static void dpp_write_config(struct dpp_configuration *config,
l_debug("Storing credential for '%s(%s)'", config->ssid,
security_to_str(SECURITY_PSK));
storage_network_sync(SECURITY_PSK, config->ssid, settings);
+
+ /*
+ * The network has yet to be seen. Once a scan is issued station will
+ * handle network creation and in turn the settings will be loaded from
+ * disk.
+ */
+ if (!network)
+ return;
+
+ /*
+ * Otherwise we need to jump through some hoops in order to update an
+ * existing network object with the new settings
+ */
+ info = known_networks_find(config->ssid, SECURITY_PSK);
+
+ __network_config_parse(settings, path, &network_config);
+
+ if (info)
+ known_network_update(info, &network_config);
+ else {
+ info = l_new(struct network_info, 1);
+ __network_info_init(info, config->ssid, SECURITY_PSK, &network_config);
+ network_set_info(network, info);
+ }
+
+ if (config->passphrase)
+ network_set_passphrase(network, config->passphrase);
+ else if (config->psk) {
+ psk = l_util_from_hexstring(config->psk, &psk_len);
+
+ if (network)
+ network_set_psk(network, psk);
+ }
}
static void dpp_scan_triggered(int err, void *user_data)
@@ -856,14 +883,34 @@ static void dpp_scan_triggered(int err, void *user_data)
l_error("Failed to trigger DPP scan");
}
+static void dpp_connect(struct dpp_sm *dpp, const char *ssid)
+{
+ struct station *station = station_find(netdev_get_ifindex(dpp->netdev));
+ struct scan_bss *bss;
+ struct network *network;
+ int ret;
+
+ network = station_network_find(station, ssid, SECURITY_PSK);
+
+ dpp_reset(dpp);
+
+ if (!network) {
+ l_debug("Network was not found after scanning");
+ return;
+ }
+
+ bss = network_bss_select(network, true);
+ ret = network_autoconnect(network, bss);
+ if (ret < 0)
+ l_debug("Failed to connect after DPP (%d) %s", ret, strerror(ret));
+}
+
static bool dpp_scan_results(int err, struct l_queue *bss_list,
const struct scan_freq_set *freqs,
void *userdata)
{
struct dpp_sm *dpp = userdata;
struct station *station = station_find(netdev_get_ifindex(dpp->netdev));
- struct scan_bss *bss;
- struct network *network;
if (err < 0)
goto reset;
@@ -880,18 +927,7 @@ static bool dpp_scan_results(int err, struct l_queue *bss_list,
station_set_scan_results(station, bss_list, freqs, false);
- network = station_network_find(station, dpp->config->ssid,
- SECURITY_PSK);
-
- dpp_reset(dpp);
-
- if (!network) {
- l_debug("Network was not found after scanning");
- return true;
- }
-
- bss = network_bss_select(network, true);
- network_autoconnect(network, bss);
+ dpp_connect(dpp, dpp->config->ssid);
return true;
@@ -1075,8 +1111,7 @@ static void dpp_handle_config_response_frame(const struct mmpdu_header *frame,
offchannel_cancel(dpp->wdev_id, dpp->offchannel_id);
if (network && bss)
- __station_connect_network(station, network, bss,
- STATION_STATE_CONNECTING);
+ dpp_connect(dpp, config->ssid);
else if (station) {
struct scan_parameters params = {0};
--
2.34.1
next prev parent reply other threads:[~2023-12-13 17:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-13 17:25 [RFC 0/4] Fix extra settings not being taken post-DPP James Prestwood
2023-12-13 17:25 ` [RFC 1/4] knownnetworks: set ops on info in __network_info_init James Prestwood
2023-12-13 17:25 ` [RFC 2/4] station: unify scan cancelation James Prestwood
2023-12-13 17:32 ` James Prestwood
2023-12-13 17:25 ` James Prestwood [this message]
2023-12-13 17:25 ` [RFC 4/4] auto-t: add a few more DPP tests for seen/known networks James Prestwood
2023-12-13 22:59 ` [RFC 0/4] Fix extra settings not being taken post-DPP Denis Kenzior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231213172546.145998-4-prestwoj@gmail.com \
--to=prestwoj@gmail.com \
--cc=iwd@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox