/pidgin/main: b68ad4695336: libpurple3 compatibility: don't drop...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Sun Apr 27 11:26:50 EDT 2014
Changeset: b68ad46953360629a484ce5f8444ba48a52f85e3
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-04-27 17:26 +0200
Branch: release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/b68ad4695336
Description:
libpurple3 compatibility: don't drop encrypted passwords
diffstat:
ChangeLog | 3 +
libpurple/account.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 110 insertions(+), 4 deletions(-)
diffs (166 lines):
diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,9 @@ version 2.10.10 (?/?/?):
* Fix a possible leak of unencrypted data when using /me command
with OTR. (Thijs Alkemade) (#15750)
+ libpurple3 compatibility:
+ * Encrypted account passwords are preserved until the new one is set.
+
Windows-Specific Changes:
* Updates to dependencies:
* NSS 3.16 and NSPR 4.10.4
diff --git a/libpurple/account.c b/libpurple/account.c
--- a/libpurple/account.c
+++ b/libpurple/account.c
@@ -44,6 +44,11 @@
typedef struct
{
PurpleConnectionErrorInfo *current_error;
+
+ /* libpurple 3.0.0 compatibility */
+ char *password_keyring;
+ char *password_mode;
+ char *password_ciphertext;
} PurpleAccountPrivate;
#define PURPLE_ACCOUNT_GET_PRIVATE(account) \
@@ -89,6 +94,15 @@ static GList *handles = NULL;
static void set_current_error(PurpleAccount *account,
PurpleConnectionErrorInfo *new_err);
+static void
+_purple_account_set_encrypted_password(PurpleAccount *account, const char *keyring,
+ const char *mode, const char *ciphertext);
+static gboolean
+_purple_account_get_encrypted_password(PurpleAccount *account, const char **keyring,
+ const char **mode, const char **ciphertext);
+static gboolean
+_purple_account_is_password_encrypted(PurpleAccount *account);
+
/*********************************************************************
* Writing to disk *
*********************************************************************/
@@ -381,6 +395,26 @@ account_to_xmlnode(PurpleAccount *accoun
{
child = xmlnode_new_child(node, "password");
xmlnode_insert_data(child, tmp, -1);
+ } else if (_purple_account_is_password_encrypted(account)) {
+ const char *keyring;
+ const char *mode;
+ const char *ciphertext;
+ gboolean success;
+
+ purple_debug_warning("account", "saving libpurple3-compatible "
+ "encrypted password\n");
+
+ success = _purple_account_get_encrypted_password(account,
+ &keyring, &mode, &ciphertext);
+ g_warn_if_fail(success);
+
+ child = xmlnode_new_child(node, "password");
+ if (keyring != NULL)
+ xmlnode_set_attrib(child, "keyring_id", keyring);
+ if (mode != NULL)
+ xmlnode_set_attrib(child, "mode", mode);
+ if (ciphertext != NULL)
+ xmlnode_insert_data(child, ciphertext, -1);
}
if ((tmp = purple_account_get_alias(account)) != NULL)
@@ -880,10 +914,29 @@ parse_account(xmlnode *node)
/* Read the password */
child = xmlnode_get_child(node, "password");
- if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
- {
- purple_account_set_remember_password(ret, TRUE);
- purple_account_set_password(ret, data);
+ if (child != NULL) {
+ const char *keyring_id = xmlnode_get_attrib(child, "keyring_id");
+ const char *mode = xmlnode_get_attrib(child, "mode");
+ data = xmlnode_get_data(child);
+ gboolean is_plaintext;
+
+ if (keyring_id == NULL || keyring_id[0] == '\0')
+ is_plaintext = TRUE;
+ else if (g_strcmp0(keyring_id, "keyring-internal") != 0)
+ is_plaintext = FALSE;
+ else if (mode == NULL || mode[0] == '\0' || g_strcmp0(mode, "cleartext") == 0)
+ is_plaintext = TRUE;
+ else
+ is_plaintext = FALSE;
+
+ if (is_plaintext) {
+ purple_account_set_remember_password(ret, TRUE);
+ purple_account_set_password(ret, data);
+ } else {
+ purple_debug_warning("account", "found encrypted password, "
+ "but it's not supported in 2.x.y\n");
+ _purple_account_set_encrypted_password(ret, keyring_id, mode, data);
+ }
g_free(data);
}
@@ -1116,6 +1169,11 @@ purple_account_destroy(PurpleAccount *ac
g_free(priv->current_error->description);
g_free(priv->current_error);
}
+
+ g_free(priv->password_keyring);
+ g_free(priv->password_mode);
+ g_free(priv->password_ciphertext);
+
g_free(priv);
PURPLE_DBUS_UNREGISTER_POINTER(account);
@@ -3245,3 +3303,48 @@ purple_accounts_uninit(void)
purple_signals_disconnect_by_handle(handle);
purple_signals_unregister_by_instance(handle);
}
+
+/* libpurple 3.0.0 compatibility */
+
+static void
+_purple_account_set_encrypted_password(PurpleAccount *account, const char *keyring,
+ const char *mode, const char *ciphertext)
+{
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ g_free(priv->password_keyring);
+ g_free(priv->password_mode);
+ g_free(priv->password_ciphertext);
+
+ priv->password_keyring = g_strdup(keyring);
+ priv->password_mode = g_strdup(mode);
+ priv->password_ciphertext = g_strdup(ciphertext);
+}
+
+static gboolean
+_purple_account_get_encrypted_password(PurpleAccount *account, const char **keyring,
+ const char **mode, const char **ciphertext)
+{
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ g_return_val_if_fail(keyring != NULL, FALSE);
+ g_return_val_if_fail(mode != NULL, FALSE);
+ g_return_val_if_fail(ciphertext != NULL, FALSE);
+
+ if (!_purple_account_is_password_encrypted(account))
+ return FALSE;
+
+ *keyring = priv->password_keyring;
+ *mode = priv->password_mode;
+ *ciphertext = priv->password_ciphertext;
+
+ return TRUE;
+}
+
+static gboolean
+_purple_account_is_password_encrypted(PurpleAccount *account)
+{
+ PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+ return (priv->password_keyring != NULL);
+}
More information about the Commits
mailing list