soc.2008.masterpassword: 29b6363e: added files that were'nt in workspace
scrouaf at soc.pidgin.im
scrouaf at soc.pidgin.im
Tue Jul 8 20:10:49 EDT 2008
-----------------------------------------------------------------
Revision: 29b6363ef076e86fb20ee700a03072441c045bf3
Ancestor: 7588a8902996e334430c61a2ff51e0c12c610d10
Author: scrouaf at soc.pidgin.im
Date: 2008-07-09T00:08:41
Branch: im.pidgin.soc.2008.masterpassword
URL: http://d.pidgin.im/viewmtn/revision/info/29b6363ef076e86fb20ee700a03072441c045bf3
Added files:
libpurple/keyring.c
libpurple/plugins/keyrings/internalkeyring.c
Added directories:
libpurple/plugins/keyrings
ChangeLog:
added files that were'nt in workspace
-------------- next part --------------
============================================================
--- libpurple/keyring.c c0b60d5d05db166a3213b538f544d74304a0bdfd
+++ libpurple/keyring.c c0b60d5d05db166a3213b538f544d74304a0bdfd
@@ -0,0 +1,488 @@
+/**
+ * @file keyring.c Keyring plugin API
+ */
+
+/* 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
+ */
+
+
+/**
+ * Most functions in this files are :
+ * - wrappers that will call the plugin
+ * - keyring managment stuff
+ * - accessors
+ *
+ * TODO :
+ * - use accessors
+ * - compare header with this file
+ * - purple_keyring_init()
+ * - purple_keyring_set_inuse()
+ *
+ * Questions :
+ * - use accessors internally
+ * - cleanup
+ * - public/opaque struct
+ * - wrapper for g_list_foreach ?
+ */
+
+#include <glib.h>
+#include "keyring.h"
+#include "account.h"
+
+/*******************************/
+/* opaque structures */
+/*******************************/
+
+/* information about a keyring */
+// FIXME : This should actually probably a public structure
+struct _PurpleKeyring
+{
+ char * name;
+ PurpleKeyringRead read_password;
+ PurpleKeyringSave save_password;
+ PurpleKeyringClose close_keyring;
+ PurpleKeyringFree free_password;
+ PurpleKeyringChangeMaster change_master;
+ PurpleKeyringImportPassword import_password;
+ PurpleKeyringExportPassword export_password;
+ gpointer r1; /* RESERVED */
+ gpointer r2; /* RESERVED */
+ gpointer r3; /* RESERVED */
+};
+
+
+/* used to import and export password info */
+struct _PurpleKeyringPasswordNode
+{
+ PurpleAccount * account;
+ char * encryption;
+ char * mode;
+ char * data;
+};
+
+
+/*******************************/
+/* globals */
+/*******************************/
+
+GList * purple_keyring_keyringlist = NULL; /* list of available keyrings */
+PurpleKeyring * purple_keyring_inuse = NULL; /* keyring being used */
+
+
+/*******************************/
+/* functions */
+/*******************************/
+
+/* manipulate keyring list, used by config interface */
+
+const GList *
+purple_keyring_get_keyringlist(void)
+/* XXX add some more abstraction so we can change from GList to anything ? */
+{
+ return purple_keyring_keyringlist;
+}
+
+const PurpleKeyring *
+purple_keyring_get_inuse(void)
+{
+ return purple_keyring_inuse;
+}
+
+
+/* change keyring to use */
+struct keyringchangeloop
+{
+ /*FIXME : type*/ cb;
+ gpointer data;
+ PurpleKeyring * new;
+ PurpleKeyring * old;
+ GList * cur; // the account we're playing with
+ char * pass;
+ GError * error;
+};
+
+void
+purple_keyring_set_inuse_loop_read(struct keyringchangeloop * info)
+{
+ GList * cur;
+ PurpleAccount * account;
+
+ cur = info->cur;
+
+ if (cur == NULL) {
+
+ /* we are done, trigger callback */
+ cur->cb(cur->error,cur->data);
+
+ } else {
+
+ account = cur->data;
+
+ info->pass
+ /* FIXME :
+ -read with callback purple_keyring_set_inuse_loop_save()
+ */
+ }
+}
+
+
+
+/* FIXME : needs to be async !!! */
+void
+purple_keyring_set_inuse(PurpleKeyring * new,
+ GError ** error,
+ /*FIXME : type*/ cb,
+ gpointer data);
+{
+
+ GList * cur;
+ PurpleKeyring * old;
+ char * password;
+
+
+ if (purple_keyring_inuse != NULL) {
+
+ /* XXX use a wrapper for g_list_foreach ? */
+ /* PSEUDOCODE (FIXME):
+ for all accounts
+ read password from old safe
+ store it in new safe
+ close old safe
+ */
+ old = purple_keyring_get_inuse();
+
+ for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next)
+ {
+// FIXME MOAR HERE password = old->read(cur)
+ }
+
+ old->close();
+ }
+
+ purple_keyring_inuse = keyring;
+ return;
+
+}
+
+/* register a keyring plugin */
+/**
+ * TODO : function to unregister a keyring ?
+ * validate input ? add magix field ?
+ */
+void
+purple_plugin_keyring_register(PurpleKeyring * info)
+{
+ purple_keyring_keyringlist = g_list_prepend(purple_keyring_keyringlist,
+ info);
+}
+
+
+/**
+ * wrappers to import and export passwords
+ */
+
+
+/**
+ * used by account.c while reading a password from xml
+ * might not really need to be async.
+ * TODO : use PurpleKeyringPasswordNode instead of xmlnode ?
+ */
+gboolean
+purple_keyring_import_password(const PurpleKeyringPasswordNode * passwordnode,
+ GError ** error, // FIXME : re-order arguments in header
+ PurpleKeyringImportCallback cb,
+ gpointer data)
+{
+ if (purple_keyring_inuse == NULL) {
+
+ g_set_error(error, ERR_PIDGINKEYRING, ERR_NOKEYRING,
+ "No Keyring configured.");
+ cb(error, data);
+
+ } else {
+ purple_keyring_inuse->import_password(passwordnode, error, cb, data);
+ }
+ return;
+}
+
+/*
+ * used by account.c while syncing accounts
+ * returned data must be g_free()'d
+ */
+void
+purple_keyring_export_password(PurpleAccount * account,
+ GError ** error, // FIXME : re-order arguments in header
+ PurpleKeyringImportCallback cb,
+ gpointer data)
+{
+ if (purple_keyring_inuse == NULL) {
+
+ g_set_error(error, ERR_PIDGINKEYRING, ERR_NOKEYRING,
+ "No Keyring configured.");
+ cb(NULL, error, data);
+
+ } else {
+ // FIXME : use accessor
+ purple_keyring_inuse->export_password(passwordnode, error, cb, data);
+ }
+ return;
+}
+
+
+/**
+ * functions called from the code to access passwords (account.h):
+ * purple_account_get_password() <- TODO : rewrite these functions :)
+ * purple_account_set_password()
+ * so these functions will call :
+ */
+void
+purple_keyring_get_password(const PurpleAccount *account,
+ GError ** error,
+ PurpleKeyringReadCallback cb,
+ gpointer data)
+{
+ if (purple_keyring_inuse == NULL) {
+
+ g_set_error(error, ERR_PIDGINKEYRING, ERR_NOKEYRING,
+ "No Keyring configured.");
+ cb(account, NULL, error, data);
+
+ } else {
+ purple_keyring_inuse->read(account, error, cb, data);
+ }
+ return;
+}
+
+void
+purple_keyring_set_password(const PurpleAccount * account,
+ gchar * password,
+ GError ** error,
+ PurpleKeyringSaveCallback cb,
+ gpointer data)
+{
+ if (purple_keyring_inuse == NULL) {
+
+ g_set_error(error, ERR_PIDGINKEYRING, ERR_NOKEYRING,
+ "No Keyring configured.");
+ cb(account, error, data);
+
+ } else {
+ purple_keyring_inuse->save(account, password, error, cb, data);
+ }
+ return;
+}
+
+/* accessors for data structure fields */
+ /* PurpleKeyring */
+const char *
+purple_keyring_get_name(PurpleKeyring * info)
+{
+ return info->name;
+}
+
+PurpleKeyringRead
+purple_keyring_get_read_password(const PurpleKeyring * info)
+{
+ return info->read_password;
+}
+
+PurpleKeyringSave
+purple_keyring_get_save_password(const PurpleKeyring * info)
+{
+ return info->save_password;
+}
+
+PurpleKeyringClose
+purple_keyring_get_close_keyring(const PurpleKeyring * info)
+{
+ return info->close_keyring;
+}
+
+PurpleKeyringFree
+purple_keyring_get_free_password(const PurpleKeyring * info)
+{
+ return info->free_password;
+}
+
+PurpleKeyringChangeMaster
+purple_keyring_get_change_master(const PurpleKeyring * info)
+{
+ return info->change_master;
+}
+
+PurpleKeyringImportPassword
+purple_keyring_get_import_password(const PurpleKeyring * info)
+{
+ return info->import_password;
+}
+
+PurpleKeyringExportPassword
+purple_keyring_get_export_password(constPurpleKeyring * info)
+{
+ return info->export_password;
+}
+
+
+void
+purple_keyring_set_name(PurpleKeyring * info,
+ char * name)
+{
+ info->name = name;
+}
+
+void
+purple_keyring_set_read_password(PurpleKeyring * info,
+ PurpleKeyringRead read)
+{
+ info->read_password = read; /* returned data must be g_free()'d */
+}
+
+void
+purple_keyring_set_save_password(PurpleKeyring * info,
+ PurpleKeyringSave save)
+{
+ info->save_password = save;
+}
+
+void
+purple_keyring_set_close_keyring(PurpleKeyring * info,
+ PurpleKeyringClose close)
+{
+ info->close_keyring = close;
+}
+
+void
+purple_keyring_set_free_password(PurpleKeyring * info,
+ PurpleKeyringFree free)
+{
+ info->free_password = free;
+}
+
+void
+purple_keyring_set_change_master(PurpleKeyring * info,
+ PurpleKeyringChangeMaster change_master)
+{
+ info->change_master = change_master;
+}
+
+void
+purple_keyring_set_import_password(PurpleKeyring * info,
+ PurpleKeyringImportPassword import_password)
+{
+ info->import_password = import_password;
+}
+void
+purple_keyring_set_export_password(PurpleKeyring * info,
+ PurpleKeyringExportPassword export_password)
+{
+ info->export_password = export_password;
+}
+
+
+ /* PurpleKeyringPasswordNode */
+
+PurpleKeyringPasswordNode *
+purple_keyring_password_node_new(void)
+{
+ PurpleKeyringPasswordNode * ret;
+
+ ret = g_malloc(sizeof(PurpleKeyringPasswordNode));
+ return ret;
+}
+
+void
+purple_keyring_password_node_free(PurpleKeyringPasswordNode * node)
+{
+ g_free(PurpleKeyringPasswordNode * node);
+ return;
+}
+
+PurpleAccount *
+purple_keyring_password_node_get_account(PurpleKeyringPasswordNode * info)
+{
+ return info->account;
+}
+
+const char *
+purple_keyring_password_node_get_encryption(PurpleKeyringPasswordNode * info)
+{
+ return info->encryption;
+}
+
+const char *
+purple_keyring_password_node_get_mode(PurpleKeyringPasswordNode * info)
+{
+ return info->mode;
+}
+
+const char *
+purple_keyring_password_node_get_data(PurpleKeyringPasswordNode * info);
+{
+ return info->data;
+}
+
+
+void
+purple_keyring_password_node_set_account(PurpleKeyringPasswordNode * info,
+ PurpleAccount * account)
+{
+ info->account = account;
+ return;
+}
+
+void
+purple_keyring_password_node_set_encryption(PurpleKeyringPasswordNode * info,
+ const char * encryption)
+{
+ info->encryption = encryption;
+ return;
+}
+
+void
+purple_keyring_password_node_set_mode(PurpleKeyringPasswordNode * info,
+ const char * mode)
+{
+ info->mode = mode;
+ return;
+}
+
+void
+purple_keyring_password_node_set_data(PurpleKeyringPasswordNode * info,
+ const char * data)
+{
+ info->data = data;
+ return;
+}
+
+
+/**
+ * prepare stuff (called at startup)
+ * TODO : see if we need to cleanup
+ */
+void purple_keyring_init()
+{//FIXME
+ /**
+ * init error GQuark (FIXME change it in headers as well)
+ * read safe to use in confing
+ * make sure said safe is loaded
+ * else fallback
+ */
+}
============================================================
--- libpurple/plugins/keyrings/internalkeyring.c ef57cd56ba4aab0b880c168e52012fffad6cb22b
+++ libpurple/plugins/keyrings/internalkeyring.c ef57cd56ba4aab0b880c168e52012fffad6cb22b
@@ -0,0 +1,323 @@
+/* TODO
+ - fix error reporting
+ - uses accessors for PurpleKeyringPasswordNode
+ - use hashtable instead of Glib
+ - plugin interface
+ - keyring info struct
+*/
+
+#include <glib.h>
+#include <string.h>
+#include "keyring.h"
+#include "account.h"
+
+/******************************/
+/** Macros and constants */
+/******************************/
+
+#define INTERNALKEYRING_VERSION "0.2a"
+#define INTERNALKEYRING_ID "???"
+#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 IS_VALID_CLEARTEXT_INFO(nodeinfo) \
+ (((nodeinfo->encryption == NULL) || (strcpy(nodeinfo->encryption, KEYRINGNAME) == 0)) \
+ && ((nodeinfo->mode == NULL) || (strcpy(nodeinfo->mode, "cleartext") == 0)) \
+ && (nodeinfo->data != NULL) && (nodeinfo->account != NULL))
+
+
+/******************************/
+/** Data Structures */
+/******************************/
+
+typedef stuct _InternalKeyring_PasswordInfo InternalKeyring_PasswordInfo;
+
+struct _InternalKeyring_PasswordInfo {
+ PurpleAccount * account;
+ gchar * password;
+};
+
+/******************************/
+/** Globals */
+/******************************/
+
+GList * InternalKeyring_passwordlist = NULL; /* use hashtable ? */
+
+
+/******************************/
+/** Internal functions */
+/******************************/
+
+/**
+ * retrieve the InternalKeyring_PasswordInfo structure for an account
+ * TODO : rewrite this to use hashtables rather than GList
+ */
+PasswordInfo * InternalKeyring_get_account_info(PurpleAccount * account)
+{
+ GList * p;
+ InternalKeyring_PasswordInfo i;
+
+ for (p = InternalKeyring_passworlist; p != NULL; p = p->next) {
+ i = (PasswordInfo)(p->data)
+ if (i->account == account)
+ return i;
+ }
+ return NULL;
+}
+
+/**
+ * Free or create an InternalKeyring_PasswordInfo structure and all pointed data.
+ * /!\ Update this when adding fields to InternalKeyring_PasswordInfo
+ * TODO : rewrite this to use hashtables rather than GList
+ * (fix InternalKeyring_Close() as well)
+ */
+void
+InternalKeyring_add_passwordinfo(InternalKeyring_PasswordInfo * info)
+{
+ InternalKeyring_passwordlist = g_list_prepend(InternalKeyring_passwordlist, info);
+ return;
+}
+
+void
+InternalKeyring_free_passwordinfo(InternalKeyring_PasswordInfo * info)
+{
+ g_free(info->password);
+ g_list_remove(InternalKeyring_passwordlist, info);
+ g_free(info);
+ return;
+}
+
+
+/******************************/
+/** Keyring interface */
+/******************************/
+
+/**
+ * returns the password if the password is known.
+ */
+void
+InternalKeyring_read(const PurpleAccount * account,
+ GError ** error,
+ PurpleKeyringReadCallback cb,
+ gpointer data)
+{
+ 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;
+
+ } 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, import
+ 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,
+ 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
+ */
+gboolean
+InternalKeyring_import_password(PurpleKeyringPasswordNode * nodeinfo)
+{
+ InternalKeyring_PasswordInfo * pwinfo;
+
+ if (IS_VALID_CLEARTEXT_INFO(nodeinfo) {
+
+ pwinfo = g_malloc0(sizeof(InternalKeyring_PasswordInfo));
+ InternalKeyring_add_passwordinfo(pwinfo);
+
+ pwinfo->password = g_malloc(strlen(nodeinfo->data) + 1);
+ strcpy(pwinfo->password, nodeinfo->data);
+
+ pwinfo->account = nodeinfo->account;
+
+ return TRUE;
+
+ } else {
+ /* invalid input */
+ return FALSE;
+ }
+}
+
+
+/**
+ * Exports password info to a PurpleKeyringPasswordNode structure
+ * (called for each account when accounts are synced)
+ * TODO : add error reporting
+ * use accessors for PurpleKeyringPasswordNode (FIXME)
+ * FIXME : REWRITE AS ASYNC
+ */
+PurpleKeyringPasswordNode *
+InternalKeyring_export_password(PurpleAccount * account)
+{
+ PurpleKeyringPasswordNode * nodeinfo
+ InternalKeyring_PasswordInfo pwinfo;
+
+ nodeinfo = purple_keyring_password_node_new();
+ pwinfo = InternalKeyring_get_account_info(account);
+
+ if (pwinfo->password == NULL)
+ return NULL;
+ else {
+ purple_keyring_password_node_set_encryption(nodeinfo, KEYRINGNAME);
+ purple_keyring_password_node_set_mode(nodeinfo, "cleartext");
+ purple_keyring_password_node_set_data(nodeinfo, password);
+
+ return nodeinfo;
+ }
+}
+
+
+/******************************/
+/** Plugin interface */
+/******************************/
+
+gboolean
+InternalKeyring_load(PurplePlugin *plugin)
+{
+ purple_plugin_keyring_register(InternalKeyring_KeyringInfo);
+ 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)
+{
+ InternalKeyring_Close(NULL);
+ return TRUE;
+}
+
+void
+InternalKeyring_destroy(PurplePlugin *plugin)
+{
+ InternalKeyring_Close(NULL);
+ return;
+}
+
+/******************************/
+/** Generic plugin stuff */
+/******************************/
+
+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-plugin", /* 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 */
+ NULL, /* ui_info */
+ NULL, /* extra_info */
+ NULL, /* prefs_info */
+ NULL, /* actions */
+ NULL, /* padding... */
+ NULL,
+ NULL,
+ NULL,
+};
More information about the Commits
mailing list