soc.2008.masterpassword: d2fecdd6: Added support for the PURPLE_PLUGIN_FLAG...

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


-----------------------------------------------------------------
Revision: d2fecdd676d4493f84d3ed47afd31fd3ea041774
Ancestor: 509008d6f0811c12ebe728dde95f76eb31a0d2c2
Author: scrouaf at soc.pidgin.im
Date: 2008-08-08T01:13:50
Branch: im.pidgin.soc.2008.masterpassword
URL: http://d.pidgin.im/viewmtn/revision/info/d2fecdd676d4493f84d3ed47afd31fd3ea041774

Deleted entries:
        libpurple/plugins/keyrings/internalkeyring.c
Added files:
        libpurple/plugins/internalkeyring.c
Modified files:
        libpurple/account.c libpurple/core.c libpurple/keyring.c
        libpurple/keyring.h libpurple/plugin.c
        libpurple/plugins/Makefile.am

ChangeLog: 

Added support for the PURPLE_PLUGIN_FLAG_AUTOLOAD flag, corrected a few bugs and crashed. The compatibility plugin is automatically loaded at startup, and works nicely in compatibility mode (read_sync, write_sync, import, export). Also, I played unsuccessfully with makefiles, so i moved the keyring up one directory. I've finally gotten to the point where I run "make && sudo make install" every now and then.

-------------- next part --------------
============================================================
--- libpurple/plugins/internalkeyring.c	ebc914dcfffeaeea37b0af97eed0e19739a7f9fd
+++ libpurple/plugins/internalkeyring.c	ebc914dcfffeaeea37b0af97eed0e19739a7f9fd
@@ -0,0 +1,303 @@
+/**
+ * @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
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef PURPLE_PLUGINS
+# define PURPLE_PLUGINS
+#endif
+
+#include <glib.h>
+
+#ifndef G_GNUC_NULL_TERMINATED
+# if __GNUC__ >= 4
+#  define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
+# else
+#  define G_GNUC_NULL_TERMINATED
+# endif
+#endif
+
+#include "account.h"
+#include "version.h"
+#include "keyring.h"
+#include "debug.h"
+#include "plugin.h"
+
+#define KEYRINGNAME			FALLBACK_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)
+
+
+GHashTable * internal_keyring_passwords = NULL;
+static PurpleKeyring * keyring_handler = NULL;
+
+/* 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 *);
+static void		internal_keyring_init(void);
+static void		internal_keyring_uninit(void);
+static gboolean		internal_keyring_load(PurplePlugin *);
+static gboolean		internal_keyring_unload(PurplePlugin *);
+static void		internal_keyring_destroy(PurplePlugin *);
+
+/***********************************************/
+/*     Keyring interface                       */
+/***********************************************/
+static void 
+internal_keyring_read(const PurpleAccount * account,
+		      PurpleKeyringReadCallback cb,
+		      gpointer data)
+{
+	char * password;
+	GError * error;
+
+	password = GET_PASSWORD(account);
+
+	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;
+}
+
+static void
+internal_keyring_save(const PurpleAccount * account,
+		      gchar * password,
+		      GDestroyNotify destroy,
+		      PurpleKeyringSaveCallback cb,
+		      gpointer data)
+{
+	gchar * copy;
+
+	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 */
+	}
+
+	if(destroy != NULL)
+		destroy(password);
+
+	cb(account, NULL, data);
+	return;
+}
+
+
+static const char * 
+internal_keyring_read_sync(const PurpleAccount * account)
+{
+	purple_debug_info("keyring", "password was read\n");
+	return GET_PASSWORD(account);
+}
+
+static void
+internal_keyring_save_sync(PurpleAccount * account,
+			   const char * password)
+{
+	gchar * copy;
+
+	if (password == NULL) {
+		g_hash_table_remove(internal_keyring_passwords, account);
+	} else {
+		copy = g_strdup(password);
+		SET_PASSWORD(account, copy);
+	}
+	purple_debug_info("keyring", "password was set\n");
+	return;
+}
+
+static void
+internal_keyring_close(GError ** error)
+{
+	internal_keyring_uninit();
+}
+
+static gboolean
+internal_keyring_import_password(PurpleAccount * account, 
+				 char * mode,
+				 char * data,
+				 GError ** error)
+{
+	gchar * copy;
+
+	if (account != NULL && 
+	    data != 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;
+
+	}
+}
+
+static gboolean 
+internal_keyring_export_password(PurpleAccount * account,
+				 const char ** mode,
+				 char ** data,
+				 GError ** error,
+				 GDestroyNotify * destroy)
+{
+	gchar * password;
+
+	password = GET_PASSWORD(account);
+
+	if (password == NULL) {
+		return FALSE;
+	} else {
+		*mode = "cleartext";
+		*data = g_strdup(password);
+		*destroy = g_free;
+		return TRUE;
+	}
+}
+
+
+
+
+static void
+internal_keyring_init()
+{
+	keyring_handler = purple_keyring_new();
+
+	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);
+
+	purple_keyring_register(keyring_handler);
+
+	internal_keyring_passwords = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
+}
+
+static void
+internal_keyring_uninit()
+{
+	purple_keyring_free(keyring_handler);
+	keyring_handler = NULL;
+
+	g_hash_table_destroy(internal_keyring_passwords);
+	internal_keyring_passwords = NULL;
+}
+
+
+
+/***********************************************/
+/*     Plugin interface                        */
+/***********************************************/
+
+static gboolean
+internal_keyring_load(PurplePlugin *plugin)
+{
+	internal_keyring_init();
+	return TRUE;
+}
+
+static gboolean
+internal_keyring_unload(PurplePlugin *plugin)
+{
+	internal_keyring_uninit();
+	return TRUE;
+}
+
+static void
+internal_keyring_destroy(PurplePlugin *plugin)
+{
+	internal_keyring_uninit();
+	return;
+}
+
+PurplePluginInfo plugininfo =
+{
+	PURPLE_PLUGIN_MAGIC,						/* magic */
+	PURPLE_MAJOR_VERSION,						/* major_version */
+	PURPLE_MINOR_VERSION,						/* minor_version */
+	PURPLE_PLUGIN_STANDARD,						/* type */
+	NULL,								/* ui_requirement */
+	PURPLE_PLUGIN_FLAG_INVISIBLE|PURPLE_PLUGIN_FLAG_AUTOLOAD,	/* flags */
+	NULL,								/* dependencies */
+	PURPLE_PRIORITY_DEFAULT,					/* priority */
+	INTERNALKEYRING_ID,						/* id */
+	"internal-keyring",						/* name */
+	INTERNALKEYRING_VERSION,					/* version */
+	"Internal Keyring Plugin",					/* summary */
+	INTERNALKEYRING_DESCRIPTION,					/* description */
+	INTERNALKEYRING_AUTHOR,						/* author */
+	"N/A",								/* homepage */
+	internal_keyring_load,						/* load */
+	internal_keyring_unload,					/* unload */
+	internal_keyring_destroy,					/* destroy */
+	NULL,								/* ui_info */
+	NULL,								/* extra_info */
+	NULL,								/* prefs_info */
+	NULL,								/* actions */
+	NULL,								/* padding... */
+	NULL,
+	NULL,
+	NULL,
+};
+
+static void                        
+init_plugin(PurplePlugin *plugin)
+{                                  
+	purple_debug_info("internalkeyring", "init plugin called.\n");
+}
+
+PURPLE_INIT_PLUGIN(internal_keyring, init_plugin, plugininfo)
+
============================================================
--- libpurple/account.c	520ccb9039f53527996e9669a95fb4402fed03d9
+++ libpurple/account.c	ecd0c062522ecdf0aa7f913f4bd091409d7274f6
@@ -385,6 +385,7 @@ account_to_xmlnode(PurpleAccount *accoun
 
 	if (purple_account_get_remember_password(account))
 	{
+		purple_debug_info("accounts", "Exporting password.\n");
 		purple_keyring_export_password(account, &keyring_id, 
 			&mode, &data, &error, &destroy);
 
@@ -794,6 +795,7 @@ parse_account(xmlnode *node)
 	char *keyring_id = NULL;
 	char *mode = NULL;
 	char *data = NULL;
+	gboolean result;
 	GError * error = NULL;
 
 	child = xmlnode_get_child(node, "protocol");
@@ -895,19 +897,23 @@ parse_account(xmlnode *node)
 	}
 
 	/* Read the password */
-	child = xmlnode_get_child(node, "password");					// FIXME : call plugin 
-
+	child = xmlnode_get_child(node, "password");
 	if (child != NULL)
 	{
-		purple_keyring_import_password(ret, keyring_id, mode, data, &error);
+		keyring_id = xmlnode_get_attrib(child, "keyring_id");
+		mode = xmlnode_get_attrib(child, "mode");
+		data = xmlnode_get_data(child);
 
-		if (error == NULL) {
+		result = purple_keyring_import_password(ret, keyring_id, mode, data, &error);
+
+		if (result == TRUE) {
+			purple_debug_info("accounts", "password imported successfully.\n");
 			purple_account_set_remember_password(ret, TRUE);
 			g_free(keyring_id);
 			g_free(mode);
 			g_free(data);
 		} else {
-
+			purple_debug_info("accounts", "failed to imported password.\n");
 			// FIXME handle error
 		}
 	}
@@ -1937,12 +1943,16 @@ purple_account_get_password(const Purple
 {
 	g_return_val_if_fail(account != NULL, NULL);
 
-	if (account->password != NULL)
+	if (account->password != NULL) {
+	
+		purple_debug_info("keyring", "password was read from stored\n");
 		return account->password;
+	
 
-	else
-	
+	} else {
+		purple_debug_info("keyring", "reading password from keyring\n");	
 		return purple_keyring_get_password_sync(account);
+	}
 }
 
 const char *
============================================================
--- libpurple/core.c	94e0158bb36c1eba61f0687830b5f0f7f671c720
+++ libpurple/core.c	791d7b8c370b7606256c18fd87e70ccc15b09ec1
@@ -35,6 +35,7 @@
 #include "ft.h"
 #include "idle.h"
 #include "imgstore.h"
+#include "keyring.h"
 #include "network.h"
 #include "notify.h"
 #include "plugin.h"
@@ -132,6 +133,7 @@ purple_core_init(const char *ui)
 
 	purple_ciphers_init();
 	purple_cmds_init();
+	purple_keyring_init();
 
 	/* Since plugins get probed so early we should probably initialize their
 	 * subsystem right away too.
============================================================
--- libpurple/keyring.c	765e0c604ae258612f4a6704bd3313e74634e43a
+++ libpurple/keyring.c	5cb004775a3a4bf0bd124f73643b9fbcd16f76c8
@@ -33,9 +33,8 @@
 #include "keyring.h"
 #include "signals.h"
 #include "core.h"
+#include "debug.h"
 
-#define FALLBACK_KEYRING	"core-scrouaf-internalkeyring"
-
 /******************************************/
 /** @name PurpleKeyring                   */
 /******************************************/
@@ -62,7 +61,7 @@ purple_keyring_new()
 PurpleKeyring * 
 purple_keyring_new()
 {
-	return g_malloc(sizeof(PurpleKeyring));
+	return g_malloc0(sizeof(PurpleKeyring));
 }
 
 /* Destructor */
@@ -258,6 +257,8 @@ purple_keyring_init()
 	PurpleCore * core;
 	const char * touse;
 
+	purple_debug_info("keyring", "keyring_it");
+
 	/* Make sure we don't have junk */
 	purple_keyring_keyrings = NULL;
 	purple_keyring_inuse = NULL;
@@ -309,7 +310,7 @@ purple_keyring_find_keyring_by_id(char *
 		keyring = l->data;
 		name = purple_keyring_get_name(keyring);
 
-		if (strcmp(id, name) == 0)
+		if (g_strcmp0(id, name) == 0)
 			return keyring;
 	}
 
@@ -499,14 +500,17 @@ purple_keyring_set_inuse(const PurpleKey
 {
 	GList * cur;
 	const PurpleKeyring * oldkeyring;
-	PurpleKeyringRead read;
+	PurpleKeyringRead read = NULL;
 	PurpleKeyringClose close;
 	struct _PurpleKeyringChangeTracker * tracker;
 	GError * error = NULL; 
 
+	purple_debug_info("keyring", "changing in use keyring\n");
+
 	oldkeyring = purple_keyring_get_inuse();
 
-	read = purple_keyring_get_read_password(oldkeyring);
+	if (oldkeyring != NULL)
+		read = purple_keyring_get_read_password(oldkeyring);
 
 	if (read == NULL) {
 		error = g_error_new(ERR_PIDGINKEYRING , ERR_NOCAP,
@@ -556,14 +560,12 @@ purple_keyring_set_inuse(const PurpleKey
 		}
 
 	} else { /* no keyring was set before. */
-
+		purple_debug_info("keyring", "setting keyring for the first time\n");
 		purple_keyring_inuse = newkeyring;
 
 		if (cb != NULL)
-			cb(newkeyring, TRUE, error, data);
+			cb(newkeyring, TRUE, NULL, data);
 
-		g_error_free(error);
-
 		return;
 	}
 }
@@ -575,6 +577,7 @@ purple_keyring_register(PurpleKeyring * 
 	const char * keyring_id;
 	PurpleCore * core;
 
+	purple_debug_info("keyring", "registering keyring.\n");
 	g_return_if_fail(keyring != NULL);
 	
 	keyring_id = purple_keyring_get_name(keyring);
@@ -584,7 +587,7 @@ purple_keyring_register(PurpleKeyring * 
 
 	/* If this is the configured keyring, use it. */
 	if (purple_keyring_inuse == NULL &&
-	    strcmp(keyring_id, purple_keyring_to_use) == 0) {
+	    g_strcmp0(keyring_id, purple_keyring_to_use) == 0) {
 
 		/** @todo add callback to make sure all is ok */
 		purple_keyring_set_inuse(keyring, TRUE, NULL, NULL);
@@ -594,6 +597,7 @@ purple_keyring_register(PurpleKeyring * 
 	core = purple_get_core();
 
 	purple_signal_emit(core, "keyring-register", keyring_id, keyring);
+	purple_debug_info("keyring", "registered keyring : %s.\n", keyring_id);
 
 	purple_keyring_keyrings = g_list_prepend(purple_keyring_keyrings,
 		keyring);
@@ -646,6 +650,8 @@ purple_keyring_import_password(PurpleAcc
 	PurpleKeyringImportPassword import;
 	const char * realid;
 
+	purple_debug_info("keyring", "importing password.\n");
+
 	inuse = purple_keyring_get_inuse();
 
 	if (inuse == NULL) {
@@ -661,8 +667,8 @@ purple_keyring_import_password(PurpleAcc
 	 *  - there is a keyringid specified and it matches the one configured
 	 *  - or the configured keyring is the fallback, compatible one.
 	 */
-	if ((keyringid != NULL && strcmp(realid, keyringid) != 0) ||
-	    strcmp(FALLBACK_KEYRING, realid)) {
+	if ((keyringid != NULL && g_strcmp0(realid, keyringid) != 0) ||
+	    g_strcmp0(FALLBACK_KEYRING, realid)) {
 		*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.");
@@ -691,6 +697,8 @@ purple_keyring_export_password(PurpleAcc
 	const PurpleKeyring * inuse;
 	PurpleKeyringExportPassword export;
 
+	purple_debug_info("keyring", "exporting password.\n");
+
 	inuse = purple_keyring_get_inuse();
 
 	if (inuse == NULL) {
============================================================
--- libpurple/keyring.h	5694f865120f4fe940171f4a052b72f6068fe679
+++ libpurple/keyring.h	46bd6836ecc1f9d53d4d505e3314f3577f86a602
@@ -34,6 +34,11 @@
 #include <glib.h>
 #include "account.h"
 
+/**
+ * Default keyring
+ */
+#define FALLBACK_KEYRING	"core-scrouaf-internalkeyring"
+
 /*******************************************************/
 /** @name data structures and types                    */
 /*******************************************************/
============================================================
--- libpurple/plugin.c	0b134dff56c99a2adb9b01b35ad136a87f5f6875
+++ libpurple/plugin.c	cf2ee324978db141392e5b749edadd703404cc0d
@@ -489,6 +489,12 @@ purple_plugin_probe(const char *filename
 		}
 	}
 
+	if (plugin->info->flags & PURPLE_PLUGIN_FLAG_AUTOLOAD) {
+		purple_debug_info("plugins", "Loading autoload plugin %s\n",
+						plugin->path);
+		purple_plugin_load(plugin);															//
+	}
+
 	return plugin;
 #else
 	return NULL;
@@ -1406,7 +1412,7 @@ purple_plugins_probe(const char *ext)
 			}
 
 			protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin,
-													(GCompareFunc)compare_prpl);
+								(GCompareFunc)compare_prpl);
 		}
 	}
 
============================================================
--- libpurple/plugins/Makefile.am	dc58e171907ab95f07bf3f76039d6e2f5be57b14
+++ libpurple/plugins/Makefile.am	673854bbe73470144a8d7e61c18c62c230e74ab5
@@ -88,7 +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
+internalkeyring_la_SOURCES  = internalkeyring.c
 
 autoaccept_la_LIBADD        = $(GLIB_LIBS)
 buddynote_la_LIBADD         = $(GLIB_LIBS)


More information about the Commits mailing list