Initial version of re-implemented GNOME Keyring plugin soc.2008.masterpassword

Sat, 23 Mar 2013 22:18:29 +0100

author
Tomasz Wasilczyk <tomkiewicz@cpw.pidgin.im>
date
Sat, 23 Mar 2013 22:18:29 +0100
branch
soc.2008.masterpassword
changeset 34135
528b3084b3b3
parent 34134
fda68dc6481c
child 34136
e9722a935271

Initial version of re-implemented GNOME Keyring plugin

libpurple/plugins/keyrings/gnomekeyring.c file | annotate | diff | comparison | revisions
--- a/libpurple/plugins/keyrings/gnomekeyring.c	Sat Mar 23 22:09:10 2013 +0100
+++ b/libpurple/plugins/keyrings/gnomekeyring.c	Sat Mar 23 22:18:29 2013 +0100
@@ -1,9 +1,6 @@
 /**
  * @file gnomekeyring.c Gnome keyring password storage
  * @ingroup plugins
- *
- * @todo
- *   cleanup error handling and reporting
  */
 
 /* purple
@@ -24,7 +21,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program ; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
  */
 
 #include "internal.h"
@@ -36,312 +33,66 @@
 
 #include <gnome-keyring.h>
 
-#define GNOMEKEYRING_NAME        N_("GNOME-Keyring")
+#define GNOMEKEYRING_NAME        N_("GNOME Keyring")
 #define GNOMEKEYRING_DESCRIPTION N_("This plugin will store passwords in GNOME Keyring.")
-#define GNOMEKEYRING_AUTHOR      "Scrouaf (scrouaf[at]soc.pidgin.im)"
+#define GNOMEKEYRING_AUTHOR      "Tomek Wasilczyk (tomkiewicz@cpw.pidgin.im)"
 #define GNOMEKEYRING_ID          "keyring-gnomekeyring"
 
 static PurpleKeyring *keyring_handler = NULL;
 
-typedef struct _InfoStorage InfoStorage;
-
-struct _InfoStorage
-{
-	PurpleAccount *account;
-	gpointer cb;
-	gpointer user_data;
-};
-
-/***********************************************/
-/*     Keyring interface                       */
-/***********************************************/
 static void
-gkp_read_continue(GnomeKeyringResult result,
-                  const char *password,
-                  gpointer data)
-/* XXX : make sure list is freed on return */
+keyring_gnome_read(PurpleAccount *account,PurpleKeyringReadCallback cb,
+	gpointer data)
 {
-	InfoStorage *storage = data;
-	PurpleAccount *account = storage->account;
-	PurpleKeyringReadCallback cb = storage->cb;
-	GError *error;
-
-	if (result != GNOME_KEYRING_RESULT_OK) {
-		switch(result) {
-			case GNOME_KEYRING_RESULT_NO_MATCH:
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_NOPASSWD,
-					"No password found for account : %s",
-					purple_account_get_username(account));
-				if(cb != NULL)
-					cb(account, NULL, error, storage->user_data);
-				g_error_free(error);
-				return;
-
-			case GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON:
-			case GNOME_KEYRING_RESULT_IO_ERROR:
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_NOCHANNEL,
-					"Failed to communicate with GNOME Keyring (account : %s).",
-					purple_account_get_username(account));
-				if(cb != NULL)
-					cb(account, NULL, error, storage->user_data);
-				g_error_free(error);
-				return;
-
-			default:
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_NOCHANNEL,
-					"Unknown error (account : %s).",
-					purple_account_get_username(account));
-				if(cb != NULL)
-					cb(account, NULL, error, storage->user_data);
-				g_error_free(error);
-				return;
-		}
-
-	} else {
-		if (cb != NULL) {
-			cb(account, password, NULL, storage->user_data);
-		}
-	}
-}
-
-static void
-gkp_read(PurpleAccount *account, PurpleKeyringReadCallback cb, gpointer data)
-{
-	InfoStorage *storage = g_new0(InfoStorage, 1);
-
-	storage->account = account;
-	storage->cb = cb;
-	storage->user_data = data;
-
-	gnome_keyring_find_password(GNOME_KEYRING_NETWORK_PASSWORD,
-	                            gkp_read_continue,
-	                            storage,
-	                            g_free,
-	                            "user", purple_account_get_username(account),
-	                            "protocol", purple_account_get_protocol_id(account),
-	                            NULL);
 }
 
 static void
-gkp_save_continue(GnomeKeyringResult result, gpointer data)
+keyring_gnome_save(PurpleAccount *account, const gchar *password,
+	PurpleKeyringSaveCallback cb, gpointer data)
 {
-	InfoStorage *storage;
-	PurpleKeyringSaveCallback cb;
-	GError *error;
-	PurpleAccount *account;
-
-	storage = data;
-	g_return_if_fail(storage != NULL);
-
-	account = storage->account;
-	cb = storage->cb;
-
-	if (result != GNOME_KEYRING_RESULT_OK) {
-		switch(result) {
-			case GNOME_KEYRING_RESULT_NO_MATCH:
-				purple_debug_info("keyring-gnome",
-					"Could not update password for %s (%s) : not found.\n",
-					purple_account_get_username(account),
-					purple_account_get_protocol_id(account));
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_NOPASSWD,
-					"Could not update password for %s : not found",
-					purple_account_get_username(account));
-				if(cb != NULL)
-					cb(account, error, storage->user_data);
-				g_error_free(error);
-				return;
-
-			case GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON:
-			case GNOME_KEYRING_RESULT_IO_ERROR:
-				purple_debug_info("keyring-gnome",
-					"Failed to communicate with GNOME Keyring (account : %s (%s)).\n",
-					purple_account_get_username(account),
-					purple_account_get_protocol_id(account));
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_NOCHANNEL,
-					"Failed to communicate with GNOME Keyring (account : %s).",
-					purple_account_get_username(account));
-				if(cb != NULL)
-					cb(account, error, storage->user_data);
-				g_error_free(error);
-				return;
-
-			default:
-				purple_debug_info("keyring-gnome",
-					"Unknown error (account : %s (%s)).\n",
-					purple_account_get_username(account),
-					purple_account_get_protocol_id(account));
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_NOCHANNEL,
-					"Unknown error (account : %s).",
-					purple_account_get_username(account));
-				if(cb != NULL)
-					cb(account, error, storage->user_data);
-				g_error_free(error);
-				return;
-		}
-
-	} else {
-		purple_debug_info("keyring-gnome", "Password for %s updated.\n",
-			purple_account_get_username(account));
-
-		if (cb != NULL)
-			cb(account, NULL, storage->user_data);
-	}
 }
 
 static void
-gkp_save(PurpleAccount *account,
-         const gchar *password,
-         PurpleKeyringSaveCallback cb,
-         gpointer data)
-{
-	InfoStorage *storage = g_new0(InfoStorage, 1);
-
-	storage->account = account;
-	storage->cb = cb;
-	storage->user_data = data;
-
-	if (password != NULL && *password != '\0') {
-		char *name;
-
-		purple_debug_info("keyring-gnome",
-			"Updating password for account %s (%s).\n",
-			purple_account_get_username(account),
-			purple_account_get_protocol_id(account));
-
-		name = g_strdup_printf("purple-%s",
-		                       purple_account_get_username(account));
-		gnome_keyring_store_password(GNOME_KEYRING_NETWORK_PASSWORD,
-		                             NULL,  /*default keyring */
-		                             name,
-		                             password,
-		                             gkp_save_continue,
-		                             storage,
-		                             g_free,    /* function to free storage */
-		                             "user", purple_account_get_username(account),
-		                             "protocol", purple_account_get_protocol_id(account),
-		                             NULL);
-		g_free(name);
-
-	} else {	/* password == NULL, delete password. */
-		purple_debug_info("keyring-gnome",
-			"Forgetting password for account %s (%s).\n",
-			purple_account_get_username(account),
-			purple_account_get_protocol_id(account));
-
-		gnome_keyring_delete_password(GNOME_KEYRING_NETWORK_PASSWORD,
-		                              gkp_save_continue,
-		                              storage, g_free,
-		                              "user", purple_account_get_username(account),
-		                              "protocol", purple_account_get_protocol_id(account),
-		                              NULL);
-	}
-}
-
-static void
-gkp_close(GError **error)
+keyring_gnome_close(GError **error)
 {
 }
 
 static gboolean
-gkp_import_password(PurpleAccount *account,
-                    const char *mode,
-                    const char *data,
-                    GError **error)
+keyring_gnome_load(PurplePlugin *plugin)
 {
-	purple_debug_info("keyring-gnome", "Importing password.\n");
-	return TRUE;
-}
+	if (!gnome_keyring_is_available()) {
+		purple_debug_info("keyring-gnome", "GNOME Keyring service is "
+			"disabled\n");
+		return FALSE;
+	}
 
-static gboolean
-gkp_export_password(PurpleAccount *account,
-                    const char **mode,
-                    char **data,
-                    GError **error,
-                    GDestroyNotify *destroy)
-{
-	purple_debug_info("keyring-gnome", "Exporting password.\n");
-	*data = NULL;
-	*mode = NULL;
-	*destroy = NULL;
+	keyring_handler = purple_keyring_new();
+
+	purple_keyring_set_name(keyring_handler, GNOMEKEYRING_NAME);
+	purple_keyring_set_id(keyring_handler, GNOMEKEYRING_ID);
+	purple_keyring_set_read_password(keyring_handler, keyring_gnome_read);
+	purple_keyring_set_save_password(keyring_handler, keyring_gnome_save);
+	purple_keyring_set_close_keyring(keyring_handler, keyring_gnome_close);
+
+	purple_keyring_register(keyring_handler);
 
 	return TRUE;
 }
 
-/* this was written just to test the pref change */
-static void
-gkp_change_master(PurpleKeyringChangeMasterCallback cb, gpointer data)
-{
-	purple_debug_info("keyring-gnome",
-		"This keyring does not support master passwords.\n");
-
-	purple_notify_info(NULL, _("GNOME Keyring plugin"),
-	                   _("Failed to change master password."),
-	                   _("This plugin does not really support master passwords, it just pretends to."));
-	if (cb)
-		cb(FALSE, NULL, data);
-}
-
 static gboolean
-gkp_init(void)
+keyring_gnome_unload(PurplePlugin *plugin)
 {
-	purple_debug_info("keyring-gnome", "Init.\n");
-
-	if (gnome_keyring_is_available()) {
-		keyring_handler = purple_keyring_new();
-
-		purple_keyring_set_name(keyring_handler, GNOMEKEYRING_NAME);
-		purple_keyring_set_id(keyring_handler, GNOMEKEYRING_ID);
-		purple_keyring_set_read_password(keyring_handler, gkp_read);
-		purple_keyring_set_save_password(keyring_handler, gkp_save);
-		purple_keyring_set_close_keyring(keyring_handler, gkp_close);
-		purple_keyring_set_change_master(keyring_handler, gkp_change_master);
-		purple_keyring_set_import_password(keyring_handler, gkp_import_password);
-		purple_keyring_set_export_password(keyring_handler, gkp_export_password);
-
-		purple_keyring_register(keyring_handler);
-
-		return TRUE;
-
-	} else {
-		purple_debug_info("keyring-gnome",
-			"Failed to communicate with daemon, not loading.\n");
+	if (purple_keyring_get_inuse() == keyring_handler) {
+		purple_debug_warning("keyring-gnome",
+			"keyring in use, cannot unload\n");
 		return FALSE;
 	}
-}
 
-static void
-gkp_uninit(void)
-{
-	purple_debug_info("keyring-gnome", "Uninit.\n");
-	gkp_close(NULL);
+	keyring_gnome_close(NULL);
+
 	purple_keyring_unregister(keyring_handler);
 	purple_keyring_free(keyring_handler);
 	keyring_handler = NULL;
-}
-
-/***********************************************/
-/*     Plugin interface                        */
-/***********************************************/
-
-static gboolean
-gkp_load(PurplePlugin *plugin)
-{
-	return gkp_init();
-}
-
-static gboolean
-gkp_unload(PurplePlugin *plugin)
-{
-	if (purple_keyring_get_inuse() == keyring_handler)
-		return FALSE;
-
-	gkp_uninit();
 
 	return TRUE;
 }
@@ -352,28 +103,25 @@
 	PURPLE_MAJOR_VERSION,		/* major_version */
 	PURPLE_MINOR_VERSION,		/* minor_version */
 	PURPLE_PLUGIN_STANDARD,		/* type */
-	NULL,						/* ui_requirement */
+	NULL,				/* ui_requirement */
 	PURPLE_PLUGIN_FLAG_INVISIBLE,	/* flags */
-	NULL,						/* dependencies */
+	NULL,				/* dependencies */
 	PURPLE_PRIORITY_DEFAULT,	/* priority */
-	GNOMEKEYRING_ID,			/* id */
-	GNOMEKEYRING_NAME,			/* name */
-	DISPLAY_VERSION,			/* version */
+	GNOMEKEYRING_ID,		/* id */
+	GNOMEKEYRING_NAME,		/* name */
+	DISPLAY_VERSION,		/* version */
 	"GNOME Keyring Plugin",		/* summary */
 	GNOMEKEYRING_DESCRIPTION,	/* description */
 	GNOMEKEYRING_AUTHOR,		/* author */
-	PURPLE_WEBSITE,				/* homepage */
-	gkp_load,					/* load */
-	gkp_unload,					/* unload */
-	NULL,						/* destroy */
-	NULL,						/* ui_info */
-	NULL,						/* extra_info */
-	NULL,						/* prefs_info */
-	NULL,						/* actions */
-	NULL,						/* padding... */
-	NULL,
-	NULL,
-	NULL,
+	PURPLE_WEBSITE,			/* homepage */
+	keyring_gnome_load,		/* load */
+	keyring_gnome_unload,		/* unload */
+	NULL,				/* destroy */
+	NULL,				/* ui_info */
+	NULL,				/* extra_info */
+	NULL,				/* prefs_info */
+	NULL,				/* actions */
+	NULL, NULL, NULL, NULL		/* padding */
 };
 
 static void
@@ -382,4 +130,3 @@
 }
 
 PURPLE_INIT_PLUGIN(gnome_keyring, init_plugin, plugininfo)
-

mercurial