25 #include <glib/gi18n.h>
30 #include <libsecret/secret.h>
32 #if HAVE_GNOME_KEYRING
33 #define GNOME_KEYRING_DEPRECATED
34 #define GNOME_KEYRING_DEPRECATED_FOR(x)
35 #include <gnome-keyring.h>
37 #ifdef HAVE_OSX_KEYCHAIN
38 #include <Security/Security.h>
39 #include <CoreFoundation/CoreFoundation.h>
40 #include <Carbon/Carbon.h>
44 G_GNUC_UNUSED
static QofLogModule log_module = GNC_MOD_GUI;
47 const SecretSchema* gnucash_get_secret_schema(
void) G_GNUC_CONST;
48 const SecretSchema* gnucash_get_secret_schema(
void)
50 static const SecretSchema secret_schema = {
51 "org.gnucash.password", SECRET_SCHEMA_NONE,
53 {
"protocol", SECRET_SCHEMA_ATTRIBUTE_STRING },
54 {
"server", SECRET_SCHEMA_ATTRIBUTE_STRING },
55 {
"port", SECRET_SCHEMA_ATTRIBUTE_INTEGER },
56 {
"user", SECRET_SCHEMA_ATTRIBUTE_STRING },
61 return &secret_schema;
64 #define SECRET_SCHEMA_GNUCASH gnucash_get_secret_schema()
72 const gchar* password)
78 label = g_strdup_printf(
"GnuCash password for %s://%s@%s", access_method, user, server);
80 secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
81 label, password, NULL, &error,
82 "protocol", access_method,
92 PWARN (
"libsecret error: %s", error->message);
93 PWARN (
"The user will be prompted for a password again next time.");
96 #elif HAVE_GNOME_KEYRING
97 GnomeKeyringResult gkr_result;
100 gkr_result = gnome_keyring_set_network_password_sync
101 (NULL, user, NULL, server, service,
102 access_method, NULL, port, password, &item_id);
104 if (gkr_result != GNOME_KEYRING_RESULT_OK)
106 PWARN (
"Gnome-keyring error: %s",
107 gnome_keyring_result_to_message(gkr_result));
108 PWARN (
"The user will be prompted for a password again next time.");
111 #ifdef HAVE_OSX_KEYCHAIN
113 SecKeychainItemRef *itemRef = NULL;
122 status = SecKeychainAddInternetPassword ( NULL,
123 strlen(server), server,
124 strlen(access_method), access_method,
126 strlen(service), service,
129 kSecAuthenticationTypeDefault,
130 strlen(password), password,
133 if ( status != noErr )
135 CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL );
136 const gchar *resultstring = CFStringGetCStringPtr(osx_resultstring,
137 GetApplicationTextEncoding());
138 PWARN (
"OS X keychain error: %s", resultstring );
139 PWARN (
"The user will be prompted for a password again next time." );
140 CFRelease ( osx_resultstring );
147 const gchar *access_method,
150 const gchar *service,
154 gboolean password_found = FALSE;
155 #ifdef HAVE_LIBSECRET
156 GError* error = NULL;
157 char* libsecret_password;
159 #if HAVE_GNOME_KEYRING
160 GnomeKeyringResult gkr_result;
161 GList *found_list = NULL;
162 GnomeKeyringNetworkPasswordData *found;
164 #ifdef HAVE_OSX_KEYCHAIN
166 UInt32 password_length;
170 g_return_val_if_fail (user != NULL, FALSE);
171 g_return_val_if_fail (password != NULL, FALSE);
175 #ifdef HAVE_LIBSECRET
176 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
177 "protocol", access_method,
183 if (libsecret_password == NULL) {
185 PWARN (
"libsecret access failed: %s.", error->message);
189 password_found = TRUE;
190 *password = g_strdup (libsecret_password);
191 secret_password_free (libsecret_password);
195 #if HAVE_GNOME_KEYRING
196 if (password_found == FALSE) {
197 gkr_result = gnome_keyring_find_network_password_sync
198 ( *user, NULL, server, service,
199 access_method, NULL, port, &found_list );
201 if (gkr_result == GNOME_KEYRING_RESULT_OK)
203 found = (GnomeKeyringNetworkPasswordData *) found_list->data;
205 *password = g_strdup(found->password);
206 password_found = TRUE;
209 PWARN (
"Gnome-keyring access failed: %s.",
210 gnome_keyring_result_to_message(gkr_result));
212 gnome_keyring_network_password_list_free(found_list);
216 #if defined(HAVE_LIBSECRET) && defined(HAVE_GNOME_KEYRING)
221 if (libsecret_password == NULL && password_found == TRUE) {
226 #ifdef HAVE_OSX_KEYCHAIN
233 status = SecKeychainFindInternetPassword( NULL,
234 strlen(server), server,
235 strlen(access_method), access_method,
236 strlen(*user), *user,
237 strlen(service), service,
240 kSecAuthenticationTypeDefault,
241 &password_length, &password_data,
244 if ( status == noErr )
246 *password = g_strndup(password_data, password_length);
247 password_found = TRUE;
248 SecKeychainItemFreeContent(NULL, password_data);
252 CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL );
253 const gchar *resultstring = CFStringGetCStringPtr(osx_resultstring,
254 GetApplicationTextEncoding());
255 PWARN (
"OS X keychain error: %s", resultstring );
256 CFRelease ( osx_resultstring );
261 if ( !password_found )
268 gchar *db_path, *heading;
271 db_path = g_strdup_printf (
"%s://%s/%s", access_method, server, service );
273 db_path = g_strdup_printf (
"%s://%s:%d/%s", access_method, server, port, service );
274 heading = g_strdup_printf (
276 _(
"Enter a user name and password to connect to: %s"),
279 password_found = gnc_get_username_password ( parent, heading,
285 if ( password_found )
290 gchar *newuser = g_strdup( *user );
291 gchar *newpassword = g_strdup( *password );
299 g_free ( newpassword );
303 return password_found;
Functions to save and retrieve passwords.
#define PWARN(format, args...)
void gnc_keyring_set_password(const gchar *access_method, const gchar *server, guint32 port, const gchar *service, const gchar *user, const gchar *password)
gboolean gnc_keyring_get_password(GtkWidget *parent, const gchar *access_method, const gchar *server, guint32 port, const gchar *service, gchar **user, gchar **password)
const gchar * QofLogModule