[network-manager-netbook] Hook up wireless authentication
- From: Tambet Ingo <tambeti src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [network-manager-netbook] Hook up wireless authentication
- Date: Thu, 28 Jan 2010 20:36:49 +0000 (UTC)
commit 317a140e378afcc5a6239e1acfa814fe29195f91
Author: Tambet Ingo <tambet gmail com>
Date: Thu Jan 28 15:31:25 2010 -0400
Hook up wireless authentication
Can't believe nobody noticed it didn't work.
libnm-gtk/nm-connection-item.c | 36 ++++++++
libnm-gtk/nm-connection-item.h | 8 ++
libnm-gtk/nm-gconf-connection.h | 3 +-
libnm-gtk/nm-wifi-item.c | 169 ++++++++++++++++++++++++++++++++-------
4 files changed, 187 insertions(+), 29 deletions(-)
---
diff --git a/libnm-gtk/nm-connection-item.c b/libnm-gtk/nm-connection-item.c
index 9c99b68..0b73b4c 100644
--- a/libnm-gtk/nm-connection-item.c
+++ b/libnm-gtk/nm-connection-item.c
@@ -18,6 +18,7 @@
*/
#include <string.h>
+#include <nm-settings-interface.h>
#include <nm-setting-connection.h>
#include <nm-settings-connection-interface.h>
#include <nm-active-connection.h>
@@ -45,6 +46,7 @@ typedef struct {
gboolean delete_allowed;
gboolean connect_pending;
+ gulong secrets_requested_id;
gulong removed_id;
gulong updated_id;
gulong acs_changed_id;
@@ -70,6 +72,32 @@ nm_connection_item_get_connection (NMConnectionItem *self)
}
static void
+secrets_requested (NMGConfConnection *connection,
+ const char *setting_name,
+ const char **hints,
+ gboolean ask_user,
+ NMNewSecretsRequestedFunc callback,
+ gpointer callback_data,
+ gpointer user_data)
+{
+ 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,
+ ask_user, callback, callback_data);
+ else {
+ GError *error;
+
+ error = g_error_new_literal (NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "No secrets providers registered");
+
+ callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), NULL, error, callback_data);
+ g_error_free (error);
+ }
+}
+
+static void
connection_removed (NMSettingsConnectionInterface *connection,
gpointer data)
{
@@ -212,6 +240,7 @@ nm_connection_item_set_connection (NMConnectionItem *self,
if (priv->connection) {
set_active_connection (self, NULL);
+ g_signal_handler_disconnect (priv->connection, priv->secrets_requested_id);
g_signal_handler_disconnect (priv->connection, priv->removed_id);
g_signal_handler_disconnect (priv->connection, priv->updated_id);
g_signal_handler_disconnect (priv->client, priv->acs_changed_id);
@@ -221,6 +250,12 @@ nm_connection_item_set_connection (NMConnectionItem *self,
if (connection) {
priv->connection = g_object_ref (connection);
+ if (NM_IS_GCONF_CONNECTION (connection))
+ priv->secrets_requested_id = g_signal_connect (connection,
+ "new-secrets-requested",
+ G_CALLBACK (secrets_requested),
+ self);
+
priv->removed_id = g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self);
priv->updated_id = g_signal_connect (connection, "updated", G_CALLBACK (connection_updated), self);
connection_update_id (self);
@@ -229,6 +264,7 @@ nm_connection_item_set_connection (NMConnectionItem *self,
G_CALLBACK (active_connections_changed), self);
active_connections_changed (priv->client, NULL, self);
} else {
+ priv->secrets_requested_id = 0;
priv->removed_id = 0;
priv->updated_id = 0;
priv->acs_changed_id = 0;
diff --git a/libnm-gtk/nm-connection-item.h b/libnm-gtk/nm-connection-item.h
index d2b1279..f2760b1 100644
--- a/libnm-gtk/nm-connection-item.h
+++ b/libnm-gtk/nm-connection-item.h
@@ -24,6 +24,7 @@
#include <nm-client.h>
#include <nm-settings-connection-interface.h>
#include <nm-list-item.h>
+#include <nm-gconf-connection.h>
G_BEGIN_DECLS
@@ -45,6 +46,13 @@ typedef struct {
typedef struct {
NMListItemClass parent_class;
+ void (*secrets_requested) (NMConnectionItem *self,
+ const char *setting_name,
+ const char **hints,
+ gboolean ask_user,
+ NMNewSecretsRequestedFunc callback,
+ gpointer callback_data);
+
NMConnection *(*create_connection) (NMConnectionItem *self);
} NMConnectionItemClass;
diff --git a/libnm-gtk/nm-gconf-connection.h b/libnm-gtk/nm-gconf-connection.h
index 00a3883..f6583e0 100644
--- a/libnm-gtk/nm-gconf-connection.h
+++ b/libnm-gtk/nm-gconf-connection.h
@@ -57,7 +57,8 @@ typedef struct {
const char *setting_name,
const char **hints,
gboolean ask_user,
- DBusGMethodInvocation *context);
+ NMNewSecretsRequestedFunc callback,
+ gpointer callback_data);
} NMGConfConnectionClass;
GType nm_gconf_connection_get_type (void);
diff --git a/libnm-gtk/nm-wifi-item.c b/libnm-gtk/nm-wifi-item.c
index c8f9005..7f93cf0 100644
--- a/libnm-gtk/nm-wifi-item.c
+++ b/libnm-gtk/nm-wifi-item.c
@@ -22,6 +22,7 @@
#include <nm-setting-wireless.h>
#include <nm-setting-wireless-security.h>
#include <nm-setting-8021x.h>
+#include <nm-settings-interface.h>
#include <nm-utils.h>
#include "nm-wifi-item.h"
#include "wireless-dialog.h"
@@ -429,21 +430,6 @@ create_connection (NMConnectionItem *item)
}
static void
-wireless_dialog_response_cb (NMAWirelessDialog *dialog,
- gint response,
- gpointer user_data)
-{
- gtk_widget_hide (GTK_WIDGET (dialog));
-
- if (response == GTK_RESPONSE_OK)
- nm_connection_item_new_connection (NM_CONNECTION_ITEM (user_data),
- nma_wireless_dialog_get_connection (dialog),
- TRUE);
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
-}
-
-static void
connect (NMListItem *item)
{
NMConnectionItem *connection_item = NM_CONNECTION_ITEM (item);
@@ -457,25 +443,151 @@ connect (NMListItem *item)
/* We don't have a connection yet, so create one */
connection = nm_connection_item_create_connection (connection_item);
- if (!connection) {
+ 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");
- return;
+}
+
+static void
+update_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data)
+{
+ if (error) {
+ g_warning ("%s: failed to update connection: (%d) %s",
+ __func__, error->code, error->message);
}
+}
- if (nm_connection_need_secrets (connection, NULL)) {
- GtkWidget *dialog;
+typedef struct {
+ NMNewSecretsRequestedFunc callback;
+ gpointer callback_data;
+} SecretsRequestInfo;
- dialog = nma_wireless_dialog_new (nm_connection_item_get_client (connection_item),
- connection,
- nm_device_item_get_device (NM_DEVICE_ITEM (item)),
- nm_wifi_item_get_ap (NM_WIFI_ITEM (item)));
+static void
+connection_secrets_response_cb (NMAWirelessDialog *dialog,
+ gint response,
+ gpointer user_data)
+{
+ SecretsRequestInfo *info = user_data;
+ NMConnection *connection;
+ GHashTable *settings = NULL;
+ NMSetting *s_wireless_sec;
+ const char *key_mgmt;
+ GError *error = NULL;
- g_signal_connect (dialog, "done", G_CALLBACK (wireless_dialog_response_cb), item);
- nma_wireless_dialog_show (NMA_WIRELESS_DIALOG (dialog));
- } else
- nm_connection_item_new_connection (connection_item, connection, TRUE);
+ gtk_widget_hide (GTK_WIDGET (dialog));
+
+ connection = nma_wireless_dialog_get_connection (dialog);
+
+ if (response != GTK_RESPONSE_OK) {
+ error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_SECRETS_REQUEST_CANCELED,
+ "%s.%d (%s): canceled",
+ __FILE__, __LINE__, __func__);
+
+ goto done;
+ }
+
+ /* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that
+ * will contain all the individual settings hashes.
+ */
+ settings = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) g_hash_table_destroy);
+
+ /* If the user chose an 802.1x-based auth method, return 802.1x secrets,
+ * not wireless secrets. Can happen with Dynamic WEP, because NM doesn't
+ * know the capabilities of the AP (since Dynamic WEP APs don't broadcast
+ * beacons), and therefore defaults to requesting WEP secrets from the
+ * wireless-security setting, not the 802.1x setting.
+ */
+
+ s_wireless_sec = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (NM_SETTING_WIRELESS_SECURITY (s_wireless_sec));
+ if (!strcmp (key_mgmt, "ieee8021x") || !strcmp (key_mgmt, "wpa-eap")) {
+ const char *auth_alg;
+
+ /* LEAP secrets aren't in the 802.1x setting */
+ auth_alg = nm_setting_wireless_security_get_auth_alg (NM_SETTING_WIRELESS_SECURITY (s_wireless_sec));
+ if (!auth_alg || strcmp (auth_alg, "leap")) {
+ NMSetting *s_8021x;
+
+ s_8021x = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ if (!s_8021x) {
+ error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
+ "%s.%d (%s): requested setting '802-1x' didn't"
+ " exist in the connection.",
+ __FILE__, __LINE__, __func__);
+ goto done;
+ }
+
+ /* Add the 802.1x setting */
+ g_hash_table_insert (settings,
+ g_strdup (nm_setting_get_name (s_8021x)),
+ nm_setting_to_hash (s_8021x));
+ }
+ }
+
+ /* Add the 802-11-wireless-security setting no matter what */
+ g_hash_table_insert (settings,
+ 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);
+
+ /* Save the connection back to GConf _after_ hashing it, because
+ * saving to GConf might trigger the GConf change notifiers, resulting
+ * in the connection being read back in from GConf which clears secrets.
+ */
+ if (NM_IS_GCONF_CONNECTION (connection)) {
+ nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
+ update_cb,
+ NULL);
+ }
+
+done:
+ if (settings)
+ g_hash_table_destroy (settings);
+
+ if (error) {
+ g_warning ("%s", error->message);
+ info->callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), NULL, error, info->callback_data);
+ g_error_free (error);
+ }
+
+ g_free (info);
+
+ if (connection)
+ nm_connection_clear_secrets (connection);
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+secrets_requested (NMConnectionItem *item,
+ const char *setting_name,
+ const char **hints,
+ gboolean ask_user,
+ NMNewSecretsRequestedFunc callback,
+ gpointer callback_data)
+{
+ GtkWidget *dialog;
+ SecretsRequestInfo *info;
+
+ dialog = nma_wireless_dialog_new (nm_connection_item_get_client (item),
+ (NMConnection *) nm_connection_item_get_connection (item),
+ nm_device_item_get_device (NM_DEVICE_ITEM (item)),
+ nm_wifi_item_get_ap (NM_WIFI_ITEM (item)));
+
+ info = g_new (SecretsRequestInfo, 1);
+ info->callback = callback;
+ info->callback_data = callback_data;
- g_object_unref (connection);
+ g_signal_connect (dialog, "done", G_CALLBACK (connection_secrets_response_cb), info);
+ nma_wireless_dialog_show (NMA_WIRELESS_DIALOG (dialog));
}
/*****************************************************************************/
@@ -595,6 +707,7 @@ nm_wifi_item_class_init (NMWifiItemClass *klass)
list_class->priority = priority;
list_class->connect = connect;
+ connection_class->secrets_requested = secrets_requested;
connection_class->create_connection = create_connection;
device_class->get_specific_object = wifi_get_specific_object;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]