soc.2008.masterpassword: f2e58a1f: Cleaned up keyring.h, updating it to the...

scrouaf at soc.pidgin.im scrouaf at soc.pidgin.im
Sat Jul 19 13:50:50 EDT 2008


-----------------------------------------------------------------
Revision: f2e58a1f7d7c8a05a740451de35cb93ae5e4b411
Ancestor: 58a53c30e18e4c80ae9aba8d074c34a3947b9d52
Author: scrouaf at soc.pidgin.im
Date: 2008-07-19T17:42:26
Branch: im.pidgin.soc.2008.masterpassword
URL: http://d.pidgin.im/viewmtn/revision/info/f2e58a1f7d7c8a05a740451de35cb93ae5e4b411

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

ChangeLog: 

Cleaned up keyring.h, updating it to the latest API ideas. Minor changes in other files. Also wrote doxygen documentation for most of the functions in keyring.h.

-------------- next part --------------
============================================================
--- libpurple/keyring.c	b6a848dc1adaf30bb204a3715524e197b26c651a
+++ libpurple/keyring.c	b9e43ecc5ffd9d4aa697dd316db6da98213f9269
@@ -34,7 +34,7 @@
  *  - unregister
  *  - use accessors
  *  - purple_keyring_init()
- *  - purple_keyring_set_inuse() needs to be async for error checking an reversability.
+ *  - purple_keyring_set_inuse() needs to be async for error checking and reversability.
  *
  * Questions :
  *  - cleanup
@@ -253,13 +253,17 @@ void 
  *	 validate input ? add magix field ?
  */
 void 
-purple_plugin_keyring_register(PurpleKeyring * info)
+purple_keyring_register(PurpleKeyring * info)
 {
+	// TODO : emit signal
 	purple_keyring_keyringlist = g_list_prepend(purple_keyring_keyringlist,
 		info);
 }
 
-
+purple_keyring_unregister(PurpleKeyring * info)
+{
+	
+}
 /**
  * wrappers to import and export passwords
  */
@@ -563,7 +567,6 @@ void purple_keyring_init()
 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/keyring.h	9a29acd9a33d03fbeea0577809e7f488fd47e038
+++ libpurple/keyring.h	ba4ac59f91aad78d10cfa5c1aa9340cb8a3b5aa3
@@ -2,7 +2,8 @@
  * @file keyring.h Keyring plugin API
  * @ingroup core
  *
- * @todo
+ * @todo 
+ *  - Offer a way to prompt the user for a password or for a password change.
  */
 
 /* purple
@@ -32,30 +33,32 @@
 #include <glib.h>
 #include "account.h"
 
-/********************************************************
- * DATA STRUCTURES **************************************
- ********************************************************/
-
+/*******************************************************/
+/** @name data structures and types                    */
+/*******************************************************/
+/*@{*/
 typedef struct _PurpleKeyring PurpleKeyring;				/* public (for now) */
-typedef struct _PurpleKeyringPasswordNode PurpleKeyringPasswordNode;	/* opaque struct */
 
-/*
+/*@}*/
+
+/**
  * XXX maybe strip a couple GError* if they're not used,
  * since they should only be interresting for the callback
  *  --> ability to forward errors ?
  *
  */
 
-/*********************************************************/
-/** @name Callbacks for basic keyring operation          */
-/*********************************************************/
+/********************************************************/
+/** @name Callbacks for basic keyring operation         */
+/********************************************************/
+/*@{*/
 
 /**
  * Callback for once a password is read. If there was a problem, the password should
  * be NULL, and the error set.
  *
  * @param account The account of which the password was asked.
- * @param password The password that was read
+ * @param password The password that was read. This should be freed when the callback returns.
  * @param error Error that could have occured. Must be freed if non NULL.
  * @param data Data passed to the callback.
  */
@@ -86,38 +89,99 @@ typedef void (*PurpleKeyringChangeMaster
 						  GError ** error,
 						  gpointer data);
 
+/*@}*/
+
+/********************************************************/
+/** @name pointers to the keyring's functions           */
+/********************************************************/
+/*@{*/
+
 /**
- * Callback for once the master password for a keyring has been changed.
- *
- * @param result Will be TRUE if the password has been changed, false otherwise.
- * @param error Error that has occured. Must be freed if non NULL.
- * @param data Data passed to the callback.
+ * Read the password for an account
+ * @param account The account which's password we want.
+ * @param cb A callback to be used once the password is found.
+ * @param data Data to be passed to the callback.
  */
-typedef void (*PurpleKeyringImportCallback)(GError ** error, gpointer data);	/* XXX add a gboolean result or just use error ? */
-typedef void (*PurpleKeyringExportCallback)(PurpleKeyringPasswordNode * result, GError ** error, gpointer data);
+typedef void (*PurpleKeyringRead)(const PurpleAccount * account,
+				  PurpleKeyringReadCallback cb,
+				  gpointer data);
 
-//gboolean purple_keyring_import_password(const PurpleKeyringPasswordNode * passwordnode);
+/**
+ * Store a password in the keyring.
+ * @param account The account for which the password is to be stored.
+ * @param password The password to be stored. This password will be freed once 
+ * the function returns, so one must take care to make a copy if they call other 
+ * async functions later. If the password is NULL, this means that the keyring
+ * should forget about that password.
+ * @param destroypassword A function that will be called to free the password.
+ * @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,
+				  gchar * password,
+				  GDestroyNotify destroypassword,
+				  PurpleKeyringSaveCallback cb,
+				  gpointer data);
 
+/**
+ * Close the keyring.
+ * This will be called so the keyring can do any cleanup it wants.
+ * @param error An error that may occur.
+ */
+typedef void (*PurpleKeyringClose)(GError ** error);
 
-/* pointers to the keyring's functions */
-// FIXME : only callback should care about errors
-typedef void (*PurpleKeyringRead)(const PurpleAccount * account, GError ** error, PurpleKeyringReadCallback cb, gpointer data);
-typedef void (*PurpleKeyringSave)(const PurpleAccount * account, gchar * password, GError ** error, PurpleKeyringSaveCallback cb, gpointer data);
-typedef void (*PurpleKeyringClose)(GError ** error);
-typedef void (*PurpleKeyringChangeMaster)(GError ** error, PurpleKeyringChangeMasterCallback cb, gpointer data);
-typedef void (*PurpleKeyringFree)(gchar * password, GError ** error);
+/**
+ * Change the master password for the keyring. If NULL, it means the Keyring
+ * has no master password capabilities.
+ * @param error An error that may occur.
+ * @param cb A callback to call once the master password has been changed.
+ * @param data A pointer to pass to the callback.
+ */
+typedef void (*PurpleKeyringChangeMaster)(GError ** error,
+					  PurpleKeyringChangeMasterCallback cb,
+					  gpointer data);
 
-typedef void (*PurpleKeyringImportPassword)(const PurpleKeyringPasswordNode * nodeinfo, GError ** error, PurpleKeyringImportCallback cb, gpointer data);
-typedef void (*PurpleKeyringExportPassword)(const PurpleAccount * account,GError ** error, PurpleKeyringExportCallback cb,     gpointer data);
 
-/* information about a keyring */
+/* */
+/**
+ * Import info on an XML node.
+ * This is not async because it is not meant to prompt for a master password and decrypt passwords.
+ * @param account The account.
+ * @param mode A keyring specific option that was stored. Can be NULL, will be freed when function returns.
+ * @param data Data that was stored, Can be NULL, will be freed when function returns (so copy it if you need it).
+ * @return TRUE on success, FALSE on failure.
+ */
+typedef gboolean (*PurpleKeyringImportPassword)(PurpleAccount * account, 
+					    char * mode,
+					    char * data,
+					    GError ** error);
+
+/**
+ * Export information that will be stored in an XML node.
+ * This is not async because it is not meant to prompt for a master password or encrypt passwords.
+ * @param account The account for which we want the info.
+ * @param mode An option field that can be used by the plugin. This is expected to be a static string.
+ * @param data The data to be stored in the XML node. This string will be freed using destroy() once not needed anymore.
+ * @param error Will be set if a problem occured.
+ * @param destroy A function to be called, if non NULL, to free data.
+ * @return TRUE on success, FALSE on failure.
+ */
+typedef gboolean (*PurpleKeyringExportPassword)(PurpleAccount * account,
+						char ** mode,
+						char ** data,
+						GError ** error,
+						GDestroyNotify ** destroy);
+
+/**
+ * information about a keyring
+ * @todo : move as hidden, so we can have hidden fields.
+ */
 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;
@@ -127,68 +191,198 @@ struct _PurpleKeyring
 };
 
 
+/*@}*/
 
 
 /***************************************/
-/** @name Keyring plugin wrapper API   */
+/** @name Keyring API                  */
 /***************************************/
+/*@{*/
 
-/* manipulate keyring list, used by config interface */
-const GList * purple_keyring_get_keyringlist();
-const PurpleKeyring * purple_keyring_get_inuse();
+/**
+ * Prepare stuff at startup
+ */
+void 
+purple_keyring_init();
 
-// FIXME : needs to be async so it can detect errors and undo changes
+/**
+ * Get the keyring list. Used by the UI.
+ */
+const GList * 
+purple_keyring_get_keyringlist();
+
+/**
+ * Get the keyring being used.
+ */
+const PurpleKeyring * 
+purple_keyring_get_inuse();
+
+/**
+ * Set the keyring to use. This function will move all passwords from
+ * the old keyring to the new one. If it fails, it will cancel all changes,
+ * close the new keyring, and notify the callback. If it succeeds, it will
+ * remove all passwords from the old safe and close that safe.
+ * @param newkeyring The new keyring to use.
+ * @param error Error that may occur.
+ * @param cb The callback to call once the change is done.
+ * @param data A pointer that will be passed to the callback.
+ */
 void
-purple_keyring_set_inuse_got_pw_cb(const PurpleAccount * account, 
-			 gchar * password, 
-			 GError ** error, 
+purple_keyring_set_inuse(const PurpleKeyring * newkeyring,
+			 PurpleKeyringSetInUseCallback cb,
 			 gpointer data);
 
-/* register a keyring plugin */
-// XXX : function to unregister a keyring ?
-void purple_plugin_keyring_register(PurpleKeyring * info);
+/**
+ * Register a keyring plugin.
+ * @param keyrint The keyring to register.
+ */
+void 
+purple_plugin_keyring_register(PurpleKeyring * keyring);
 
-/* used by account.c while reading a password from xml */
-void purple_keyring_import_password(const PurpleKeyringPasswordNode * passwordnode, 
-					GError ** error, 
-					PurpleKeyringImportCallback cb, 
-					gpointer data);
 /**
+ * Unregister a keyring plugin. In case the keyring is in use,
+ * passwords will be moved to a fallback safe, and the keyring
+ * to unregister will be properly closed.
+ * @param keyrint The keyring to unregister.
+ */
+void 
+purple_plugin_keyring_unregister(PurpleKeyring * keyring);
+
+/*@}*/
+
+
+/***************************************/
+/** @name Keyring plugin wrappers      */
+/***************************************/
+/*@{*/
+
+/**
+ * used by account.c while reading a password from xml.
+ * @param account The account.
+ * @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.
+ */
+void purple_keyring_import_password(PurpleAccount * account, 
+				    char * keyringid,
+				    char * mode,
+				    char * data,
+				    GError ** error);
+
+/**
  * used by account.c while syncing accounts
- *  returned data must be g_free()'d
+ * @param account The account for which we want the info.
+ * @param keyringid The plugin id to be stored in the XML node. This will be NULL or a string that can be considered static.
+ * @param mode An option field that can be used by the plugin. This will be NULL or a string that can be considered static.
+ * @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.
  */
-void purple_keyring_export_password(PurpleAccount * account,
-				    GError ** error,
-				    PurpleKeyringExportCallback cb,
-				    gpointer data);
+void 
+purple_keyring_export_password(PurpleAccount * account,
+			       char ** keyringid,
+			       char ** mode,
+			       char ** data,
+			       GError ** error,
+			       GDestroyNotify ** destroy);
 
 
-/* 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);
-void purple_keyring_set_password(const PurpleAccount * account, 
-				 gchar * password, 
-				 GError ** error, 
-				 PurpleKeyringSaveCallback cb,
-				 gpointer data);
 
-/* accessors for data structure fields */
-	/* PurpleKeyring */
-/*
- * TODO : constructor/destructor
- *	  move it back as public. It would actually make much more sense
- * 	  since devs could build static structure
+/** 
+ * functions called from the code to access passwords (account.h):
+ *	purple_account_get_password()
+ *	purple_account_set_password()
+ * @todo :
+ *	- rewrite these functions to use the sync functions for compatibility,
+ *	- build an async way to access the async functions, and patch all libpurple 
+ *	code that calls the accessors to use new ones.
  */
+
+/**
+ * Read a password from the active safe.
+ * This should be renamed purple_keyring_get_password() when getting
+ * to 3.0, while dropping purple_keyring_get_password_sync().
+ * @param account The account for which we want the password.
+ * @param cb The callback to be called.
+ * @param data A pointer passed to the callback.
+ */
+void 
+purple_keyring_get_password_async(const PurpleAccount * account,
+				  PurpleKeyringReadCallback cb,
+				  gpointer data);
+
+/**
+ * Set a password to be remembered.
+ * This should be renamed purple_keyring_set_password() when getting
+ * to 3.0, while dropping purple_keyring_set_password_sync().keyring
+ * @param account The account for which the password is to be saved.
+ * @param password The password to save.
+ * @param destroypassword A function called to free the password. Can be NULL.
+ * @param cb A callback for once the password is saved.
+ * @param data A pointer to be passed to the callback.
+ */
+void 
+purple_keyring_set_password_async(const PurpleAccount * account, 
+				  gchar * password,
+				  GDestroyNotify destroypassword,
+				  PurpleKeyringSaveCallback cb,
+				  gpointer data);
+
+/**
+ * Read a password in a synchronous way.
+ * This is here only for compatibility reasons. Keyrings are not
+ * expected to support this (and shouldn't), and new code should
+ * use purple_keyring_get_password_async() instead.
+ * @param account The account for which we want the password.
+ * @return A pointer to the the password.
+ */
+char * 
+purple_keyring_get_password_sync(const PurpleAccount * account);
+
+/**
+ * Save a password in a synchronous way.
+ * This is here only for compatibility reasons. Keyrings are not
+ * expected to support this (and shouldn't), and new code should
+ * use purple_keyring_set_password_async() instead.
+ * @param account The account for which we want the password.
+ * @param password The password to save.
+ */
+void 
+purple_keyring_set_password_sync(PurpleAccount * account,
+				 const char *password);
+
+/**
+ * Close a safe.
+ * @param keyring The safe to close.
+ * @param error Error that might occur.
+ */
+void
+purple_keyring_close(PurpleKeyring * keyring,
+		     GError ** error);
+
+/**
+ * Change the master password for a safe (if the safe supports it).
+ * @param cb A callback to notify once we're done.
+ * @param data A pointer to be passed to the callback.
+ */
+void 
+purple_keyring_change_master(PurpleKeyringChangeMasterCallback cb,
+			     gpointer data);
+
+/*@}*/
+
+/***************************************/
+/** @name PurpleKeyring Accessors      */
+/***************************************/
+/*@{*/
+
+PurpleKeyring * purple_keyring_new();
+void purple_keyring_free(PurpleKeyring * keyring);
+
 const char * purple_keyring_get_name(const PurpleKeyring * info);
 PurpleKeyringRead purple_keyring_get_read_password(const PurpleKeyring * info);
 PurpleKeyringSave purple_keyring_get_save_password(const PurpleKeyring * info);
 PurpleKeyringClose purple_keyring_get_close_keyring(const PurpleKeyring * info);
-PurpleKeyringFree purple_keyring_get_free_password(const PurpleKeyring * info);
 PurpleKeyringChangeMaster purple_keyring_get_change_master(const PurpleKeyring * info);
 PurpleKeyringImportPassword purple_keyring_get_import_password(const PurpleKeyring * info);
 PurpleKeyringExportPassword purple_keyring_get_export_password(const PurpleKeyring * info);
@@ -197,34 +391,16 @@ void purple_keyring_set_close_keyring(Pu
 void purple_keyring_set_read_password(PurpleKeyring * info, PurpleKeyringRead read);
 void purple_keyring_set_save_password(PurpleKeyring * info, PurpleKeyringSave save);
 void purple_keyring_set_close_keyring(PurpleKeyring * info, PurpleKeyringClose close);
-void purple_keyring_set_free_password(PurpleKeyring * info, PurpleKeyringFree free);
 void purple_keyring_set_change_master(PurpleKeyring * info, PurpleKeyringChangeMaster change_master);
 void purple_keyring_set_import_password(PurpleKeyring * info, PurpleKeyringImportPassword import_password);
 void purple_keyring_set_export_password(PurpleKeyring * info, PurpleKeyringExportPassword export_password);
 
-	/* PurpleKeyringPasswordNode */
+/*@}*/
 
-PurpleKeyringPasswordNode * purple_keyring_password_node_new();
-void purple_keyring_password_node_delete(PurpleKeyringPasswordNode * node);
-
-const PurpleAccount * 
-purple_keyring_password_node_get_account(const PurpleKeyringPasswordNode * info);
-
-const char * purple_keyring_password_node_get_encryption(const PurpleKeyringPasswordNode * info);		/* info to be kept must be copied */
-const char * purple_keyring_password_node_get_mode(const PurpleKeyringPasswordNode * info);			/* strings will be freed after use*/
-const char * purple_keyring_password_node_get_data(const PurpleKeyringPasswordNode * info);			/* (in most cases) */
-
-void purple_keyring_password_node_set_account(PurpleKeyringPasswordNode * info, PurpleAccount * account);
-void purple_keyring_password_node_set_encryption(PurpleKeyringPasswordNode * info, const char * encryption);
-void purple_keyring_password_node_set_mode(PurpleKeyringPasswordNode * info, const char * mode);
-void purple_keyring_password_node_set_data(PurpleKeyringPasswordNode * info, const char * data);
-
-/* prepare some stuff at startup */
-void purple_keyring_init();
-
 /***************************************/
 /** @name Error Codes                  */
 /***************************************/
+/*@{*/
 
 /**
  * Error domain GQuark. 
@@ -243,8 +419,9 @@ enum PurpleKeyringError
 	ERR_WRONGPASS,		/**< user submitted wrong password when prompted. */
 	ERR_WRONGFORMAT,	/**< data passed is not in suitable format. */
 	ERR_NOKEYRING,		/**< no keyring configured. */
-	ERR_NOCHANNEL
+	ERR_NOCHANNEL,		/**< failed to communicate with the backend */
+	ERR_UNKNOWN		/**< unknown error */
 };
 
-
+/*}@*/
 #endif /* _PURPLE_KEYRING_H_ */
============================================================
--- libpurple/plugins/keyrings/internalkeyring.c	4df58eb1a06f0e9ff3d91edb0b5695e053666763
+++ libpurple/plugins/keyrings/internalkeyring.c	fe3f1560ce21ea6b9a3a1689ff1ba087ed612ddb
@@ -49,7 +49,7 @@ GList * InternalKeyring_passwordlist = N
  * retrieve the InternalKeyring_PasswordInfo structure for an account
  * TODO : rewrite this to use hashtables rather than GList
  */
-InternalKeyring_PasswordInfo * 
+static InternalKeyring_PasswordInfo * 
 InternalKeyring_get_account_info(const PurpleAccount * account)
 {
 	GList * p;
@@ -69,14 +69,14 @@ InternalKeyring_get_account_info(const P
  * XXX : rewrite this to use hashtables rather than GList
  *        (fix InternalKeyring_Close() as well)
  */
-void
+static void
 InternalKeyring_add_passwordinfo(InternalKeyring_PasswordInfo * info)
 {
 	InternalKeyring_passwordlist = g_list_prepend(InternalKeyring_passwordlist, info);
 	return;
 }
 
-void
+static void
 InternalKeyring_free_passwordinfo(InternalKeyring_PasswordInfo * info)
 {
 	g_free(info->password);
@@ -89,7 +89,7 @@ InternalKeyring_free_passwordinfo(Intern
  * wrapper so we can use it in close
  * TODO : find a more elegant way
  */
-void
+static void
 InternalKeyring_free_passwordinfo_from_g_list(gpointer info, gpointer data)
 {
 	InternalKeyring_free_passwordinfo((InternalKeyring_PasswordInfo*)info);
@@ -110,10 +110,10 @@ InternalKeyring_is_valid_cleartext(const
 	data = purple_keyring_password_node_get_data(node);
 	account = purple_keyring_password_node_get_account(node);
 
-	if (((enc == NULL) || (strcmp(enc, KEYRINGNAME) == 0))
-	  &&((mode == NULL) || (strcmp(mode, "cleartext") == 0))
-	  &&(data != NULL)
-	  &&(account != NULL)) {
+	if ((enc == NULL || strcmp(enc, KEYRINGNAME) == 0)&&
+	    (mode == NULL || strcmp(mode, "cleartext") == 0)&&
+	    data != NULL &&
+	    account != NULL) {
 
 		return TRUE;
 
@@ -306,14 +306,35 @@ InternalKeyring_export_password(const Pu
 }
 
 
+
 /******************************/
+/** Keyring plugin stuff      */
+/******************************/
+
+PurpleKeyring InternalKeyring_KeyringInfo =
+{
+	"internalkeyring",
+	InternalKeyring_read,
+	InternalKeyring_save,
+	InternalKeyring_close,
+	InternalKeyring_free,
+	NULL,				/* change_master */
+	InternalKeyring_import_password,
+	InternalKeyring_export_password,
+	NULL,				/* RESERVED */
+	NULL,				/* RESERVED */
+	NULL				/* RESERVED */
+};
+
+
+/******************************/
 /** Plugin interface          */
 /******************************/
 
 gboolean 
 InternalKeyring_load(PurplePlugin *plugin)
 {
-//	purple_plugin_keyring_register(InternalKeyring_KeyringInfo);	/* FIXME : structure doesn't exist yet */
+	purple_plugin_keyring_register(&InternalKeyring_KeyringInfo);	/* FIXME : structure should be hidden */
 	return TRUE;
 }
 
@@ -335,27 +356,7 @@ InternalKeyring_destroy(PurplePlugin *pl
 	return;
 }
 
-/******************************/
-/** Generic plugin stuff      */
-/******************************/
 
-PurpleKeyring InternalKeyring_KeyringInfo =
-{
-	"internalkeyring",
-	InternalKeyring_read,
-	InternalKeyring_save,
-	InternalKeyring_close,
-	InternalKeyring_free,
-	NULL,				/* change_master */
-	InternalKeyring_import_password,
-	InternalKeyring_export_password,
-	NULL,				/* RESERVED */
-	NULL,				/* RESERVED */
-	NULL				/* RESERVED */
-};
-
-
-
 PurplePluginInfo plugininfo =
 {
 	PURPLE_PLUGIN_MAGIC,						/* magic */
@@ -385,3 +386,5 @@ PurplePluginInfo plugininfo =
 	NULL,
 	NULL,
 };
+
+


More information about the Commits mailing list