[network-manager-applet] applet: make more robust against wireless dialog secrets response (rh #582428)



commit 3cf5b3e586b21022a08bd462b94cfa30b4a99997
Author: Dan Williams <dcbw redhat com>
Date:   Sun Apr 25 23:59:40 2010 -0700

    applet: make more robust against wireless dialog secrets response (rh #582428)
    
    If the user cancels the wireless dialog while it's waiting for
    authorization for secrets or something, the user could have clicked
    the cancel button and closed the dialog.  Then when the	secrets	request
    comes back the dialog is closed and we go boom when we try to
    access the dead dialog's private members.
    
    So ensure that closing the dialog results in the secrets callback
    not trying to access the dialog at all, and make the buttons
    insensitive while the secrets call is going on.

 src/wireless-dialog.c |   53 +++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 47 insertions(+), 6 deletions(-)
---
diff --git a/src/wireless-dialog.c b/src/wireless-dialog.c
index 1a1ea2e..0a8ebb7 100644
--- a/src/wireless-dialog.c
+++ b/src/wireless-dialog.c
@@ -52,6 +52,12 @@ G_DEFINE_TYPE (NMAWirelessDialog, nma_wireless_dialog, GTK_TYPE_DIALOG)
                                             NMAWirelessDialogPrivate))
 
 typedef struct {
+	NMAWirelessDialog *self;
+	NMConnection *connection;
+	gboolean canceled;
+} GetSecretsInfo;
+
+typedef struct {
 	NMApplet *applet;
 
 	char *glade_file;
@@ -74,6 +80,8 @@ typedef struct {
 
 	guint revalidate_id;
 
+	GetSecretsInfo *secrets_info;
+
 	gboolean disposed;
 } NMAWirelessDialogPrivate;
 
@@ -293,6 +301,13 @@ stuff_changed_cb (WirelessSecurity *sec, gpointer user_data)
 	if (is_system_connection (self))
 		valid = TRUE;
 
+	/* But if there's an in-progress secrets call (which might require authorization)
+	 * then we don't want to enable the OK button because we don't have all the
+	 * connection details yet.
+	 */
+	if (priv->secrets_info)
+		valid = FALSE;
+
 	gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_OK, valid);
 }
 
@@ -332,6 +347,13 @@ out:
 	if (is_system_connection (self))
 		valid = TRUE;
 
+	/* But if there's an in-progress secrets call (which might require authorization)
+	 * then we don't want to enable the OK button because we don't have all the
+	 * connection details yet.
+	 */
+	if (priv->secrets_info)
+		valid = FALSE;
+
 	gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_OK, valid);
 }
 
@@ -741,11 +763,6 @@ add_security_item (NMAWirelessDialog *self,
 	wireless_security_unref (sec);
 }
 
-typedef struct {
-	NMAWirelessDialog *self;
-	NMConnection *connection;
-} GetSecretsInfo;
-
 static void
 get_secrets_cb (NMSettingsConnectionInterface *connection,
                 GHashTable *secrets,
@@ -753,12 +770,26 @@ get_secrets_cb (NMSettingsConnectionInterface *connection,
                 gpointer user_data)
 {
 	GetSecretsInfo *info = user_data;
-	NMAWirelessDialogPrivate *priv = NMA_WIRELESS_DIALOG_GET_PRIVATE (info->self);
+	NMAWirelessDialogPrivate *priv;
 	GHashTableIter hash_iter;
 	gpointer key, value;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 
+	if (info->canceled)
+		goto out;
+
+	priv = NMA_WIRELESS_DIALOG_GET_PRIVATE (info->self);
+	if (priv->secrets_info == info) {
+		priv->secrets_info = NULL;
+
+		/* Buttons should only be re-enabled if this secrets response is the
+		 * in-progress one.
+		 */
+		gtk_dialog_set_response_sensitive (GTK_DIALOG (info->self), GTK_RESPONSE_CANCEL, TRUE);
+		gtk_dialog_set_response_sensitive (GTK_DIALOG (info->self), GTK_RESPONSE_OK, TRUE);
+	}
+
 	if (error) {
 		g_warning ("%s: error getting connection secrets: (%d) %s",
 		           __func__,
@@ -988,9 +1019,16 @@ security_combo_init (NMAWirelessDialog *self, gboolean auth_only)
 		if (setting_name) {
 			GetSecretsInfo *info;
 
+			/* Desensitize the dialog's buttons while we wait for the secrets
+			 * operation to complete.
+			 */
+			gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_OK, FALSE);
+			gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_CANCEL, FALSE);
+
 			info = g_malloc0 (sizeof (GetSecretsInfo));
 			info->self = self;
 			info->connection = g_object_ref (priv->connection);
+			priv->secrets_info = info;
 
 			nm_settings_connection_interface_get_secrets (NM_SETTINGS_CONNECTION_INTERFACE (priv->connection),
 			                                              setting_name,
@@ -1377,6 +1415,9 @@ dispose (GObject *object)
 
 	priv->disposed = TRUE;
 
+	if (priv->secrets_info)
+		priv->secrets_info->canceled = TRUE;
+
 	g_free (priv->glade_file);
 
 	g_object_unref (priv->xml);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]