[PATCH v2 2/3] DBus: add interworking credentials.
Damien Dejean
damiendejean at chromium.org
Tue Dec 7 23:45:31 PST 2021
Add "AddCred", "RemoveCred" and "RemoveAllCreds" methods to the D-Bus
API of the network interface to allow the caller to manipulate a set of
interworking credentials.
Signed-off-by: Damien Dejean <damiendejean at chromium.org>
---
tests/hwsim/test_dbus.py | 45 ++++
wpa_supplicant/ctrl_iface.c | 55 +----
wpa_supplicant/dbus/dbus_new.c | 23 ++
wpa_supplicant/dbus/dbus_new.h | 4 +
wpa_supplicant/dbus/dbus_new_handlers.c | 266 ++++++++++++++++++++++++
wpa_supplicant/dbus/dbus_new_handlers.h | 14 ++
wpa_supplicant/wpa_supplicant.c | 73 +++++++
wpa_supplicant/wpa_supplicant_i.h | 4 +
8 files changed, 433 insertions(+), 51 deletions(-)
diff --git a/tests/hwsim/test_dbus.py b/tests/hwsim/test_dbus.py
index 1143802c6..4edd0fd73 100644
--- a/tests/hwsim/test_dbus.py
+++ b/tests/hwsim/test_dbus.py
@@ -6091,3 +6091,48 @@ def test_dbus_roam(dev, apdev):
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
+
+def test_dbus_creds(dev, apdev):
+ "D-Bus interworking credentials"
+ (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
+ iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
+
+ args = {'domain': 'server.w1.fi',
+ 'realm': 'server.w1.fi',
+ 'roaming_consortium': '50a9bf',
+ 'required_roaming_consortium': '23bf50',
+ 'eap': 'TTLS',
+ 'phase2': 'auth=MSCHAPV2',
+ 'username': 'user',
+ 'password': 'password',
+ 'domain_suffix_match': 'server.w1.fi',
+ 'ca_cert': 'auth_serv/ca.pem'}
+
+ path = iface.AddCred(dbus.Dictionary(args, signature='sv'))
+ for k, v in args.items():
+ if k == 'password':
+ continue
+ prop = dev[0].get_cred(0, k)
+ if prop != v:
+ raise Exception('Credential add failed: %s does not match %s' % (prop, v))
+
+ iface.RemoveCred(path)
+ if not "FAIL" in dev[0].get_cred(0, 'domain'):
+ raise Exception("Credential remove failed")
+
+ # Removal of multiple credentials
+ cred1 = {'domain': 'server1.w1.fi','realm': 'server1.w1.fi','eap': 'TTLS'}
+ iface.AddCred(dbus.Dictionary(cred1, signature='sv'))
+ if "FAIL" in dev[0].get_cred(0, 'domain'):
+ raise Exception("Failed to add credential")
+
+ cred2 = {'domain': 'server2.w1.fi','realm': 'server2.w1.fi','eap': 'TTLS'}
+ iface.AddCred(dbus.Dictionary(cred2, signature='sv'))
+ if "FAIL" in dev[0].get_cred(1, 'domain'):
+ raise Exception("Failed to add credential")
+
+ iface.RemoveAllCreds()
+ if not "FAIL" in dev[0].get_cred(0, 'domain'):
+ raise Exception("Credential remove failed")
+ if not "FAIL" in dev[0].get_cred(1, 'domain'):
+ raise Exception("Credential remove failed")
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 90f3e9fe9..b271a2292 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -3793,47 +3793,6 @@ static int wpa_supplicant_ctrl_iface_add_cred(struct wpa_supplicant *wpa_s,
}
-static int wpas_ctrl_remove_cred(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred)
-{
- struct wpa_ssid *ssid;
- char str[20];
- int id;
-
- if (cred == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred");
- return -1;
- }
-
- id = cred->id;
- if (wpa_config_remove_cred(wpa_s->conf, id) < 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred");
- return -1;
- }
-
- wpa_msg(wpa_s, MSG_INFO, CRED_REMOVED "%d", id);
-
- /* Remove any network entry created based on the removed credential */
- ssid = wpa_s->conf->ssid;
- while (ssid) {
- if (ssid->parent_cred == cred) {
- int res;
-
- wpa_printf(MSG_DEBUG, "Remove network id %d since it "
- "used the removed credential", ssid->id);
- res = os_snprintf(str, sizeof(str), "%d", ssid->id);
- if (os_snprintf_error(sizeof(str), res))
- str[sizeof(str) - 1] = '\0';
- ssid = ssid->next;
- wpa_supplicant_ctrl_iface_remove_network(wpa_s, str);
- } else
- ssid = ssid->next;
- }
-
- return 0;
-}
-
-
static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
char *cmd)
{
@@ -3844,13 +3803,7 @@ static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
* "provisioning_sp=<FQDN> */
if (os_strcmp(cmd, "all") == 0) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED all");
- cred = wpa_s->conf->cred;
- while (cred) {
- prev = cred;
- cred = cred->next;
- wpas_ctrl_remove_cred(wpa_s, prev);
- }
- return 0;
+ return wpa_supplicant_remove_all_creds(wpa_s);
}
if (os_strncmp(cmd, "sp_fqdn=", 8) == 0) {
@@ -3866,7 +3819,7 @@ static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
if (os_strcmp(prev->domain[i], cmd + 8)
!= 0)
continue;
- wpas_ctrl_remove_cred(wpa_s, prev);
+ wpa_supplicant_remove_cred(wpa_s, prev);
break;
}
}
@@ -3883,7 +3836,7 @@ static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
cred = cred->next;
if (prev->provisioning_sp &&
os_strcmp(prev->provisioning_sp, cmd + 16) == 0)
- wpas_ctrl_remove_cred(wpa_s, prev);
+ wpa_supplicant_remove_cred(wpa_s, prev);
}
return 0;
}
@@ -3892,7 +3845,7 @@ static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED id=%d", id);
cred = wpa_config_get_cred(wpa_s->conf, id);
- return wpas_ctrl_remove_cred(wpa_s, cred);
+ return wpa_supplicant_remove_cred(wpa_s, cred);
}
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 2c01943f7..bfa49d654 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -3570,6 +3570,29 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
END_ARGS
}
},
+#ifdef CONFIG_INTERWORKING
+ { "AddCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_add_cred,
+ {
+ { "args", "a{sv}", ARG_IN },
+ { "path", "o", ARG_OUT },
+ END_ARGS
+ }
+ },
+ { "RemoveCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_remove_cred,
+ {
+ { "path", "o", ARG_IN },
+ END_ARGS
+ }
+ },
+ { "RemoveAllCreds", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_remove_all_creds,
+ {
+ END_ARGS
+ }
+ },
+#endif /* CONFIG_INTERWORKING */
{ NULL, NULL, NULL, { END_ARGS } }
};
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 42db3892e..8ae0afeaa 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -16,6 +16,7 @@
struct wpa_global;
struct wpa_supplicant;
struct wpa_ssid;
+struct wpa_cred;
struct wps_event_m2d;
struct wps_event_fail;
struct wps_credential;
@@ -96,6 +97,9 @@ enum wpas_dbus_sta_prop {
#define WPAS_DBUS_NEW_P2P_PEERS_PART "Peers"
#define WPAS_DBUS_NEW_IFACE_P2P_PEER WPAS_DBUS_NEW_INTERFACE ".Peer"
+#define WPAS_DBUS_NEW_CREDENTIALS_PART "Credentials"
+#define WPAS_DBUS_NEW_IFACE_CREDENTIAL WPAS_DBUS_NEW_INTERFACE ".Credential"
+
/* Top-level Errors */
#define WPAS_DBUS_ERROR_UNKNOWN_ERROR \
WPAS_DBUS_NEW_INTERFACE ".UnknownError"
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index db9f30c9a..c1abff94c 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -148,6 +148,9 @@ static const char * const dont_quote[] = {
#ifdef CONFIG_P2P
"go_p2p_dev_addr", "p2p_client_list", "psk_list",
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+ "roaming_consortium", "required_roaming_consortium",
+#endif /* CONFIG_INTERWORKING */
NULL
};
@@ -328,6 +331,110 @@ error:
}
+/**
+ * set_cred_properties - Set the properties of a configured set of
+ * crendentials.
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * @cred: wpa_cred structure for a configured credential
+ * @iter: DBus message iterator containing dictionary of network
+ * properties to set.
+ * @error: On failure, an error describing the failure
+ * Returns: TRUE if the request succeeds, FALSE if it failed
+ */
+dbus_bool_t set_cred_properties(struct wpa_supplicant *wpa_s,
+ struct wpa_cred *cred,
+ DBusMessageIter *iter,
+ DBusError *error)
+{
+ struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
+ DBusMessageIter iter_dict;
+ char *value = NULL;
+
+ if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
+ return FALSE;
+
+ while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+ size_t size = 50;
+ int ret;
+
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+ goto error;
+
+ value = NULL;
+ if (entry.type == DBUS_TYPE_ARRAY &&
+ entry.array_type == DBUS_TYPE_BYTE) {
+ if (entry.array_len <= 0)
+ goto error;
+
+ size = entry.array_len * 2 + 1;
+ value = os_zalloc(size);
+ if (value == NULL)
+ goto error;
+
+ ret = wpa_snprintf_hex(value, size,
+ (u8 *) entry.bytearray_value,
+ entry.array_len);
+ if (ret <= 0)
+ goto error;
+ } else if (entry.type == DBUS_TYPE_STRING) {
+ if (should_quote_opt(entry.key)) {
+ size = os_strlen(entry.str_value);
+
+ size += 3;
+ value = os_zalloc(size);
+ if (value == NULL)
+ goto error;
+
+ ret = os_snprintf(value, size, "\"%s\"",
+ entry.str_value);
+ if (os_snprintf_error(size, ret))
+ goto error;
+ } else {
+ value = os_strdup(entry.str_value);
+ if (value == NULL)
+ goto error;
+ }
+ } else if (entry.type == DBUS_TYPE_UINT32) {
+ value = os_zalloc(size);
+ if (value == NULL)
+ goto error;
+
+ ret = os_snprintf(value, size, "%u",
+ entry.uint32_value);
+ if (os_snprintf_error(size, ret))
+ goto error;
+ } else if (entry.type == DBUS_TYPE_INT32) {
+ value = os_zalloc(size);
+ if (value == NULL)
+ goto error;
+
+ ret = os_snprintf(value, size, "%d",
+ entry.int32_value);
+ if (os_snprintf_error(size, ret))
+ goto error;
+ } else
+ goto error;
+
+ ret = wpa_config_set_cred(cred, entry.key, value, 0);
+ if (ret < 0)
+ goto error;
+
+ os_free(value);
+ value = NULL;
+ wpa_dbus_dict_entry_clear(&entry);
+ }
+
+ return TRUE;
+
+error:
+ os_free(value);
+ wpa_dbus_dict_entry_clear(&entry);
+ dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+ "invalid message format");
+ return FALSE;
+}
+
+
/**
* wpas_dbus_simple_property_getter - Get basic type property
* @iter: Message iter to use when appending arguments
@@ -1514,6 +1621,165 @@ DBusMessage * wpas_dbus_handler_abort_scan(DBusMessage *message,
return NULL;
}
+/**
+ * wpas_dbus_new_iface_add_cred - Add a new set of credentials
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: A dbus message containing the object path of the new credential
+ *
+ * Handler function for "AddCred" method call of a network interface.
+ */
+DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter;
+ struct wpa_cred *cred = NULL;
+ char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
+ DBusError error;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (wpa_s->dbus_new_path)
+ cred = wpa_config_add_cred(wpa_s->conf);
+ if (cred == NULL) {
+ wpa_printf(MSG_ERROR, "%s[dbus]: can't add new interface.",
+ __func__);
+ reply = wpas_dbus_error_unknown_error(
+ message,
+ "wpa_supplicant could not add a credential on this interface.");
+ goto err;
+ }
+
+ dbus_error_init(&error);
+ if (!set_cred_properties(wpa_s, cred, &iter, &error)) {
+ wpa_printf(MSG_DEBUG,
+ "%s[dbus]: control interface couldn't set credential properties",
+ __func__);
+ reply = wpas_dbus_reply_new_from_error(message, &error,
+ DBUS_ERROR_INVALID_ARGS,
+ "Failed to add credential");
+ dbus_error_free(&error);
+ goto err;
+ }
+
+ /* Construct the object path for this network. */
+ os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
+ "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%d",
+ wpa_s->dbus_new_path, cred->id);
+
+ reply = dbus_message_new_method_return(message);
+ if (reply == NULL) {
+ reply = wpas_dbus_error_no_memory(message);
+ goto err;
+ }
+ if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID)) {
+ dbus_message_unref(reply);
+ reply = wpas_dbus_error_no_memory(message);
+ goto err;
+ }
+
+ return reply;
+
+err:
+ if (cred) {
+ wpa_config_remove_cred(wpa_s->conf, cred->id);
+ }
+ return reply;
+}
+
+/**
+ * wpas_dbus_handler_remove_cred - Remove a configured set of credentials
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL on success or dbus error on failure
+ *
+ * Handler function for "RemoveCred" method call of a network interface.
+ */
+DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessage *reply = NULL;
+ const char *op;
+ char *iface, *cred_id;
+ int id;
+ struct wpa_cred *cred;
+ int result;
+
+ dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
+ DBUS_TYPE_INVALID);
+
+ /* Extract the network ID and ensure the network */
+ /* is actually a child of this interface */
+ iface = wpas_dbus_new_decompose_object_path(op,
+ WPAS_DBUS_NEW_CREDENTIALS_PART,
+ &cred_id);
+ if (iface == NULL || cred_id == NULL || !wpa_s->dbus_new_path ||
+ os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
+ reply = wpas_dbus_error_invalid_args(message, op);
+ goto out;
+ }
+
+ errno = 0;
+ id = strtoul(cred_id, NULL, 10);
+ if (errno != 0) {
+ reply = wpas_dbus_error_invalid_args(message, op);
+ goto out;
+ }
+
+ cred = wpa_config_get_cred(wpa_s->conf, id);
+ if (!cred) {
+ wpa_printf(MSG_ERROR,
+ "%s[dbus]: could not find credential %s",
+ __func__, op);
+ reply = wpas_dbus_error_invalid_args(message,
+ "could not find credentials");
+ goto out;
+ }
+
+ result = wpa_supplicant_remove_cred(wpa_s, cred);
+ if (result == -1) {
+ wpa_printf(MSG_ERROR,
+ "%s[dbus]: error occurred when removing cred %d",
+ __func__, id);
+ reply = wpas_dbus_error_unknown_error(
+ message,
+ "error removing the specified credential on its interface.");
+ goto out;
+ }
+
+out:
+ os_free(iface);
+ return reply;
+}
+
+/**
+ * wpas_dbus_handler_remove_all_creds - Remove all the configured sets of
+ * credentials.
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "RemoveAllCreds" method call of a network interface.
+ */
+DBusMessage * wpas_dbus_handler_remove_all_creds(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ int res;
+ DBusMessage *reply = NULL;
+
+ res = wpa_supplicant_remove_all_creds(wpa_s);
+ if (res < 0) {
+ wpa_printf(MSG_ERROR,
+ "%s[dbus]: failed to remove all credentials",
+ __func__);
+ reply = wpas_dbus_error_unknown_error(message,
+ "failed to remove all credentials");
+ }
+
+ return reply;
+}
/**
* wpas_dbus_handler_signal_poll - Request immediate signal properties
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index c36383f05..8a9f26a7e 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -144,6 +144,20 @@ DBusMessage * wpas_dbus_handler_eap_logoff(DBusMessage *message,
DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
struct wpa_supplicant *wpa_s);
+dbus_bool_t set_cred_properties(struct wpa_supplicant *wpa_s,
+ struct wpa_cred *cred,
+ DBusMessageIter *iter,
+ DBusError *error);
+
+DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_handler_remove_all_creds(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
DECLARE_ACCESSOR(wpas_dbus_getter_capabilities);
DECLARE_ACCESSOR(wpas_dbus_getter_state);
DECLARE_ACCESSOR(wpas_dbus_getter_scanning);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index b80f1d4f0..34da9cac4 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -4512,6 +4512,79 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
}
+/**
+ * wpa_supplicant_remove_cred - Remove the set of provided credentials and all
+ * the network entries created based on the removed credentials.
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * @cred: the set of credentials to remove
+ */
+int wpa_supplicant_remove_cred(struct wpa_supplicant* wpa_s,
+ struct wpa_cred* cred)
+{
+ struct wpa_ssid *ssid;
+ int id;
+
+ if (cred == NULL) {
+ wpa_printf(MSG_DEBUG, "Could not find cred");
+ return -1;
+ }
+
+ id = cred->id;
+ if (wpa_config_remove_cred(wpa_s->conf, id) < 0) {
+ wpa_printf(MSG_DEBUG, "Could not find cred %d", id);
+ return -1;
+ }
+
+ wpa_msg(wpa_s, MSG_INFO, CRED_REMOVED "%d", id);
+
+ /* Remove any network entry created based on the removed credential */
+ ssid = wpa_s->conf->ssid;
+ while (ssid) {
+ if (ssid->parent_cred == cred) {
+ int res;
+ wpa_printf(MSG_DEBUG, "Remove network id %d since it "
+ "used the removed credential", ssid->id);
+ res = wpa_supplicant_remove_network(wpa_s, ssid->id);
+ if (res == -1) {
+ wpa_printf(MSG_DEBUG,
+ "Could not find network id=%d",
+ ssid->id);
+ }
+ ssid = ssid->next;
+ } else
+ ssid = ssid->next;
+ }
+
+ return 0;
+}
+
+
+/**
+ * wpa_supplicant_remove_cred - Remove all the interworking credentials.
+ * @wpa_s: wpa_supplicant structure for a network interface
+ */
+int wpa_supplicant_remove_all_creds(struct wpa_supplicant* wpa_s)
+{
+ int res;
+ struct wpa_cred *cred, *prev;
+
+ cred = wpa_s->conf->cred;
+ while (cred) {
+ prev = cred;
+ cred = cred->next;
+ res = wpa_supplicant_remove_cred(wpa_s, prev);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG, "Remove all credentials failed "
+ "because remove of credential id=%d failed",
+ prev->id);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
/**
* wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
* @wpa_s: wpa_supplicant structure for a network interface
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index cbc955159..d68350ae9 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -38,6 +38,7 @@ struct wpa_bss;
struct wpa_scan_results;
struct hostapd_hw_modes;
struct wpa_driver_associate_params;
+struct wpa_cred;
/*
* Forward declarations of private structures used within the ctrl_iface
@@ -1578,6 +1579,9 @@ void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
+int wpa_supplicant_remove_cred(struct wpa_supplicant* wpa_s,
+ struct wpa_cred* cred);
+int wpa_supplicant_remove_all_creds(struct wpa_supplicant* wpa_s);
int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
const char *pkcs11_engine_path,
const char *pkcs11_module_path);
--
2.34.1.400.ga245620fadb-goog
More information about the Hostap
mailing list