25 #include <glib/gi18n.h> 30 #include <libsecret/secret.h> 31 #elif HAVE_GNOME_KEYRING 32 #define GNOME_KEYRING_DEPRECATED 33 #define GNOME_KEYRING_DEPRECATED_FOR(x) 34 #include <gnome-keyring.h> 36 #ifdef HAVE_OSX_KEYCHAIN 37 #include <Security/Security.h> 38 #include <CoreFoundation/CoreFoundation.h> 39 #include <Carbon/Carbon.h> 41 #pragma GCC diagnostic warning "-Wdeprecated-declarations" 45 G_GNUC_UNUSED
static QofLogModule log_module = GNC_MOD_GUI;
48 const SecretSchema* gnucash_get_secret_schema(
void) G_GNUC_CONST;
49 const SecretSchema* gnucash_get_secret_schema(
void)
51 static const SecretSchema secret_schema = {
52 "org.gnucash.password", SECRET_SCHEMA_NONE,
54 {
"protocol", SECRET_SCHEMA_ATTRIBUTE_STRING },
55 {
"server", SECRET_SCHEMA_ATTRIBUTE_STRING },
56 {
"port", SECRET_SCHEMA_ATTRIBUTE_INTEGER },
57 {
"user", SECRET_SCHEMA_ATTRIBUTE_STRING },
62 return &secret_schema;
65 #define SECRET_SCHEMA_GNUCASH gnucash_get_secret_schema() 68 #ifdef HAVE_OSX_KEYCHAIN 71 gnc_log_osx_keychain_error (
const gchar *context, OSStatus status)
73 CFStringRef osx_resultstring = SecCopyErrorMessageString (status, NULL);
74 char resultstring[256] =
"";
77 CFStringGetCString (osx_resultstring, resultstring,
78 sizeof resultstring, kCFStringEncodingUTF8);
79 CFRelease (osx_resultstring);
81 PWARN (
"OS X keychain error in %s (status %d): %s",
82 context, (
int) status, resultstring);
91 const gchar* password)
97 g_return_if_fail(access_method != NULL && server != NULL &&
98 service != NULL && user != NULL && password != NULL);
100 label = g_strdup_printf(
"GnuCash password for %s://%s@%s", access_method, user, server);
103 secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
104 label, password, NULL, &error,
105 "protocol", access_method,
110 secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
111 label, password, NULL, &error,
112 "protocol", access_method,
122 PWARN (
"libsecret error: %s", error->message);
123 PWARN (
"The user will be prompted for a password again next time.");
126 #elif HAVE_GNOME_KEYRING 127 GnomeKeyringResult gkr_result;
130 g_return_if_fail(access_method != NULL && server != NULL &&
131 service != NULL && user != NULL && password != NULL);
133 gkr_result = gnome_keyring_set_network_password_sync
134 (NULL, user, NULL, server, service,
135 access_method, NULL, port, password, &item_id);
137 if (gkr_result != GNOME_KEYRING_RESULT_OK)
139 PWARN (
"Gnome-keyring error: %s",
140 gnome_keyring_result_to_message(gkr_result));
141 PWARN (
"The user will be prompted for a password again next time.");
144 #ifdef HAVE_OSX_KEYCHAIN 146 SecKeychainItemRef *itemRef = NULL;
148 g_return_if_fail(access_method != NULL && server != NULL &&
149 service != NULL && user != NULL && password != NULL);
158 SecKeychainAddInternetPassword (NULL,
159 strlen(server), server,
160 strlen(access_method),
163 strlen(service), service,
166 kSecAuthenticationTypeDefault,
171 if ( status != noErr )
173 gnc_log_osx_keychain_error (
"gnc_keyring_set_password", status);
174 PWARN (
"The user will be prompted for a password again next time." );
181 const gchar *access_method,
184 const gchar *service,
188 gboolean password_found = FALSE;
189 gchar *db_path, *heading;
190 #ifdef HAVE_LIBSECRET 191 GError* error = NULL;
192 char* libsecret_password;
193 #elif HAVE_GNOME_KEYRING 194 GnomeKeyringResult gkr_result;
195 GList *found_list = NULL;
196 GnomeKeyringNetworkPasswordData *found;
198 #ifdef HAVE_OSX_KEYCHAIN 200 UInt32 password_length;
204 g_return_val_if_fail (user != NULL, FALSE);
205 g_return_val_if_fail (password != NULL, FALSE);
209 #ifdef HAVE_LIBSECRET 216 secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
217 "Dummy password",
"dummy", NULL, &error,
218 "protocol", PROJECT_NAME,
219 "server", PROJECT_NAME,
220 "user", PROJECT_NAME,
222 secret_password_clear_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
223 "protocol", PROJECT_NAME,
224 "server", PROJECT_NAME,
225 "user", PROJECT_NAME,
230 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
231 "protocol", access_method,
236 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
237 "protocol", access_method,
243 if (libsecret_password != NULL) {
244 *password = g_strdup (libsecret_password);
245 secret_password_free (libsecret_password);
251 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
252 "protocol", access_method,
258 if (libsecret_password != NULL) {
259 *password = g_strdup (libsecret_password);
260 secret_password_free (libsecret_password);
271 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_COMPAT_NETWORK, NULL, &error,
272 "protocol", access_method,
278 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_COMPAT_NETWORK, NULL, &error,
279 "protocol", access_method,
286 if (libsecret_password != NULL) {
287 *password = g_strdup (libsecret_password);
288 secret_password_free (libsecret_password);
299 PWARN (
"libsecret access failed: %s.", error->message);
303 #elif HAVE_GNOME_KEYRING 304 gkr_result = gnome_keyring_find_network_password_sync
305 ( *user, NULL, server, service,
306 access_method, NULL, port, &found_list );
308 if (gkr_result == GNOME_KEYRING_RESULT_OK)
310 found = (GnomeKeyringNetworkPasswordData *) found_list->data;
312 *password = g_strdup(found->password);
313 gnome_keyring_network_password_list_free(found_list);
319 PWARN (
"Gnome-keyring access failed: %s.",
320 gnome_keyring_result_to_message(gkr_result));
321 gnome_keyring_network_password_list_free(found_list);
324 #ifdef HAVE_OSX_KEYCHAIN 331 status = SecKeychainFindInternetPassword( NULL,
332 strlen(server), server,
333 strlen(access_method), access_method,
334 strlen(*user), *user,
335 strlen(service), service,
338 kSecAuthenticationTypeDefault,
339 &password_length, &password_data,
342 if ( status == noErr )
344 *password = g_strndup(password_data, password_length);
345 SecKeychainItemFreeContent(NULL, password_data);
350 gnc_log_osx_keychain_error (
"gnc_keyring_get_password", status);
362 db_path = g_strdup_printf (
"%s://%s/%s", access_method, server, service );
364 db_path = g_strdup_printf (
"%s://%s:%d/%s", access_method, server, port, service );
365 heading = g_strdup_printf (
367 _(
"Enter a user name and password to connect to: %s"),
370 password_found = gnc_get_username_password ( parent, heading,
376 if ( password_found )
381 gchar *newuser = g_strdup( *user );
382 gchar *newpassword = g_strdup( *password );
390 g_free ( newpassword );
393 return password_found;
Functions to save and retrieve passwords.
#define PWARN(format, args...)
Log a warning.
void gnc_keyring_set_password(const gchar *access_method, const gchar *server, guint32 port, const gchar *service, const gchar *user, const gchar *password)
Attempt to store a password in some trusted keystore.
gboolean gnc_keyring_get_password(GtkWidget *parent, const gchar *access_method, const gchar *server, guint32 port, const gchar *service, gchar **user, gchar **password)
Attempt to retrieve a password to connect to a remote service.