r19026 - gnucash/trunk/src/gnome-utils - Enable the use of gnome-keyring during loading and saving of data.

Geert Janssens gjanssens at code.gnucash.org
Sat Apr 17 12:17:55 EDT 2010


Author: gjanssens
Date: 2010-04-17 12:17:55 -0400 (Sat, 17 Apr 2010)
New Revision: 19026
Trac: http://svn.gnucash.org/trac/changeset/19026

Modified:
   gnucash/trunk/src/gnome-utils/gnc-file.c
   gnucash/trunk/src/gnome-utils/gnc-keyring.c
   gnucash/trunk/src/gnome-utils/gnc-keyring.h
Log:
Enable the use of gnome-keyring during loading and saving of data.
- The database passwords will no longer be stored in history
- During save as, the user-entered password will be stored in gnome-keyring
- During open, the user-entered password will be stored in gnome-keyring
- When a file is opened from history (no file specified at startup or
  user selects an entry in the File menu's history) the password is
  fetched from the gnome-keyring.

This currently works on linux. On Mac OS X or Windows no passwords are stored
and the user is asked for a password when a file is loaded from history.
Adding keyring/keychain capability on these systems is tbd.

Modified: gnucash/trunk/src/gnome-utils/gnc-file.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-file.c	2010-04-16 05:26:25 UTC (rev 19025)
+++ gnucash/trunk/src/gnome-utils/gnc-file.c	2010-04-17 16:17:55 UTC (rev 19026)
@@ -36,6 +36,7 @@
 #include "gnc-file.h"
 #include "gnc-gui-query.h"
 #include "gnc-hooks.h"
+#include "gnc-keyring.h"
 #include "gnc-splash.h"
 #include "gnc-ui.h"
 #include "gnc-ui-util.h"
@@ -510,7 +511,7 @@
     if ( gnc_uri_is_file_uri ( url ) )
         file = gnc_uri_get_path ( url );
     else
-        file = gnc_uri_normalize_uri ( url, TRUE ); /* FIXME this saves the password visibly in history ! */
+        file = gnc_uri_normalize_uri ( url, FALSE ); /* Note that the password is not saved in history ! */
 
     gnc_history_add_file (file);
 }
@@ -645,11 +646,20 @@
     char * newfile;
     QofBackendError io_err = ERR_BACKEND_NO_ERR;
 
+    gchar *protocol=NULL;
+    gchar *hostname=NULL;
+    gchar *username=NULL;
+    gchar *password=NULL;
+    gchar *path=NULL;
+    gint32 port=0;
+
+
+    ENTER(" ");
+
     if (!filename) return FALSE;
 
-    /* FIXME Verify if it is ok that a password is stored
-     * in the uri here.
-     */
+    /* Convert user input into a normalized uri
+     * Note that the normalized uri for internal use can have a password */
     newfile = gnc_uri_normalize_uri ( filename, TRUE );
     if (!newfile)
     {
@@ -658,6 +668,29 @@
         return FALSE;
     }
 
+    gnc_uri_get_components (newfile, &protocol, &hostname,
+                            &port, &username, &password, &path);
+
+    /* If the file to open is a database, and no password was given,
+     * attempt to look it up in a keyring. If that fails the keyring
+     * function will ask the user to enter a password. The user can
+     * cancel this dialog, in which case the open file action will be
+     * abandoned.
+     */
+    if ( !gnc_uri_is_file_protocol (protocol) && !password)
+    {
+        gboolean have_valid_pw = FALSE;
+        have_valid_pw = gnc_keyring_get_password ( NULL, protocol, hostname, port,
+                                   path, &username, &password );
+        if (!have_valid_pw)
+            return FALSE;
+
+        /* Got password. Recreate the uri to use internally. */
+        g_free ( newfile );
+        newfile = gnc_uri_create_uri ( protocol, hostname, port,
+                                       username, password, path);
+    }
+
     /* disable events while moving over to the new set of accounts;
      * the mass deletion of accounts and transactions during
      * switchover would otherwise cause excessive redraws. */
@@ -790,6 +823,13 @@
         xaccLogSetBaseName (logpath);
         g_free ( logpath );
 
+        /* If the new "file" is a database, attempt to store the password
+         * in a keyring. GnuCash itself will not save it.
+         */
+        if ( !gnc_uri_is_file_protocol (protocol))
+            gnc_keyring_set_password ( protocol, hostname, port,
+                                       path, username, password );
+
         xaccLogDisable();
         gnc_window_show_progress(_("Loading user data..."), 0.0);
         qof_session_load (new_session, gnc_window_show_progress);
@@ -1121,13 +1161,20 @@
     const char *oldfile;
     gchar *logpath = NULL;
 
+    gchar *protocol=NULL;
+    gchar *hostname=NULL;
+    gchar *username=NULL;
+    gchar *password=NULL;
+    gchar *path=NULL;
+    gint32 port=0;
+
+
     QofBackendError io_err = ERR_BACKEND_NO_ERR;
 
     ENTER(" ");
 
-    /* Check to see if the user specified the same file as the current
-     * file. If so, then just do a simple save, instead of a full save as */
-    /* FIXME Check if it is ok to have a password in the uri here */
+    /* Convert user input into a normalized uri
+     * Note that the normalized uri for internal use can have a password */
     newfile = gnc_uri_normalize_uri ( filename, TRUE );
     if (!newfile)
     {
@@ -1136,6 +1183,11 @@
         return;
     }
 
+    gnc_uri_get_components (newfile, &protocol, &hostname,
+                            &port, &username, &password, &path);
+
+    /* Check to see if the user specified the same file as the current
+     * file. If so, then just do a simple save, instead of a full save as */
     session = gnc_get_current_session ();
     oldfile = qof_session_get_url(session);
     if (oldfile && (strcmp(oldfile, newfile) == 0))
@@ -1151,6 +1203,7 @@
     /* -- this session code is NOT identical in FileOpen and FileSaveAs -- */
 
     save_in_progress++;
+
     new_session = qof_session_new ();
     qof_session_begin (new_session, newfile, FALSE, FALSE);
 
@@ -1219,12 +1272,18 @@
      * Databases don't have a file path, so no logging will be
      * done for them in the current setup.
      */
-    if ( gnc_uri_is_file_uri ( newfile ) )
+    if ( gnc_uri_is_file_protocol ( protocol ) )
         logpath = gnc_uri_get_path(newfile);
     PINFO ("logpath=%s", logpath ? logpath : "(null)");
     xaccLogSetBaseName (logpath);
     g_free ( logpath );
 
+    /* If the new "file" is a database, attempt to store the password
+     * in a keyring. GnuCash itself will not save it.
+     */
+    if ( !gnc_uri_is_file_protocol (protocol))
+        gnc_keyring_set_password ( protocol, hostname, port,
+                                   path, username, password );
 
     /* Prevent race condition between swapping the contents of the two
      * sessions, and actually installing the new session as the current

Modified: gnucash/trunk/src/gnome-utils/gnc-keyring.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-keyring.c	2010-04-16 05:26:25 UTC (rev 19025)
+++ gnucash/trunk/src/gnome-utils/gnc-keyring.c	2010-04-17 16:17:55 UTC (rev 19026)
@@ -49,11 +49,11 @@
 
 #ifdef HAVE_GNOME_KEYRING
     GnomeKeyringResult  gkr_result;
-    guint32 *item_id = NULL;
+    guint32 item_id = 0;
 
     gkr_result = gnome_keyring_set_network_password_sync
                  (NULL, user, NULL, server, service,
-                  access_method, NULL, port, password, item_id);
+                  access_method, NULL, port, password, &item_id);
 
     if (gkr_result != GNOME_KEYRING_RESULT_OK)
     {

Modified: gnucash/trunk/src/gnome-utils/gnc-keyring.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-keyring.h	2010-04-16 05:26:25 UTC (rev 19025)
+++ gnucash/trunk/src/gnome-utils/gnc-keyring.h	2010-04-17 16:17:55 UTC (rev 19026)
@@ -51,8 +51,6 @@
  *  used to create a unique key, so the password can later be
  *  retrieved again with the same parameters.
  *
- *  @param parent Used to transition from in case the user is prompted
- *                for a password.
  *  @param access_method Service type the user attempts to access. Can
  *                things like 'mysql', 'postgres' and so on.
  *  @param server Server the user wishes to connect to.
@@ -60,9 +58,7 @@
  *                be ignored in the search for a password.
  *  @param service The service the user wishes to access on the server.
  *                This can be a database name or a path.
- *  @param user   The username to access the service. Remember, although
- *                you pass it to search for the password, it can have
- *                changed when the function returns.
+ *  @param user   The username to access the service.
  *  @param password The password to access the service.
  */
 void gnc_keyring_set_password ( const gchar *access_method,



More information about the gnucash-changes mailing list