From: Andrew Zaborowski <balrogg@gmail.com>
To: iwd@lists.01.org
Subject: [PATCH 08/11] wsc: Add wsc_new_p2p_enrollee, refactor
Date: Mon, 21 Oct 2019 15:55:07 +0200 [thread overview]
Message-ID: <20191021135510.12657-8-balrogg@gmail.com> (raw)
In-Reply-To: <20191021135510.12657-1-balrogg@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 9759 bytes --]
From: Andrew Zaborowski <andrew.zaborowski@intel.com>
Until now WSC could only be triggered by calling a DBus method and
success and error paths would end with a reply to the DBus method.
Instead use a wsc done callback pointer so that the WSC connection
logic can be triggered through DBus or a C API. The DBus method reply
is sent from inside the callback when WSC is triggered through DBus.
Export a function that adds a new entry point to start the WSC
connection for the P2P provisioning phase. The function doesn't have
anything specific to P2P at this point.
---
Makefile.am | 2 +-
src/wsc.c | 181 +++++++++++++++++++++++++++++++++++++---------------
2 files changed, 131 insertions(+), 52 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index ecd1c228..03be9577 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -199,7 +199,7 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h src/missing.h \
src/agent.h src/agent.c \
src/storage.h src/storage.c \
src/network.h src/network.c \
- src/wsc.c \
+ src/wsc.h src/wsc.c \
src/backtrace.h src/backtrace.c \
src/knownnetworks.h \
src/knownnetworks.c \
diff --git a/src/wsc.c b/src/wsc.c
index d971797a..61683e7b 100644
--- a/src/wsc.c
+++ b/src/wsc.c
@@ -44,6 +44,7 @@
#include "src/storage.h"
#include "src/iwd.h"
#include "src/network.h"
+#include "src/wsc.h"
#define WALK_TIME 120
@@ -60,18 +61,14 @@ struct wsc {
uint32_t scan_id;
struct scan_bss *target;
uint32_t station_state_watch;
- struct {
- char ssid[33];
- enum security security;
- union {
- uint8_t psk[32];
- char passphrase[64];
- };
- uint8_t addr[6];
- bool has_passphrase;
- } creds[3];
+ struct wsc_credentials creds[3];
uint32_t n_creds;
struct l_settings *eap_settings;
+ char *pin;
+
+ wsc_done_cb_t done_cb;
+ void *done_data;
+ uint16_t config_method;
bool wsc_association : 1;
};
@@ -160,15 +157,12 @@ static void wsc_try_credentials(struct wsc *wsc)
l_dbus_message_unref(wsc->pending);
wsc->pending = NULL;
- goto done;
+ return;
}
dbus_pending_reply(&wsc->pending,
wsc_error_not_reachable(wsc->pending));
station_set_autoconnect(wsc->station, true);
-done:
- memset(wsc->creds, 0, sizeof(wsc->creds));
- wsc->n_creds = 0;
}
static void wsc_store_credentials(struct wsc *wsc)
@@ -224,6 +218,22 @@ static void wsc_disconnect_cb(struct netdev *netdev, bool success,
station_set_autoconnect(wsc->station, true);
}
+static void wsc_connect_cleanup(struct wsc *wsc)
+{
+ wsc->wsc_association = false;
+
+ l_settings_free(wsc->eap_settings);
+ wsc->eap_settings = NULL;
+
+ if (wsc->pin) {
+ explicit_bzero(wsc->pin, strlen(wsc->pin));
+ l_free(wsc->pin);
+ wsc->pin = NULL;
+ }
+
+ wsc->target = NULL;
+}
+
static void wsc_connect_cb(struct netdev *netdev, enum netdev_result result,
void *event_data, void *user_data)
{
@@ -231,33 +241,34 @@ static void wsc_connect_cb(struct netdev *netdev, enum netdev_result result,
l_debug("%d, result: %d", netdev_get_ifindex(wsc->netdev), result);
- wsc->wsc_association = false;
-
- l_settings_free(wsc->eap_settings);
- wsc->eap_settings = NULL;
+ wsc_connect_cleanup(wsc);
if (result == NETDEV_RESULT_HANDSHAKE_FAILED && wsc->n_creds > 0) {
- wsc_store_credentials(wsc);
- wsc_try_credentials(wsc);
+ struct wsc_credentials creds[L_ARRAY_SIZE(wsc->creds)];
+ uint32_t n_creds = wsc->n_creds;
+
+ memcpy(creds, wsc->creds, sizeof(creds));
+ explicit_bzero(wsc->creds, sizeof(creds));
+ wsc->n_creds = 0;
+ wsc->done_cb(0, creds, n_creds, wsc->done_data);
+ explicit_bzero(creds, sizeof(creds));
return;
}
switch (result) {
case NETDEV_RESULT_ABORTED:
- dbus_pending_reply(&wsc->pending,
- dbus_error_aborted(wsc->pending));
+ wsc->done_cb(-ECANCELED, NULL, 0, wsc->done_data);
return;
case NETDEV_RESULT_HANDSHAKE_FAILED:
- dbus_pending_reply(&wsc->pending,
- wsc_error_no_credentials(wsc->pending));
+ wsc->done_cb(-ENOKEY, NULL, 0, wsc->done_data);
break;
default:
- dbus_pending_reply(&wsc->pending,
- dbus_error_failed(wsc->pending));
+ wsc->done_cb(-EIO, NULL, 0, wsc->done_data);
break;
}
- station_set_autoconnect(wsc->station, true);
+ if (wsc->station)
+ station_set_autoconnect(wsc->station, true);
}
static void wsc_credential_obtained(struct wsc *wsc,
@@ -451,30 +462,24 @@ static void wsc_connect(struct wsc *wsc)
l_settings_set_uint(settings, "WSC", "RFBand",
freq_to_rf_band(bss->frequency));
l_settings_set_uint(settings, "WSC", "ConfigurationMethods",
- WSC_CONFIGURATION_METHOD_VIRTUAL_DISPLAY_PIN |
- WSC_CONFIGURATION_METHOD_VIRTUAL_PUSH_BUTTON |
- WSC_CONFIGURATION_METHOD_KEYPAD);
+ wsc->config_method);
l_settings_set_string(settings, "WSC", "PrimaryDeviceType",
"0-00000000-0");
l_settings_set_string(settings, "WSC", "EnrolleeMAC",
util_address_to_string(netdev_get_address(wsc->netdev)));
- if (!strcmp(l_dbus_message_get_member(wsc->pending), "StartPin")) {
- const char *pin;
-
- if (l_dbus_message_get_arguments(wsc->pending, "s", &pin)) {
- enum wsc_device_password_id dpid;
+ if (wsc->config_method == WSC_CONFIGURATION_METHOD_KEYPAD) {
+ enum wsc_device_password_id dpid;
- if (strlen(pin) == 4 || wsc_pin_is_checksum_valid(pin))
- dpid = WSC_DEVICE_PASSWORD_ID_DEFAULT;
- else
- dpid = WSC_DEVICE_PASSWORD_ID_USER_SPECIFIED;
+ if (strlen(wsc->pin) == 4 ||
+ wsc_pin_is_checksum_valid(wsc->pin))
+ dpid = WSC_DEVICE_PASSWORD_ID_DEFAULT;
+ else
+ dpid = WSC_DEVICE_PASSWORD_ID_USER_SPECIFIED;
- l_settings_set_uint(settings, "WSC",
- "DevicePasswordId", dpid);
- l_settings_set_string(settings, "WSC",
- "DevicePassword", pin);
- }
+ l_settings_set_uint(settings, "WSC", "DevicePasswordId", dpid);
+ l_settings_set_string(settings, "WSC", "DevicePassword",
+ wsc->pin);
}
handshake_state_set_event_func(hs, wsc_handshake_event, wsc);
@@ -511,8 +516,38 @@ static void wsc_connect(struct wsc *wsc)
return;
error:
handshake_state_free(hs);
- dbus_pending_reply(&wsc->pending,
- dbus_error_failed(wsc->pending));
+ wsc_connect_cleanup(wsc);
+ wsc->done_cb(r, NULL, 0, wsc->done_data);
+}
+
+/* Done callback for when WSC is triggered by DBus methods */
+static void wsc_dbus_done_cb(int err, struct wsc_credentials *creds,
+ unsigned int n_creds, void *user_data)
+{
+ struct wsc *wsc = user_data;
+
+ l_debug("err=%i", err);
+
+ if (err == -ECANCELED) {
+ dbus_pending_reply(&wsc->pending,
+ dbus_error_aborted(wsc->pending));
+ return;
+ } else if (err == -ENOKEY) {
+ dbus_pending_reply(&wsc->pending,
+ wsc_error_no_credentials(wsc->pending));
+ return;
+ } else if (err == -EBUSY) {
+ dbus_pending_reply(&wsc->pending,
+ dbus_error_busy(wsc->pending));
+ return;
+ } else if (err) {
+ dbus_pending_reply(&wsc->pending,
+ dbus_error_failed(wsc->pending));
+ return;
+ }
+
+ wsc_store_credentials(wsc);
+ wsc_try_credentials(wsc);
}
static void station_state_watch(enum station_state state, void *userdata)
@@ -541,6 +576,22 @@ static void wsc_check_can_connect(struct wsc *wsc, struct scan_bss *target)
wsc->target = target;
station_set_autoconnect(wsc->station, false);
+ if (!strcmp(l_dbus_message_get_member(wsc->pending), "StartPin")) {
+ char *pin;
+
+ wsc->config_method = WSC_CONFIGURATION_METHOD_KEYPAD;
+
+ if (!l_dbus_message_get_arguments(wsc->pending, "s", &pin))
+ goto error;
+
+ wsc->pin = l_strdup(pin);
+ } else
+ wsc->config_method =
+ WSC_CONFIGURATION_METHOD_VIRTUAL_PUSH_BUTTON;
+
+ wsc->done_cb = wsc_dbus_done_cb;
+ wsc->done_data = wsc;
+
switch (station_get_state(wsc->station)) {
case STATION_STATE_DISCONNECTED:
wsc_connect(wsc);
@@ -564,7 +615,7 @@ static void wsc_check_can_connect(struct wsc *wsc, struct scan_bss *target)
break;
}
error:
- wsc->target = NULL;
+ wsc_connect_cleanup(wsc);
dbus_pending_reply(&wsc->pending, dbus_error_failed(wsc->pending));
}
@@ -1074,12 +1125,12 @@ static void wsc_free(void *userdata)
struct wsc *wsc = userdata;
wsc_cancel_scan(wsc);
+ wsc_connect_cleanup(wsc);
if (wsc->station_state_watch) {
station_remove_state_watch(wsc->station,
wsc->station_state_watch);
wsc->station_state_watch = 0;
- wsc->target = NULL;
}
if (wsc->pending)
@@ -1090,9 +1141,6 @@ static void wsc_free(void *userdata)
dbus_pending_reply(&wsc->pending_cancel,
dbus_error_aborted(wsc->pending_cancel));
- if (wsc->eap_settings)
- l_settings_free(wsc->eap_settings);
-
l_free(wsc);
}
@@ -1139,6 +1187,37 @@ static void wsc_netdev_watch(struct netdev *netdev,
}
}
+struct wsc *wsc_new_p2p_enrollee(struct netdev *netdev, struct scan_bss *target,
+ char *pin, wsc_done_cb_t done_cb,
+ void *user_data)
+{
+ struct wsc *wsc;
+
+ wsc = l_new(struct wsc, 1);
+ wsc->netdev = netdev;
+ wsc->target = target;
+ wsc->config_method = pin ? WSC_CONFIGURATION_METHOD_KEYPAD :
+ WSC_CONFIGURATION_METHOD_PUSH_BUTTON;
+ wsc->done_cb = done_cb;
+ wsc->done_data = user_data;
+ wsc->pin = l_strdup(pin);
+
+ wsc_connect(wsc);
+
+ /*
+ * Wsc objects created this way are not handled in wsc_remove_interface,
+ * the caller is expected to watch interfaces going away and there's no
+ * need to handle the event in both places.
+ */
+
+ return wsc;
+}
+
+void wsc_destroy(struct wsc *wsc)
+{
+ wsc_free(wsc);
+}
+
static int wsc_init(void)
{
l_debug("");
--
2.20.1
next prev parent reply other threads:[~2019-10-21 13:55 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-21 13:55 [PATCH 01/11] netdev: Add a wdev_id based frame watch API Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 02/11] netdev: Report RSSI to frame watch callbacks Andrew Zaborowski
2019-10-22 3:34 ` Denis Kenzior
2019-10-22 13:46 ` Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 03/11] netdev: Extend checks for P2P scenarios Andrew Zaborowski
2019-10-22 3:36 ` Denis Kenzior
2019-10-21 13:55 ` [PATCH 04/11] eapol: Move the EAP event handler to handshake state Andrew Zaborowski
2019-10-22 4:11 ` Denis Kenzior
2019-10-22 14:00 ` Andrew Zaborowski
2019-10-22 14:34 ` Denis Kenzior
2019-10-21 13:55 ` [PATCH 05/11] unit: Update test-wsc to use handshake_state_set_eap_event_func Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 06/11] wsc: Replace netdev_connect_wsc with netdev_connect usage Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 07/11] netdev: Drop unused netdev_connect_wsc Andrew Zaborowski
2019-10-21 13:55 ` Andrew Zaborowski [this message]
2019-10-22 14:47 ` [PATCH 08/11] wsc: Add wsc_new_p2p_enrollee, refactor Denis Kenzior
2019-10-22 23:46 ` Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 09/11] wsc: Accept extra IEs in wsc_new_p2p_enrollee Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 10/11] wiphy: Add wiphy_get_max_roc_duration Andrew Zaborowski
2019-10-22 3:26 ` Denis Kenzior
2019-10-21 13:55 ` [PATCH 11/11] wiphy: Add wiphy_get_supported_rates Andrew Zaborowski
2019-10-22 14:53 ` [PATCH 01/11] netdev: Add a wdev_id based frame watch API Denis Kenzior
2019-10-22 23:56 ` Andrew Zaborowski
2019-10-23 0:23 ` Denis Kenzior
2019-10-23 1:04 ` Andrew Zaborowski
2019-10-23 1:32 ` Denis Kenzior
2019-10-24 0:59 ` Andrew Zaborowski
2019-10-24 2:53 ` Denis Kenzior
2019-10-24 3:22 ` Andrew Zaborowski
2019-10-24 15:29 ` Denis Kenzior
2019-10-24 21:47 ` Andrew Zaborowski
2019-10-24 22:16 ` Denis Kenzior
2019-10-24 22:45 ` Andrew Zaborowski
2019-10-25 1:27 ` Denis Kenzior
2019-10-25 2:59 ` Andrew Zaborowski
2019-10-25 3:56 ` Denis Kenzior
2019-10-25 4:42 ` Andrew Zaborowski
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=20191021135510.12657-8-balrogg@gmail.com \
--to=balrogg@gmail.com \
--cc=iwd@lists.01.org \
/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