OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/password_manager/password_store_gnome.h" | 5 #include "chrome/browser/password_manager/native_backend_gnome_x.h" |
6 | 6 |
7 #if defined(DLOPEN_GNOME_KEYRING) | 7 #if defined(DLOPEN_GNOME_KEYRING) |
8 #include <dlfcn.h> | 8 #include <dlfcn.h> |
9 #endif | 9 #endif |
10 | 10 |
11 #include <map> | 11 #include <map> |
12 #include <string> | 12 #include <string> |
13 | 13 |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
16 #include "base/task.h" | |
17 #include "base/time.h" | 16 #include "base/time.h" |
18 #include "base/utf_string_conversions.h" | 17 #include "base/utf_string_conversions.h" |
| 18 #include "chrome/browser/chrome_thread.h" |
19 | 19 |
20 using std::map; | 20 using std::map; |
21 using std::string; | 21 using std::string; |
22 using std::vector; | |
23 using webkit_glue::PasswordForm; | 22 using webkit_glue::PasswordForm; |
24 | 23 |
25 /* Many of the gnome_keyring_* functions use variable arguments, which makes | 24 /* Many of the gnome_keyring_* functions use variable arguments, which makes |
26 * them difficult if not impossible to wrap in C. Therefore, we want the | 25 * them difficult if not impossible to wrap in C. Therefore, we want the |
27 * actual uses below to either call the functions directly (if we are linking | 26 * actual uses below to either call the functions directly (if we are linking |
28 * against libgnome-keyring), or call them via appropriately-typed function | 27 * against libgnome-keyring), or call them via appropriately-typed function |
29 * pointers (if we are dynamically loading libgnome-keyring). | 28 * pointers (if we are dynamically loading libgnome-keyring). |
30 * | 29 * |
31 * Thus, instead of making a wrapper class with two implementations, we use | 30 * Thus, instead of making a wrapper class with two implementations, we use |
32 * the preprocessor to rename the calls below in the dynamic load case, and | 31 * the preprocessor to rename the calls below in the dynamic load case, and |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 return true; | 128 return true; |
130 } | 129 } |
131 | 130 |
132 } // namespace | 131 } // namespace |
133 | 132 |
134 #endif // DLOPEN_GNOME_KEYRING | 133 #endif // DLOPEN_GNOME_KEYRING |
135 | 134 |
136 #define GNOME_KEYRING_APPLICATION_CHROME "chrome" | 135 #define GNOME_KEYRING_APPLICATION_CHROME "chrome" |
137 | 136 |
138 // Schema is analagous to the fields in PasswordForm. | 137 // Schema is analagous to the fields in PasswordForm. |
139 const GnomeKeyringPasswordSchema PasswordStoreGnome::kGnomeSchema = { | 138 const GnomeKeyringPasswordSchema NativeBackendGnome::kGnomeSchema = { |
140 GNOME_KEYRING_ITEM_GENERIC_SECRET, { | 139 GNOME_KEYRING_ITEM_GENERIC_SECRET, { |
141 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 140 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
142 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 141 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
143 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 142 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
144 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 143 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
145 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 144 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
146 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 145 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
147 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 146 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
148 { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 147 { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
149 { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 148 { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
150 { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 149 { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
151 { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 150 { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
152 { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 151 { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
153 // This field is always "chrome" so that we can search for it. | 152 // This field is always "chrome" so that we can search for it. |
154 { "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 153 { "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
155 { NULL } | 154 { NULL } |
156 } | 155 } |
157 }; | 156 }; |
158 | 157 |
159 PasswordStoreGnome::PasswordStoreGnome(LoginDatabase* login_db, | 158 NativeBackendGnome::NativeBackendGnome() { |
160 Profile* profile, | |
161 WebDataService* web_data_service) { | |
162 } | 159 } |
163 | 160 |
164 PasswordStoreGnome::~PasswordStoreGnome() { | 161 NativeBackendGnome::~NativeBackendGnome() { |
165 } | 162 } |
166 | 163 |
167 bool PasswordStoreGnome::Init() { | 164 bool NativeBackendGnome::Init() { |
168 return PasswordStore::Init() && | 165 return LoadGnomeKeyring() && gnome_keyring_is_available(); |
169 LoadGnomeKeyring() && | |
170 gnome_keyring_is_available(); | |
171 } | 166 } |
172 | 167 |
173 void PasswordStoreGnome::AddLoginImpl(const PasswordForm& form) { | 168 bool NativeBackendGnome::AddLogin(const PasswordForm& form) { |
174 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); | 169 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
175 AddLoginHelper(form, base::Time::Now()); | 170 GnomeKeyringResult result = gnome_keyring_store_password_sync( |
| 171 &kGnomeSchema, |
| 172 NULL, // Default keyring. |
| 173 form.origin.spec().c_str(), // Display name. |
| 174 UTF16ToUTF8(form.password_value).c_str(), |
| 175 "origin_url", form.origin.spec().c_str(), |
| 176 "action_url", form.action.spec().c_str(), |
| 177 "username_element", UTF16ToUTF8(form.username_element).c_str(), |
| 178 "username_value", UTF16ToUTF8(form.username_value).c_str(), |
| 179 "password_element", UTF16ToUTF8(form.password_element).c_str(), |
| 180 "submit_element", UTF16ToUTF8(form.submit_element).c_str(), |
| 181 "signon_realm", form.signon_realm.c_str(), |
| 182 "ssl_valid", form.ssl_valid, |
| 183 "preferred", form.preferred, |
| 184 "date_created", Int64ToString(form.date_created.ToTimeT()).c_str(), |
| 185 "blacklisted_by_user", form.blacklisted_by_user, |
| 186 "scheme", form.scheme, |
| 187 "application", GNOME_KEYRING_APPLICATION_CHROME, |
| 188 NULL); |
| 189 |
| 190 if (result != GNOME_KEYRING_RESULT_OK) { |
| 191 LOG(ERROR) << "Keyring save failed: " |
| 192 << gnome_keyring_result_to_message(result); |
| 193 return false; |
| 194 } |
| 195 return true; |
176 } | 196 } |
177 | 197 |
178 void PasswordStoreGnome::UpdateLoginImpl(const PasswordForm& form) { | 198 bool NativeBackendGnome::UpdateLogin(const PasswordForm& form) { |
179 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by | 199 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by |
180 // origin_url, username_element, username_value, password_element, and | 200 // origin_url, username_element, username_value, password_element, and |
181 // signon_realm. We then compare the result to the updated form. If they | 201 // signon_realm. We then compare the result to the updated form. If they |
182 // differ in any of the action, password_value, ssl_valid, or preferred | 202 // differ in any of the action, password_value, ssl_valid, or preferred |
183 // fields, then we add a new login with those fields updated and only delete | 203 // fields, then we add a new login with those fields updated and only delete |
184 // the original on success. | 204 // the original on success. |
185 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); | 205 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
186 GList* found = NULL; | 206 GList* found = NULL; |
187 // Search gnome keyring for matching passwords. | 207 // Search gnome keyring for matching passwords. |
188 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( | 208 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( |
189 GNOME_KEYRING_ITEM_GENERIC_SECRET, | 209 GNOME_KEYRING_ITEM_GENERIC_SECRET, |
190 &found, | 210 &found, |
191 "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 211 "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
192 form.origin.spec().c_str(), | 212 form.origin.spec().c_str(), |
193 "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 213 "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
194 UTF16ToUTF8(form.username_element).c_str(), | 214 UTF16ToUTF8(form.username_element).c_str(), |
195 "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 215 "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
196 UTF16ToUTF8(form.username_value).c_str(), | 216 UTF16ToUTF8(form.username_value).c_str(), |
197 "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 217 "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
198 UTF16ToUTF8(form.password_element).c_str(), | 218 UTF16ToUTF8(form.password_element).c_str(), |
199 "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 219 "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
200 form.signon_realm.c_str(), | 220 form.signon_realm.c_str(), |
201 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 221 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
202 GNOME_KEYRING_APPLICATION_CHROME, | 222 GNOME_KEYRING_APPLICATION_CHROME, |
203 NULL); | 223 NULL); |
204 vector<PasswordForm*> forms; | 224 if (result != GNOME_KEYRING_RESULT_OK) { |
205 if (result == GNOME_KEYRING_RESULT_OK) { | |
206 FillFormVector(found, &forms); | |
207 for (size_t i = 0; i < forms.size(); ++i) { | |
208 if (forms[i]->action != form.action || | |
209 forms[i]->password_value != form.password_value || | |
210 forms[i]->ssl_valid != form.ssl_valid || | |
211 forms[i]->preferred != form.preferred) { | |
212 PasswordForm updated = *forms[i]; | |
213 updated.action = form.action; | |
214 updated.password_value = form.password_value; | |
215 updated.ssl_valid = form.ssl_valid; | |
216 updated.preferred = form.preferred; | |
217 if (AddLoginHelper(updated, updated.date_created)) | |
218 RemoveLoginImpl(*forms[i]); | |
219 } | |
220 delete forms[i]; | |
221 } | |
222 } else { | |
223 LOG(ERROR) << "Keyring find failed: " | 225 LOG(ERROR) << "Keyring find failed: " |
224 << gnome_keyring_result_to_message(result); | 226 << gnome_keyring_result_to_message(result); |
| 227 return false; |
225 } | 228 } |
| 229 bool ok = true; |
| 230 PasswordFormList forms; |
| 231 ConvertFormList(found, &forms); |
| 232 for (size_t i = 0; i < forms.size(); ++i) { |
| 233 if (forms[i]->action != form.action || |
| 234 forms[i]->password_value != form.password_value || |
| 235 forms[i]->ssl_valid != form.ssl_valid || |
| 236 forms[i]->preferred != form.preferred) { |
| 237 PasswordForm updated = *forms[i]; |
| 238 updated.action = form.action; |
| 239 updated.password_value = form.password_value; |
| 240 updated.ssl_valid = form.ssl_valid; |
| 241 updated.preferred = form.preferred; |
| 242 if (AddLogin(updated)) |
| 243 RemoveLogin(*forms[i]); |
| 244 else |
| 245 ok = false; |
| 246 } |
| 247 delete forms[i]; |
| 248 } |
| 249 return ok; |
226 } | 250 } |
227 | 251 |
228 void PasswordStoreGnome::RemoveLoginImpl(const PasswordForm& form) { | 252 bool NativeBackendGnome::RemoveLogin(const PasswordForm& form) { |
229 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); | 253 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
230 // We find forms using the same fields as LoginDatabase::RemoveLogin(). | 254 // We find forms using the same fields as LoginDatabase::RemoveLogin(). |
231 GnomeKeyringResult result = gnome_keyring_delete_password_sync( | 255 GnomeKeyringResult result = gnome_keyring_delete_password_sync( |
232 &kGnomeSchema, | 256 &kGnomeSchema, |
233 "origin_url", form.origin.spec().c_str(), | 257 "origin_url", form.origin.spec().c_str(), |
234 "action_url", form.action.spec().c_str(), | 258 "action_url", form.action.spec().c_str(), |
235 "username_element", UTF16ToUTF8(form.username_element).c_str(), | 259 "username_element", UTF16ToUTF8(form.username_element).c_str(), |
236 "username_value", UTF16ToUTF8(form.username_value).c_str(), | 260 "username_value", UTF16ToUTF8(form.username_value).c_str(), |
237 "password_element", UTF16ToUTF8(form.password_element).c_str(), | 261 "password_element", UTF16ToUTF8(form.password_element).c_str(), |
238 "submit_element", UTF16ToUTF8(form.submit_element).c_str(), | 262 "submit_element", UTF16ToUTF8(form.submit_element).c_str(), |
239 "signon_realm", form.signon_realm.c_str(), | 263 "signon_realm", form.signon_realm.c_str(), |
240 NULL); | 264 NULL); |
241 if (result != GNOME_KEYRING_RESULT_OK) { | 265 if (result != GNOME_KEYRING_RESULT_OK) { |
242 LOG(ERROR) << "Keyring delete failed: " | 266 LOG(ERROR) << "Keyring delete failed: " |
243 << gnome_keyring_result_to_message(result); | 267 << gnome_keyring_result_to_message(result); |
| 268 return false; |
244 } | 269 } |
| 270 return true; |
245 } | 271 } |
246 | 272 |
247 void PasswordStoreGnome::RemoveLoginsCreatedBetweenImpl( | 273 bool NativeBackendGnome::RemoveLoginsCreatedBetween( |
248 const base::Time& delete_begin, | 274 const base::Time& delete_begin, |
249 const base::Time& delete_end) { | 275 const base::Time& delete_end) { |
250 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); | 276 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
251 GList* found = NULL; | 277 bool ok = true; |
252 // Search GNOME keyring for all passwords, then delete the ones in the range. | 278 // We could walk the list and delete items as we find them, but it is much |
253 // We need to search for something, otherwise we get no results - so we search | 279 // easier to build the list and use RemoveLogin() to delete them. |
254 // for the fixed application string. | 280 PasswordFormList forms; |
255 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( | 281 if (!GetAllLogins(&forms)) |
256 GNOME_KEYRING_ITEM_GENERIC_SECRET, | 282 return false; |
257 &found, | 283 |
258 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 284 for (size_t i = 0; i < forms.size(); ++i) { |
259 GNOME_KEYRING_APPLICATION_CHROME, | 285 if (delete_begin <= forms[i]->date_created && |
260 NULL); | 286 (delete_end.is_null() || forms[i]->date_created < delete_end)) { |
261 if (result == GNOME_KEYRING_RESULT_OK) { | 287 if (!RemoveLogin(*forms[i])) |
262 // We could walk the list and delete items as we find them, but it is much | 288 ok = false; |
263 // easier to build the vector and use RemoveLoginImpl() to delete them. | |
264 vector<PasswordForm*> forms; | |
265 FillFormVector(found, &forms); | |
266 for (size_t i = 0; i < forms.size(); ++i) { | |
267 if (delete_begin <= forms[i]->date_created && | |
268 (delete_end.is_null() || forms[i]->date_created < delete_end)) { | |
269 RemoveLoginImpl(*forms[i]); | |
270 } | |
271 delete forms[i]; | |
272 } | 289 } |
273 } else if (result != GNOME_KEYRING_RESULT_NO_MATCH) { | 290 delete forms[i]; |
274 LOG(ERROR) << "Keyring find failed: " | |
275 << gnome_keyring_result_to_message(result); | |
276 } | 291 } |
| 292 return ok; |
277 } | 293 } |
278 | 294 |
279 void PasswordStoreGnome::GetLoginsImpl(GetLoginsRequest* request, | 295 bool NativeBackendGnome::GetLogins(const PasswordForm& form, |
280 const PasswordForm& form) { | 296 PasswordFormList* forms) { |
281 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); | 297 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
282 GList* found = NULL; | 298 GList* found = NULL; |
283 // Search gnome keyring for matching passwords. | 299 // Search gnome keyring for matching passwords. |
284 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( | 300 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( |
285 GNOME_KEYRING_ITEM_GENERIC_SECRET, | 301 GNOME_KEYRING_ITEM_GENERIC_SECRET, |
286 &found, | 302 &found, |
287 "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 303 "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
288 form.signon_realm.c_str(), | 304 form.signon_realm.c_str(), |
289 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 305 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
290 GNOME_KEYRING_APPLICATION_CHROME, | 306 GNOME_KEYRING_APPLICATION_CHROME, |
291 NULL); | 307 NULL); |
292 vector<PasswordForm*> forms; | 308 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
293 if (result == GNOME_KEYRING_RESULT_OK) { | 309 return true; |
294 FillFormVector(found, &forms); | 310 if (result != GNOME_KEYRING_RESULT_OK) { |
295 } else if (result != GNOME_KEYRING_RESULT_NO_MATCH) { | |
296 LOG(ERROR) << "Keyring find failed: " | 311 LOG(ERROR) << "Keyring find failed: " |
297 << gnome_keyring_result_to_message(result); | 312 << gnome_keyring_result_to_message(result); |
298 } | |
299 NotifyConsumer(request, forms); | |
300 } | |
301 | |
302 void PasswordStoreGnome::GetAutofillableLoginsImpl( | |
303 GetLoginsRequest* request) { | |
304 std::vector<PasswordForm*> forms; | |
305 FillAutofillableLogins(&forms); | |
306 NotifyConsumer(request, forms); | |
307 } | |
308 | |
309 void PasswordStoreGnome::GetBlacklistLoginsImpl( | |
310 GetLoginsRequest* request) { | |
311 std::vector<PasswordForm*> forms; | |
312 FillBlacklistLogins(&forms); | |
313 NotifyConsumer(request, forms); | |
314 } | |
315 | |
316 bool PasswordStoreGnome::FillAutofillableLogins( | |
317 std::vector<PasswordForm*>* forms) { | |
318 return FillSomeLogins(true, forms); | |
319 } | |
320 | |
321 bool PasswordStoreGnome::FillBlacklistLogins( | |
322 std::vector<PasswordForm*>* forms) { | |
323 return FillSomeLogins(false, forms); | |
324 } | |
325 | |
326 bool PasswordStoreGnome::AddLoginHelper(const PasswordForm& form, | |
327 const base::Time& date_created) { | |
328 GnomeKeyringResult result = gnome_keyring_store_password_sync( | |
329 &kGnomeSchema, | |
330 NULL, // Default keyring. | |
331 form.origin.spec().c_str(), // Display name. | |
332 UTF16ToUTF8(form.password_value).c_str(), | |
333 "origin_url", form.origin.spec().c_str(), | |
334 "action_url", form.action.spec().c_str(), | |
335 "username_element", UTF16ToUTF8(form.username_element).c_str(), | |
336 "username_value", UTF16ToUTF8(form.username_value).c_str(), | |
337 "password_element", UTF16ToUTF8(form.password_element).c_str(), | |
338 "submit_element", UTF16ToUTF8(form.submit_element).c_str(), | |
339 "signon_realm", form.signon_realm.c_str(), | |
340 "ssl_valid", form.ssl_valid, | |
341 "preferred", form.preferred, | |
342 "date_created", Int64ToString(date_created.ToTimeT()).c_str(), | |
343 "blacklisted_by_user", form.blacklisted_by_user, | |
344 "scheme", form.scheme, | |
345 "application", GNOME_KEYRING_APPLICATION_CHROME, | |
346 NULL); | |
347 | |
348 if (result != GNOME_KEYRING_RESULT_OK) { | |
349 LOG(ERROR) << "Keyring save failed: " | |
350 << gnome_keyring_result_to_message(result); | |
351 return false; | 313 return false; |
352 } | 314 } |
| 315 ConvertFormList(found, forms); |
353 return true; | 316 return true; |
354 } | 317 } |
355 | 318 |
356 bool PasswordStoreGnome::FillSomeLogins( | 319 bool NativeBackendGnome::GetLoginsCreatedBetween(const base::Time& get_begin, |
357 bool autofillable, | 320 const base::Time& get_end, |
358 std::vector<PasswordForm*>* forms) { | 321 PasswordFormList* forms) { |
| 322 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
| 323 // We could walk the list and add items as we find them, but it is much |
| 324 // easier to build the list and then filter the results. |
| 325 PasswordFormList all_forms; |
| 326 if (!GetAllLogins(&all_forms)) |
| 327 return false; |
| 328 |
| 329 forms->reserve(forms->size() + all_forms.size()); |
| 330 for (size_t i = 0; i < all_forms.size(); ++i) { |
| 331 if (get_begin <= all_forms[i]->date_created && |
| 332 (get_end.is_null() || all_forms[i]->date_created < get_end)) { |
| 333 forms->push_back(all_forms[i]); |
| 334 } else { |
| 335 delete all_forms[i]; |
| 336 } |
| 337 } |
| 338 |
| 339 return true; |
| 340 } |
| 341 |
| 342 bool NativeBackendGnome::GetAutofillableLogins(PasswordFormList* forms) { |
| 343 return GetLoginsList(forms, true); |
| 344 } |
| 345 |
| 346 bool NativeBackendGnome::GetBlacklistLogins(PasswordFormList* forms) { |
| 347 return GetLoginsList(forms, false); |
| 348 } |
| 349 |
| 350 bool NativeBackendGnome::GetLoginsList(PasswordFormList* forms, |
| 351 bool autofillable) { |
359 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); | 352 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
360 GList* found = NULL; | 353 GList* found = NULL; |
361 uint32_t blacklisted_by_user = !autofillable; | 354 uint32_t blacklisted_by_user = !autofillable; |
362 // Search gnome keyring for matching passwords. | 355 // Search gnome keyring for matching passwords. |
363 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( | 356 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( |
364 GNOME_KEYRING_ITEM_GENERIC_SECRET, | 357 GNOME_KEYRING_ITEM_GENERIC_SECRET, |
365 &found, | 358 &found, |
366 "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32, | 359 "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32, |
367 blacklisted_by_user, | 360 blacklisted_by_user, |
368 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 361 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
369 GNOME_KEYRING_APPLICATION_CHROME, | 362 GNOME_KEYRING_APPLICATION_CHROME, |
370 NULL); | 363 NULL); |
371 if (result == GNOME_KEYRING_RESULT_OK) { | 364 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
372 FillFormVector(found, forms); | 365 return true; |
373 } else if (result != GNOME_KEYRING_RESULT_NO_MATCH) { | 366 if (result != GNOME_KEYRING_RESULT_OK) { |
374 LOG(ERROR) << "Keyring find failed: " | 367 LOG(ERROR) << "Keyring find failed: " |
375 << gnome_keyring_result_to_message(result); | 368 << gnome_keyring_result_to_message(result); |
376 return false; | 369 return false; |
377 } | 370 } |
| 371 ConvertFormList(found, forms); |
378 return true; | 372 return true; |
379 } | 373 } |
380 | 374 |
381 void PasswordStoreGnome::FillFormVector(GList* found, | 375 bool NativeBackendGnome::GetAllLogins(PasswordFormList* forms) { |
382 std::vector<PasswordForm*>* forms) { | 376 GList* found = NULL; |
| 377 // We need to search for something, otherwise we get no results - so we search |
| 378 // for the fixed application string. |
| 379 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( |
| 380 GNOME_KEYRING_ITEM_GENERIC_SECRET, |
| 381 &found, |
| 382 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 383 GNOME_KEYRING_APPLICATION_CHROME, |
| 384 NULL); |
| 385 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
| 386 return true; |
| 387 if (result != GNOME_KEYRING_RESULT_OK) { |
| 388 LOG(ERROR) << "Keyring find failed: " |
| 389 << gnome_keyring_result_to_message(result); |
| 390 return false; |
| 391 } |
| 392 ConvertFormList(found, forms); |
| 393 return true; |
| 394 } |
| 395 |
| 396 void NativeBackendGnome::ConvertFormList(GList* found, |
| 397 PasswordFormList* forms) { |
383 GList* element = g_list_first(found); | 398 GList* element = g_list_first(found); |
384 while (element != NULL) { | 399 while (element != NULL) { |
385 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); | 400 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); |
386 char* password = data->secret; | 401 char* password = data->secret; |
387 | 402 |
388 GnomeKeyringAttributeList* attributes = data->attributes; | 403 GnomeKeyringAttributeList* attributes = data->attributes; |
389 // Read the string and int attributes into the appropriate map. | 404 // Read the string and int attributes into the appropriate map. |
390 map<string, string> string_attribute_map; | 405 map<string, string> string_attribute_map; |
391 map<string, uint32> uint_attribute_map; | 406 map<string, uint32> uint_attribute_map; |
392 for (unsigned int i = 0; i < attributes->len; ++i) { | 407 for (unsigned int i = 0; i < attributes->len; ++i) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 form->blacklisted_by_user = uint_attribute_map["blacklisted_by_user"]; | 439 form->blacklisted_by_user = uint_attribute_map["blacklisted_by_user"]; |
425 form->scheme = static_cast<PasswordForm::Scheme>( | 440 form->scheme = static_cast<PasswordForm::Scheme>( |
426 uint_attribute_map["scheme"]); | 441 uint_attribute_map["scheme"]); |
427 | 442 |
428 forms->push_back(form); | 443 forms->push_back(form); |
429 | 444 |
430 element = g_list_next(element); | 445 element = g_list_next(element); |
431 } | 446 } |
432 gnome_keyring_found_list_free(found); | 447 gnome_keyring_found_list_free(found); |
433 } | 448 } |
OLD | NEW |