[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