[network-manager-netbook] Fix wireless authentication once again



commit 9181e7d6824eb1c81414d4edbd789812075b8779
Author: Tambet Ingo <tambet gmail com>
Date:   Tue Mar 2 11:36:43 2010 -0400

    Fix wireless authentication once again
    
    In some cases (WPA-EAP), we can't even produce a valid connection without
    user's help by filling in the authentication dialog. Turn the automatic
    connection creation to asyncronous, and check if it needs secrets before
    returning it. Fixes bnc584155.

 libnm-gtk/nm-connection-item.c |   87 +++++++++++++++++++++++++++++++++++++--
 libnm-gtk/nm-connection-item.h |    9 ++++-
 libnm-gtk/nm-wifi-item.c       |   27 +++++++++----
 src/nmn-item-renderer.c        |   81 ++++++++++++++++++++----------------
 4 files changed, 154 insertions(+), 50 deletions(-)
---
diff --git a/libnm-gtk/nm-connection-item.c b/libnm-gtk/nm-connection-item.c
index 0b73b4c..7e5e027 100644
--- a/libnm-gtk/nm-connection-item.c
+++ b/libnm-gtk/nm-connection-item.c
@@ -83,7 +83,9 @@ secrets_requested (NMGConfConnection *connection,
     NMConnectionItem *self = NM_CONNECTION_ITEM (user_data);
 
     if (NM_CONNECTION_ITEM_GET_CLASS (self)->secrets_requested)
-        NM_CONNECTION_ITEM_GET_CLASS (self)->secrets_requested (self, setting_name, hints,
+        NM_CONNECTION_ITEM_GET_CLASS (self)->secrets_requested (self,
+                                                                (NMConnection *) connection,
+                                                                setting_name, hints,
                                                                 ask_user, callback, callback_data);
     else {
         GError *error;
@@ -302,15 +304,90 @@ nm_connection_item_new_connection (NMConnectionItem *self,
     nm_gconf_write_connection (connection, NULL, NULL);
 }
 
+static void
+create_connection_secrets_received (NMSettingsConnectionInterface *connection,
+                                    GHashTable *settings,
+                                    GError *error,
+                                    gpointer user_data)
+{
+    GSimpleAsyncResult *result = user_data;
+
+    if (error)
+        g_simple_async_result_set_from_error (result, error);
+    else {
+        /* Create a duplicate of the connection - otherwise we'll loose the secrets as soon as
+           this function returns */
+        g_simple_async_result_set_op_res_gpointer (result,
+                                                   nm_connection_duplicate (NM_CONNECTION (connection)),
+                                                   g_object_unref);
+
+        g_object_unref (connection);
+    }
+
+    g_simple_async_result_complete_in_idle (result);
+    g_object_unref (result);
+}
+
+void
+nm_connection_item_create_connection (NMConnectionItem *self,
+                                      GAsyncReadyCallback callback,
+                                      gpointer user_data)
+{
+    NMConnection *connection;
+    GSimpleAsyncResult *result;
+
+    g_return_if_fail (NM_IS_CONNECTION_ITEM (self));
+
+    if (NM_CONNECTION_ITEM_GET_CLASS (self)->create_connection)
+        connection = NM_CONNECTION_ITEM_GET_CLASS (self)->create_connection (self);
+    else
+        connection = NULL;
+
+    if (connection) {
+        const char *setting_name;
+        GPtrArray *hints_array = NULL;
+
+        result = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+                                            nm_connection_item_create_connection_finish);
+
+        setting_name = nm_connection_need_secrets (connection, &hints_array);
+        if (hints_array)
+            /* Hints are for weaks, bah. */
+            g_ptr_array_free (hints_array, TRUE);
+
+        if (setting_name)
+            secrets_requested ((NMGConfConnection *) connection, setting_name, NULL, TRUE,
+                               create_connection_secrets_received, result, self);
+        else {
+            /* No extra secrets needed, we're done */
+            g_simple_async_result_set_op_res_gpointer (result, connection, g_object_unref);
+            g_simple_async_result_complete_in_idle (result);
+        }
+    } else {
+        result = g_simple_async_result_new_error (G_OBJECT (self), callback, user_data,
+                                                  0, 0, "%s", "Could not create the new connection");
+        g_simple_async_result_complete_in_idle (result);
+    }
+}
+
 NMConnection *
-nm_connection_item_create_connection (NMConnectionItem *self)
+nm_connection_item_create_connection_finish (NMConnectionItem *self,
+                                             GAsyncResult *result,
+                                             GError **error)
 {
+    NMConnection *connection;
+
     g_return_val_if_fail (NM_IS_CONNECTION_ITEM (self), NULL);
 
-    if (NM_CONNECTION_ITEM_GET_CLASS (self)->create_connection)
-        return NM_CONNECTION_ITEM_GET_CLASS (self)->create_connection (self);
+    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error) ||
+        !g_simple_async_result_is_valid (result, G_OBJECT (self), nm_connection_item_create_connection_finish))
+        return NULL;
+
+    connection = (NMConnection *) g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+    if (connection)
+        g_object_ref (connection);
 
-    return NULL;
+    return connection;
 }
 
 static void
diff --git a/libnm-gtk/nm-connection-item.h b/libnm-gtk/nm-connection-item.h
index f2760b1..b949bfb 100644
--- a/libnm-gtk/nm-connection-item.h
+++ b/libnm-gtk/nm-connection-item.h
@@ -21,6 +21,7 @@
 #define NM_CONNECTION_ITEM_H
 
 #include <glib-object.h>
+#include <gio/gio.h>
 #include <nm-client.h>
 #include <nm-settings-connection-interface.h>
 #include <nm-list-item.h>
@@ -47,6 +48,7 @@ typedef struct {
     NMListItemClass parent_class;
 
     void (*secrets_requested) (NMConnectionItem *self,
+                               NMConnection *connection,
                                const char *setting_name,
                                const char **hints,
                                gboolean ask_user,
@@ -67,8 +69,13 @@ void                           nm_connection_item_new_connection (NMConnectionIt
                                                                   NMConnection *connection,
                                                                   gboolean connect);
 
+void                           nm_connection_item_create_connection (NMConnectionItem *self,
+                                                                     GAsyncReadyCallback callback,
+                                                                     gpointer user_data);
 
-NMConnection                  *nm_connection_item_create_connection (NMConnectionItem *self);
+NMConnection                  *nm_connection_item_create_connection_finish (NMConnectionItem *self,
+                                                                            GAsyncResult *result,
+                                                                            GError **error);
 
 G_END_DECLS
 
diff --git a/libnm-gtk/nm-wifi-item.c b/libnm-gtk/nm-wifi-item.c
index 7f93cf0..634fa4b 100644
--- a/libnm-gtk/nm-wifi-item.c
+++ b/libnm-gtk/nm-wifi-item.c
@@ -430,6 +430,21 @@ create_connection (NMConnectionItem *item)
 }
 
 static void
+connection_created_cb (GObject *source_object,
+                       GAsyncResult *result,
+                       gpointer user_data)
+{
+    NMConnectionItem *connection_item = NM_CONNECTION_ITEM (source_object);
+    NMConnection *connection;
+
+    connection = nm_connection_item_create_connection_finish (connection_item, result, NULL);
+    if (connection) {
+        nm_connection_item_new_connection (connection_item, connection, TRUE);
+        g_object_unref (connection);
+    }
+}
+
+static void
 connect (NMListItem *item)
 {
     NMConnectionItem *connection_item = NM_CONNECTION_ITEM (item);
@@ -442,12 +457,7 @@ connect (NMListItem *item)
     }
 
     /* We don't have a connection yet, so create one */
-    connection = nm_connection_item_create_connection (connection_item);
-    if (connection) {
-        nm_connection_item_new_connection (connection_item, connection, TRUE);
-        g_object_unref (connection);
-    } else
-        g_warning ("Could not create a new WiFi connection");
+    nm_connection_item_create_connection (connection_item, connection_created_cb, NULL);
 }
 
 static void
@@ -536,7 +546,7 @@ connection_secrets_response_cb (NMAWirelessDialog *dialog,
                          g_strdup (nm_setting_get_name (s_wireless_sec)),
                          nm_setting_to_hash (s_wireless_sec));
 
-	info->callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), settings, NULL, info->callback_data);
+	info->callback ((NMSettingsConnectionInterface *) connection, settings, NULL, info->callback_data);
 
 	/* Save the connection back to GConf _after_ hashing it, because
 	 * saving to GConf might trigger the GConf change notifiers, resulting
@@ -568,6 +578,7 @@ done:
 
 static void
 secrets_requested (NMConnectionItem *item,
+                   NMConnection *connection,
                    const char *setting_name,
                    const char **hints,
                    gboolean ask_user,
@@ -578,7 +589,7 @@ secrets_requested (NMConnectionItem *item,
     SecretsRequestInfo *info;
 
     dialog = nma_wireless_dialog_new (nm_connection_item_get_client (item),
-                                      (NMConnection *) nm_connection_item_get_connection (item),
+                                      connection,
                                       nm_device_item_get_device (NM_DEVICE_ITEM (item)),
                                       nm_wifi_item_get_ap (NM_WIFI_ITEM (item)));
 
diff --git a/src/nmn-item-renderer.c b/src/nmn-item-renderer.c
index 7438041..85c6062 100644
--- a/src/nmn-item-renderer.c
+++ b/src/nmn-item-renderer.c
@@ -197,50 +197,51 @@ update_connection_cb (NMSettingsConnectionInterface *connection,
         nm_list_item_connect (nmn_item_renderer_get_item (self));
 }
 
-static gboolean
-details_need_updating (NmnItemRenderer *self)
+static void
+connect_with_updated_details (NmnItemRenderer *self,
+                              NMConnection *connection,
+                              gboolean new_connection)
 {
-    NMConnectionItem *connection_item;
     NmnConnectionDetails *details;
-    NMConnection *connection;
-    NMSetting *current_config;
-    NMSetting *new_config;
-    gboolean new_connection = FALSE;
+    gboolean changed = FALSE;
 
     details = GET_PRIVATE (self)->details;
-    if (!details)
-        return FALSE;
-
-    connection_item = NM_CONNECTION_ITEM (nmn_item_renderer_get_item (self));
-    connection = (NMConnection *) nm_connection_item_get_connection (connection_item);
-    if (!connection) {
-        connection = nm_connection_item_create_connection (connection_item);
-        new_connection = TRUE;
-
-        if (!connection) {
-            g_warning ("Could not create a new connection");
-            return;
+    if (details) {
+        NMSetting *current_config;
+        NMSetting *new_config;
+
+        current_config = nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+        new_config = NM_SETTING (nmn_connection_details_get_data (NMN_CONNECTION_DETAILS (details)));
+
+        if (current_config == NULL || nm_setting_compare (current_config, new_config, 0) == FALSE) {
+            nm_connection_add_setting (connection, new_config);
+            changed = TRUE;
         }
     }
 
-    current_config = nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
-    new_config = NM_SETTING (nmn_connection_details_get_data (NMN_CONNECTION_DETAILS (details)));
-    g_assert (new_config);
-
-    if (current_config == NULL || nm_setting_compare (current_config, new_config, 0) == FALSE) {
-        nm_connection_add_setting (connection, new_config);
+    if (new_connection) {
+        NMConnectionItem *connection_item = NM_CONNECTION_ITEM (nmn_item_renderer_get_item (self));
 
-        if (new_connection) {
-            nm_connection_item_new_connection (connection_item, connection, TRUE);
-            g_object_unref (connection);
-        } else
-            nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
-                                                     update_connection_cb, self);
+        nm_connection_item_new_connection (connection_item, connection, TRUE);
+        g_object_unref (connection);
+    } else if (changed)
+        nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
+                                                 update_connection_cb, self);
+    else
+        nm_list_item_connect (nmn_item_renderer_get_item (self));
+}
 
-        return TRUE;
-    }
+static void
+connection_created_cb (GObject *object,
+                       GAsyncResult *result,
+                       gpointer user_data)
+{
+    NMConnection *connection;
+    GError *error = NULL;
 
-    return FALSE;
+    connection = nm_connection_item_create_connection_finish (NM_CONNECTION_ITEM (object), result, &error);
+    if (connection)
+        connect_with_updated_details (NMN_ITEM_RENDERER (user_data), connection, TRUE);
 }
 
 static void
@@ -251,8 +252,16 @@ connect_button_clicked (GtkButton *button, gpointer user_data)
 
     item = nmn_item_renderer_get_item (self);
     if (nm_list_item_get_status (item) == NM_LIST_ITEM_STATUS_DISCONNECTED) {
-        if (!details_need_updating (self))
-            nm_list_item_connect (item);
+        NMConnectionItem *connection_item;
+        NMConnection *connection;
+
+        connection_item = NM_CONNECTION_ITEM (nmn_item_renderer_get_item (self));
+        connection = (NMConnection *) nm_connection_item_get_connection (connection_item);
+        if (connection)
+            connect_with_updated_details (self, connection, FALSE);
+        else
+            /* We don't have a connection yet, so create one */
+            nm_connection_item_create_connection (connection_item, connection_created_cb, self);
     } else
         nm_list_item_disconnect (item);
 }



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