--- a/configure.ac +++ b/configure.ac @@ -2222,6 +2222,20 @@ MSN, Yahoo!, Novell Groupwise and Google fi dnl ####################################################################### +dnl # Check for gnome-keyring +dnl #--enable-gnome-keyring=(yes|no) +dnl ####################################################################### +AC_ARG_ENABLE(gnome-keyring, + AC_HELP_STRING([--enable-gnome-keyring], + [use gnome keyring for storing password [default=no]]),, + enable_gnome_keyring=no) +if test "x$enable_gnome_keyring" = "xyes"; then + PKG_CHECK_MODULES(PURPLE_KEYRING, + gnome-keyring-1, + AC_DEFINE(PURPLE_ENABLE_KEYRING, [], [Set if we should use gnome-keyring])) +fi + +dnl ####################################################################### dnl # Check for Tcl dnl ####################################################################### AC_ARG_ENABLE(tcl, [AC_HELP_STRING([--disable-tcl], --- a/libpurple/account.c +++ b/libpurple/account.c @@ -54,6 +54,16 @@ typedef struct #define PURPLE_ACCOUNT_GET_PRIVATE(account) \ ((PurpleAccountPrivate *) (account->priv)) +#ifdef PURPLE_ENABLE_KEYRING +#include + +static char * +purple_account_get_password_from_keyring(const char *_prpl, const char *_user); +static gboolean +purple_account_set_password_in_keyring(const char *_prpl, const char *_user, + const char *password); +#endif + /* TODO: Should use PurpleValue instead of this? What about "ui"? */ typedef struct { @@ -394,8 +404,13 @@ account_to_xmlnode(PurpleAccount *accoun if (purple_account_get_remember_password(account) && ((tmp = purple_account_get_password(account)) != NULL)) { +#ifdef PURPLE_ENABLE_KEYRING + purple_account_set_password_in_keyring(purple_account_get_protocol_id(account), + purple_account_get_username(account), tmp); +#else child = xmlnode_new_child(node, "password"); xmlnode_insert_data(child, tmp, -1); +#endif } else if (_purple_account_is_password_encrypted(account)) { const char *keyring = NULL; const char *mode = NULL; @@ -903,6 +918,7 @@ parse_account(xmlnode *node) char *protocol_id = NULL; char *name = NULL; char *data; + gboolean got_pwd = FALSE; child = xmlnode_get_child(node, "protocol"); if (child != NULL) @@ -927,36 +943,51 @@ parse_account(xmlnode *node) } ret = purple_account_new(name, _purple_oscar_convert(name, protocol_id)); /* XXX: */ +#ifdef PURPLE_ENABLE_KEYRING + + /* Read the password from GNOME Keyring */ + data = purple_account_get_password_from_keyring(protocol_id, name); + if (data) + { + got_pwd = TRUE; + purple_account_set_remember_password(ret, TRUE); + purple_account_set_password(ret, data); + g_free(data); + } +#endif g_free(name); g_free(protocol_id); /* Read the password */ - child = xmlnode_get_child(node, "password"); - if (child != NULL) { - const char *keyring_id = xmlnode_get_attrib(child, "keyring_id"); - const char *mode = xmlnode_get_attrib(child, "mode"); - gboolean is_plaintext; - - data = xmlnode_get_data(child); - - 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); + if (!got_pwd) + { + child = xmlnode_get_child(node, "password"); + if (child != NULL) { + const char *keyring_id = xmlnode_get_attrib(child, "keyring_id"); + const char *mode = xmlnode_get_attrib(child, "mode"); + gboolean is_plaintext; + + data = xmlnode_get_data(child); + + 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); } - g_free(data); } /* Read the alias */ @@ -3375,6 +3406,64 @@ purple_accounts_uninit(void) purple_signals_unregister_by_instance(handle); } +#ifdef PURPLE_ENABLE_KEYRING +static char * +purple_account_get_password_from_keyring(const char *_prpl, const char *_user) +{ + GnomeKeyringNetworkPasswordData *found_item; + GnomeKeyringResult result; + GList *matches; + char *password; + + matches = NULL; + + result = gnome_keyring_find_network_password_sync( + _user, /* user */ + NULL, /* domain */ + "gaim.local", /* server */ + NULL, /* object */ + _prpl, /* protocol */ + NULL, /* authtype */ + 1863, /* port */ + &matches); + + if (result != GNOME_KEYRING_RESULT_OK) + return NULL; + + g_assert(matches != NULL && matches->data != NULL); + + found_item = (GnomeKeyringNetworkPasswordData *) matches->data; + + password = g_strdup(found_item->password); + + gnome_keyring_network_password_list_free(matches); + + return password; +} + +static gboolean +purple_account_set_password_in_keyring(const char *_prpl, const char *_user, + const char *_password) +{ + GnomeKeyringResult result; + guint32 item_id; + + result = gnome_keyring_set_network_password_sync( + NULL, /* default keyring */ + _user, /* user */ + NULL, /* domain */ + "gaim.local", /* server */ + NULL, /* object */ + _prpl, /* protocol */ + NULL, /* authtype */ + 1863, /* port */ + _password, /* password */ + &item_id); + + return (result == GNOME_KEYRING_RESULT_OK); +} +#endif + /* libpurple 3.0.0 compatibility */ static void --- a/libpurple/Makefile.am +++ b/libpurple/Makefile.am @@ -309,6 +309,7 @@ libpurple_la_LIBADD = \ $(GLIB_LIBS) \ $(LIBXML_LIBS) \ $(NETWORKMANAGER_LIBS) \ + $(PURPLE_KEYRING_LIBS) \ $(INTLLIBS) \ $(FARSTREAM_LIBS) \ $(GSTREAMER_LIBS) \ @@ -334,7 +335,8 @@ AM_CPPFLAGS = \ $(GSTAPP_CFLAGS) \ $(GSTINTERFACES_CFLAGS) \ $(IDN_CFLAGS) \ - $(NETWORKMANAGER_CFLAGS) + $(NETWORKMANAGER_CFLAGS) \ + $(PURPLE_KEYRING_CFLAGS) # INSTALL_SSL_CERTIFICATES is true when SSL_CERTIFICATES_DIR is empty. # We want to use SSL_CERTIFICATES_DIR when it's not empty.