gnucash maint: Multiple changes pushed
Geert Janssens
gjanssens at code.gnucash.org
Fri May 8 15:45:40 EDT 2015
Updated via https://github.com/Gnucash/gnucash/commit/5a4a8ac5 (commit)
via https://github.com/Gnucash/gnucash/commit/f604348d (commit)
from https://github.com/Gnucash/gnucash/commit/61021c46 (commit)
commit 5a4a8ac5d6e038e8ce87a398e43b43998194e667
Author: Geert Janssens <janssens-geert at telenet.be>
Date: Fri May 8 21:43:40 2015 +0200
Bug 746873 - Gnucash asks sql passwords before wallet password
Work around a bug in libsecret. Under certain conditions
libsecret will silently fail to find a password even though
it is stored. The workaround uses another interface call
to force unlocking the secret store which works around the bug.
This workaround should be removed once a fix for
https://bugzilla.gnome.org/show_bug.cgi?id=748625
will be commonly available.
diff --git a/src/gnome-utils/gnc-keyring.c b/src/gnome-utils/gnc-keyring.c
index d6eaa23..5c91e06 100644
--- a/src/gnome-utils/gnc-keyring.c
+++ b/src/gnome-utils/gnc-keyring.c
@@ -180,6 +180,24 @@ gboolean gnc_keyring_get_password ( GtkWidget *parent,
*password = NULL;
#ifdef HAVE_LIBSECRET
+ /* Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=746873
+ * and by extension for https://bugzilla.gnome.org/show_bug.cgi?id=748625
+ * Store a dummy password and delete it again. This forces libsecret
+ * to open the keychain, where only a call to secret_password_lookup_sync
+ * sometimes fails to do so. More details can be found in the bug reports
+ * referenced above. */
+ secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
+ "Dummy password", "dummy", NULL, &error,
+ "protocol", "gnucash",
+ "server", "gnucash",
+ "user", "gnucash",
+ NULL);
+ secret_password_clear_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
+ "protocol", "gnucash",
+ "server", "gnucash",
+ "user", "gnucash",
+ NULL);
+
/* Note: only use the port attribute if it was set by the user. */
if (port == 0)
libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
commit f604348d9b1bc9bb715157c4f7c621358e6daf54
Author: Geert Janssens <janssens-geert at telenet.be>
Date: Tue Apr 28 10:38:37 2015 +0200
Bug 746873 - Gnucash asks sql passwords before wallet password
If libsecret is available use it to search for both
libsecret based passwords as gnome-keyring based ones.
This catches the situation where a password was stored
earlier using gnome-keyring, while the user is now trying
to retrieve it on a system that only has libsecret available.
This used to fail because gnucash depended on gnome-keyring
to be present in that situation.
diff --git a/src/gnome-utils/gnc-keyring.c b/src/gnome-utils/gnc-keyring.c
index 9a1e16f..d6eaa23 100644
--- a/src/gnome-utils/gnc-keyring.c
+++ b/src/gnome-utils/gnc-keyring.c
@@ -28,8 +28,7 @@
#include "gnc-keyring.h"
#ifdef HAVE_LIBSECRET
#include <libsecret/secret.h>
-#endif
-#if HAVE_GNOME_KEYRING
+#elif HAVE_GNOME_KEYRING
#define GNOME_KEYRING_DEPRECATED
#define GNOME_KEYRING_DEPRECATED_FOR(x)
#include <gnome-keyring.h>
@@ -77,13 +76,21 @@ void gnc_keyring_set_password (const gchar *access_method,
label = g_strdup_printf("GnuCash password for %s://%s@%s", access_method, user, server);
- secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
- label, password, NULL, &error,
- "protocol", access_method,
- "server", server,
- "port", port,
- "user", user,
- NULL);
+ if (port == 0)
+ secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
+ label, password, NULL, &error,
+ "protocol", access_method,
+ "server", server,
+ "user", user,
+ NULL);
+ else
+ secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
+ label, password, NULL, &error,
+ "protocol", access_method,
+ "server", server,
+ "port", port,
+ "user", user,
+ NULL);
g_free(label);
@@ -117,7 +124,7 @@ void gnc_keyring_set_password (const gchar *access_method,
* distinguish between these two.
*/
// FIXME I'm not sure this works if a password was already in the keychain
- // I may have to do a lookup first and if it exists, run some update
+ // I may have to do a lookup first and if it exists, run some
// update function instead
status = SecKeychainAddInternetPassword ( NULL, /* keychain */
strlen(server), server, /* servername */
@@ -152,11 +159,11 @@ gboolean gnc_keyring_get_password ( GtkWidget *parent,
gchar **password)
{
gboolean password_found = FALSE;
+ gchar *db_path, *heading;
#ifdef HAVE_LIBSECRET
GError* error = NULL;
char* libsecret_password;
-#endif
-#if HAVE_GNOME_KEYRING
+#elif HAVE_GNOME_KEYRING
GnomeKeyringResult gkr_result;
GList *found_list = NULL;
GnomeKeyringNetworkPasswordData *found;
@@ -173,55 +180,101 @@ gboolean gnc_keyring_get_password ( GtkWidget *parent,
*password = NULL;
#ifdef HAVE_LIBSECRET
+ /* Note: only use the port attribute if it was set by the user. */
+ if (port == 0)
+ libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
+ "protocol", access_method,
+ "server", server,
+ "user", *user,
+ NULL);
+ else
+ libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
+ "protocol", access_method,
+ "server", server,
+ "port", port,
+ "user", *user,
+ NULL);
+
+ if (libsecret_password != NULL) {
+ *password = g_strdup (libsecret_password);
+ secret_password_free (libsecret_password);
+ return TRUE;
+ }
+
+ /* No password found yet. Perhaps it was written with a port equal to 0.
+ * Gnucash versions prior to 2.6.7 did this unfortunately... */
libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
"protocol", access_method,
"server", server,
- "port", port,
+ "port", 0,
"user", *user,
NULL);
- if (libsecret_password == NULL) {
- if (error != NULL) {
- PWARN ("libsecret access failed: %s.", error->message);
- g_error_free(error);
- }
- } else {
- password_found = TRUE;
+ if (libsecret_password != NULL) {
*password = g_strdup (libsecret_password);
secret_password_free (libsecret_password);
+
+ /* Ok, got an password with 0 port.
+ Store a copy in a more recent gnucash style. */
+ gnc_keyring_set_password(access_method, server, port, service, *user, *password);
+ return TRUE;
}
-#endif /* HAVE_LIBSECRET */
-#if HAVE_GNOME_KEYRING
- if (password_found == FALSE) {
- gkr_result = gnome_keyring_find_network_password_sync
- ( *user, NULL, server, service,
- access_method, NULL, port, &found_list );
+ /* No password was found while querying libsecret using the gnucash schema,
+ Look for a password stored via gnome-keyring instead */
+ if (port == 0)
+ libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_COMPAT_NETWORK, NULL, &error,
+ "protocol", access_method,
+ "server", server,
+ "object", service,
+ "user", *user,
+ NULL);
+ else
+ libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_COMPAT_NETWORK, NULL, &error,
+ "protocol", access_method,
+ "server", server,
+ "port", port,
+ "object", service,
+ "user", *user,
+ NULL);
- if (gkr_result == GNOME_KEYRING_RESULT_OK)
- {
- found = (GnomeKeyringNetworkPasswordData *) found_list->data;
- if (found->password)
- *password = g_strdup(found->password);
- password_found = TRUE;
- }
- else
- PWARN ("Gnome-keyring access failed: %s.",
- gnome_keyring_result_to_message(gkr_result));
+ if (libsecret_password != NULL) {
+ *password = g_strdup (libsecret_password);
+ secret_password_free (libsecret_password);
- gnome_keyring_network_password_list_free(found_list);
+ /* Ok, got an old gnome-keyring password.
+ * Store a copy of it in a libsecret compatible format. */
+ gnc_keyring_set_password(access_method, server, port, service, *user, *password);
+ return TRUE;
}
-#endif /* HAVE_GNOME_KEYRING */
-#if defined(HAVE_LIBSECRET) && defined(HAVE_GNOME_KEYRING)
- /* If we were not able to retrieve the password with libsecret and the new
- * schema and libgnome-keyring was successful to retrieve the password using
- * the old schema, we immediatly store it in the new schema.
- */
- if (libsecret_password == NULL && password_found == TRUE) {
- gnc_keyring_set_password(access_method, server, port, service, *user, *password);
+ /* Something went wrong while attempting to access libsecret
+ * Log the error message and carry on... */
+ if (error != NULL) {
+ PWARN ("libsecret access failed: %s.", error->message);
+ g_error_free(error);
}
-#endif /* HAVE_LIBSECRET && HAVE_GNOME_KEYRING */
+
+#elif HAVE_GNOME_KEYRING
+ gkr_result = gnome_keyring_find_network_password_sync
+ ( *user, NULL, server, service,
+ access_method, NULL, port, &found_list );
+
+ if (gkr_result == GNOME_KEYRING_RESULT_OK)
+ {
+ found = (GnomeKeyringNetworkPasswordData *) found_list->data;
+ if (found->password)
+ *password = g_strdup(found->password);
+ gnome_keyring_network_password_list_free(found_list);
+ return TRUE;
+ }
+
+ /* Something went wrong while attempting to access libsecret
+ * Log the error message and carry on... */
+ PWARN ("Gnome-keyring access failed: %s.",
+ gnome_keyring_result_to_message(gkr_result));
+ gnome_keyring_network_password_list_free(found_list);
+#endif /* HAVE_LIBSECRET or HAVE_GNOME_KEYRING */
#ifdef HAVE_OSX_KEYCHAIN
/* mysql and postgres aren't valid protocols on Mac OS X.
@@ -244,8 +297,8 @@ gboolean gnc_keyring_get_password ( GtkWidget *parent,
if ( status == noErr )
{
*password = g_strndup(password_data, password_length);
- password_found = TRUE;
SecKeychainItemFreeContent(NULL, password_data);
+ return TRUE;
}
else
{
@@ -258,46 +311,42 @@ gboolean gnc_keyring_get_password ( GtkWidget *parent,
}
#endif /* HAVE_OSX_KEYCHAIN */
- if ( !password_found )
+ /* If we got here, either no proper password store is
+ * available on this system, or we couldn't retrieve
+ * a password from it. In both cases, just ask the user
+ * to enter one
+ */
+
+ if ( port == 0 )
+ db_path = g_strdup_printf ( "%s://%s/%s", access_method, server, service );
+ else
+ db_path = g_strdup_printf ( "%s://%s:%d/%s", access_method, server, port, service );
+ heading = g_strdup_printf ( /* Translators: %s is a path to a database or any other url,
+ like mysql://user@server.somewhere/somedb, http://www.somequotes.com/thequotes */
+ _("Enter a user name and password to connect to: %s"),
+ db_path );
+
+ password_found = gnc_get_username_password ( parent, heading,
+ *user, NULL,
+ user, password );
+ g_free ( db_path );
+ g_free ( heading );
+
+ if ( password_found )
{
- /* If we got here, either no proper password store is
- * available on this system, or we couldn't retrieve
- * a password from it. In both cases, just ask the user
- * to enter one
- */
- gchar *db_path, *heading;
-
- if ( port == 0 )
- db_path = g_strdup_printf ( "%s://%s/%s", access_method, server, service );
- else
- db_path = g_strdup_printf ( "%s://%s:%d/%s", access_method, server, port, service );
- heading = g_strdup_printf ( /* Translators: %s is a path to a database or any other url,
- like mysql://user@server.somewhere/somedb, http://www.somequotes.com/thequotes */
- _("Enter a user name and password to connect to: %s"),
- db_path );
-
- password_found = gnc_get_username_password ( parent, heading,
- *user, NULL,
- user, password );
- g_free ( db_path );
- g_free ( heading );
-
- if ( password_found )
- {
- /* User entered new user/password information
- * Let's try to add it to a password store.
- */
- gchar *newuser = g_strdup( *user );
- gchar *newpassword = g_strdup( *password );
- gnc_keyring_set_password ( access_method,
- server,
- port,
- service,
- newuser,
- newpassword );
- g_free ( newuser );
- g_free ( newpassword );
- }
+ /* User entered new user/password information
+ * Let's try to add it to a password store.
+ */
+ gchar *newuser = g_strdup( *user );
+ gchar *newpassword = g_strdup( *password );
+ gnc_keyring_set_password ( access_method,
+ server,
+ port,
+ service,
+ newuser,
+ newpassword );
+ g_free ( newuser );
+ g_free ( newpassword );
}
return password_found;
Summary of changes:
src/gnome-utils/gnc-keyring.c | 239 +++++++++++++++++++++++++++---------------
1 file changed, 153 insertions(+), 86 deletions(-)
More information about the gnucash-changes
mailing list