summary refs log tree commit diff
path: root/src/nm-activation-request.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-activation-request.c')
-rw-r--r--src/nm-activation-request.c214
1 files changed, 138 insertions, 76 deletions
diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c
index 2c084b87..30e98fca 100644
--- a/src/nm-activation-request.c
+++ b/src/nm-activation-request.c
@@ -26,10 +26,9 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
-#include "gsystem-local-alloc.h"
 
 #include "nm-activation-request.h"
-#include "nm-logging.h"
+#include "nm-default.h"
 #include "nm-setting-wireless-security.h"
 #include "nm-setting-8021x.h"
 #include "nm-device.h"
@@ -66,42 +65,101 @@ enum {
 
 /*******************************************************************/
 
+NMSettingsConnection *
+nm_act_request_get_settings_connection (NMActRequest *req)
+{
+	g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL);
+
+	return nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (req));
+}
+
 NMConnection *
-nm_act_request_get_connection (NMActRequest *req)
+nm_act_request_get_applied_connection (NMActRequest *req)
 {
 	g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL);
 
-	return nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (req));
+	return nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (req));
 }
 
 /*******************************************************************/
 
-typedef struct {
+struct _NMActRequestGetSecretsCallId {
 	NMActRequest *self;
-	guint32 call_id;
 	NMActRequestSecretsFunc callback;
 	gpointer callback_data;
-} GetSecretsInfo;
+	NMSettingsConnectionCallId call_id;
+};
+
+typedef struct _NMActRequestGetSecretsCallId GetSecretsInfo;
+
+static GetSecretsInfo *
+_get_secrets_info_new (NMActRequest *self, NMActRequestSecretsFunc callback, gpointer callback_data)
+{
+	GetSecretsInfo *info;
+
+	info = g_slice_new0 (GetSecretsInfo);
+	info->self = self;
+	info->callback = callback;
+	info->callback_data = callback_data;
+
+	return info;
+}
+
+static void
+_get_secrets_info_free (GetSecretsInfo *info)
+{
+	g_slice_free (GetSecretsInfo, info);
+}
 
 static void
 get_secrets_cb (NMSettingsConnection *connection,
-                guint32 call_id,
+                NMSettingsConnectionCallId call_id_s,
                 const char *agent_username,
                 const char *setting_name,
                 GError *error,
                 gpointer user_data)
 {
 	GetSecretsInfo *info = user_data;
-	NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (info->self);
+	NMActRequestPrivate *priv;
+
+	g_return_if_fail (info && info->call_id == call_id_s);
+	g_return_if_fail (NM_IS_ACT_REQUEST (info->self));
+
+	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+		return;
+
+	priv = NM_ACT_REQUEST_GET_PRIVATE (info->self);
+
+	g_return_if_fail (g_slist_find (priv->secrets_calls, info));
 
-	g_return_if_fail (info->call_id == call_id);
 	priv->secrets_calls = g_slist_remove (priv->secrets_calls, info);
 
-	info->callback (info->self, call_id, NM_CONNECTION (connection), error, info->callback_data);
-	g_free (info);
+	if (info->callback)
+		info->callback (info->self, info, connection, error, info->callback_data);
+
+	_get_secrets_info_free (info);
 }
 
-guint32
+/**
+ * nm_act_request_get_secrets:
+ * @self:
+ * @setting_name:
+ * @flags:
+ * @hint:
+ * @callback:
+ * @callback_data:
+ *
+ * Asnychronously starts the request for secrets. This function cannot
+ * fail.
+ *
+ * The return call-id can be used to cancel the request. You are
+ * only allowed to cancel a still pending operation (once).
+ * The callback will always be invoked once, even for canceling
+ * or disposing of NMActRequest.
+ *
+ * Returns: a call-id.
+ */
+NMActRequestGetSecretsCallId
 nm_act_request_get_secrets (NMActRequest *self,
                             const char *setting_name,
                             NMSecretAgentGetSecretsFlags flags,
@@ -111,68 +169,82 @@ nm_act_request_get_secrets (NMActRequest *self,
 {
 	NMActRequestPrivate *priv;
 	GetSecretsInfo *info;
-	guint32 call_id;
-	NMConnection *connection;
+	NMSettingsConnectionCallId call_id_s;
+	NMSettingsConnection *settings_connection;
+	NMConnection *applied_connection;
 	const char *hints[2] = { hint, NULL };
 
-	g_return_val_if_fail (self, 0);
 	g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0);
 
 	priv = NM_ACT_REQUEST_GET_PRIVATE (self);
 
-	info = g_malloc0 (sizeof (GetSecretsInfo));
-	info->self = self;
-	info->callback = callback;
-	info->callback_data = callback_data;
+	settings_connection = nm_act_request_get_settings_connection (self);
+	applied_connection = nm_act_request_get_applied_connection (self);
+
+	info = _get_secrets_info_new (self, callback, callback_data);
+
+	priv->secrets_calls = g_slist_append (priv->secrets_calls, info);
 
 	if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self)))
 		flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED;
 
-	connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self));
-	call_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (connection),
-	                                              nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)),
-	                                              setting_name,
-	                                              flags,
-	                                              hints,
-	                                              get_secrets_cb,
-	                                              info,
-	                                              NULL);
-	if (call_id > 0) {
-		info->call_id = call_id;
-		priv->secrets_calls = g_slist_append (priv->secrets_calls, info);
-	} else
-		g_free (info);
-
-	return call_id;
+	call_id_s = nm_settings_connection_get_secrets (settings_connection,
+	                                                applied_connection,
+	                                                nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)),
+	                                                setting_name,
+	                                                flags,
+	                                                hints,
+	                                                get_secrets_cb,
+	                                                info);
+	info->call_id = call_id_s;
+	g_return_val_if_fail (call_id_s, NULL);
+	return info;
+}
+
+static void
+_do_cancel_secrets (NMActRequest *self, GetSecretsInfo *info, gboolean is_disposing)
+{
+	NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
+
+	nm_assert (info && info->self == self);
+	nm_assert (g_slist_find (priv->secrets_calls, info));
+
+	priv->secrets_calls = g_slist_remove (priv->secrets_calls, info);
+
+	nm_settings_connection_cancel_secrets (nm_act_request_get_settings_connection (self), info->call_id);
+
+	if (info->callback) {
+		gs_free_error GError *error = NULL;
+
+		nm_utils_error_set_cancelled (&error, is_disposing, "NMActRequest");
+		info->callback (self, info, NULL, error, info->callback_data);
+	}
+
+	_get_secrets_info_free (info);
 }
 
 void
-nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id)
+nm_act_request_cancel_secrets (NMActRequest *self, NMActRequestGetSecretsCallId call_id)
 {
 	NMActRequestPrivate *priv;
-	NMConnection *connection;
-	GSList *iter;
 
-	g_return_if_fail (self);
 	g_return_if_fail (NM_IS_ACT_REQUEST (self));
-	g_return_if_fail (call_id > 0);
+	g_return_if_fail (call_id);
 
 	priv = NM_ACT_REQUEST_GET_PRIVATE (self);
 
-	connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self));
-	for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
-		GetSecretsInfo *info = iter->data;
+	if (!g_slist_find (priv->secrets_calls, call_id))
+		g_return_if_reached ();
 
-		/* Remove the matching info */
-		if (info->call_id == call_id) {
-			priv->secrets_calls = g_slist_remove_link (priv->secrets_calls, iter);
-			g_slist_free (iter);
+	_do_cancel_secrets (self, call_id, FALSE);
+}
 
-			nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), call_id);
-			g_free (info);
-			break;
-		}
-	}
+void
+nm_act_request_clear_secrets (NMActRequest *self)
+{
+	g_return_if_fail (NM_IS_ACT_REQUEST (self));
+
+	nm_active_connection_clear_secrets ((NMActiveConnection *) self);
 }
 
 /********************************************************************/
@@ -392,30 +464,28 @@ master_failed (NMActiveConnection *self)
 /**
  * nm_act_request_new:
  *
- * @connection: the connection to activate @device with
+ * @settings_connection: (allow-none): the connection to activate @device with
  * @specific_object: the object path of the specific object (ie, WiFi access point,
  *    etc) that will be used to activate @connection and @device
  * @subject: the #NMAuthSubject representing the requestor of the activation
- * @device: the device/interface to configure according to @connection; or %NULL
- * if the connection describes a software device which will be created during
- * connection activation
+ * @device: the device/interface to configure according to @connection
  *
  * Creates a new device-based activation request.
  *
  * Returns: the new activation request on success, %NULL on error.
  */
 NMActRequest *
-nm_act_request_new (NMConnection *connection,
+nm_act_request_new (NMSettingsConnection *settings_connection,
                     const char *specific_object,
                     NMAuthSubject *subject,
                     NMDevice *device)
 {
-	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
-	g_return_val_if_fail (!device || NM_IS_DEVICE (device), NULL);
+	g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
+	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 	g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
 
 	return (NMActRequest *) g_object_new (NM_TYPE_ACT_REQUEST,
-	                                      NM_ACTIVE_CONNECTION_INT_CONNECTION, connection,
+	                                      NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION, settings_connection,
 	                                      NM_ACTIVE_CONNECTION_INT_DEVICE, device,
 	                                      NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object,
 	                                      NM_ACTIVE_CONNECTION_INT_SUBJECT, subject,
@@ -430,9 +500,12 @@ nm_act_request_init (NMActRequest *req)
 static void
 dispose (GObject *object)
 {
-	NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
-	NMConnection *connection;
-	GSList *iter;
+	NMActRequest *self = NM_ACT_REQUEST (object);
+	NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
+
+	/* Kill any in-progress secrets requests */
+	while (priv->secrets_calls)
+		_do_cancel_secrets (self, priv->secrets_calls->data, TRUE);
 
 	/* Clear any share rules */
 	if (priv->share_rules) {
@@ -440,17 +513,6 @@ dispose (GObject *object)
 		clear_share_rules (NM_ACT_REQUEST (object));
 	}
 
-	/* Kill any in-progress secrets requests */
-	connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (object));
-	for (iter = priv->secrets_calls; connection && iter; iter = g_slist_next (iter)) {
-		GetSecretsInfo *info = iter->data;
-
-		nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), info->call_id);
-		g_free (info);
-	}
-	g_slist_free (priv->secrets_calls);
-	priv->secrets_calls = NULL;
-
 	G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
 }
 
@@ -462,7 +524,7 @@ get_property (GObject *object, guint prop_id,
 
 	device = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (object));
 	if (!device) {
-		g_value_set_boxed (value, "/");
+		g_value_set_string (value, "/");
 		return;
 	}