/cpw/tomkiewicz/masterpassword: c67266e97d75: Don't drop exporte...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Sat Apr 27 19:18:00 EDT 2013


Changeset: c67266e97d75ad21a221065621a9030c6db3d5ad
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2013-04-28 01:17 +0200
Branch:	 soc.2008.masterpassword
URL: https://hg.pidgin.im/cpw/tomkiewicz/masterpassword/rev/c67266e97d75

Description:

Don't drop exported passwords, when keyring plugin is not loadable

diffstat:

 libpurple/account.c |   2 +-
 libpurple/keyring.c |  86 +++++++++++++++++++++++++++++++++++++++++-----------
 libpurple/keyring.h |  36 +++++++++------------
 3 files changed, 84 insertions(+), 40 deletions(-)

diffs (252 lines):

diff --git a/libpurple/account.c b/libpurple/account.c
--- a/libpurple/account.c
+++ b/libpurple/account.c
@@ -971,7 +971,7 @@ parse_account(xmlnode *node)
 		data = xmlnode_get_data(child);
 		result = purple_keyring_import_password(ret, keyring_id, mode, data, NULL);
 
-		if (result == TRUE) {
+		if (result == TRUE || purple_keyring_get_inuse() == NULL) {
 			purple_account_set_remember_password(ret, TRUE);
 		} else {
 			purple_debug_error("account", "Failed to import password.\n");
diff --git a/libpurple/keyring.c b/libpurple/keyring.c
--- a/libpurple/keyring.c
+++ b/libpurple/keyring.c
@@ -278,6 +278,25 @@ static guint purple_keyring_pref_cb_id;
 static GList *purple_keyring_loaded_plugins = NULL;
 static PurpleKeyringChangeTracker *current_change_tracker = NULL;
 static gboolean purple_keyring_is_quitting = FALSE;
+static GHashTable *purple_keyring_failed_imports = NULL;
+
+typedef struct
+{
+	gchar *keyring_id;
+	gchar *mode;
+	gchar *data;
+} purple_keyring_failed_import;
+
+static void
+purple_keyring_failed_import_free(purple_keyring_failed_import *import)
+{
+	g_return_if_fail(import != NULL);
+
+	g_free(import->keyring_id);
+	g_free(import->mode);
+	g_free(import->data);
+	g_free(import);
+}
 
 static void
 purple_keyring_pref_cb(const char *pref,
@@ -347,6 +366,10 @@ purple_keyring_init(void)
 	purple_keyring_keyrings = NULL;
 	purple_keyring_inuse = NULL;
 
+	purple_keyring_failed_imports = g_hash_table_new_full(g_direct_hash,
+		g_direct_equal, NULL,
+		(GDestroyNotify)purple_keyring_failed_import_free);
+
 	purple_signal_register(purple_keyring_get_handle(),
 		"keyring-register",
 		purple_marshal_VOID__POINTER_POINTER,
@@ -428,6 +451,9 @@ purple_keyring_uninit(void)
 	purple_signals_disconnect_by_handle(purple_keyring_get_handle());
 	purple_prefs_disconnect_callback(purple_keyring_pref_cb_id);
 	purple_keyring_pref_cb_id = 0;
+
+	g_hash_table_destroy(purple_keyring_failed_imports);
+	purple_keyring_failed_imports = NULL;
 }
 
 void *
@@ -860,14 +886,14 @@ purple_keyring_unregister(PurpleKeyring 
 /*@}*/
 
 
-/***************************************/
-/** @name Keyring plugin wrappers      */
-/***************************************/
+/**************************************************************************/
+/** @name Keyring plugin wrappers                                         */
+/**************************************************************************/
 /*@{*/
 
 gboolean
 purple_keyring_import_password(PurpleAccount *account,
-                               const char *keyringid,
+                               const char *keyring_id,
                                const char *mode,
                                const char *data,
                                GError **error)
@@ -879,31 +905,38 @@ purple_keyring_import_password(PurpleAcc
 	purple_debug_misc("keyring", "Importing password for account %s (%s) to keyring %s.\n",
 		purple_account_get_username(account),
 		purple_account_get_protocol_id(account),
-		keyringid);
+		keyring_id);
 
 	inuse = purple_keyring_get_inuse();
 
 	if (inuse == NULL) {
+		purple_keyring_failed_import *import;
 		if (error != NULL) {
 			*error = g_error_new(PURPLE_KEYRING_ERROR,
 				PURPLE_KEYRING_ERROR_NOKEYRING,
 				"No keyring configured, cannot import password "
 				"info");
 		}
-		purple_debug_error("Keyring",
+		purple_debug_warning("Keyring",
 			"No keyring configured, cannot import password info for account %s (%s).\n",
 			purple_account_get_username(account), purple_account_get_protocol_id(account));
+
+		import = g_new0(purple_keyring_failed_import, 1);
+		import->keyring_id = g_strdup(keyring_id);
+		import->mode = g_strdup(mode);
+		import->data = g_strdup(data);
+		g_hash_table_insert(purple_keyring_failed_imports, account, import);
 		return FALSE;
 	}
 
 	realid = purple_keyring_get_id(inuse);
 	/*
 	 * we want to be sure that either :
-	 *  - there is a keyringid specified and it matches the one configured
+	 *  - there is a keyring_id specified and it matches the one configured
 	 *  - or the configured keyring is the fallback, compatible one.
 	 */
-	if ((keyringid != NULL && g_strcmp0(realid, keyringid) != 0) ||
-	    (keyringid == NULL && g_strcmp0(PURPLE_DEFAULT_KEYRING, realid))) {
+	if ((keyring_id != NULL && g_strcmp0(realid, keyring_id) != 0) ||
+	    (keyring_id == NULL && g_strcmp0(PURPLE_DEFAULT_KEYRING, realid))) {
 		if (error != NULL) {
 			*error = g_error_new(PURPLE_KEYRING_ERROR,
 				PURPLE_KEYRING_ERROR_INTERNAL,
@@ -912,7 +945,7 @@ purple_keyring_import_password(PurpleAcc
 		}
 		purple_debug_info("keyring",
 			"Specified keyring id does not match the configured one (%s vs. %s). Data will be lost.\n",
-			keyringid, realid);
+			keyring_id, realid);
 		return FALSE;
 	}
 
@@ -931,7 +964,7 @@ purple_keyring_import_password(PurpleAcc
 
 gboolean
 purple_keyring_export_password(PurpleAccount *account,
-                               const char **keyringid,
+                               const char **keyring_id,
                                const char **mode,
                                char **data,
                                GError **error,
@@ -943,24 +976,39 @@ purple_keyring_export_password(PurpleAcc
 	inuse = purple_keyring_get_inuse();
 
 	if (inuse == NULL) {
-		*error = g_error_new(PURPLE_KEYRING_ERROR, PURPLE_KEYRING_ERROR_NOKEYRING,
-			"No keyring configured, cannot export password info");
-		purple_debug_error("keyring",
-			"No keyring configured, cannot export password info.\n");
-		return FALSE;
+		purple_keyring_failed_import *import = g_hash_table_lookup(
+			purple_keyring_failed_imports, account);
+
+		if (import == NULL) {
+			*error = g_error_new(PURPLE_KEYRING_ERROR, PURPLE_KEYRING_ERROR_NOKEYRING,
+				"No keyring configured, cannot export password info");
+			purple_debug_warning("keyring",
+				"No keyring configured, cannot export password info.\n");
+			return FALSE;
+		} else {
+			purple_debug_info("keyring", "No keyring configured, getting fallback export data for %s (%s).\n",
+				purple_account_get_username(account),
+				purple_account_get_protocol_id(account));
+
+			*keyring_id = import->keyring_id;
+			*mode = import->mode;
+			*data = g_strdup(import->data);
+			*destroy = g_free;
+			return TRUE;
+		}
 	}
 
-	*keyringid = purple_keyring_get_id(inuse);
+	*keyring_id = purple_keyring_get_id(inuse);
 
 	if (purple_debug_is_verbose()) {
 		purple_debug_misc("keyring",
 			"Exporting password for account %s (%s) from keyring "
 			"%s...\n",
 			purple_account_get_username(account),
-			purple_account_get_protocol_id(account), *keyringid);
+			purple_account_get_protocol_id(account), *keyring_id);
 	}
 
-	if (*keyringid == NULL) {
+	if (*keyring_id == NULL) {
 		*error = g_error_new(PURPLE_KEYRING_ERROR, PURPLE_KEYRING_ERROR_INTERNAL,
 			"Plugin does not have a keyring id");
 		purple_debug_info("keyring",
diff --git a/libpurple/keyring.h b/libpurple/keyring.h
--- a/libpurple/keyring.h
+++ b/libpurple/keyring.h
@@ -264,17 +264,15 @@ purple_keyring_get_options(void);
  *
  * It's 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.
+ * @param account    The account.
+ * @param keyring_id 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.
- *
- * @todo Get rid of keyringid.
  */
 gboolean
-purple_keyring_import_password(PurpleAccount *account, const gchar *keyringid,
+purple_keyring_import_password(PurpleAccount *account, const gchar *keyring_id,
 	const gchar *mode, const gchar *data, GError **error);
 
 /**
@@ -282,23 +280,21 @@ purple_keyring_import_password(PurpleAcc
  *
  * It's used by account.c while syncing accounts to xml.
  *
- * @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.
+ * @param account    The account for which we want the info.
+ * @param keyring_id 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.
  *
  * @return TRUE if the info was exported successfully, FALSE otherwise.
- *
- * @todo Get rid of keyringid.
  */
 gboolean
-purple_keyring_export_password(PurpleAccount *account, const gchar **keyringid,
+purple_keyring_export_password(PurpleAccount *account, const gchar **keyring_id,
 	const gchar **mode, gchar **data, GError **error,
 	GDestroyNotify *destroy);
 



More information about the Commits mailing list