[network-manager-netbook] Fix wireless authentication once again
- From: Tambet Ingo <tambeti src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-netbook] Fix wireless authentication once again
- Date: Tue, 2 Mar 2010 20:34:20 +0000 (UTC)
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]