diff --git a/CMakeLists.txt b/CMakeLists.txt index f5ac5c5b7f95..0164a50cf2e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,8 @@ option(USE_LUA "Build lua scripting support" ON) option(DONT_USE_INTERNAL_LUA "Never fall back to the intree copy of lua" ON) option(USE_FLICKR "Enable Flickr support" ON) option(USE_GLIBJSON "Enable GlibJson support" ON) +option(USE_KWALLET "Build kwallet password storage back-end" ON) +option(USE_LIBSECRET "Build libsecret password storage back-end" ON) option(USE_GNOME_KEYRING "Build gnome-keyring password storage back-end" ON) option(USE_UNITY "Use libunity to report progress in the launcher" OFF) option(USE_SQUISH "Use thumbnail compression via libsquish" ON) diff --git a/build.sh b/build.sh index 4331bda36925..c45effc5a913 100755 --- a/build.sh +++ b/build.sh @@ -41,6 +41,9 @@ parse_feature() flickr) OPT_FLICKR=$value ;; + libsecret) + OPT_LIBSECRET=$value + ;; kwallet) OPT_KWALLET=$value ;; @@ -208,6 +211,7 @@ cmake_boolean_option() CMAKE_MORE_OPTIONS="" cmake_boolean_option USE_FLICKR $OPT_FLICKR +cmake_boolean_option USE_LIBSECRET $OPT_LIBSECRET cmake_boolean_option USE_KWALLET $OPT_KWALLET cmake_boolean_option USE_GNOME_KEYRING $OPT_GNOME_KEYRING cmake_boolean_option USE_OPENMP $OPT_OPENMP diff --git a/data/darktableconfig.xml.in b/data/darktableconfig.xml.in index 6d2002973bf0..8920d422d66f 100644 --- a/data/darktableconfig.xml.in +++ b/data/darktableconfig.xml.in @@ -1227,8 +1227,9 @@ - - + + + auto diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 86ceced8c964..9d9786195985 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,7 +232,17 @@ endif(USE_OPENJPEG) # # Detect compile of optional pwstorage backends # -if(USE_GNOME_KEYRING) +if(USE_LIBSECRET) + find_package(Libsecret) + if(LIBSECRET_FOUND) + set(SOURCES ${SOURCES} "common/pwstorage/backend_libsecret.c") + include_directories(SYSTEM ${LIBSECRET_INCLUDE_DIRS}) + list(APPEND LIBS ${LIBSECRET_LIBRARIES}) + add_definitions("-DHAVE_LIBSECRET") + endif(LIBSECRET_FOUND) +endif(USE_LIBSECRET) + +if(USE_GNOME_KEYRING AND NOT USE_LIBSECRET) find_package(GnomeKeyring) if(GNOMEKEYRING_FOUND) if(${GnomeKeyring_VERSION} VERSION_LESS "3.12.0") @@ -245,7 +255,11 @@ if(USE_GNOME_KEYRING) set(GNOMEKEYRING_FOUND FALSE) endif(${GnomeKeyring_VERSION} VERSION_LESS "3.12.0") endif(GNOMEKEYRING_FOUND) -endif(USE_GNOME_KEYRING) +endif(USE_GNOME_KEYRING AND NOT USE_LIBSECRET) + +if(USE_KWALLET AND NOT USE_LIBSECRET) + add_definitions("-DHAVE_KWALLET") +endif(USE_KWALLET AND NOT USE_LIBSECRET) if(USE_MAC_INTEGRATION) find_package(MacIntegration) diff --git a/src/common/darktable.c b/src/common/darktable.c index 5621edd92979..57d2cf2c46df 100644 --- a/src/common/darktable.c +++ b/src/common/darktable.c @@ -749,9 +749,6 @@ int dt_init(int argc, char *argv[], const int init_gui,lua_State *L) darktable.thumbnail_height /= 16; darktable.thumbnail_height *= 16; - // Initialize the password storage engine - darktable.pwstorage=dt_pwstorage_new(); - // FIXME: move there into dt_database_t dt_pthread_mutex_init(&(darktable.db_insert), NULL); dt_pthread_mutex_init(&(darktable.plugin_threadsafe), NULL); @@ -780,6 +777,9 @@ int dt_init(int argc, char *argv[], const int init_gui,lua_State *L) /* capabilities set to NULL */ darktable.capabilities = NULL; + // Initialize the password storage engine + darktable.pwstorage=dt_pwstorage_new(); + #ifdef HAVE_GRAPHICSMAGICK /* GraphicsMagick init */ InitializeMagick(darktable.progname); diff --git a/src/common/pwstorage/backend_libsecret.c b/src/common/pwstorage/backend_libsecret.c new file mode 100644 index 000000000000..a11ba95d8c0c --- /dev/null +++ b/src/common/pwstorage/backend_libsecret.c @@ -0,0 +1,281 @@ +// This file is part of darktable +// +// Copyright (c) 2014 Moritz Lipp . +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "backend_libsecret.h" +#include "control/conf.h" + +#include +#include +#include + +#define DARKTABLE_KEYRING PACKAGE_NAME + +#define GFOREACH(item, list) for(GList *__glist = list; __glist && (item = __glist->data, true); __glist = __glist->next) + +const SecretSchema * secret_darktable_get_schema (void) G_GNUC_CONST; +#define SECRET_SCHEMA_DARKTABLE secret_darktable_get_schema () + +static GHashTable* secret_to_attributes(SecretValue* value); +static SecretValue* attributes_to_secret(GHashTable* attributes); + +const SecretSchema * +secret_darktable_get_schema (void) +{ + static const SecretSchema darktable_schema = { + "org.darktable.Password", SECRET_SCHEMA_NONE, + { + { "slot", SECRET_SCHEMA_ATTRIBUTE_STRING }, + { "magic", SECRET_SCHEMA_ATTRIBUTE_STRING }, + { "NULL", 0 }, + } + }; + + return &darktable_schema; +} + +const backend_libsecret_context_t* +dt_pwstorage_libsecret_new() +{ + backend_libsecret_context_t* context = g_malloc(sizeof(backend_libsecret_context_t)); + + context->secret_service = secret_service_get_sync(SECRET_SERVICE_NONE, NULL, NULL); + if (context->secret_service == NULL) { + return NULL; + } + + /* Ensure to load all collections */ + if (secret_service_load_collections_sync(context->secret_service, NULL, NULL) == FALSE) { + dt_pwstorage_libsecret_destroy(context); + return NULL; + } + + GList* collections = secret_service_get_collections(context->secret_service); + SecretCollection* item = NULL; + + gboolean collection_exists = FALSE; + GFOREACH(item, collections) { + if (g_strcmp0(secret_collection_get_label(item), DARKTABLE_KEYRING)) { + context->secret_collection = item; + collection_exists = TRUE; + break; + } + } + + if (collection_exists == FALSE) { + context->secret_collection = + secret_collection_create_sync(context->secret_service, DARKTABLE_KEYRING, + NULL, SECRET_COLLECTION_CREATE_NONE, NULL, NULL); + + if (context->secret_collection == NULL) { + dt_pwstorage_libsecret_destroy(context); + return NULL; + } + } + + return context; +} + +void +dt_pwstorage_libsecret_destroy(const backend_libsecret_context_t *context) +{ + if (context == NULL) { + return; + } + + if (context->secret_service != NULL) { + g_object_unref(context->secret_service); + } + + if (context->secret_collection != NULL) { + g_object_unref(context->secret_collection); + } + + g_free((backend_libsecret_context_t*) context); +} + +gboolean dt_pwstorage_libsecret_set(const backend_libsecret_context_t* context, + const gchar* slot, GHashTable* attributes) +{ + if (context == NULL || slot == NULL || strlen(slot) == 0 || attributes == NULL) { + return FALSE; + } + + /* Convert attributes to secret */ + SecretValue* secret_value = attributes_to_secret(attributes); + + if (secret_value == NULL) { + return FALSE; + } + + /* Insert slot as a attribute */ + GHashTable* secret_attributes = secret_attributes_build(SECRET_SCHEMA_DARKTABLE, + "slot", slot, "magic", PACKAGE_NAME, NULL); + + /* Save the item */ + gchar* label = g_strdup_printf("darktable@%s", slot); + + GError* error = NULL; + SecretItem* item = secret_item_create_sync( + context->secret_collection, + SECRET_SCHEMA_DARKTABLE, + secret_attributes, + label, + secret_value, + SECRET_ITEM_CREATE_REPLACE, + NULL, + &error); + + if (item == NULL) { + return FALSE; + } else { + return TRUE; + } +} + +GHashTable* dt_pwstorage_libsecret_get(const backend_libsecret_context_t* + context, const gchar* slot) +{ + if (context == NULL || slot == NULL || strlen(slot) == 0) { + goto error_out; + } + + /* Setup search attributes */ + GHashTable* secret_attributes = secret_attributes_build(SECRET_SCHEMA_DARKTABLE, + "slot", slot, "magic", PACKAGE_NAME, NULL); + + /* Search for item */ + GError* error = NULL; + GList* items = secret_collection_search_sync( + context->secret_collection, + SECRET_SCHEMA_DARKTABLE, + secret_attributes, + SECRET_SEARCH_NONE, + NULL, + &error); + + /* Since the search flag is set to SECRET_SEARCH_NONE only one + * matching item is returned. */ + if (items == NULL || g_list_length(items) != 1) { + goto error_out; + } + + SecretItem* item = (SecretItem*) g_list_nth_data(items, 0); + + if (item == NULL) { + goto error_out; + } + + /* Load secret */ + secret_item_load_secret_sync(item, NULL, NULL); + + SecretValue* value = secret_item_get_secret(item); + + if (value == NULL) { + goto error_out; + } + + GHashTable* attributes = secret_to_attributes(value); + + if (attributes == NULL) { + secret_value_unref(value); + goto error_out; + } + + secret_value_unref(value); + + return attributes; + +error_out: + + return g_hash_table_new(g_str_hash, g_str_equal); +} + +static void append_pair_to_json(gpointer key, gpointer value, gpointer data) +{ + JsonBuilder* json_builder = (JsonBuilder*) data; + + json_builder_set_member_name(json_builder, (char*) key); + json_builder_add_string_value(json_builder, (char*) value); +} + +static SecretValue* attributes_to_secret(GHashTable* attributes) +{ + /* Build JSON */ + JsonBuilder* json_builder = json_builder_new(); + json_builder_begin_object(json_builder); + g_hash_table_foreach(attributes, append_pair_to_json, json_builder); + json_builder_end_object(json_builder); + + /* Generate JSON */ + JsonGenerator* json_generator = json_generator_new(); + json_generator_set_root(json_generator, json_builder_get_root(json_builder)); + gchar *json_data = json_generator_to_data(json_generator, 0); + + /* Create secret */ + SecretValue* secret = secret_value_new(json_data, -1, "text/plain"); + + g_object_unref(json_generator); + g_object_unref(json_builder); + + return secret; +} + +static GHashTable* secret_to_attributes(SecretValue* secret) +{ + if (secret == NULL) { + return NULL; + } + + /* Parse JSON from data */ + JsonParser* json_parser = json_parser_new(); + + if (json_parser_load_from_data(json_parser, secret_value_get_text(secret), -1, NULL) == FALSE) { + g_object_unref(json_parser); + return NULL; + } + + /* Read JSON */ + JsonNode* json_root = json_parser_get_root(json_parser); + JsonReader* json_reader = json_reader_new(json_root); + + GHashTable* attributes = g_hash_table_new(g_str_hash, g_str_equal); + + /* Save each element as an attribute pair */ + gint n_attributes = json_reader_count_members(json_reader); + for (gint i = 0; i < n_attributes; i++) { + if (json_reader_read_element(json_reader, i) == FALSE) { + continue; + } + + const gchar* key = json_reader_get_member_name(json_reader); + const gchar* value = json_reader_get_string_value(json_reader); + + g_hash_table_insert(attributes, (gpointer) g_strdup(key), (gpointer) g_strdup(value)); + + json_reader_end_element(json_reader); + } + + g_object_unref(json_reader); + g_object_unref(json_parser); + + return attributes; +} diff --git a/src/common/pwstorage/backend_libsecret.h b/src/common/pwstorage/backend_libsecret.h new file mode 100644 index 000000000000..f41eff0940ba --- /dev/null +++ b/src/common/pwstorage/backend_libsecret.h @@ -0,0 +1,74 @@ +// This file is part of darktable +// +// Copyright (c) 2014 Moritz Lipp . +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef __BACKEND_LIBSECRET_H__ +#define __BACKEND_LIBSECRET_H__ + +#include +#include + +typedef struct backend_libsecret_context_t +{ + SecretService* secret_service; + SecretCollection* secret_collection; +} backend_libsecret_context_t; + +/** + * Initializes a new libsecret backend context. + * + * @return The libsecret context + */ +const backend_libsecret_context_t* dt_pwstorage_libsecret_new(); + +/** + * Destroys the libsecret backend context. + * + * @param context The libsecret context + */ +void dt_pwstorage_libsecret_destroy(const backend_libsecret_context_t *context); + +/** + * Store (key,value) pairs. + * + * @param slot The slot + * @param hash_table List of (key,value) pairs + * + * @return TRUE If function succeeded, otherwise FALSE + */ +gboolean dt_pwstorage_libsecret_set(const backend_libsecret_context_t* context, + const gchar* slot, GHashTable* attributes); + +/** + * Loads (key, value) pairs + * + * @param context + * @param slot + * + * @return table List of (key,value) pairs + */ +GHashTable* dt_pwstorage_libsecret_get(const backend_libsecret_context_t* + context, const gchar* slot); + +#endif // __BACKEND_LIBSECRET_H__ + +// vim: shiftwidth=2 expandtab tabstop=2 cindent +// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-space on; diff --git a/src/common/pwstorage/pwstorage.c b/src/common/pwstorage/pwstorage.c index f16c072218fa..ba451d294d91 100644 --- a/src/common/pwstorage/pwstorage.c +++ b/src/common/pwstorage/pwstorage.c @@ -20,11 +20,17 @@ #include "pwstorage.h" +#ifdef HAVE_LIBSECRET +#include "backend_libsecret.h" +#endif + #ifdef HAVE_GKEYRING #include "backend_gkeyring.h" #endif +#ifdef HAVE_KWALLET #include "backend_kwallet.h" +#endif #include "control/conf.h" @@ -34,6 +40,17 @@ /** Initializes a new pwstorage context. */ const dt_pwstorage_t* dt_pwstorage_new() { + /* add password storage capabilities */ +#ifdef HAVE_LIBSECRET + dt_capabilities_add("libsecret"); +#endif +#ifdef HAVE_KWALLET + dt_capabilities_add("kwallet"); +#endif +#ifdef HAVE_GKEYRING + dt_capabilities_add("gnome-keyring"); +#endif + dt_pwstorage_t *pwstorage = g_malloc(sizeof(dt_pwstorage_t)); dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_new] Creating new context %p\n", pwstorage); @@ -41,30 +58,36 @@ const dt_pwstorage_t* dt_pwstorage_new() return NULL; gchar* _backend_str = dt_conf_get_string( "plugins/pwstorage/pwstorage_backend" ); - gint _backend = -1; + gint _backend = PW_STORAGE_BACKEND_NONE; if (strcmp(_backend_str, "auto") == 0) { const gchar *desktop = getenv("XDG_CURRENT_DESKTOP"); if (g_strcmp0(desktop, "KDE") == 0) _backend = PW_STORAGE_BACKEND_KWALLET; - else if (g_strcmp0(desktop, "GNOME") == 0) + if (g_strcmp0(desktop, "GNOME") == 0) _backend = PW_STORAGE_BACKEND_GNOME_KEYRING; else if (g_strcmp0(desktop, "Unity") == 0) _backend = PW_STORAGE_BACKEND_GNOME_KEYRING; else if (g_strcmp0(desktop, "XFCE") == 0) _backend = PW_STORAGE_BACKEND_GNOME_KEYRING; - else - _backend = PW_STORAGE_BACKEND_NONE; dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_new] autodetected storage backend.\n"); } else if(strcmp(_backend_str, "none") == 0) _backend = PW_STORAGE_BACKEND_NONE; +#ifdef HAVE_LIBSECRET + else if(strcmp(_backend_str, "libsecret") == 0) + _backend = PW_STORAGE_BACKEND_LIBSECRET; +#endif +#ifdef HAVE_KWALLET else if(strcmp(_backend_str, "kwallet") == 0) _backend = PW_STORAGE_BACKEND_KWALLET; +#endif +#ifdef HAVE_GKEYRING else if(strcmp(_backend_str, "gnome keyring") == 0) _backend = PW_STORAGE_BACKEND_GNOME_KEYRING; +#endif g_free(_backend_str); @@ -77,7 +100,26 @@ const dt_pwstorage_t* dt_pwstorage_new() pwstorage->backend_context = NULL; dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_new] no storage backend. not storing username/password. please change in preferences, core tab.\n"); break; + case PW_STORAGE_BACKEND_LIBSECRET: +#ifdef HAVE_LIBSECRET + dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_new] using libsecret backend for username/password storage"); + pwstorage->backend_context = (void*)dt_pwstorage_libsecret_new(); + if (pwstorage->backend_context == NULL) + { + dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_new] error starting libsecret. using no storage backend.\n"); + pwstorage->backend_context = NULL; + pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_NONE; + } else { + pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_LIBSECRET; + } + break; +#else + dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_new] libsecret backend not available. using no storage backend.\n"); + pwstorage->backend_context = NULL; + pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_NONE; +#endif case PW_STORAGE_BACKEND_KWALLET: +#ifdef HAVE_KWALLET dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_new] using kwallet backend for username/password storage"); pwstorage->backend_context = (void*)dt_pwstorage_kwallet_new(); if(pwstorage->backend_context == NULL) @@ -92,6 +134,11 @@ const dt_pwstorage_t* dt_pwstorage_new() } dt_print(DT_DEBUG_PWSTORAGE," done.\n"); break; +#else + dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_new] kwallet backend not available. using no storage backend.\n"); + pwstorage->backend_context = NULL; + pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_NONE; +#endif case PW_STORAGE_BACKEND_GNOME_KEYRING: #ifdef HAVE_GKEYRING dt_print (DT_DEBUG_PWSTORAGE,"[pwstorage_new] using gnome keyring backend for usersname/password storage.\n"); @@ -117,6 +164,9 @@ const dt_pwstorage_t* dt_pwstorage_new() case PW_STORAGE_BACKEND_NONE: dt_conf_set_string( "plugins/pwstorage/pwstorage_backend", "none" ); break; + case PW_STORAGE_BACKEND_LIBSECRET: + dt_conf_set_string( "plugins/pwstorage/pwstorage_backend", "libsecret" ); + break; case PW_STORAGE_BACKEND_KWALLET: dt_conf_set_string( "plugins/pwstorage/pwstorage_backend", "kwallet" ); break; @@ -137,8 +187,15 @@ void dt_pwstorage_destroy(const dt_pwstorage_t *pwstorage) case PW_STORAGE_BACKEND_NONE: // nothing to be done break; + case PW_STORAGE_BACKEND_LIBSECRET: +#ifdef HAVE_LIBSECRET + dt_pwstorage_libsecret_destroy(pwstorage->backend_context); +#endif + break; case PW_STORAGE_BACKEND_KWALLET: +#ifdef HAVE_KWALLET dt_pwstorage_kwallet_destroy(pwstorage->backend_context); +#endif break; case PW_STORAGE_BACKEND_GNOME_KEYRING: #ifdef HAVE_GKEYRING @@ -156,13 +213,20 @@ gboolean dt_pwstorage_set(const gchar* slot, GHashTable* table) case PW_STORAGE_BACKEND_NONE: dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_set] no backend. not storing anything.\n"); break; + case PW_STORAGE_BACKEND_LIBSECRET: +#if HAVE_LIBSECRET + return dt_pwstorage_libsecret_set((backend_libsecret_context_t*) + darktable.pwstorage->backend_context, slot, table); +#endif + break; case PW_STORAGE_BACKEND_KWALLET: +#ifdef HAVE_KWALLET return dt_pwstorage_kwallet_set((backend_kwallet_context_t*)darktable.pwstorage->backend_context, slot, table); +#endif + break; case PW_STORAGE_BACKEND_GNOME_KEYRING: #ifdef HAVE_GKEYRING return dt_pwstorage_gkeyring_set(slot, table); -#else - dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_set] no gkeyring backend support on this system. not storing anything.\n"); #endif break; } @@ -177,13 +241,20 @@ GHashTable* dt_pwstorage_get(const gchar* slot) case PW_STORAGE_BACKEND_NONE: dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_get] no backend. not reading anything.\n"); break; + case PW_STORAGE_BACKEND_LIBSECRET: +#if HAVE_LIBSECRET + return dt_pwstorage_libsecret_get((backend_libsecret_context_t*) + darktable.pwstorage->backend_context, slot); +#endif + break; case PW_STORAGE_BACKEND_KWALLET: +#ifdef HAVE_KWALLET return dt_pwstorage_kwallet_get((backend_kwallet_context_t*)darktable.pwstorage->backend_context, slot); +#endif + break; case PW_STORAGE_BACKEND_GNOME_KEYRING: #ifdef HAVE_GKEYRING return dt_pwstorage_gkeyring_get(slot); -#else - dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_get] no kwallet backend support on this system. not reading anything.\n"); #endif break; } diff --git a/src/common/pwstorage/pwstorage.h b/src/common/pwstorage/pwstorage.h index 76825a970ec9..32bff23945f1 100644 --- a/src/common/pwstorage/pwstorage.h +++ b/src/common/pwstorage/pwstorage.h @@ -23,7 +23,8 @@ typedef enum pw_storage_backend_t { PW_STORAGE_BACKEND_NONE = 0, PW_STORAGE_BACKEND_KWALLET, - PW_STORAGE_BACKEND_GNOME_KEYRING + PW_STORAGE_BACKEND_GNOME_KEYRING, + PW_STORAGE_BACKEND_LIBSECRET } pw_storage_backend_t; /** pwstorage context */