1 // This file is part of darktable
2 // Copyright (c) 2010-2016 Tobias Ellinghaus <me@houz.org>.
3
4 // darktable is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // darktable is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with darktable. If not, see <http://www.gnu.org/licenses/>.
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include "pwstorage.h"
22
23 #ifdef HAVE_LIBSECRET
24 #include "backend_libsecret.h"
25 #endif
26
27 #ifdef HAVE_KWALLET
28 #include "backend_kwallet.h"
29 #endif
30
31 #include "control/conf.h"
32 #include "control/control.h"
33
34 #include <glib.h>
35 #include <string.h>
36
37 /** Initializes a new pwstorage context. */
dt_pwstorage_new()38 const dt_pwstorage_t *dt_pwstorage_new()
39 {
40 /* add password storage capabilities */
41 #ifdef HAVE_LIBSECRET
42 dt_capabilities_add("libsecret");
43 #endif
44 #ifdef HAVE_KWALLET
45 dt_capabilities_add("kwallet");
46 #endif
47
48 dt_pwstorage_t *pwstorage = g_malloc(sizeof(dt_pwstorage_t));
49 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_new] Creating new context %p\n", pwstorage);
50
51 if(pwstorage == NULL) return NULL;
52
53 const char *_backend_str = dt_conf_get_string_const("plugins/pwstorage/pwstorage_backend");
54 gint _backend = PW_STORAGE_BACKEND_NONE;
55
56 if(strcmp(_backend_str, "auto") == 0)
57 {
58 const gchar *desktop = getenv("XDG_CURRENT_DESKTOP");
59 if(g_strcmp0(desktop, "KDE") == 0)
60 _backend = PW_STORAGE_BACKEND_KWALLET;
61 else if(g_strcmp0(desktop, "GNOME") == 0)
62 _backend = PW_STORAGE_BACKEND_LIBSECRET;
63 else if(g_strcmp0(desktop, "Unity") == 0)
64 _backend = PW_STORAGE_BACKEND_LIBSECRET;
65 else if(g_strcmp0(desktop, "XFCE") == 0)
66 _backend = PW_STORAGE_BACKEND_LIBSECRET;
67
68 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_new] autodetected storage backend.\n");
69 }
70 else if(strcmp(_backend_str, "none") == 0)
71 _backend = PW_STORAGE_BACKEND_NONE;
72 #ifdef HAVE_LIBSECRET
73 else if(strcmp(_backend_str, "libsecret") == 0)
74 _backend = PW_STORAGE_BACKEND_LIBSECRET;
75 #endif
76 #ifdef HAVE_KWALLET
77 else if(strcmp(_backend_str, "kwallet") == 0)
78 _backend = PW_STORAGE_BACKEND_KWALLET;
79 #endif
80 else if(strcmp(_backend_str, "gnome keyring") == 0)
81 {
82 fprintf(stderr, "[pwstorage_new] GNOME Keyring backend is no longer supported.\n");
83 dt_control_log(_("GNOME Keyring backend is no longer supported. configure a different one"));
84 _backend = PW_STORAGE_BACKEND_NONE;
85 }
86
87 switch(_backend)
88 {
89 default:
90 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_new] unknown storage backend. Using none.\n");
91 case PW_STORAGE_BACKEND_NONE:
92 pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_NONE;
93 pwstorage->backend_context = NULL;
94 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_new] no storage backend. not storing username/password. "
95 "please change in preferences, core tab.\n");
96 break;
97 case PW_STORAGE_BACKEND_LIBSECRET:
98 #ifdef HAVE_LIBSECRET
99 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_new] using libsecret backend for username/password storage.\n");
100 pwstorage->backend_context = (void *)dt_pwstorage_libsecret_new();
101 if(pwstorage->backend_context == NULL)
102 {
103 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_new] error starting libsecret. using no storage backend.\n");
104 pwstorage->backend_context = NULL;
105 pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_NONE;
106 }
107 else
108 {
109 pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_LIBSECRET;
110 }
111 break;
112 #else
113 dt_print(DT_DEBUG_PWSTORAGE,
114 "[pwstorage_new] libsecret backend not available. using no storage backend.\n");
115 pwstorage->backend_context = NULL;
116 pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_NONE;
117 #endif
118 case PW_STORAGE_BACKEND_KWALLET:
119 #ifdef HAVE_KWALLET
120 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_new] using kwallet backend for username/password storage.\n");
121 pwstorage->backend_context = (void *)dt_pwstorage_kwallet_new();
122 if(pwstorage->backend_context == NULL)
123 {
124 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_new] error starting kwallet. using no storage backend.\n");
125 pwstorage->backend_context = NULL;
126 pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_NONE;
127 }
128 else
129 {
130 pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_KWALLET;
131 }
132 dt_print(DT_DEBUG_PWSTORAGE, " done.\n");
133 break;
134 #else
135 dt_print(DT_DEBUG_PWSTORAGE,
136 "[pwstorage_new] kwallet backend not available. using no storage backend.\n");
137 pwstorage->backend_context = NULL;
138 pwstorage->pw_storage_backend = PW_STORAGE_BACKEND_NONE;
139 #endif
140 }
141
142 switch(pwstorage->pw_storage_backend)
143 {
144 case PW_STORAGE_BACKEND_NONE:
145 dt_conf_set_string("plugins/pwstorage/pwstorage_backend", "none");
146 break;
147 case PW_STORAGE_BACKEND_LIBSECRET:
148 dt_conf_set_string("plugins/pwstorage/pwstorage_backend", "libsecret");
149 break;
150 case PW_STORAGE_BACKEND_KWALLET:
151 dt_conf_set_string("plugins/pwstorage/pwstorage_backend", "kwallet");
152 break;
153 }
154
155 return pwstorage;
156 }
157
158 /** Cleanup and destroy pwstorage context. \remarks After this point pointer at pwstorage is invalid. */
dt_pwstorage_destroy(const dt_pwstorage_t * pwstorage)159 void dt_pwstorage_destroy(const dt_pwstorage_t *pwstorage)
160 {
161 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_new] Destroying context %p\n", pwstorage);
162 switch(darktable.pwstorage->pw_storage_backend)
163 {
164 case PW_STORAGE_BACKEND_NONE:
165 // nothing to be done
166 break;
167 case PW_STORAGE_BACKEND_LIBSECRET:
168 #ifdef HAVE_LIBSECRET
169 dt_pwstorage_libsecret_destroy(pwstorage->backend_context);
170 #endif
171 break;
172 case PW_STORAGE_BACKEND_KWALLET:
173 #ifdef HAVE_KWALLET
174 dt_pwstorage_kwallet_destroy(pwstorage->backend_context);
175 #endif
176 break;
177 }
178 }
179
180 /** Store (key,value) pairs. */
dt_pwstorage_set(const gchar * slot,GHashTable * table)181 gboolean dt_pwstorage_set(const gchar *slot, GHashTable *table)
182 {
183 switch(darktable.pwstorage->pw_storage_backend)
184 {
185 case PW_STORAGE_BACKEND_NONE:
186 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_set] no backend. not storing anything.\n");
187 break;
188 case PW_STORAGE_BACKEND_LIBSECRET:
189 #if HAVE_LIBSECRET
190 return dt_pwstorage_libsecret_set((backend_libsecret_context_t *)darktable.pwstorage->backend_context,
191 slot, table);
192 #endif
193 break;
194 case PW_STORAGE_BACKEND_KWALLET:
195 #ifdef HAVE_KWALLET
196 return dt_pwstorage_kwallet_set((backend_kwallet_context_t *)darktable.pwstorage->backend_context, slot,
197 table);
198 #endif
199 break;
200 }
201 return FALSE;
202 }
203
204 /** Load (key,value) pairs. */
dt_pwstorage_get(const gchar * slot)205 GHashTable *dt_pwstorage_get(const gchar *slot)
206 {
207 switch(darktable.pwstorage->pw_storage_backend)
208 {
209 case PW_STORAGE_BACKEND_NONE:
210 dt_print(DT_DEBUG_PWSTORAGE, "[pwstorage_get] no backend. not reading anything.\n");
211 break;
212 case PW_STORAGE_BACKEND_LIBSECRET:
213 #if HAVE_LIBSECRET
214 return dt_pwstorage_libsecret_get((backend_libsecret_context_t *)darktable.pwstorage->backend_context,
215 slot);
216 #endif
217 break;
218 case PW_STORAGE_BACKEND_KWALLET:
219 #ifdef HAVE_KWALLET
220 return dt_pwstorage_kwallet_get((backend_kwallet_context_t *)darktable.pwstorage->backend_context, slot);
221 #endif
222 break;
223 }
224
225 return g_hash_table_new(g_str_hash, g_str_equal);
226 }
227
228 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
229 // vim: shiftwidth=2 expandtab tabstop=2 cindent
230 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
231