Thu, 07 Aug 2008 20:16:45 +0000
dded import/export in account.c, new version of internalkeyring.c, and added stuff to makefiles.
--- a/libpurple/Makefile.am Tue Aug 05 16:54:24 2008 +0000 +++ b/libpurple/Makefile.am Thu Aug 07 20:16:45 2008 +0000 @@ -50,6 +50,7 @@ ft.c \ idle.c \ imgstore.c \ + keyring.c \ log.c \ mime.c \ nat-pmp.c \ @@ -103,6 +104,7 @@ gaim-compat.h \ idle.h \ imgstore.h \ + keyring.h \ log.h \ mime.h \ nat-pmp.h \
--- a/libpurple/account.c Tue Aug 05 16:54:24 2008 +0000 +++ b/libpurple/account.c Thu Aug 07 20:16:45 2008 +0000 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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_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,8 +1532,14 @@ { 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 @@ 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 *
--- a/libpurple/keyring.c Tue Aug 05 16:54:24 2008 +0000 +++ b/libpurple/keyring.c Thu Aug 07 20:16:45 2008 +0000 @@ -28,6 +28,7 @@ */ #include <glib.h> +#include <string.h>> #include "account.h" #include "keyring.h" #include "signals.h" @@ -336,11 +337,9 @@ 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 @@ gboolean force; }; -void +static void purple_keyring_set_inuse_check_error_cb(const PurpleAccount * account, GError * error, gpointer data) @@ -379,7 +378,7 @@ 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 @@ 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 @@ } -void +static void purple_keyring_set_inuse_got_pw_cb(const PurpleAccount * account, gchar * password, GError * error, @@ -501,7 +502,9 @@ PurpleKeyringRead read; PurpleKeyringClose close; struct _PurpleKeyringChangeTracker * tracker; - GError * error; + GError * error = NULL; + + oldkeyring = purple_keyring_get_inuse(); read = purple_keyring_get_read_password(oldkeyring); @@ -567,7 +570,7 @@ void -purple_plugin_keyring_register(PurpleKeyring * keyring) +purple_keyring_register(PurpleKeyring * keyring) { const char * keyring_id; PurpleCore * core; @@ -598,7 +601,7 @@ void -purple_plugin_keyring_unregister(PurpleKeyring * keyring) +purple_keyring_unregister(PurpleKeyring * keyring) { PurpleCore * core; const PurpleKeyring * inuse; @@ -632,11 +635,12 @@ /*@{*/ -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 @@ *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 @@ *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 @@ *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 @@ *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 @@ *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 PurpleAccount * account) { PurpleKeyringReadSync read; - PurpleKeyring * keyring; const PurpleKeyring * inuse; if (account == NULL) { @@ -859,7 +857,7 @@ } else { - read = purple_keyring_get_read_sync(keyring); + read = purple_keyring_get_read_sync(inuse); if (read == NULL){ @@ -978,7 +976,7 @@ /***************************************/ /*@{*/ -GQuark purple_keyring_error_domain() +GQuark purple_keyring_error_domain(void) { return g_quark_from_static_string("Libpurple keyring"); }
--- a/libpurple/keyring.h Tue Aug 05 16:54:24 2008 +0000 +++ b/libpurple/keyring.h Thu Aug 07 20:16:45 2008 +0000 @@ -198,9 +198,9 @@ */ typedef gboolean (*PurpleKeyringExportPassword)(PurpleAccount * account, const char ** mode, - const char ** data, + char ** data, GError ** error, - GDestroyNotify ** destroy); + GDestroyNotify * destroy); /*@}*/ @@ -215,25 +215,25 @@ * 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 @@ * @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 @@ * @param keyrint The keyring to unregister. */ void -purple_plugin_keyring_unregister(PurpleKeyring * keyring); +purple_keyring_unregister(PurpleKeyring * keyring); /*@}*/ @@ -284,8 +284,9 @@ * @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 @@ * @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 @@ /***************************************/ /*@{*/ -PurpleKeyring * purple_keyring_new(); +PurpleKeyring * purple_keyring_new(void); void purple_keyring_free(PurpleKeyring * keyring); const char * purple_keyring_get_name(const PurpleKeyring * info);
--- a/libpurple/plugins/Makefile.am Tue Aug 05 16:54:24 2008 +0000 +++ b/libpurple/plugins/Makefile.am Thu Aug 07 20:16:45 2008 +0000 @@ -41,6 +41,7 @@ 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 @@ offlinemsg.la \ psychic.la \ statenotify.la \ - $(DBUS_LTLIB) + $(DBUS_LTLIB) \ + internalkeyring.la noinst_LTLIBRARIES = \ ciphertest.la \ @@ -86,6 +88,7 @@ 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 @@ signals_test_la_LIBADD = $(GLIB_LIBS) simple_la_LIBADD = $(GLIB_LIBS) statenotify_la_LIBADD = $(GLIB_LIBS) +internalkeyring_la_LIBADD = $(GLIB_LIBS) if ENABLE_DBUS
--- a/libpurple/plugins/keyrings/internalkeyring.c Tue Aug 05 16:54:24 2008 +0000 +++ b/libpurple/plugins/keyrings/internalkeyring.c Thu Aug 07 20:16:45 2008 +0000 @@ -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@etu.utc.fr>" -#define INTERNALKEYRING_DESCRIPTION \ - "This keyring plugin offers a password storage backend compatible with the former storage system." -/******************************/ -/** Data Structures */ -/******************************/ - -typedef struct _InternalKeyring_PasswordInfo InternalKeyring_PasswordInfo; - -struct _InternalKeyring_PasswordInfo { - const PurpleAccount * account; - gchar * password; -}; +#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" -/******************************/ -/** Globals */ -/******************************/ +#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) -GList * InternalKeyring_passwordlist = NULL; /* use hashtable ? */ - - -/******************************/ -/** Internal functions */ -/******************************/ +GHashTable * internal_keyring_passwords = NULL; +static PurpleKeyring * keyring_handler = NULL; -/** - * 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) -{ - GList * p; - InternalKeyring_PasswordInfo * i; +/* 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 *); - for (p = InternalKeyring_passwordlist; p != NULL; p = p->next) { - i = (InternalKeyring_PasswordInfo*)(p->data); - if (i->account == account) - return i; - } - return NULL; -} +/***********************************************/ +/* Keyring interface */ +/***********************************************/ +static void +internal_keyring_read(const PurpleAccount * account, + PurpleKeyringReadCallback cb, + gpointer data) +{ + char * password; + GError * error; -/** - * 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) -{ - InternalKeyring_passwordlist = g_list_prepend(InternalKeyring_passwordlist, info); + 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 -InternalKeyring_free_passwordinfo(InternalKeyring_PasswordInfo * info) +internal_keyring_save(const PurpleAccount * account, + gchar * password, + GDestroyNotify destroy, + PurpleKeyringSaveCallback cb, + gpointer data) { - g_free(info->password); - InternalKeyring_passwordlist = g_list_remove(InternalKeyring_passwordlist, info); - g_free(info); - return; -} + gchar * copy; -/** - * 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) -{ - InternalKeyring_free_passwordinfo((InternalKeyring_PasswordInfo*)info); + 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; } -gboolean -InternalKeyring_is_valid_cleartext(const PurpleKeyringPasswordNode * node) +static const char * +internal_keyring_read_sync(const PurpleAccount * account) +{ + return GET_PASSWORD(account); +} + +static void +internal_keyring_save_sync(PurpleAccount * account, + const char * password) { - const char * enc; - const char * mode; - const char * data; - const PurpleAccount * account; + gchar * copy; + + if (password == NULL) { + g_hash_table_remove(internal_keyring_passwords, account); + } else { + copy = g_strdup(password); + SET_PASSWORD(account, copy); + } + return; +} - 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); +static void +internal_keyring_close(GError ** error) +{ + internal_keyring_uninit(); +} - if ((enc == NULL || strcmp(enc, KEYRINGNAME) == 0)&& - (mode == NULL || strcmp(mode, "cleartext") == 0)&& +static gboolean +internal_keyring_import_password(PurpleAccount * account, + char * mode, + char * data, + GError ** error) +{ + gchar * copy; + + 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); - - if ( info == NULL ) { /* no info on account */ - - g_set_error(error, ERR_PIDGINKEYRING, ERR_NOACCOUNT, - "No info for account."); - cb(account, NULL, error, data); - return; + gchar * password; - } 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; - - } else { - - ret = info->password; - cb(account, ret, error, data); - } -} - -/* - * 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); + password = GET_PASSWORD(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) -{ - InternalKeyring_PasswordInfo * pwinfo; - const char * data; - - if (InternalKeyring_is_valid_cleartext(nodeinfo)) { - - pwinfo = g_malloc0(sizeof(InternalKeyring_PasswordInfo)); - InternalKeyring_add_passwordinfo(pwinfo); - - 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; - + return FALSE; } else { - /* invalid input */ - //return FALSE; - } -} - - -/** - * 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) -{ - PurpleKeyringPasswordNode * nodeinfo; - InternalKeyring_PasswordInfo * pwinfo; - - 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; + *mode = "cleartext"; + *data = g_strdup(password); + *destroy = g_free; + return TRUE; } } -/******************************/ -/** Keyring plugin stuff */ -/******************************/ -PurpleKeyring InternalKeyring_KeyringInfo = +void +internal_keyring_init() { - "internalkeyring", - InternalKeyring_read, - InternalKeyring_save, - InternalKeyring_close, - InternalKeyring_free, - NULL, /* change_master */ - InternalKeyring_import_password, - InternalKeyring_export_password, - NULL, /* RESERVED */ - NULL, /* RESERVED */ - NULL /* RESERVED */ -}; + 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); +} + +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 */ -/******************************/ +/***********************************************/ +/* Plugin interface */ +/***********************************************/ -gboolean -InternalKeyring_load(PurplePlugin *plugin) +static gboolean +internal_keyring_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 @@ 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 @@ NULL, }; -