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() 73 const gchar* password)
79 g_return_if_fail(access_method != NULL && server != NULL &&
80 service != NULL && user != NULL && password != NULL);
82 label = g_strdup_printf(
"GnuCash password for %s://%s@%s", access_method, user, server);
85 secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
86 label, password, NULL, &error,
87 "protocol", access_method,
92 secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
93 label, password, NULL, &error,
94 "protocol", access_method,
104 PWARN (
"libsecret error: %s", error->message);
105 PWARN (
"The user will be prompted for a password again next time.");
108 #elif HAVE_GNOME_KEYRING 109 GnomeKeyringResult gkr_result;
112 g_return_if_fail(access_method != NULL && server != NULL &&
113 service != NULL && user != NULL && password != NULL);
115 gkr_result = gnome_keyring_set_network_password_sync
116 (NULL, user, NULL, server, service,
117 access_method, NULL, port, password, &item_id);
119 if (gkr_result != GNOME_KEYRING_RESULT_OK)
121 PWARN (
"Gnome-keyring error: %s",
122 gnome_keyring_result_to_message(gkr_result));
123 PWARN (
"The user will be prompted for a password again next time.");
126 #ifdef HAVE_OSX_KEYCHAIN 128 SecKeychainItemRef *itemRef = NULL;
130 g_return_if_fail(access_method != NULL && server != NULL &&
131 service != NULL && user != NULL && password != NULL);
140 SecKeychainAddInternetPassword (NULL,
141 strlen(server), server,
142 strlen(access_method),
145 strlen(service), service,
148 kSecAuthenticationTypeDefault,
153 if ( status != noErr )
155 CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL );
156 const gchar *resultstring =
157 CFStringGetCStringPtr(osx_resultstring,
158 GetApplicationTextEncoding());
159 PWARN (
"OS X keychain error: %s", resultstring );
160 PWARN (
"The user will be prompted for a password again next time." );
161 CFRelease ( osx_resultstring );
168 const gchar *access_method,
171 const gchar *service,
175 gboolean password_found = FALSE;
176 gchar *db_path, *heading;
177 #ifdef HAVE_LIBSECRET 178 GError* error = NULL;
179 char* libsecret_password;
180 #elif HAVE_GNOME_KEYRING 181 GnomeKeyringResult gkr_result;
182 GList *found_list = NULL;
183 GnomeKeyringNetworkPasswordData *found;
185 #ifdef HAVE_OSX_KEYCHAIN 187 UInt32 password_length;
191 g_return_val_if_fail (user != NULL, FALSE);
192 g_return_val_if_fail (password != NULL, FALSE);
196 #ifdef HAVE_LIBSECRET 203 secret_password_store_sync (SECRET_SCHEMA_GNUCASH, SECRET_COLLECTION_DEFAULT,
204 "Dummy password",
"dummy", NULL, &error,
205 "protocol", PROJECT_NAME,
206 "server", PROJECT_NAME,
207 "user", PROJECT_NAME,
209 secret_password_clear_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
210 "protocol", PROJECT_NAME,
211 "server", PROJECT_NAME,
212 "user", PROJECT_NAME,
217 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
218 "protocol", access_method,
223 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
224 "protocol", access_method,
230 if (libsecret_password != NULL) {
231 *password = g_strdup (libsecret_password);
232 secret_password_free (libsecret_password);
238 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_GNUCASH, NULL, &error,
239 "protocol", access_method,
245 if (libsecret_password != NULL) {
246 *password = g_strdup (libsecret_password);
247 secret_password_free (libsecret_password);
258 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_COMPAT_NETWORK, NULL, &error,
259 "protocol", access_method,
265 libsecret_password = secret_password_lookup_sync (SECRET_SCHEMA_COMPAT_NETWORK, NULL, &error,
266 "protocol", access_method,
273 if (libsecret_password != NULL) {
274 *password = g_strdup (libsecret_password);
275 secret_password_free (libsecret_password);
286 PWARN (
"libsecret access failed: %s.", error->message);
290 #elif HAVE_GNOME_KEYRING 291 gkr_result = gnome_keyring_find_network_password_sync
292 ( *user, NULL, server, service,
293 access_method, NULL, port, &found_list );
295 if (gkr_result == GNOME_KEYRING_RESULT_OK)
297 found = (GnomeKeyringNetworkPasswordData *) found_list->data;
299 *password = g_strdup(found->password);
300 gnome_keyring_network_password_list_free(found_list);
306 PWARN (
"Gnome-keyring access failed: %s.",
307 gnome_keyring_result_to_message(gkr_result));
308 gnome_keyring_network_password_list_free(found_list);
311 #ifdef HAVE_OSX_KEYCHAIN 318 status = SecKeychainFindInternetPassword( NULL,
319 strlen(server), server,
320 strlen(access_method), access_method,
321 strlen(*user), *user,
322 strlen(service), service,
325 kSecAuthenticationTypeDefault,
326 &password_length, &password_data,
329 if ( status == noErr )
331 *password = g_strndup(password_data, password_length);
332 SecKeychainItemFreeContent(NULL, password_data);
337 CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL );
338 const gchar *resultstring = CFStringGetCStringPtr(osx_resultstring,
339 GetApplicationTextEncoding());
340 PWARN (
"OS X keychain error: %s", resultstring );
341 CFRelease ( osx_resultstring );
353 db_path = g_strdup_printf (
"%s://%s/%s", access_method, server, service );
355 db_path = g_strdup_printf (
"%s://%s:%d/%s", access_method, server, port, service );
356 heading = g_strdup_printf (
358 _(
"Enter a user name and password to connect to: %s"),
361 password_found = gnc_get_username_password ( parent, heading,
367 if ( password_found )
372 gchar *newuser = g_strdup( *user );
373 gchar *newpassword = g_strdup( *password );
381 g_free ( newpassword );
384 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.