soc.2008.masterpassword: 509008d6: dded import/export in account.c, new ver..

scrouaf at soc.pidgin.im scrouaf at soc.pidgin.im
Thu Aug 7 21:20:43 EDT 2008


-----------------------------------------------------------------
Revision: 509008d6f0811c12ebe728dde95f76eb31a0d2c2
Ancestor: 791d49b0c33c36958b82258ebafdceed86573a03
Author: scrouaf at soc.pidgin.im
Date: 2008-08-07T20:16:45
Branch: im.pidgin.soc.2008.masterpassword
URL: http://d.pidgin.im/viewmtn/revision/info/509008d6f0811c12ebe728dde95f76eb31a0d2c2

Modified files:
        libpurple/Makefile.am libpurple/account.c
        libpurple/keyring.c libpurple/keyring.h
        libpurple/plugins/Makefile.am
        libpurple/plugins/keyrings/internalkeyring.c

ChangeLog: 

dded import/export in account.c, new version of internalkeyring.c, and added stuff to makefiles.

-------------- next part --------------
============================================================
--- libpurple/Makefile.am	ea431ecfb45e9b1e546b7f8dd0d012a98bb1aaf7
+++ libpurple/Makefile.am	343b52fcb9218c1813ffa1808d0932e34a6a0a7a
@@ -50,6 +50,7 @@ purple_coresources = \
 	ft.c \
 	idle.c \
 	imgstore.c \
+	keyring.c \
 	log.c \
 	mime.c \
 	nat-pmp.c \
@@ -103,6 +104,7 @@ purple_coreheaders = \
 	gaim-compat.h \
 	idle.h \
 	imgstore.h \
+	keyring.h \
 	log.h \
 	mime.h \
 	nat-pmp.h \
============================================================
--- libpurple/account.c	14b3700d39f8d77051fd9a1caff0488692644889
+++ libpurple/account.c	520ccb9039f53527996e9669a95fb4402fed03d9
@@ -28,6 +28,7 @@
 #include "core.h"
 #include "dbus-maybe.h"
 #include "debug.h"
+#include "keyring.h"
 #include "network.h"
 #include "notify.h"
 #include "pounce.h"
@@ -44,8 +45,6 @@
 /**
  * TODO :
  *  - grab Trannie's code for asynch connection
- *  - re-write account parsing and syncing as async
- *  - read password _after_ the rest of the account
  */
 
 
@@ -368,8 +367,13 @@ account_to_xmlnode(PurpleAccount *accoun
 
 	xmlnode *node, *child;
 	const char *tmp;
+	const char *keyring_id;
+	const char *mode;
+	char *data;
 	PurplePresence *presence;
 	PurpleProxyInfo *proxy_info;
+	GError * error;
+	GDestroyNotify destroy;
 
 	node = xmlnode_new("account");
 
@@ -379,11 +383,25 @@ account_to_xmlnode(PurpleAccount *accoun
 	child = xmlnode_new_child(node, "name");
 	xmlnode_insert_data(child, purple_account_get_username(account), -1);
 
-	if (purple_account_get_remember_password(account) &&			//  FIXME : change this so it asks the plugin for the node
-		((tmp = purple_account_get_password(account)) != NULL))
+	if (purple_account_get_remember_password(account))
 	{
-		child = xmlnode_new_child(node, "password");
-		xmlnode_insert_data(child, tmp, -1);
+		purple_keyring_export_password(account, &keyring_id, 
+			&mode, &data, &error, &destroy);
+
+		if (error != NULL) {
+
+			/* Output debug info */
+
+		} else {
+
+			child = xmlnode_new_child(node, "password");
+			xmlnode_set_attrib(child, "keyringid", keyring_id);
+			xmlnode_set_attrib(child, "mode", mode);
+			xmlnode_insert_data(child, data, -1);
+
+			if (destroy != NULL)
+				destroy(data);
+		}
 	}
 
 	if ((tmp = purple_account_get_alias(account)) != NULL)
@@ -773,7 +791,10 @@ parse_account(xmlnode *node)
 	xmlnode *child;
 	char *protocol_id = NULL;
 	char *name = NULL;
-	char *data;
+	char *keyring_id = NULL;
+	char *mode = NULL;
+	char *data = NULL;
+	GError * error = NULL;
 
 	child = xmlnode_get_child(node, "protocol");
 	if (child != NULL)
@@ -801,15 +822,6 @@ parse_account(xmlnode *node)
 	g_free(name);
 	g_free(protocol_id);
 
-	/* Read the password */
-	child = xmlnode_get_child(node, "password");					// FIXME : call plugin 
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		purple_account_set_remember_password(ret, TRUE);
-		purple_account_set_password(ret, data);
-		g_free(data);
-	}
-
 	/* Read the alias */
 	child = xmlnode_get_child(node, "alias");
 	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
@@ -882,6 +894,24 @@ parse_account(xmlnode *node)
 		parse_current_error(child, ret);
 	}
 
+	/* Read the password */
+	child = xmlnode_get_child(node, "password");					// FIXME : call plugin 
+
+	if (child != NULL)
+	{
+		purple_keyring_import_password(ret, keyring_id, mode, data, &error);
+
+		if (error == NULL) {
+			purple_account_set_remember_password(ret, TRUE);
+			g_free(keyring_id);
+			g_free(mode);
+			g_free(data);
+		} else {
+
+			// FIXME handle error
+		}
+	}
+
 	return ret;
 }
 
@@ -1502,9 +1532,15 @@ purple_account_set_password(PurpleAccoun
 {
 	g_return_if_fail(account != NULL);
 
-	g_free(account->password);
-	account->password = g_strdup(password);
+	if (account->password != NULL)
+		g_free(account->password);
 
+	if (purple_account_get_remember_password(account) == FALSE)
+		account->password = g_strdup(password);
+
+	else
+		purple_keyring_set_password_sync(account, password);
+
 	schedule_accounts_save();
 }
 
@@ -1895,12 +1931,18 @@ purple_account_get_username(const Purple
 	return account->username;
 }
 
+/* XXX will be replaced by the async code in 3.0 */
 const char *
 purple_account_get_password(const PurpleAccount *account)
 {
 	g_return_val_if_fail(account != NULL, NULL);
 
-	return account->password;
+	if (account->password != NULL)
+		return account->password;
+
+	else
+	
+		return purple_keyring_get_password_sync(account);
 }
 
 const char *
============================================================
--- libpurple/keyring.c	f3ca027916718615c3fcb40f1bcb27f1a83db8b0
+++ libpurple/keyring.c	765e0c604ae258612f4a6704bd3313e74634e43a
@@ -28,6 +28,7 @@
  */
 
 #include <glib.h>
+#include <string.h>>
 #include "account.h"
 #include "keyring.h"
 #include "signals.h"
@@ -336,11 +337,9 @@ purple_keyring_drop_passwords(const Purp
 	GList * cur;
 	PurpleKeyringSave save;
 
-	GError * error;
-
 	save = purple_keyring_get_save_password(keyring);
 
-	r_return_if_fail(save != NULL);
+	g_return_if_fail(save != NULL);
 
 	for (cur = purple_accounts_get_all(); 
 	     cur != NULL;
@@ -363,7 +362,7 @@ struct _PurpleKeyringChangeTracker
 	gboolean force;
 };
 
-void
+static void
 purple_keyring_set_inuse_check_error_cb(const PurpleAccount * account,
 					GError * error,
 					gpointer data)
@@ -379,7 +378,7 @@ purple_keyring_set_inuse_check_error_cb(
 
 	tracker->read_outstanding--;
 
-	name = purple_account_get_username(account);
+	name = purple_account_get_username(account);;
 
 
 	if ((error != NULL) && (error->domain == ERR_PIDGINKEYRING)) {
@@ -389,16 +388,18 @@ purple_keyring_set_inuse_check_error_cb(
 		switch(error->code) {
 
 			case ERR_NOCAP :
-				g_debug("Keyring could not save passwords : %s", name, error->message);
+				g_debug("Keyring could not save password for account %s : %s", name, error->message);
 				break;
 
 			case ERR_NOPASSWD :
-				g_debug("No password found while changing keyring for account %s", name, error->message);
+				g_debug("No password found while changing keyring for account %s : %s",
+					 name, error->message);
 				break;
 
 			case ERR_NOCHANNEL :
-				g_debug("Failed to communicate with backend while changing keyring for account %s : %s Aborting changes.", name, error->message);
-				tracker->abort == TRUE;
+				g_debug("Failed to communicate with backend while changing keyring for account %s : %s Aborting changes.",
+					 name, error->message);
+				tracker->abort = TRUE;
 				break;
 
 			default :
@@ -434,7 +435,7 @@ purple_keyring_set_inuse_check_error_cb(
 }
 
 
-void
+static void
 purple_keyring_set_inuse_got_pw_cb(const PurpleAccount * account, 
 				  gchar * password, 
 				  GError * error, 
@@ -501,8 +502,10 @@ purple_keyring_set_inuse(const PurpleKey
 	PurpleKeyringRead read;
 	PurpleKeyringClose close;
 	struct _PurpleKeyringChangeTracker * tracker;
-	GError * error;
+	GError * error = NULL; 
 
+	oldkeyring = purple_keyring_get_inuse();
+
 	read = purple_keyring_get_read_password(oldkeyring);
 
 	if (read == NULL) {
@@ -567,7 +570,7 @@ void 
 
 
 void 
-purple_plugin_keyring_register(PurpleKeyring * keyring)
+purple_keyring_register(PurpleKeyring * keyring)
 {
 	const char * keyring_id;
 	PurpleCore * core;
@@ -598,7 +601,7 @@ void 
 
 
 void 
-purple_plugin_keyring_unregister(PurpleKeyring * keyring)
+purple_keyring_unregister(PurpleKeyring * keyring)
 {
 	PurpleCore * core;
 	const PurpleKeyring * inuse;
@@ -632,11 +635,12 @@ purple_plugin_keyring_unregister(PurpleK
 /*@{*/
 
 
-void purple_keyring_import_password(PurpleAccount * account, 
-				    char * keyringid,
-				    char * mode,
-				    char * data,
-				    GError ** error)
+gboolean
+purple_keyring_import_password(PurpleAccount * account, 
+			       char * keyringid,
+			       char * mode,
+			       char * data,
+			       GError ** error)
 {
 	const PurpleKeyring * inuse;
 	PurpleKeyringImportPassword import;
@@ -648,7 +652,7 @@ void purple_keyring_import_password(Purp
 		*error = g_error_new(ERR_PIDGINKEYRING , ERR_NOKEYRING,
 			"No keyring configured, cannot import password info");
 		g_debug("No keyring configured, cannot import password info");
-		return;
+		return FALSE;
 	}
 
 	realid = purple_keyring_get_name(inuse);
@@ -662,7 +666,7 @@ void purple_keyring_import_password(Purp
 		*error = g_error_new(ERR_PIDGINKEYRING , ERR_INVALID,
 			"Specified keyring id does not match the configured one.");
 		g_debug("Specified keyring id does not match the configured one.");
-		return;
+		return FALSE;
 	}
 
 	import = purple_keyring_get_import_password(inuse);
@@ -670,25 +674,22 @@ void purple_keyring_import_password(Purp
 		*error = g_error_new(ERR_PIDGINKEYRING , ERR_NOCAP,
 			"Keyring cannot import password info.");
 		g_debug("Keyring cannot import password info. This might be normal");
-		return;
+		return FALSE;
 	}
 	
-	import(account, mode, data, error);
-
-	return;
+	return import(account, mode, data, error);
 }
 
-void 
+gboolean
 purple_keyring_export_password(PurpleAccount * account,
 			       const char ** keyringid,
 			       const char ** mode,
-			       const char ** data,
+			       char ** data,
 			       GError ** error,
-			       GDestroyNotify ** destroy)
+			       GDestroyNotify * destroy)
 {
 	const PurpleKeyring * inuse;
 	PurpleKeyringExportPassword export;
-	const char * realid;
 
 	inuse = purple_keyring_get_inuse();
 
@@ -705,7 +706,7 @@ purple_keyring_export_password(PurpleAcc
 		*error = g_error_new(ERR_PIDGINKEYRING , ERR_INVALID,
 			"Plugin does not have a keyring id");
 		g_debug("Plugin does not have a keyring id");
-		return;
+		return FALSE;
 	}
 
 	export = purple_keyring_get_export_password(inuse);
@@ -714,12 +715,10 @@ purple_keyring_export_password(PurpleAcc
 		*error = g_error_new(ERR_PIDGINKEYRING , ERR_NOCAP,
 			"Keyring cannot export password info.");
 		g_debug("Keyring cannot export password info. This might be normal");
-		return;
+		return FALSE;
 	}
 
-	export(account, mode, data, error, destroy);
-
-	return;
+	return export(account, mode, data, error, destroy);
 }
 
 
@@ -843,7 +842,6 @@ purple_keyring_get_password_sync(const P
 purple_keyring_get_password_sync(const PurpleAccount * account)
 {
 	PurpleKeyringReadSync read;
-	PurpleKeyring * keyring;
 	const PurpleKeyring * inuse;
 
 	if (account == NULL) {
@@ -859,7 +857,7 @@ purple_keyring_get_password_sync(const P
 
 		} else {
 
-			read = purple_keyring_get_read_sync(keyring);
+			read = purple_keyring_get_read_sync(inuse);
 
 			if (read == NULL){
 
@@ -978,7 +976,7 @@ purple_keyring_change_master(PurpleKeyri
 /***************************************/
 /*@{*/
 
-GQuark purple_keyring_error_domain()
+GQuark purple_keyring_error_domain(void)
 {
 	return g_quark_from_static_string("Libpurple keyring");
 }
============================================================
--- libpurple/keyring.h	624d3d7937e242c93b82d4ed7a4271b1ef6fc0c3
+++ libpurple/keyring.h	5694f865120f4fe940171f4a052b72f6068fe679
@@ -198,9 +198,9 @@ typedef gboolean (*PurpleKeyringExportPa
  */
 typedef gboolean (*PurpleKeyringExportPassword)(PurpleAccount * account,
 						const char ** mode,
-						const char ** data,
+						char ** data,
 						GError ** error,
-						GDestroyNotify ** destroy);
+						GDestroyNotify * destroy);
 
 
 /*@}*/
@@ -215,25 +215,25 @@ void 
  * Prepare stuff at startup.
  */
 void 
-purple_keyring_init();
+purple_keyring_init(void);
 
 /**
  * Do some cleanup.
  */
 void
-purple_keyring_uninit();
+purple_keyring_uninit(void);
 
 /**
  * Get the keyring list. Used by the UI.
  */
 const GList * 
-purple_keyring_get_keyrings();
+purple_keyring_get_keyrings(void);
 
 /**
  * Get the keyring being used.
  */
 const PurpleKeyring * 
-purple_keyring_get_inuse();
+purple_keyring_get_inuse(void);
 
 /**
  * Set the keyring to use. This function will move all passwords from
@@ -259,7 +259,7 @@ void 
  * @param keyrint The keyring to register.
  */
 void 
-purple_plugin_keyring_register(PurpleKeyring * keyring);
+purple_keyring_register(PurpleKeyring * keyring);
 
 /**
  * Unregister a keyring plugin. In case the keyring is in use,
@@ -268,7 +268,7 @@ void 
  * @param keyrint The keyring to unregister.
  */
 void 
-purple_plugin_keyring_unregister(PurpleKeyring * keyring);
+purple_keyring_unregister(PurpleKeyring * keyring);
 
 /*@}*/
 
@@ -284,8 +284,9 @@ purple_plugin_keyring_unregister(PurpleK
  * @param keyringid The plugin ID that was stored in the xml file. Can be NULL.
  * @param mode A keyring specific option that was stored. Can be NULL.
  * @param data Data that was stored, can be NULL.
+ * @return TRUE if the input was accepted, FALSE otherwise.
  */
-void purple_keyring_import_password(PurpleAccount * account, 
+gboolean purple_keyring_import_password(PurpleAccount * account, 
 				    char * keyringid,
 				    char * mode,
 				    char * data,
@@ -299,14 +300,15 @@ void purple_keyring_import_password(Purp
  * @param data The data to be stored in the XML node. This string must be freed using destroy() once not needed anymore if it is not NULL.
  * @param error Will be set if a problem occured.
  * @param destroy A function to be called, if non NULL, to free data.
+ * @return TRUE if the info was exported successfully, FALSE otherwise.
  */
-void 
+gboolean
 purple_keyring_export_password(PurpleAccount * account,
 			       const char ** keyringid,
 			       const char ** mode,
-			       const char ** data,
+			       char ** data,
 			       GError ** error,
-			       GDestroyNotify ** destroy);
+			       GDestroyNotify * destroy);
 
 
 
@@ -398,7 +400,7 @@ purple_keyring_change_master(PurpleKeyri
 /***************************************/
 /*@{*/
 
-PurpleKeyring * purple_keyring_new();
+PurpleKeyring * purple_keyring_new(void);
 void purple_keyring_free(PurpleKeyring * keyring);
 
 const char * purple_keyring_get_name(const PurpleKeyring * info);
============================================================
--- libpurple/plugins/Makefile.am	062a44d8df3bfe3f9e5756ecf6e7fde29d836736
+++ libpurple/plugins/Makefile.am	dc58e171907ab95f07bf3f76039d6e2f5be57b14
@@ -41,6 +41,7 @@ statenotify_la_LDFLAGS      = -module -a
 signals_test_la_LDFLAGS		= -module -avoid-version
 simple_la_LDFLAGS			= -module -avoid-version
 statenotify_la_LDFLAGS      = -module -avoid-version
+internalkeyring_la_LDFLAGS  = -module -avoid-version
 
 # this can't be in a conditional otherwise automake 1.4 yells
 dbus_example_la_LDFLAGS     = -module -avoid-version
@@ -57,7 +58,8 @@ plugin_LTLIBRARIES = \
 	offlinemsg.la       \
 	psychic.la          \
 	statenotify.la      \
-	$(DBUS_LTLIB)
+	$(DBUS_LTLIB)       \
+	internalkeyring.la
 
 noinst_LTLIBRARIES = \
 	ciphertest.la \
@@ -86,6 +88,7 @@ statenotify_la_SOURCES      = statenotif
 signals_test_la_SOURCES		= signals-test.c
 simple_la_SOURCES			= simple.c
 statenotify_la_SOURCES      = statenotify.c
+internalkeyring_la_SOURCES  = keyrings/internalkeyring.c
 
 autoaccept_la_LIBADD        = $(GLIB_LIBS)
 buddynote_la_LIBADD         = $(GLIB_LIBS)
@@ -102,6 +105,7 @@ statenotify_la_LIBADD       = $(GLIB_LIB
 signals_test_la_LIBADD		= $(GLIB_LIBS)
 simple_la_LIBADD			= $(GLIB_LIBS)
 statenotify_la_LIBADD       = $(GLIB_LIBS)
+internalkeyring_la_LIBADD   = $(GLIB_LIBS)
 
 if ENABLE_DBUS
 
============================================================
--- libpurple/plugins/keyrings/internalkeyring.c	fe3f1560ce21ea6b9a3a1689ff1ba087ed612ddb
+++ libpurple/plugins/keyrings/internalkeyring.c	2d11bc7ba98ac3b7113d733f2c1b76d1128655ed
@@ -1,362 +1,245 @@
-/* TODO
- - fix error reporting
- - use hashtable instead of Glib
- - plugin interface
- - move keyring info struct upwards
-*/
+/**
+ * @file internalkeyring.c internal keyring
+ * @ingroup core
+ *
+ * @todo 
+ *   cleanup error handling and reporting
+ */
 
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+
 #include <glib.h>
-#include <string.h>
+#include "account.h"
 #include "version.h"
 #include "keyring.h"
-#include "account.h"
 
-/******************************/
-/** Macros and constants      */
-/******************************/
 
-#define KEYRINGNAME			"internalkeyring"
-#define INTERNALKEYRING_VERSION		"0.2a"
-#define INTERNALKEYRING_ID		"core-scrouaf-internalkeyring"
-#define INTERNALKEYRING_AUTHOR		"Vivien Bernet-Rollande <vbernetr at etu.utc.fr>"
-#define INTERNALKEYRING_DESCRIPTION	\
-	"This keyring plugin offers a password storage backend compatible with the former storage system."
+#define KEYRINGNAME			"internal_keyring"
+#define INTERNALKEYRING_VERSION		"0.7"
+#define INTERNALKEYRING_DESCRIPTION	"This plugin provides the default password storage behaviour for libpurple."
+#define	INTERNALKEYRING_AUTHOR		"Scrouaf (scrouaf[at]soc.pidgin.im)"
+#define INTERNALKEYRING_ID		"core-internalkeyring-scrouaf"
 
+#define GET_PASSWORD(account) \
+	g_hash_table_lookup (internal_keyring_passwords, account)
+#define SET_PASSWORD(account, password) \
+	g_hash_table_replace(internal_keyring_passwords, account, password)
 
-/******************************/
-/** Data Structures           */
-/******************************/
+GHashTable * internal_keyring_passwords = NULL;
+static PurpleKeyring * keyring_handler = NULL;
 
-typedef struct _InternalKeyring_PasswordInfo InternalKeyring_PasswordInfo;
+/* a few prototypes : */
+static void 		internal_keyring_read(const PurpleAccount *, PurpleKeyringReadCallback, gpointer);
+static void 		internal_keyring_save(const PurpleAccount *, gchar *, GDestroyNotify, PurpleKeyringSaveCallback, gpointer);
+static const char * 	internal_keyring_read_sync(const PurpleAccount *);
+static void 		internal_keyring_save_sync(PurpleAccount *, const gchar *);
+static void		internal_keyring_close(GError **);
+static gboolean		internal_keyring_import_password(PurpleAccount *, char *, char *, GError **);
+static gboolean 	internal_keyring_export_password(PurpleAccount *, const char **, char **, GError **, GDestroyNotify *);
+void 			internal_keyring_init(void);
+void 			internal_keyring_uninit(void);
+static gboolean		internal_keyring_load(PurplePlugin *);
+static gboolean		internal_keyring_unload(PurplePlugin *);
+static void		internal_keyring_destroy(PurplePlugin *);
 
-struct _InternalKeyring_PasswordInfo {
-	const PurpleAccount * account;
-	gchar * password;
-};
+/***********************************************/
+/*     Keyring interface                       */
+/***********************************************/
+static void 
+internal_keyring_read(const PurpleAccount * account,
+		      PurpleKeyringReadCallback cb,
+		      gpointer data)
+{
+	char * password;
+	GError * error;
 
-/******************************/
-/** Globals                   */
-/******************************/
+	password = GET_PASSWORD(account);
 
-GList * InternalKeyring_passwordlist = NULL;		/* use hashtable ? */
+	if (password != NULL) {
+		cb(account, password, NULL, data);
+	} else {
+		error = g_error_new(ERR_PIDGINKEYRING, 
+			ERR_NOPASSWD, "password not found");
+		cb(account, NULL, error, data);
+		g_error_free(error);
+	}
+	return;
+}
 
-
-/******************************/
-/** Internal functions        */
-/******************************/
-
-/**
- * retrieve the InternalKeyring_PasswordInfo structure for an account
- * TODO : rewrite this to use hashtables rather than GList
- */
-static InternalKeyring_PasswordInfo * 
-InternalKeyring_get_account_info(const PurpleAccount * account)
+static void
+internal_keyring_save(const PurpleAccount * account,
+		      gchar * password,
+		      GDestroyNotify destroy,
+		      PurpleKeyringSaveCallback cb,
+		      gpointer data)
 {
-	GList * p;
-	InternalKeyring_PasswordInfo * i;
+	gchar * copy;
 
-	for (p = InternalKeyring_passwordlist; p != NULL; p = p->next)  {
-		i = (InternalKeyring_PasswordInfo*)(p->data);
-		if (i->account == account)
-			return i;
+	if (password == NULL) {
+		g_hash_table_remove(internal_keyring_passwords, account);
+	} else {
+		copy = g_strdup(password);
+		SET_PASSWORD((void *)account, copy);	/* cast prevents warning because account is const */
 	}
-	return NULL;
+
+	if(destroy != NULL)
+		destroy(password);
+
+	cb(account, NULL, data);
+	return;
 }
 
-/**
- * Free or create an InternalKeyring_PasswordInfo structure and all pointed data.
- * XXX /!\ Update this when adding fields to InternalKeyring_PasswordInfo
- * XXX : rewrite this to use hashtables rather than GList
- *        (fix InternalKeyring_Close() as well)
- */
-static void
-InternalKeyring_add_passwordinfo(InternalKeyring_PasswordInfo * info)
+
+static const char * 
+internal_keyring_read_sync(const PurpleAccount * account)
 {
-	InternalKeyring_passwordlist = g_list_prepend(InternalKeyring_passwordlist, info);
-	return;
+	return GET_PASSWORD(account);
 }
 
 static void
-InternalKeyring_free_passwordinfo(InternalKeyring_PasswordInfo * info)
+internal_keyring_save_sync(PurpleAccount * account,
+			   const char * password)
 {
-	g_free(info->password);
-	InternalKeyring_passwordlist = g_list_remove(InternalKeyring_passwordlist, info);
-	g_free(info);
+	gchar * copy;
+
+	if (password == NULL) {
+		g_hash_table_remove(internal_keyring_passwords, account);
+	} else {
+		copy = g_strdup(password);
+		SET_PASSWORD(account, copy);
+	}
 	return;
 }
 
-/**
- * wrapper so we can use it in close
- * TODO : find a more elegant way
- */
 static void
-InternalKeyring_free_passwordinfo_from_g_list(gpointer info, gpointer data)
+internal_keyring_close(GError ** error)
 {
-	InternalKeyring_free_passwordinfo((InternalKeyring_PasswordInfo*)info);
-	return;
+	internal_keyring_uninit();
 }
 
-
-gboolean
-InternalKeyring_is_valid_cleartext(const PurpleKeyringPasswordNode * node)
+static gboolean
+internal_keyring_import_password(PurpleAccount * account, 
+				 char * mode,
+				 char * data,
+				 GError ** error)
 {
-	const char * enc;
-	const char * mode;
-	const char * data;
-	const PurpleAccount * account;	
+	gchar * copy;
 
-	enc = purple_keyring_password_node_get_encryption(node);
-	mode = purple_keyring_password_node_get_mode(node);
-	data = purple_keyring_password_node_get_data(node);
-	account = purple_keyring_password_node_get_account(node);
-
-	if ((enc == NULL || strcmp(enc, KEYRINGNAME) == 0)&&
-	    (mode == NULL || strcmp(mode, "cleartext") == 0)&&
+	if (account != NULL && 
 	    data != NULL &&
-	    account != NULL) {
+	    (mode == NULL || g_strcmp0(mode, "cleartext") == 0)) {
 
+		copy = g_strdup(data);
+		SET_PASSWORD(account, copy);
 		return TRUE;
 
 	} else {
 
+		*error = g_error_new(ERR_PIDGINKEYRING, ERR_NOPASSWD, "no password for account");
 		return FALSE;
 
 	}
 }
 
-/******************************/
-/** Keyring interface         */
-/******************************/
-
-/**
- * returns the password if the password is known.
- */
-void 
-InternalKeyring_read(const PurpleAccount * account,
-		     GError ** error, 
-		     PurpleKeyringReadCallback cb,
-		     gpointer data)
+static gboolean 
+internal_keyring_export_password(PurpleAccount * account,
+				 const char ** mode,
+				 char ** data,
+				 GError ** error,
+				 GDestroyNotify * destroy)
 {
-	InternalKeyring_PasswordInfo * info;
-	char * ret;
-	
-	info = InternalKeyring_get_account_info(account);
+	gchar * password;
 
-	if ( info == NULL ) {				/* no info on account */
+	password = GET_PASSWORD(account);
 
-		g_set_error(error, ERR_PIDGINKEYRING, ERR_NOACCOUNT, 
-			"No info for account.");
-		cb(account, NULL, error, data);
-		return;
-
-	} else if (info->password == NULL) {		/* unknown password */
-
-		g_set_error(error, ERR_PIDGINKEYRING, ERR_NOPASSWD, 
-			"No Password for this account.");
-		cb(account, NULL, error, data);
-		return;
-
+	if (password == NULL) {
+		return FALSE;
 	} else {
-
-		ret = info->password;
-		cb(account, ret, error, data);
+		*mode = "cleartext";
+		*data = g_strdup(password);
+		*destroy = g_free;
+		return TRUE;
 	}
 }
 
-/*
- * save a new password
- */
-void
-InternalKeyring_save(const PurpleAccount * account, 
-		     gchar * password,
-		     GError ** error,
-		     PurpleKeyringSaveCallback cb,
-		     gpointer data)
-{
-	InternalKeyring_PasswordInfo * info;
 
-	info = InternalKeyring_get_account_info(account);
 
-	if (password == NULL) {
-		/* forget password */
-		if (info == NULL) {
-			g_set_error(error, ERR_PIDGINKEYRING, ERR_NOPASSWD, 
-				"No Password for this account.");
-			cb(account, error, data);
-			return;
-		}
 
-		InternalKeyring_free_passwordinfo(info);
-
-		if (cb != NULL)
-			cb(account, error, data);
-		return;
-
-	} else {	/* password != NULL */
-
-		if ( info == NULL ) {
-			info = g_malloc0(sizeof (InternalKeyring_PasswordInfo));
-			InternalKeyring_add_passwordinfo(info);
-		}
-
-		/* if we already had a password, forget about it */
-		if ( info->password != NULL )	
-			g_free(info->password);
-
-		info->password = g_malloc(strlen( password + 1 ));
-		strcpy(info->password, password);
-
-		if (cb != NULL)
-			cb(account, error, data);
-		return;
-	}
-}
-
-/*
- * clears and frees all PasswordInfo structures.
- * TODO : rewrite using Hashtable
- */
-void 
-InternalKeyring_close(GError ** error)
-{
-	g_list_foreach(InternalKeyring_passwordlist,
-		InternalKeyring_free_passwordinfo_from_g_list, NULL);
-	return;
-}
-
-/*
- * does nothing since we don't want to free the stored info
- */
-void 
-InternalKeyring_free(gchar * password,
-		     GError ** error)
-{
-	return;		/* nothing to free or cleanup until we forget the password */
-}
-
-/**
- * Imports password info from a PurpleKeyringPasswordNode structure
- * (called for each account when accounts.xml is parsed)
- * returns TRUE if sucessful, FALSE otherwise.
- * TODO : add error reporting 
- *	  use accessors for PurpleKeyringPasswordNode (FIXME)
- *	  FIXME : REWRITE AS ASYNC
- */
 void
-InternalKeyring_import_password(const PurpleKeyringPasswordNode * nodeinfo,
-				GError ** error,
-				PurpleKeyringImportCallback cb,
-				gpointer cbdata)
+internal_keyring_init()
 {
-	InternalKeyring_PasswordInfo * pwinfo;
-	const char * data;
+	keyring_handler = purple_keyring_new();
 
-	if (InternalKeyring_is_valid_cleartext(nodeinfo)) {
+	purple_keyring_set_name(keyring_handler, KEYRINGNAME);
+	purple_keyring_set_read_sync(keyring_handler, internal_keyring_read_sync);
+	purple_keyring_set_save_sync(keyring_handler, internal_keyring_save_sync);
+	purple_keyring_set_read_password(keyring_handler, internal_keyring_read);
+	purple_keyring_set_save_password(keyring_handler, internal_keyring_save);
+	purple_keyring_set_close_keyring(keyring_handler, internal_keyring_close);
+	purple_keyring_set_change_master(keyring_handler, NULL);
+	purple_keyring_set_import_password(keyring_handler, internal_keyring_import_password);
+	purple_keyring_set_export_password(keyring_handler, internal_keyring_export_password);
 
-		pwinfo = g_malloc0(sizeof(InternalKeyring_PasswordInfo));
-		InternalKeyring_add_passwordinfo(pwinfo);
+	purple_keyring_register(keyring_handler);
 
-		data = purple_keyring_password_node_get_data(nodeinfo);		
-		pwinfo->password = g_malloc(strlen(data) + 1);
-		strcpy(pwinfo->password, data);
-
-		pwinfo->account = purple_keyring_password_node_get_account(nodeinfo);
-
-		//return TRUE;
-
-	} else {
-		/* invalid input */
-		//return FALSE;
-	}		
+	internal_keyring_passwords = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
 }
 
-
-/**
- * Exports password info to a PurpleKeyringPasswordNode structure
- * (called for each account when accounts are synced)
- * TODO : add proper error reporting 
- */
 void
-InternalKeyring_export_password(const PurpleAccount * account,
-				GError ** error,
-				PurpleKeyringExportCallback cb,
-				gpointer data)
+internal_keyring_uninit()
 {
-	PurpleKeyringPasswordNode * nodeinfo;
-	InternalKeyring_PasswordInfo * pwinfo;
+	purple_keyring_free(keyring_handler);
+	keyring_handler = NULL;
 
-	nodeinfo = purple_keyring_password_node_new();
-	pwinfo = InternalKeyring_get_account_info(account);
-
-	if (pwinfo->password == NULL) {
-
-		// FIXME : error
-		cb(NULL, error, data);
-		return;
-
-	} else {
-
-		purple_keyring_password_node_set_encryption(nodeinfo, KEYRINGNAME);
-		purple_keyring_password_node_set_mode(nodeinfo, "cleartext");
-		purple_keyring_password_node_set_data(nodeinfo, pwinfo->password);
-
-		cb(nodeinfo, error, data);
-		return;
-	}
+	g_hash_table_destroy(internal_keyring_passwords);
+	internal_keyring_passwords = NULL;
 }
 
 
+/***********************************************/
+/*     Plugin interface                        */
+/***********************************************/
 
-/******************************/
-/** Keyring plugin stuff      */
-/******************************/
-
-PurpleKeyring InternalKeyring_KeyringInfo =
+static gboolean
+internal_keyring_load(PurplePlugin *plugin)
 {
-	"internalkeyring",
-	InternalKeyring_read,
-	InternalKeyring_save,
-	InternalKeyring_close,
-	InternalKeyring_free,
-	NULL,				/* change_master */
-	InternalKeyring_import_password,
-	InternalKeyring_export_password,
-	NULL,				/* RESERVED */
-	NULL,				/* RESERVED */
-	NULL				/* RESERVED */
-};
-
-
-/******************************/
-/** Plugin interface          */
-/******************************/
-
-gboolean 
-InternalKeyring_load(PurplePlugin *plugin)
-{
-	purple_plugin_keyring_register(&InternalKeyring_KeyringInfo);	/* FIXME : structure should be hidden */
+	purple_keyring_init();
 	return TRUE;
 }
 
-/**
- * TODO : handle error, maybe return FALSE on problem
- * (no reason for it to fail unless data is corrupted though)
- */
-gboolean 
-InternalKeyring_unload(PurplePlugin *plugin)
+static gboolean
+internal_keyring_unload(PurplePlugin *plugin)
 {
-	InternalKeyring_close(NULL);
+	purple_keyring_uninit();
 	return TRUE;
 }
 
-void 
-InternalKeyring_destroy(PurplePlugin *plugin)
+static void
+internal_keyring_destroy(PurplePlugin *plugin)
 {
-	InternalKeyring_close(NULL);
+	purple_keyring_uninit();
 	return;
 }
 
-
 PurplePluginInfo plugininfo =
 {
 	PURPLE_PLUGIN_MAGIC,						/* magic */
@@ -368,15 +251,15 @@ PurplePluginInfo plugininfo =
 	NULL,								/* dependencies */
 	PURPLE_PRIORITY_DEFAULT,					/* priority */
 	INTERNALKEYRING_ID,						/* id */
-	"internal-keyring-plugin",					/* name */
+	"internal-keyring",						/* name */
 	INTERNALKEYRING_VERSION,					/* version */
 	"Internal Keyring Plugin",					/* summary */
 	INTERNALKEYRING_DESCRIPTION,					/* description */
 	INTERNALKEYRING_AUTHOR,						/* author */
 	"N/A",								/* homepage */
-	InternalKeyring_load,						/* load */
-	InternalKeyring_unload,						/* unload */
-	InternalKeyring_destroy,					/* destroy */
+	internal_keyring_load,						/* load */
+	internal_keyring_unload,					/* unload */
+	internal_keyring_destroy,					/* destroy */
 	NULL,								/* ui_info */
 	NULL,								/* extra_info */
 	NULL,								/* prefs_info */
@@ -387,4 +270,3 @@ PurplePluginInfo plugininfo =
 	NULL,
 };
 
-


More information about the Commits mailing list