[network-manager-applet: 13/13] bluetooth: handle network password requests



commit 3fee46a3b0fc617cb03c2a7ca1a3be922ec5918d
Author: Dan Williams <dcbw redhat com>
Date:   Fri Feb 19 01:56:14 2010 -0800

    bluetooth: handle network password requests

 src/applet-device-bt.c |  197 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 197 insertions(+), 0 deletions(-)
---
diff --git a/src/applet-device-bt.c b/src/applet-device-bt.c
index d1ad0d2..52dccf9 100644
--- a/src/applet-device-bt.c
+++ b/src/applet-device-bt.c
@@ -31,6 +31,8 @@
 #include <nm-device.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-bluetooth.h>
+#include <nm-setting-cdma.h>
+#include <nm-setting-gsm.h>
 #include <nm-device-bt.h>
 #include <nm-utils.h>
 
@@ -39,6 +41,7 @@
 #include "wired-dialog.h"
 #include "utils.h"
 #include "gconf-helpers.h"
+#include "applet-dialogs.h"
 
 typedef struct {
 	NMApplet *applet;
@@ -247,6 +250,199 @@ bt_get_icon (NMDevice *device,
 	return pixbuf;
 }
 
+typedef struct {
+	NMANewSecretsRequestedFunc callback;
+	gpointer callback_data;
+	NMApplet *applet;
+	NMSettingsConnectionInterface *connection;
+	NMActiveConnection *active_connection;
+	GtkWidget *dialog;
+	GtkEntry *secret_entry;
+	char *secret_name;
+	char *setting_name;
+} NMBtSecretsInfo;
+
+static void
+destroy_secrets_dialog (gpointer user_data, GObject *finalized)
+{
+	NMBtSecretsInfo *info = user_data;
+
+	gtk_widget_hide (info->dialog);
+	gtk_widget_destroy (info->dialog);
+
+	g_object_unref (info->connection);
+	g_free (info->secret_name);
+	g_free (info->setting_name);
+	g_free (info);
+}
+
+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);
+	}
+}
+
+static void
+get_bt_secrets_cb (GtkDialog *dialog,
+                   gint response,
+                   gpointer user_data)
+{
+	NMBtSecretsInfo *info = user_data;
+	NMSetting *setting;
+	GHashTable *settings_hash;
+	GHashTable *secrets;
+	GError *err = NULL;
+
+	/* Got a user response, clear the NMActiveConnection destroy handler for
+	 * this dialog since this function will now take over dialog destruction.
+	 */
+	g_object_weak_unref (G_OBJECT (info->active_connection), destroy_secrets_dialog, info);
+
+	if (response != GTK_RESPONSE_OK) {
+		g_set_error (&err,
+		             NM_SETTINGS_INTERFACE_ERROR,
+		             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+		             "%s.%d (%s): canceled",
+		             __FILE__, __LINE__, __func__);
+		goto done;
+	}
+
+	setting = nm_connection_get_setting_by_name (NM_CONNECTION (info->connection), info->setting_name);
+	if (!setting) {
+		g_set_error (&err,
+		             NM_SETTINGS_INTERFACE_ERROR,
+		             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+		             "%s.%d (%s): unhandled setting '%s'",
+		             __FILE__, __LINE__, __func__, info->setting_name);
+		goto done;
+	}
+
+	/* Normally we'd want to get all the settings's secrets and return those
+	 * to NM too (since NM wants them), but since the only other secrets for 3G
+	 * connections are PINs, and since the phone obviously has to be unlocked
+	 * to even make the Bluetooth connection, we can skip doing that here for
+	 * Bluetooth devices.
+	 */
+
+	/* Update the password */
+	g_object_set (G_OBJECT (setting),
+	              info->secret_name, gtk_entry_get_text (info->secret_entry),
+	              NULL);
+
+	secrets = nm_setting_to_hash (NM_SETTING (setting));
+	if (!secrets) {
+		g_set_error (&err,
+		             NM_SETTINGS_INTERFACE_ERROR,
+		             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+		             "%s.%d (%s): failed to hash setting '%s'.",
+		             __FILE__, __LINE__, __func__,
+		             nm_setting_get_name (NM_SETTING (setting)));
+		goto done;
+	}
+
+	/* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that
+	 * will contain all the individual settings hashes.
+	 */
+	settings_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+	                                       g_free, (GDestroyNotify) g_hash_table_destroy);
+
+	g_hash_table_insert (settings_hash, g_strdup (nm_setting_get_name (NM_SETTING (setting))), secrets);
+	info->callback (info->connection, settings_hash, NULL, info->callback_data);
+	g_hash_table_destroy (settings_hash);
+
+	/* 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 (NMA_IS_GCONF_CONNECTION (info->connection))
+		nm_settings_connection_interface_update (info->connection, update_cb, NULL);
+
+ done:
+	if (err) {
+		g_warning ("%s", err->message);
+		info->callback (info->connection, NULL, err, info->callback_data);
+		g_error_free (err);
+	}
+
+	nm_connection_clear_secrets (NM_CONNECTION (info->connection));
+	destroy_secrets_dialog (info, NULL);
+}
+
+static gboolean
+bt_get_secrets (NMDevice *device,
+                NMSettingsConnectionInterface *connection,
+                NMActiveConnection *active_connection,
+                const char *setting_name,
+                const char **hints,
+                NMANewSecretsRequestedFunc callback,
+                gpointer callback_data,
+                NMApplet *applet,
+                GError **error)
+{
+	NMBtSecretsInfo *info;
+	GtkWidget *widget;
+	GtkEntry *secret_entry = NULL;
+
+	if (!hints || !g_strv_length ((char **) hints)) {
+		g_set_error (error,
+		             NM_SETTINGS_INTERFACE_ERROR,
+		             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+		             "%s.%d (%s): missing secrets hints.",
+		             __FILE__, __LINE__, __func__);
+		return FALSE;
+	}
+
+	if (   (!strcmp (setting_name, NM_SETTING_CDMA_SETTING_NAME) && !strcmp (hints[0], NM_SETTING_CDMA_PASSWORD))
+	    || (!strcmp (setting_name, NM_SETTING_GSM_SETTING_NAME) && !strcmp (hints[0], NM_SETTING_GSM_PASSWORD)))
+		widget = applet_mobile_password_dialog_new (device, NM_CONNECTION (connection), &secret_entry);
+	else {
+		g_set_error (error,
+		             NM_SETTINGS_INTERFACE_ERROR,
+		             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+		             "%s.%d (%s): unknown secrets hint '%s'.",
+		             __FILE__, __LINE__, __func__, hints[0]);
+		return FALSE;
+	}
+
+	if (!widget || !secret_entry) {
+		g_set_error (error,
+		             NM_SETTINGS_INTERFACE_ERROR,
+		             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+		             "%s.%d (%s): error asking for CDMA secrets.",
+		             __FILE__, __LINE__, __func__);
+		return FALSE;
+	}
+
+	info = g_malloc0 (sizeof (NMBtSecretsInfo));
+	info->callback = callback;
+	info->callback_data = callback_data;
+	info->applet = applet;
+	info->active_connection = active_connection;
+	info->connection = g_object_ref (connection);
+	info->secret_name = g_strdup (hints[0]);
+	info->setting_name = g_strdup (setting_name);
+	info->dialog = widget;
+	info->secret_entry = secret_entry;
+
+	g_signal_connect (widget, "response", G_CALLBACK (get_bt_secrets_cb), info);
+
+	/* Attach a destroy notifier to the NMActiveConnection so we can destroy
+	 * the dialog when the active connection goes away.
+	 */
+	g_object_weak_ref (G_OBJECT (active_connection), destroy_secrets_dialog, info);
+
+	gtk_window_set_position (GTK_WINDOW (widget), GTK_WIN_POS_CENTER_ALWAYS);
+	gtk_widget_realize (GTK_WIDGET (widget));
+	gtk_window_present (GTK_WINDOW (widget));
+
+	return TRUE;
+}
+
 NMADeviceClass *
 applet_device_bt_get_class (NMApplet *applet)
 {
@@ -260,6 +456,7 @@ applet_device_bt_get_class (NMApplet *applet)
 	dclass->add_menu_item = bt_add_menu_item;
 	dclass->device_state_changed = bt_device_state_changed;
 	dclass->get_icon = bt_get_icon;
+	dclass->get_secrets = bt_get_secrets;
 
 	return dclass;
 }



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