soc.2008.masterpassword: 416bb144: Added the gnome keyring plugin, and fina...

scrouaf at soc.pidgin.im scrouaf at soc.pidgin.im
Mon Aug 11 00:12:40 EDT 2008


-----------------------------------------------------------------
Revision: 416bb144ae1d3030a1839755ff48c285164a30f3
Ancestor: e5468291c93e8b3eaabc5045630392afc3e6bc51
Author: scrouaf at soc.pidgin.im
Date: 2008-08-11T04:03:53
Branch: im.pidgin.soc.2008.masterpassword
URL: http://d.pidgin.im/viewmtn/revision/info/416bb144ae1d3030a1839755ff48c285164a30f3

Added files:
        libpurple/plugins/keyrings/Makefile.am
        libpurple/plugins/keyrings/gnomekeyring.c
        libpurple/plugins/keyrings/internalkeyring.c
Modified files:
        configure.ac libpurple/keyring.h
        libpurple/plugins/Makefile.am

ChangeLog: 

Added the gnome keyring plugin, and finally got makefiles to work.

-------------- next part --------------
============================================================
--- libpurple/plugins/keyrings/Makefile.am	dcd3320d138b0cbb58e2b1404a526afc08cd884f
+++ libpurple/plugins/keyrings/Makefile.am	dcd3320d138b0cbb58e2b1404a526afc08cd884f
@@ -0,0 +1,40 @@
+EXTRA_DIST = \
+		Makefile.mingw
+
+plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+
+gnomekeyring_la_LDFLAGS     = -module -avoid-version
+internalkeyring_la_LDFLAGS  = -module -avoid-version
+
+GNOME_KEYRING_CFLAGS = -I/usr/include/gnome-keyring-1
+
+GKRSOURCES = gnomekeyring.c
+IKSOURCES = internalkeyring.c
+
+if PLUGINS
+
+plugin_LTLIBRARIES = \
+	gnomekeyring.la       \
+	internalkeyring.la
+
+gnomekeyring_la_SOURCES     = gnomekeyring.c
+internalkeyring_la_SOURCES  = internalkeyring.c
+
+gnomekeyring_la_LIBADD  = $(GLIB_LIBS) $(GNOME_KEYRING_LIBS)
+internalkeyring_la_LIBADD   = $(GLIB_LIBS)
+
+endif #PLUGINS
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/libpurple \
+	-I$(top_builddir)/libpurple \
+	$(GLIB_CFLAGS) \
+	$(DEBUG_CFLAGS) \
+	$(PLUGIN_CFLAGS) \
+	$(GNOME_KEYRING_CFLAGS)
+
+gnomekeyring_la_CFLAGS = $(AM_CPPFLAGS) $(GNOME_KEYRING_CFLAGS)
+internalkeyring_la_CFLAGS = $(AM_CPPFLAGS)
+
+
+
============================================================
--- libpurple/plugins/keyrings/gnomekeyring.c	6dc26ae46caa529ce83ca3d66f329a1babdbeb62
+++ libpurple/plugins/keyrings/gnomekeyring.c	6dc26ae46caa529ce83ca3d66f329a1babdbeb62
@@ -0,0 +1,441 @@
+/**
+ * @file gnomekeyring.c Gnome keyring password storage
+ * @ingroup plugins
+ *
+ * @todo 
+ *   cleanup error handling and reporting
+ *   refuse unloading when active (in internal keyring too)
+ */
+
+/* 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>
+#include <gnome-keyring.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 GNOMEKEYRING_NAME		"Gnome-Keyring"
+#define GNOMEKEYRING_VERSION		"0.2"
+#define GNOMEKEYRING_DESCRIPTION	"This plugin provides the default password storage behaviour for libpurple."
+#define	GNOMEKEYRING_AUTHOR		"Scrouaf (scrouaf[at]soc.pidgin.im)"
+#define GNOMEKEYRING_ID		"core-scrouaf-gnomekeyring"
+
+#define ERR_GNOMEKEYRINGPLUGIN 	gkp_error_domain()
+
+static PurpleKeyring * keyring_handler = NULL;
+
+typedef struct _InfoStorage InfoStorage;
+
+struct _InfoStorage
+{
+	gpointer cb;
+	gpointer user_data;
+	PurpleAccount * account;
+};
+
+
+
+
+/* a few prototypes : */
+static GQuark 		gkp_error_domain(void);
+static void 		gkp_read(PurpleAccount *, PurpleKeyringReadCallback, gpointer);
+static void		gkp_read_continue(GnomeKeyringResult, const char *, gpointer);
+static void 		gkp_save(PurpleAccount *, gchar *, GDestroyNotify, PurpleKeyringSaveCallback, gpointer);
+static void		gkp_save_continue(GnomeKeyringResult, gpointer);
+static const char * 	gkp_read_sync(const PurpleAccount *);
+static void 		gkp_save_sync(PurpleAccount *, const gchar *);
+static void		gkp_close(GError **);
+static gboolean		gkp_import_password(PurpleAccount *, char *, char *, GError **);
+static gboolean 	gkp_export_password(PurpleAccount *, const char **, char **, GError **, GDestroyNotify *);
+static gboolean		gkp_init(void);
+static void		gkp_uninit(void);
+static gboolean		gkp_load(PurplePlugin *);
+static gboolean		gkp_unload(PurplePlugin *);
+static void		gkp_destroy(PurplePlugin *);
+
+GQuark gkp_error_domain(void)
+{
+	return g_quark_from_static_string("Gnome-Keyring plugin");
+}
+
+
+/***********************************************/
+/*     Keyring interface                       */
+/***********************************************/
+static void 
+gkp_read(PurpleAccount * account,
+	 PurpleKeyringReadCallback cb,
+	 gpointer data)
+{
+	InfoStorage * storage = g_malloc(sizeof(InfoStorage));
+
+	storage->cb = cb;
+	storage->user_data = data;
+	storage->account = account;
+
+	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_read_continue(GnomeKeyringResult result,
+                       const char *password,
+                       gpointer data)
+/* XXX : make sure list is freed on return */
+{
+	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(ERR_GNOMEKEYRINGPLUGIN, 
+					ERR_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(ERR_GNOMEKEYRINGPLUGIN, 
+					ERR_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(ERR_GNOMEKEYRINGPLUGIN, 
+					ERR_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);
+		return;
+
+	}
+
+}
+
+
+static void
+gkp_save(PurpleAccount * account,
+	 gchar * password,
+	 GDestroyNotify destroy,
+	 PurpleKeyringSaveCallback cb,
+	 gpointer data)
+{
+	InfoStorage * storage = g_malloc(sizeof(InfoStorage));
+
+	storage->account = account;
+	storage->cb = cb;
+	storage->user_data = data;
+
+	if(password != NULL) {
+		gnome_keyring_store_password(GNOME_KEYRING_NETWORK_PASSWORD,
+					     NULL, 	/*default keyring */
+					     g_strdup_printf("pidgin-%s", purple_account_get_username(account)),
+					     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);
+	
+		if (destroy)
+			destroy(password);
+
+	} else {	/* password == NULL, delete password. */
+
+		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);
+
+	}
+	return;
+}
+
+static void
+gkp_save_continue(GnomeKeyringResult result,
+            gpointer data)
+{
+	InfoStorage * storage = data;
+	PurpleKeyringSaveCallback cb = storage->cb;
+	GError * error;
+	PurpleAccount * account = storage->account;
+
+	if (result != GNOME_KEYRING_RESULT_OK) {
+		switch(result)
+		{
+			case GNOME_KEYRING_RESULT_NO_MATCH :
+				error = g_error_new(ERR_GNOMEKEYRINGPLUGIN, 
+					ERR_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 :
+				error = g_error_new(ERR_GNOMEKEYRINGPLUGIN, 
+					ERR_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 :
+				error = g_error_new(ERR_GNOMEKEYRINGPLUGIN, 
+					ERR_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("gnome-keyring-plugin", "password for %s updated.\n",
+			purple_account_get_username(account));
+
+		if(cb != NULL)
+			cb(account, NULL, storage->user_data);
+		return;
+	
+	}
+}
+
+static const char * 
+gkp_read_sync(const PurpleAccount * account)
+/**
+ * This is tricky, since the calling function will not free the password. 
+ * Since we free the password on the next request, the last request will leak.
+ * But that part of the code shouldn't be used anyway. It might however be an issue
+ * if another call is made and the old pointer still used.
+ * Elegant solution would include a hashtable or a linked list, but would be
+ * complex. Also, this might just be dropped at 1.0 of the plugin
+ */
+{
+	GnomeKeyringResult result;
+	static char * password = NULL;
+
+	gnome_keyring_free_password(password);
+
+	result = gnome_keyring_find_password_sync(GNOME_KEYRING_NETWORK_PASSWORD,
+		&password,
+		"user", purple_account_get_username(account),
+		"protocol", purple_account_get_protocol_id(account),
+		NULL);
+
+	return password;
+}
+
+static void
+gkp_save_sync(PurpleAccount * account,
+	const char * password)
+{
+	char * copy = g_strdup(password);
+	gkp_save(account, copy, NULL, NULL, NULL);
+	g_free(copy);
+}
+
+static void
+gkp_close(GError ** error)
+{
+	gkp_uninit();
+}
+
+static gboolean
+gkp_import_password(PurpleAccount * account, 
+		    char * mode,
+		    char * data,
+		    GError ** error)
+{
+	return TRUE;
+}
+
+static gboolean 
+gkp_export_password(PurpleAccount * account,
+				 const char ** mode,
+				 char ** data,
+				 GError ** error,
+				 GDestroyNotify * destroy)
+{
+	*data = NULL;
+	*mode = NULL;
+	destroy = NULL;
+
+	return TRUE;
+}
+
+
+
+
+static gboolean
+gkp_init()
+{
+	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_sync(keyring_handler, gkp_read_sync);
+		purple_keyring_set_save_sync(keyring_handler, gkp_save_sync);
+		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, NULL);
+		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("gnome-keyring-plugin",
+			"failed to communicate with daemon, not loading.");
+		return FALSE;
+	}
+}
+
+static void
+gkp_uninit()
+{
+	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)
+{
+	gkp_uninit();
+	return TRUE;
+}
+
+static void
+gkp_destroy(PurplePlugin *plugin)
+{
+	gkp_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 */
+	GNOMEKEYRING_ID,						/* id */
+	GNOMEKEYRING_NAME,						/* name */
+	GNOMEKEYRING_VERSION,					/* version */
+	"Internal Keyring Plugin",					/* summary */
+	GNOMEKEYRING_DESCRIPTION,					/* description */
+	GNOMEKEYRING_AUTHOR,						/* author */
+	"N/A",								/* homepage */
+	gkp_load,						/* load */
+	gkp_unload,					/* unload */
+	gkp_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/plugins/keyrings/internalkeyring.c	d6f5ea559eb568dac11ec0b224ad0ba744e5d7d1
+++ libpurple/plugins/keyrings/internalkeyring.c	d6f5ea559eb568dac11ec0b224ad0ba744e5d7d1
@@ -0,0 +1,304 @@
+/**
+ * @file internalkeyring.c internal keyring
+ * @ingroup plugins
+ *
+ * @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 INTERNALKEYRING_NAME		"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		FALLBACK_KEYRING
+
+
+#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, INTERNALKEYRING_NAME);
+	purple_keyring_set_id(keyring_handler, INTERNALKEYRING_ID);
+	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 */
+	INTERNALKEYRING_NAME,						/* 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)
+
============================================================
--- configure.ac	8ef5c285cd8b5e4142deba992afb15fc8c372056
+++ configure.ac	f81ec614e92be4e419ba08b60855618d6ce4b478
@@ -2391,6 +2391,7 @@ AC_OUTPUT([Makefile
 		   libpurple/purple.pc
 		   libpurple/purple-uninstalled.pc
 		   libpurple/plugins/Makefile
+		   libpurple/plugins/keyrings/Makefile
 		   libpurple/plugins/mono/Makefile
 		   libpurple/plugins/mono/api/Makefile
 		   libpurple/plugins/mono/loader/Makefile
============================================================
--- libpurple/keyring.h	7c9a3afbd3f7e05d76cf1cc711f4219cb6234b8e
+++ libpurple/keyring.h	e32f85339ae46262e4b6d77c9a78219a2641ada1
@@ -69,7 +69,7 @@ typedef void (*PurpleKeyringReadCallback
  * @param data Data passed to the callback.
  */
 typedef void (*PurpleKeyringReadCallback)(const PurpleAccount * account,
-					  gchar * password,
+					  const gchar * password,
 					  GError * error,
 					  gpointer data);
 
@@ -121,7 +121,7 @@ typedef void (*PurpleKeyringSetInUseCall
  * @param cb A callback to be used once the password is found.
  * @param data Data to be passed to the callback.
  */
-typedef void (*PurpleKeyringRead)(const PurpleAccount * account,
+typedef void (*PurpleKeyringRead)(PurpleAccount * account,
 				  PurpleKeyringReadCallback cb,
 				  gpointer data);
 
@@ -136,7 +136,7 @@ typedef void (*PurpleKeyringRead)(const 
  * @param cb A callback to be called once the password is saved.
  * @param data A pointer to be passed to the callback
  */
-typedef void (*PurpleKeyringSave)(const PurpleAccount * account,
+typedef void (*PurpleKeyringSave)(PurpleAccount * account,
 				  gchar * password,
 				  GDestroyNotify destroypassword,
 				  PurpleKeyringSaveCallback cb,
============================================================
--- libpurple/plugins/Makefile.am	734c1c75bbd85b817ce930c0e5e187bcb8a805d1
+++ libpurple/plugins/Makefile.am	06ff22f116ec7f3d5975b067ba43dfb15af466dd
@@ -42,7 +42,6 @@ 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
@@ -59,8 +58,7 @@ plugin_LTLIBRARIES = \
 	offlinemsg.la       \
 	psychic.la          \
 	statenotify.la      \
-	$(DBUS_LTLIB)       \
-	internalkeyring.la
+	$(DBUS_LTLIB)
 
 noinst_LTLIBRARIES = \
 	ciphertest.la \
@@ -89,7 +87,6 @@ statenotify_la_SOURCES      = statenotif
 signals_test_la_SOURCES		= signals-test.c
 simple_la_SOURCES			= simple.c
 statenotify_la_SOURCES      = statenotify.c
-internalkeyring_la_SOURCES  = internalkeyring.c
 
 autoaccept_la_LIBADD        = $(GLIB_LIBS)
 buddynote_la_LIBADD         = $(GLIB_LIBS)
@@ -106,7 +103,6 @@ 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
 


More information about the Commits mailing list