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.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@19026 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Geert Janssens 2010-04-17 16:17:55 +00:00
parent 33798cd3d3
commit 72484a458c
3 changed files with 70 additions and 15 deletions

View File

@ -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 @@ gnc_add_history (QofSession * session)
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 @@ gnc_post_file_open (const char * filename)
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 @@ gnc_post_file_open (const char * filename)
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 @@ gnc_post_file_open (const char * filename)
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 @@ gnc_file_do_save_as (const char* filename)
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 @@ gnc_file_do_save_as (const char* filename)
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 @@ gnc_file_do_save_as (const char* filename)
/* -- 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 @@ gnc_file_do_save_as (const char* filename)
* 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

View File

@ -49,11 +49,11 @@ void gnc_keyring_set_password (const gchar *access_method,
#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)
{

View File

@ -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,