1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/native_backend_gnome_x.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <dbus/dbus-glib.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <dlfcn.h> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gnome-keyring.h> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map> 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/synchronization/waitable_event.h" 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::PasswordForm; 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Many of the gnome_keyring_* functions use variable arguments, which makes 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// them difficult if not impossible to wrap in C. Therefore, we want the 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// actual uses below to either call the functions directly (if we are linking 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// against libgnome-keyring), or call them via appropriately-typed function 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// pointers (if we are dynamically loading libgnome-keyring). 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Thus, instead of making a wrapper class with two implementations, we use 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the preprocessor to rename the calls below in the dynamic load case, and 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// provide a function to initialize a set of function pointers that have the 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// alternate names. We also make sure the types are correct, since otherwise 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// dynamic loading like this would leave us vulnerable to signature changes. 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(DLOPEN_GNOME_KEYRING) 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Call a given parameter with the name of each function we use from GNOME 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Keyring. 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define GNOME_KEYRING_FOR_EACH_FUNC(F) \ 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch F(is_available) \ 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch F(store_password) \ 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch F(delete_password) \ 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch F(find_itemsv) \ 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch F(result_to_message) \ 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen F(list_keyring_names) \ 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch F(list_item_ids) \ 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch F(item_get_attributes) \ 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch F(item_get_info) \ 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch F(item_info_get_secret) 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Define the actual function pointers that we'll use in application code. 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define GNOME_KEYRING_DEFINE_WRAPPER(name) \ 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typeof(&gnome_keyring_##name) wrap_gnome_keyring_##name; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_DEFINE_WRAPPER) 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#undef GNOME_KEYRING_DEFINE_WRAPPER 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make it easy to initialize the function pointers above with a loop below. 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define GNOME_KEYRING_FUNCTION(name) \ 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch {"gnome_keyring_"#name, reinterpret_cast<void**>(&wrap_gnome_keyring_##name)}, 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst struct { 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* name; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void** pointer; 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} gnome_keyring_functions[] = { 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_FUNCTION) 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch {NULL, NULL} 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#undef GNOME_KEYRING_FUNCTION 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#undef GNOME_KEYRING_FOR_EACH_FUNC 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Allow application code below to use the normal function names, but actually 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// end up using the function pointers above instead. 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define gnome_keyring_is_available \ 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_gnome_keyring_is_available 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define gnome_keyring_store_password \ 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_gnome_keyring_store_password 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define gnome_keyring_delete_password \ 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_gnome_keyring_delete_password 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define gnome_keyring_find_itemsv \ 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_gnome_keyring_find_itemsv 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define gnome_keyring_result_to_message \ 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_gnome_keyring_result_to_message 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define gnome_keyring_list_keyring_names \ 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wrap_gnome_keyring_list_keyring_names 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define gnome_keyring_list_item_ids \ 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_gnome_keyring_list_item_ids 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define gnome_keyring_item_get_attributes \ 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_gnome_keyring_item_get_attributes 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define gnome_keyring_item_get_info \ 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_gnome_keyring_item_get_info 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define gnome_keyring_item_info_get_secret \ 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_gnome_keyring_item_info_get_secret 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/* Load the library and initialize the function pointers. */ 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool LoadGnomeKeyring() { 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* handle = dlopen("libgnome-keyring.so.0", RTLD_NOW | RTLD_GLOBAL); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!handle) { 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We wanted to use GNOME Keyring, but we couldn't load it. Warn, because 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // either the user asked for this, or we autodetected it incorrectly. (Or 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the system has broken libraries, which is also good to warn about.) 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Could not load libgnome-keyring.so.0: " << dlerror(); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; gnome_keyring_functions[i].name; ++i) { 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dlerror(); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *gnome_keyring_functions[i].pointer = 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dlsym(handle, gnome_keyring_functions[i].name); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* error = dlerror(); 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (error) { 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Unable to load symbol " 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_functions[i].name << ": " << error; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dlclose(handle); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We leak the library handle. That's OK: this function is called only once. 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Older versions of GNOME Keyring have bugs that prevent them from working 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// correctly with the find_itemsv API. (In particular, the non-pageable memory 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// allocator is rather busted.) There is no official way to check the version, 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// nor could we figure out any reasonable unofficial way to do it. So we work 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// around it by using a much slower API. 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else // !defined(DLOPEN_GNOME_KEYRING) 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool LoadGnomeKeyring() { 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't need to do anything here. When linking directly, we also assume 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that whoever is compiling this code has checked that the version is OK. 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // !defined(DLOPEN_GNOME_KEYRING) 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define GNOME_KEYRING_APPLICATION_CHROME "chrome" 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Convert the attributes of a given keyring entry into a new PasswordForm. 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note: does *not* get the actual password, as that is not a key attribute! 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns NULL if the attributes are for the wrong application. 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPasswordForm* FormFromAttributes(GnomeKeyringAttributeList* attrs) { 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read the string and int attributes into the appropriate map. 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::map<std::string, std::string> string_attr_map; 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::map<std::string, uint32_t> uint_attr_map; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (guint i = 0; i < attrs->len; ++i) { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringAttribute attr = gnome_keyring_attribute_list_index(attrs, i); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (attr.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string_attr_map[attr.name] = attr.value.string; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else if (attr.type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint_attr_map[attr.name] = attr.value.integer; 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check to make sure this is a password we care about. 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (string_attr_map["application"] != GNOME_KEYRING_APPLICATION_CHROME) 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* form = new PasswordForm(); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->origin = GURL(string_attr_map["origin_url"]); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->action = GURL(string_attr_map["action_url"]); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->username_element = UTF8ToUTF16(string_attr_map["username_element"]); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->username_value = UTF8ToUTF16(string_attr_map["username_value"]); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->password_element = UTF8ToUTF16(string_attr_map["password_element"]); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->submit_element = UTF8ToUTF16(string_attr_map["submit_element"]); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->signon_realm = string_attr_map["signon_realm"]; 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->ssl_valid = uint_attr_map["ssl_valid"]; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->preferred = uint_attr_map["preferred"]; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64 date_created = 0; 1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool date_ok = base::StringToInt64(string_attr_map["date_created"], 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick &date_created); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(date_ok); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->date_created = base::Time::FromTimeT(date_created); 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->blacklisted_by_user = uint_attr_map["blacklisted_by_user"]; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->scheme = static_cast<PasswordForm::Scheme>(uint_attr_map["scheme"]); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return form; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Parse all the results from the given GList into a PasswordFormList, and free 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the GList. PasswordForms are allocated on the heap, and should be deleted by 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the consumer. 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConvertFormList(GList* found, 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NativeBackendGnome::PasswordFormList* forms) { 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GList* element = g_list_first(found); 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (element != NULL) { 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringAttributeList* attrs = data->attributes; 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* form = FormFromAttributes(attrs); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form) { 19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (data->secret) { 19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen form->password_value = UTF8ToUTF16(data->secret); 19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(WARNING) << "Unable to access password from list element!"; 19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->push_back(form); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Could not initialize PasswordForm from attributes!"; 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch element = g_list_next(element); 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Schema is analagous to the fields in PasswordForm. 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst GnomeKeyringPasswordSchema kGnomeSchema = { 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_ITEM_GENERIC_SECRET, { 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This field is always "chrome" so that we can search for it. 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { NULL } 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Sadly, PasswordStore goes to great lengths to switch from the originally 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// calling thread to the DB thread, and to provide an asynchronous API to 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// callers while using a synchronous (virtual) API provided by subclasses like 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// PasswordStoreX -- but GNOME Keyring really wants to be on the GLib main 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// thread, which is the UI thread to us. So we end up having to switch threads 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// again, possibly back to the very same thread (in case the UI thread is the 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// caller, e.g. in the password management UI), and *block* the DB thread 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// waiting for a response from the UI thread to provide the synchronous API 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// PasswordStore expects of us. (It will then in turn switch back to the 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// original caller to send the asynchronous reply to the original request.) 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class represents a call to a GNOME Keyring method. A RunnableMethod 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// should be posted to the UI thread to call one of its action methods, and then 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a WaitResult() method should be called to wait for the result. Each instance 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// supports only one outstanding method at a time, though multiple instances may 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// be used in parallel. 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass GKRMethod { 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef NativeBackendGnome::PasswordFormList PasswordFormList; 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod() : event_(false, false), result_(GNOME_KEYRING_RESULT_CANCELLED) {} 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Action methods. These call gnome_keyring_* functions. Call from UI thread. 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AddLogin(const PasswordForm& form); 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void AddLoginSearch(const PasswordForm& form); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void UpdateLoginSearch(const PasswordForm& form); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RemoveLogin(const PasswordForm& form); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void GetLogins(const PasswordForm& form); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION) 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void GetLoginsList(uint32_t blacklisted_by_user); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void GetAllLogins(); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void GetKeyrings(); 262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void GetItemIds(const char* keyring); 263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void GetItemAttrs(const char* keyring, guint id); 264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void GetItemInfo(const char* keyring, guint id); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use after AddLogin, RemoveLogin. 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult WaitResult(); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList, 271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // GetAllLogins. 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult WaitResult(PasswordFormList* forms); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION) 275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Use after GetKeyrings(). 276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GnomeKeyringResult WaitResult(std::vector<std::string>* keyrings); 277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use after GetItemIds(). 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult WaitResult(std::vector<guint>* item_ids); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use after GetItemAttrs(). 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult WaitResult(PasswordForm** form); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use after GetItemInfo(). 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult WaitResult(string16* password); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All these callbacks are called on UI thread. 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void OnOperationDone(GnomeKeyringResult result, gpointer data); 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void OnOperationGetList(GnomeKeyringResult result, GList* list, 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer data); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION) 296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static void OnOperationGetKeyrings(GnomeKeyringResult result, GList* list, 297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gpointer data); 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void OnOperationGetIds(GnomeKeyringResult result, GList* list, 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer data); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void OnOperationGetAttrs(GnomeKeyringResult result, 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringAttributeList* attrs, 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer data); 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void OnOperationGetInfo(GnomeKeyringResult result, 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringItemInfo* info, 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer data); 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::WaitableEvent event_; 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult result_; 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NativeBackendGnome::PasswordFormList forms_; 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION) 315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<std::string> keyrings_; 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<guint> item_ids_; 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> form_; 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 password_; 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::AddLogin(const PasswordForm& form) { 323731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen time_t date_created = form.date_created.ToTimeT(); 32572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If we are asked to save a password with 0 date, use the current time. 32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We don't want to actually save passwords as though on January 1, 1970. 32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!date_created) 32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen date_created = time(NULL); 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gnome_keyring_store_password( 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGnomeSchema, 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // Default keyring. 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.origin.spec().c_str(), // Display name. 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF16ToUTF8(form.password_value).c_str(), 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnOperationDone, 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, // data 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // destroy_data 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "origin_url", form.origin.spec().c_str(), 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "action_url", form.action.spec().c_str(), 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "username_element", UTF16ToUTF8(form.username_element).c_str(), 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "username_value", UTF16ToUTF8(form.username_value).c_str(), 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "password_element", UTF16ToUTF8(form.password_element).c_str(), 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "submit_element", UTF16ToUTF8(form.submit_element).c_str(), 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "signon_realm", form.signon_realm.c_str(), 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ssl_valid", form.ssl_valid, 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "preferred", form.preferred, 34672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "date_created", base::Int64ToString(date_created).c_str(), 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "blacklisted_by_user", form.blacklisted_by_user, 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "scheme", form.scheme, 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "application", GNOME_KEYRING_APPLICATION_CHROME, 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GKRMethod::AddLoginSearch(const PasswordForm& form) { 354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Search GNOME Keyring for matching passwords to update. 356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gnome_keyring_find_itemsv( 357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GNOME_KEYRING_ITEM_GENERIC_SECRET, 358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnOperationGetList, 359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this, // data 360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL, // destroy_data 361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen form.origin.spec().c_str(), 363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF16ToUTF8(form.username_element).c_str(), 365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF16ToUTF8(form.username_value).c_str(), 367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF16ToUTF8(form.password_element).c_str(), 369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF16ToUTF8(form.submit_element).c_str(), 371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen form.signon_realm.c_str(), 373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GNOME_KEYRING_APPLICATION_CHROME, 375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL); 376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::UpdateLoginSearch(const PasswordForm& form) { 379731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Search GNOME Keyring for matching passwords to update. 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gnome_keyring_find_itemsv( 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_ITEM_GENERIC_SECRET, 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnOperationGetList, 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, // data 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // destroy_data 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.origin.spec().c_str(), 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF16ToUTF8(form.username_element).c_str(), 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF16ToUTF8(form.username_value).c_str(), 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF16ToUTF8(form.password_element).c_str(), 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.signon_realm.c_str(), 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_APPLICATION_CHROME, 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::RemoveLogin(const PasswordForm& form) { 402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We find forms using the same fields as LoginDatabase::RemoveLogin(). 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gnome_keyring_delete_password( 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kGnomeSchema, 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnOperationDone, 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, // data 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // destroy_data 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "origin_url", form.origin.spec().c_str(), 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "action_url", form.action.spec().c_str(), 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "username_element", UTF16ToUTF8(form.username_element).c_str(), 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "username_value", UTF16ToUTF8(form.username_value).c_str(), 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "password_element", UTF16ToUTF8(form.password_element).c_str(), 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "submit_element", UTF16ToUTF8(form.submit_element).c_str(), 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "signon_realm", form.signon_realm.c_str(), 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::GetLogins(const PasswordForm& form) { 420731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Search GNOME Keyring for matching passwords. 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gnome_keyring_find_itemsv( 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_ITEM_GENERIC_SECRET, 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnOperationGetList, 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, // data 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // destroy_data 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.signon_realm.c_str(), 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_APPLICATION_CHROME, 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION) 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::GetLoginsList(uint32_t blacklisted_by_user) { 436731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Search GNOME Keyring for matching passwords. 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gnome_keyring_find_itemsv( 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_ITEM_GENERIC_SECRET, 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnOperationGetList, 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, // data 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // destroy_data 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32, 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch blacklisted_by_user, 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_APPLICATION_CHROME, 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::GetAllLogins() { 451731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We need to search for something, otherwise we get no results - so 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we search for the fixed application string. 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gnome_keyring_find_itemsv( 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_ITEM_GENERIC_SECRET, 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnOperationGetList, 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, // data 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // destroy_data 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GNOME_KEYRING_APPLICATION_CHROME, 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GKRMethod::GetKeyrings() { 465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gnome_keyring_list_keyring_names(OnOperationGetKeyrings, this, NULL); 467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GKRMethod::GetItemIds(const char* keyring) { 470731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gnome_keyring_list_item_ids(keyring, OnOperationGetIds, this, NULL); 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GKRMethod::GetItemAttrs(const char* keyring, guint id) { 475731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gnome_keyring_item_get_attributes(keyring, id, OnOperationGetAttrs, this, 477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL); 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GKRMethod::GetItemInfo(const char* keyring, guint id) { 481731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gnome_keyring_item_get_info(keyring, id, OnOperationGetInfo, this, NULL); 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGnomeKeyringResult GKRMethod::WaitResult() { 487731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event_.Wait(); 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result_; 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGnomeKeyringResult GKRMethod::WaitResult(PasswordFormList* forms) { 493731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event_.Wait(); 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->swap(forms_); 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result_; 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION) 500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenGnomeKeyringResult GKRMethod::WaitResult(std::vector<std::string>* keyrings) { 501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen event_.Wait(); 503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen keyrings->swap(keyrings_); 504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result_; 505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGnomeKeyringResult GKRMethod::WaitResult(std::vector<guint>* item_ids) { 508731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event_.Wait(); 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item_ids->swap(item_ids_); 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result_; 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGnomeKeyringResult GKRMethod::WaitResult(PasswordForm** form) { 515731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event_.Wait(); 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *form = form_.release(); 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result_; 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGnomeKeyringResult GKRMethod::WaitResult(string16* password) { 522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event_.Wait(); 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *password = password_; 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result_; 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::OnOperationDone(GnomeKeyringResult result, gpointer data) { 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod* method = static_cast<GKRMethod*>(data); 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->result_ = result; 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->event_.Signal(); 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list, 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer data) { 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod* method = static_cast<GKRMethod*>(data); 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->result_ = result; 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->forms_.clear(); 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |list| will be freed after this callback returns, so convert it now. 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConvertFormList(list, &method->forms_); 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->event_.Signal(); 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION) 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GKRMethod::OnOperationGetKeyrings(GnomeKeyringResult result, GList* list, 550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gpointer data) { 551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GKRMethod* method = static_cast<GKRMethod*>(data); 552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen method->result_ = result; 553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen method->keyrings_.clear(); 554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GList* element = g_list_first(list); 555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (element != NULL) { 556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char* data = static_cast<const char*>(element->data); 557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen method->keyrings_.push_back(std::string(data)); 558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen element = g_list_next(element); 559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen method->event_.Signal(); 561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::OnOperationGetIds(GnomeKeyringResult result, GList* list, 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer data) { 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod* method = static_cast<GKRMethod*>(data); 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->result_ = result; 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->item_ids_.clear(); 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |list| will be freed after this callback returns, so save it now. 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (GList* i = list; i; i = i->next) { 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint id = GPOINTER_TO_UINT(i->data); 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->item_ids_.push_back(id); 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->event_.Signal(); 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::OnOperationGetAttrs(GnomeKeyringResult result, 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringAttributeList* attrs, 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer data) { 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod* method = static_cast<GKRMethod*>(data); 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->result_ = result; 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |attrs| will be freed after this callback returns, so convert it now. 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result == GNOME_KEYRING_RESULT_OK) 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->form_.reset(FormFromAttributes(attrs)); 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->event_.Signal(); 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GKRMethod::OnOperationGetInfo(GnomeKeyringResult result, 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringItemInfo* info, 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer data) { 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod* method = static_cast<GKRMethod*>(data); 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->result_ = result; 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |info| will be freed after this callback returns, so use it now. 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result == GNOME_KEYRING_RESULT_OK) { 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* secret = gnome_keyring_item_info_get_secret(info); 59872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (secret) { 59972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen method->password_ = UTF8ToUTF16(secret); 60072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // gnome_keyring_item_info_get_secret() allocates and returns a new copy 60172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // of the secret, so we have to free it afterward. 60272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen free(secret); 60372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 60472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(WARNING) << "Unable to access password from item info!"; 60572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method->event_.Signal(); 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// GKRMethod isn't reference counted, but it always outlasts runnable 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// methods against it because the caller waits for those methods to run. 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<> 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct RunnableMethodTraits<GKRMethod> { 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RetainCallee(GKRMethod*) {} 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ReleaseCallee(GKRMethod*) {} 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNativeBackendGnome::NativeBackendGnome() { 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNativeBackendGnome::~NativeBackendGnome() { 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::Init() { 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return LoadGnomeKeyring() && gnome_keyring_is_available(); 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool NativeBackendGnome::RawAddLogin(const PasswordForm& form) { 632731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod method; 634731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 635731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(&method, 636731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &GKRMethod::AddLogin, 637731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick form)); 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult result = method.WaitResult(); 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != GNOME_KEYRING_RESULT_OK) { 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Keyring save failed: " 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_result_to_message(result); 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool NativeBackendGnome::AddLogin(const PasswordForm& form) { 648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Based on LoginDatabase::AddLogin(), we search for an existing match based 649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // on origin_url, username_element, username_value, password_element, submit 650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // element, and signon_realm first, remove that, and then add the new entry. 651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We'd add the new one first, and then delete the original, but then the 652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // delete might actually delete the newly-added entry! 653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GKRMethod method; 655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(&method, 657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &GKRMethod::AddLoginSearch, 658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen form)); 659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PasswordFormList forms; 660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GnomeKeyringResult result = method.WaitResult(&forms); 661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result != GNOME_KEYRING_RESULT_OK && 662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result != GNOME_KEYRING_RESULT_NO_MATCH) { 663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(ERROR) << "Keyring find failed: " 664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << gnome_keyring_result_to_message(result); 665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (forms.size() > 0) { 668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (forms.size() > 1) { 669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(WARNING) << "Adding login when there are " << forms.size() << 670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen " matching logins already! Will replace only the first."; 671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RemoveLogin(*forms[0]); 673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < forms.size(); ++i) 674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen delete forms[i]; 675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return RawAddLogin(form); 677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::UpdateLogin(const PasswordForm& form) { 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Based on LoginDatabase::UpdateLogin(), we search for forms to update by 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // origin_url, username_element, username_value, password_element, and 682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // signon_realm. We then compare the result to the updated form. If they 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // differ in any of the action, password_value, ssl_valid, or preferred 684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // fields, then we remove the original, and then add the new entry. We'd add 685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the new one first, and then delete the original, but then the delete might 686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // actually delete the newly-added entry! 687731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod method; 689731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(&method, 691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &GKRMethod::UpdateLoginSearch, 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form)); 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormList forms; 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult result = method.WaitResult(&forms); 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != GNOME_KEYRING_RESULT_OK) { 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Keyring find failed: " 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_result_to_message(result); 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ok = true; 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < forms.size(); ++i) { 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (forms[i]->action != form.action || 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms[i]->password_value != form.password_value || 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms[i]->ssl_valid != form.ssl_valid || 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms[i]->preferred != form.preferred) { 706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RemoveLogin(*forms[i]); 707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < forms.size(); ++i) { 710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (forms[i]->action != form.action || 711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen forms[i]->password_value != form.password_value || 712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen forms[i]->ssl_valid != form.ssl_valid || 713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen forms[i]->preferred != form.preferred) { 714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen forms[i]->action = form.action; 715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen forms[i]->password_value = form.password_value; 716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen forms[i]->ssl_valid = form.ssl_valid; 717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen forms[i]->preferred = form.preferred; 718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!RawAddLogin(*forms[i])) 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ok = false; 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete forms[i]; 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ok; 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::RemoveLogin(const PasswordForm& form) { 727731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod method; 729731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 730731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(&method, 731731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &GKRMethod::RemoveLogin, 732731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick form)); 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult result = method.WaitResult(); 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != GNOME_KEYRING_RESULT_OK) { 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Keyring delete failed: " 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_result_to_message(result); 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::RemoveLoginsCreatedBetween( 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const base::Time& delete_begin, 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const base::Time& delete_end) { 745731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ok = true; 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We could walk the list and delete items as we find them, but it is much 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // easier to build the list and use RemoveLogin() to delete them. 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormList forms; 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetAllLogins(&forms)) 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < forms.size(); ++i) { 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delete_begin <= forms[i]->date_created && 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (delete_end.is_null() || forms[i]->date_created < delete_end)) { 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!RemoveLogin(*forms[i])) 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ok = false; 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete forms[i]; 760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ok; 762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::GetLogins(const PasswordForm& form, 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormList* forms) { 766731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod method; 768731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 769731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::UI, 770731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FROM_HERE, 771731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(&method, &GKRMethod::GetLogins, form)); 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult result = method.WaitResult(forms); 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result == GNOME_KEYRING_RESULT_NO_MATCH) 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != GNOME_KEYRING_RESULT_OK) { 776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Keyring find failed: " 777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_result_to_message(result); 778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::GetLoginsCreatedBetween(const base::Time& get_begin, 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const base::Time& get_end, 785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormList* forms) { 786731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We could walk the list and add items as we find them, but it is much 788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // easier to build the list and then filter the results. 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormList all_forms; 790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetAllLogins(&all_forms)) 791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->reserve(forms->size() + all_forms.size()); 794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < all_forms.size(); ++i) { 795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (get_begin <= all_forms[i]->date_created && 796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (get_end.is_null() || all_forms[i]->date_created < get_end)) { 797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->push_back(all_forms[i]); 798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete all_forms[i]; 800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::GetAutofillableLogins(PasswordFormList* forms) { 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GetLoginsList(forms, true); 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::GetBlacklistLogins(PasswordFormList* forms) { 811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GetLoginsList(forms, false); 812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::GetLoginsList(PasswordFormList* forms, 815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool autofillable) { 816731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32_t blacklisted_by_user = !autofillable; 819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION) 821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod method; 822731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 823731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(&method, 824731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &GKRMethod::GetLoginsList, 825731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick blacklisted_by_user)); 826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult result = method.WaitResult(forms); 827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result == GNOME_KEYRING_RESULT_NO_MATCH) 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != GNOME_KEYRING_RESULT_OK) { 830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Keyring find failed: " 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_result_to_message(result); 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormList all_forms; 837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetAllLogins(&all_forms)) 838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now manually filter the results for the values we care about. 840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < all_forms.size(); ++i) { 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (all_forms[i]->blacklisted_by_user == blacklisted_by_user) 842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->push_back(all_forms[i]); 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete all_forms[i]; 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NativeBackendGnome::GetAllLogins(PasswordFormList* forms) { 851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GKRMethod method; 852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(GNOME_KEYRING_WORK_AROUND_MEMORY_CORRUPTION) 853731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 854731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(&method, 855731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &GKRMethod::GetAllLogins)); 856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GnomeKeyringResult result = method.WaitResult(forms); 857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result == GNOME_KEYRING_RESULT_NO_MATCH) 858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != GNOME_KEYRING_RESULT_OK) { 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Keyring find failed: " 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_result_to_message(result); 862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 866731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 867731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(&method, 868ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &GKRMethod::GetKeyrings)); 869ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<std::string> keyrings; 870ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GnomeKeyringResult result = method.WaitResult(&keyrings); 871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != GNOME_KEYRING_RESULT_OK) { 872ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(ERROR) << "Keyring list failed: " 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_result_to_message(result); 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 877ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We could parallelize this, but there probably aren't many keyrings. 878ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<std::pair<const char *, guint> > item_list; 879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < keyrings.size(); ++i) { 880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char *keyring = keyrings[i].c_str(); 881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 882ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(&method, 883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &GKRMethod::GetItemIds, 884ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen keyring)); 885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<guint> item_ids; 886ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GnomeKeyringResult result = method.WaitResult(&item_ids); 887ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result != GNOME_KEYRING_RESULT_OK) { 888ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(ERROR) << "Keyring itemid list failed: " 889ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << gnome_keyring_result_to_message(result); 890ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 891ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 892ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t j = 0; j < item_ids.size(); ++j) 893ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen item_list.push_back(std::make_pair(keyring, item_ids[j])); 894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We can parallelize getting the item attributes. 897ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GKRMethod* methods = new GKRMethod[item_list.size()]; 898ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < item_list.size(); ++i) { 899731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 900731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(&methods[i], 901731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &GKRMethod::GetItemAttrs, 902ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen item_list[i].first, 903ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen item_list[i].second)); 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool success = true; 907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We can also parallelize getting the item info (i.e. passwords). 909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormList all_forms; 910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen all_forms.resize(item_list.size()); 911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < item_list.size(); ++i) { 912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = methods[i].WaitResult(&all_forms[i]); 913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != GNOME_KEYRING_RESULT_OK) { 91472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(ERROR) << "Keyring get item attributes failed: " 915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_result_to_message(result); 916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We explicitly do not break out here. We must wait on all the other 917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // methods first, and we may have already posted new methods. So, we just 918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // note the failure and continue. 919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch success = false; 920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (all_forms[i]) { 922731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 923731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(&methods[i], 924731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &GKRMethod::GetItemInfo, 925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen item_list[i].first, 926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen item_list[i].second)); 927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now just wait for all the passwords to come in. 931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < item_list.size(); ++i) { 932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!all_forms[i]) 933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = methods[i].WaitResult(&all_forms[i]->password_value); 935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != GNOME_KEYRING_RESULT_OK) { 93672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(ERROR) << "Keyring get item info failed: " 937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << gnome_keyring_result_to_message(result); 938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete all_forms[i]; 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch all_forms[i] = NULL; 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We explicitly do not break out here (see above). 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch success = false; 942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete[] methods; 946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (success) { 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we succeeded, output all the forms. 949ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < item_list.size(); ++i) { 950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (all_forms[i]) 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->push_back(all_forms[i]); 952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Otherwise, free them. 955ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < item_list.size(); ++i) 956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete all_forms[i]; 957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return success; 960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 962