15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/native_backend_gnome_x.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <dlfcn.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gnome-keyring.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/autofill/core/common/password_form.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/password_manager/core/browser/psl_matching_helper.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using autofill::PasswordForm; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UTF8ToUTF16; 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UTF16ToUTF8; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GNOME_KEYRING_DEFINE_POINTER(name) \ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typeof(&::gnome_keyring_##name) GnomeKeyringLoader::gnome_keyring_##name; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_DEFINE_POINTER) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef GNOME_KEYRING_DEFINE_POINTER 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GnomeKeyringLoader::keyring_loaded = false; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(DLOPEN_GNOME_KEYRING) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GNOME_KEYRING_FUNCTION_INFO(name) \ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"gnome_keyring_"#name, reinterpret_cast<void**>(&gnome_keyring_##name)}, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GnomeKeyringLoader::FunctionInfo GnomeKeyringLoader::functions[] = { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_FUNCTION_INFO) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {NULL, NULL} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef GNOME_KEYRING_FUNCTION_INFO 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Load the library and initialize the function pointers. */ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GnomeKeyringLoader::LoadGnomeKeyring() { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keyring_loaded) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* handle = dlopen("libgnome-keyring.so.0", RTLD_NOW | RTLD_GLOBAL); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handle) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We wanted to use GNOME Keyring, but we couldn't load it. Warn, because 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either the user asked for this, or we autodetected it incorrectly. (Or 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the system has broken libraries, which is also good to warn about.) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Could not load libgnome-keyring.so.0: " << dlerror(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; functions[i].name; ++i) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dlerror(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *functions[i].pointer = dlsym(handle, functions[i].name); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* error = dlerror(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Unable to load symbol " 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << functions[i].name << ": " << error; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dlclose(handle); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyring_loaded = true; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We leak the library handle. That's OK: this function is called only once. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else // defined(DLOPEN_GNOME_KEYRING) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GnomeKeyringLoader::LoadGnomeKeyring() { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keyring_loaded) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GNOME_KEYRING_ASSIGN_POINTER(name) \ 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gnome_keyring_##name = &::gnome_keyring_##name; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_ASSIGN_POINTER) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef GNOME_KEYRING_ASSIGN_POINTER 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyring_loaded = true; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(DLOPEN_GNOME_KEYRING) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGnomeKeyringAppString[] = "chrome"; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert the attributes of a given keyring entry into a new PasswordForm. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: does *not* get the actual password, as that is not a key attribute! 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns NULL if the attributes are for the wrong application. 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<PasswordForm> FormFromAttributes(GnomeKeyringAttributeList* attrs) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read the string and int attributes into the appropriate map. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, std::string> string_attr_map; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, uint32_t> uint_attr_map; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (guint i = 0; i < attrs->len; ++i) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringAttribute attr = gnome_keyring_attribute_list_index(attrs, i); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (attr.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_attr_map[attr.name] = attr.value.string; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (attr.type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint_attr_map[attr.name] = attr.value.integer; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check to make sure this is a password we care about. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& app_value = string_attr_map["application"]; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringPiece(app_value).starts_with(kGnomeKeyringAppString)) 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return scoped_ptr<PasswordForm>(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<PasswordForm> form(new PasswordForm()); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->origin = GURL(string_attr_map["origin_url"]); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->action = GURL(string_attr_map["action_url"]); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->username_element = UTF8ToUTF16(string_attr_map["username_element"]); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->username_value = UTF8ToUTF16(string_attr_map["username_value"]); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->password_element = UTF8ToUTF16(string_attr_map["password_element"]); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->submit_element = UTF8ToUTF16(string_attr_map["submit_element"]); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->signon_realm = string_attr_map["signon_realm"]; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->ssl_valid = uint_attr_map["ssl_valid"]; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->preferred = uint_attr_map["preferred"]; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 date_created = 0; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool date_ok = base::StringToInt64(string_attr_map["date_created"], 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &date_created); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(date_ok); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->date_created = base::Time::FromTimeT(date_created); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->blacklisted_by_user = uint_attr_map["blacklisted_by_user"]; 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) form->type = static_cast<PasswordForm::Type>(uint_attr_map["type"]); 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) form->times_used = uint_attr_map["times_used"]; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->scheme = static_cast<PasswordForm::Scheme>(uint_attr_map["scheme"]); 139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int64 date_synced = 0; 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::StringToInt64(string_attr_map["date_synced"], &date_synced); 141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) form->date_synced = base::Time::FromInternalValue(date_synced); 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) form->display_name = UTF8ToUTF16(string_attr_map["display_name"]); 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) form->avatar_url = GURL(string_attr_map["avatar_url"]); 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) form->federation_url = GURL(string_attr_map["federation_url"]); 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) form->is_zero_click = uint_attr_map["is_zero_click"]; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return form.Pass(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parse all the results from the given GList into a PasswordFormList, and free 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the GList. PasswordForms are allocated on the heap, and should be deleted by 1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// the consumer. If not NULL, |lookup_form| is used to filter out results -- 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// only credentials with signon realms passing the PSL matching against 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// |lookup_form->signon_realm| will be kept. PSL matched results get their 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// signon_realm, origin, and action rewritten to those of |lookup_form_|, with 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the original signon_realm saved into the result's original_signon_realm data 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// member. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConvertFormList(GList* found, 1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const PasswordForm* lookup_form, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NativeBackendGnome::PasswordFormList* forms) { 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_manager::PSLDomainMatchMetric psl_domain_match_metric = 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_manager::PSL_DOMAIN_MATCH_NONE; 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (GList* element = g_list_first(found); element != NULL; 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) element = g_list_next(element)) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringAttributeList* attrs = data->attributes; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<PasswordForm> form(FormFromAttributes(attrs)); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (form) { 1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (lookup_form && form->signon_realm != lookup_form->signon_realm) { 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is not an exact match, we try PSL matching. 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (lookup_form->scheme != PasswordForm::SCHEME_HTML || 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) form->scheme != PasswordForm::SCHEME_HTML || 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !(password_manager::IsPublicSuffixDomainMatch( 1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu lookup_form->signon_realm, form->signon_realm))) { 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND; 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) form->original_signon_realm = form->signon_realm; 1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu form->signon_realm = lookup_form->signon_realm; 1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu form->origin = lookup_form->origin; 1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu form->action = lookup_form->action; 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->secret) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->password_value = UTF8ToUTF16(data->secret); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Unable to access password from list element!"; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) forms->push_back(form.release()); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Could not initialize PasswordForm from attributes!"; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (lookup_form) { 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL signon_realm(lookup_form->signon_realm); 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string registered_domain = 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_manager::GetRegistryControlledDomain(signon_realm); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "PasswordManager.PslDomainMatchTriggering", 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_manager::ShouldPSLDomainMatchingApply(registered_domain) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? psl_domain_match_metric 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : password_manager::PSL_DOMAIN_MATCH_NOT_USED, 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_manager::PSL_DOMAIN_MATCH_COUNT); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Schema is analagous to the fields in PasswordForm. 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// TODO(gcasto): Adding 'form_data' would be nice, but we would need to 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// serialize in a way that is guaranteed to not have any embedded NULLs. Pickle 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// doesn't make this guarantee, so we just don't serialize this field. Since 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// it's only used to crowd source data collection it doesn't matter that much 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// if it's not available on this platform. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GnomeKeyringPasswordSchema kGnomeSchema = { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GNOME_KEYRING_ITEM_GENERIC_SECRET, { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { "type", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { "times_used", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) { "date_synced", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) { "display_name", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) { "avatar_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) { "federation_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) { "is_zero_click", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This field is always "chrome" so that we can search for it. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { NULL } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sadly, PasswordStore goes to great lengths to switch from the originally 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calling thread to the DB thread, and to provide an asynchronous API to 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callers while using a synchronous (virtual) API provided by subclasses like 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PasswordStoreX -- but GNOME Keyring really wants to be on the GLib main 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread, which is the UI thread to us. So we end up having to switch threads 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// again, possibly back to the very same thread (in case the UI thread is the 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// caller, e.g. in the password management UI), and *block* the DB thread 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// waiting for a response from the UI thread to provide the synchronous API 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PasswordStore expects of us. (It will then in turn switch back to the 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// original caller to send the asynchronous reply to the original request.) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class represents a call to a GNOME Keyring method. A RunnableMethod 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be posted to the UI thread to call one of its action methods, and then 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a WaitResult() method should be called to wait for the result. Each instance 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// supports only one outstanding method at a time, though multiple instances may 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be used in parallel. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GKRMethod : public GnomeKeyringLoader { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef NativeBackendGnome::PasswordFormList PasswordFormList; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod() : event_(false, false), result_(GNOME_KEYRING_RESULT_CANCELLED) {} 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Action methods. These call gnome_keyring_* functions. Call from UI thread. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See GetProfileSpecificAppString() for more information on the app string. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddLogin(const PasswordForm& form, const char* app_string); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddLoginSearch(const PasswordForm& form, const char* app_string); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdateLoginSearch(const PasswordForm& form, const char* app_string); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveLogin(const PasswordForm& form, const char* app_string); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetLogins(const PasswordForm& form, const char* app_string); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetAllLogins(const char* app_string); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use after AddLogin, RemoveLogin. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringResult WaitResult(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetAllLogins. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringResult WaitResult(PasswordFormList* forms); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct GnomeKeyringAttributeListFreeDeleter { 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) inline void operator()(void* list) const { 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gnome_keyring_attribute_list_free( 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<GnomeKeyringAttributeList*>(list)); 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef scoped_ptr<GnomeKeyringAttributeList, 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GnomeKeyringAttributeListFreeDeleter> ScopedAttributeList; 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Helper methods to abbreviate Gnome Keyring long API names. 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void AppendString(ScopedAttributeList* list, 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* name, 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* value); 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void AppendString(ScopedAttributeList* list, 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* name, 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& value); 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void AppendUint32(ScopedAttributeList* list, 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* name, 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) guint32 value); 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All these callbacks are called on UI thread. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void OnOperationDone(GnomeKeyringResult result, gpointer data); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void OnOperationGetList(GnomeKeyringResult result, GList* list, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpointer data); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent event_; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringResult result_; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NativeBackendGnome::PasswordFormList forms_; 3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If the credential search is specified by a single form and needs to use PSL 3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // matching, then the specifying form is stored in |lookup_form_|. If PSL 3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // matching is used to find a result, then the results signon realm, origin 3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // and action are stored are replaced by those of |lookup_form_|. 3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Additionally, |lookup_form_->signon_realm| is also used to narrow down the 3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // found logins to those which indeed PSL-match the look-up. And finally, 3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // |lookup_form_| set to NULL means that PSL matching is not required. 3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<PasswordForm> lookup_form_; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GKRMethod::AddLogin(const PasswordForm& form, const char* app_string) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_t date_created = form.date_created.ToTimeT(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are asked to save a password with 0 date, use the current time. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't want to actually save passwords as though on January 1, 1970. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!date_created) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) date_created = time(NULL); 327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int64 date_synced = form.date_synced.ToInternalValue(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gnome_keyring_store_password( 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kGnomeSchema, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Default keyring. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form.origin.spec().c_str(), // Display name. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UTF16ToUTF8(form.password_value).c_str(), 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnOperationDone, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, // data 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // destroy_data 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "origin_url", form.origin.spec().c_str(), 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "action_url", form.action.spec().c_str(), 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "username_element", UTF16ToUTF8(form.username_element).c_str(), 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "username_value", UTF16ToUTF8(form.username_value).c_str(), 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "password_element", UTF16ToUTF8(form.password_element).c_str(), 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "submit_element", UTF16ToUTF8(form.submit_element).c_str(), 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "signon_realm", form.signon_realm.c_str(), 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ssl_valid", form.ssl_valid, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "preferred", form.preferred, 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "date_created", base::Int64ToString(date_created).c_str(), 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "blacklisted_by_user", form.blacklisted_by_user, 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "type", form.type, 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "times_used", form.times_used, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "scheme", form.scheme, 350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "date_synced", base::Int64ToString(date_synced).c_str(), 35103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "display_name", UTF16ToUTF8(form.display_name).c_str(), 35203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "avatar_url", form.avatar_url.spec().c_str(), 35303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "federation_url", form.federation_url.spec().c_str(), 35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "is_zero_click", form.is_zero_click, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "application", app_string, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GKRMethod::AddLoginSearch(const PasswordForm& form, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* app_string) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu lookup_form_.reset(NULL); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search GNOME Keyring for matching passwords to update. 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "origin_url", form.origin.spec()); 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "username_element", UTF16ToUTF8(form.username_element)); 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "username_value", UTF16ToUTF8(form.username_value)); 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "password_element", UTF16ToUTF8(form.password_element)); 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "submit_element", UTF16ToUTF8(form.submit_element)); 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "signon_realm", form.signon_realm); 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "application", app_string); 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) attrs.get(), 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOperationGetList, 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*data=*/this, 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*destroy_data=*/NULL); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GKRMethod::UpdateLoginSearch(const PasswordForm& form, 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* app_string) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu lookup_form_.reset(NULL); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search GNOME Keyring for matching passwords to update. 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "origin_url", form.origin.spec()); 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "username_element", UTF16ToUTF8(form.username_element)); 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "username_value", UTF16ToUTF8(form.username_value)); 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "password_element", UTF16ToUTF8(form.password_element)); 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "signon_realm", form.signon_realm); 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "application", app_string); 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) attrs.get(), 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOperationGetList, 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*data=*/this, 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*destroy_data=*/NULL); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GKRMethod::RemoveLogin(const PasswordForm& form, const char* app_string) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We find forms using the same fields as LoginDatabase::RemoveLogin(). 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gnome_keyring_delete_password( 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kGnomeSchema, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnOperationDone, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, // data 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // destroy_data 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "origin_url", form.origin.spec().c_str(), 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "username_element", UTF16ToUTF8(form.username_element).c_str(), 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "username_value", UTF16ToUTF8(form.username_value).c_str(), 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "password_element", UTF16ToUTF8(form.password_element).c_str(), 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "submit_element", UTF16ToUTF8(form.submit_element).c_str(), 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "signon_realm", form.signon_realm.c_str(), 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "application", app_string, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GKRMethod::GetLogins(const PasswordForm& form, const char* app_string) { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu lookup_form_.reset(new PasswordForm(form)); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search GNOME Keyring for matching passwords. 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!password_manager::ShouldPSLDomainMatchingApply( 4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_manager::GetRegistryControlledDomain( 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL(form.signon_realm)))) { 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "signon_realm", form.signon_realm); 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "application", app_string); 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) attrs.get(), 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOperationGetList, 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*data=*/this, 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*destroy_data=*/NULL); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GKRMethod::GetLoginsList(uint32_t blacklisted_by_user, 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* app_string) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu lookup_form_.reset(NULL); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search GNOME Keyring for matching passwords. 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendUint32(&attrs, "blacklisted_by_user", blacklisted_by_user); 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "application", app_string); 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) attrs.get(), 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOperationGetList, 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*data=*/this, 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*destroy_data=*/NULL); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GKRMethod::GetAllLogins(const char* app_string) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu lookup_form_.reset(NULL); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to search for something, otherwise we get no results - so 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we search for the fixed application string. 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(&attrs, "application", app_string); 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) attrs.get(), 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOperationGetList, 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*data=*/this, 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /*destroy_data=*/NULL); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GnomeKeyringResult GKRMethod::WaitResult() { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.Wait(); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result_; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GnomeKeyringResult GKRMethod::WaitResult(PasswordFormList* forms) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.Wait(); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (forms->empty()) { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Normal case. Avoid extra allocation by swapping. 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forms->swap(forms_); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rare case. Append forms_ to *forms. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forms->insert(forms->end(), forms_.begin(), forms_.end()); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forms_.clear(); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result_; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* name, 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* value) { 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gnome_keyring_attribute_list_append_string(list->get(), name, value); 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* name, 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& value) { 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendString(list, name, value.c_str()); 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GKRMethod::AppendUint32(GKRMethod::ScopedAttributeList* list, 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* name, 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) guint32 value) { 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gnome_keyring_attribute_list_append_uint32(list->get(), name, value); 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GKRMethod::OnOperationDone(GnomeKeyringResult result, gpointer data) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod* method = static_cast<GKRMethod*>(data); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method->result_ = result; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method->event_.Signal(); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list, 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpointer data) { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod* method = static_cast<GKRMethod*>(data); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method->result_ = result; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method->forms_.clear(); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |list| will be freed after this callback returns, so convert it now. 5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ConvertFormList(list, method->lookup_form_.get(), &method->forms_); 5195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu method->lookup_form_.reset(NULL); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method->event_.Signal(); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochNativeBackendGnome::NativeBackendGnome(LocalProfileId id) 526effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : profile_id_(id) { 527effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch app_string_ = GetProfileSpecificAppString(); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeBackendGnome::~NativeBackendGnome() { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeBackendGnome::Init() { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LoadGnomeKeyring() && gnome_keyring_is_available(); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeBackendGnome::RawAddLogin(const PasswordForm& form) { 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod method; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GKRMethod::AddLogin, 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&method), 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form, app_string_.c_str())); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringResult result = method.WaitResult(); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != GNOME_KEYRING_RESULT_OK) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Keyring save failed: " 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << gnome_keyring_result_to_message(result); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)password_manager::PasswordStoreChangeList NativeBackendGnome::AddLogin( 554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const PasswordForm& form) { 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Based on LoginDatabase::AddLogin(), we search for an existing match based 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on origin_url, username_element, username_value, password_element, submit 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // element, and signon_realm first, remove that, and then add the new entry. 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'd add the new one first, and then delete the original, but then the 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // delete might actually delete the newly-added entry! 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod method; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GKRMethod::AddLoginSearch, 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&method), 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form, app_string_.c_str())); 566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedVector<autofill::PasswordForm> forms; 567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GnomeKeyringResult result = method.WaitResult(&forms.get()); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != GNOME_KEYRING_RESULT_OK && 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result != GNOME_KEYRING_RESULT_NO_MATCH) { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Keyring find failed: " 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << gnome_keyring_result_to_message(result); 572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return password_manager::PasswordStoreChangeList(); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 574cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) password_manager::PasswordStoreChangeList changes; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (forms.size() > 0) { 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (forms.size() > 1) { 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Adding login when there are " << forms.size() 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " matching logins already! Will replace only the first."; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (RemoveLogin(*forms[0])) { 582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) changes.push_back(password_manager::PasswordStoreChange( 583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) password_manager::PasswordStoreChange::REMOVE, *forms[0])); 584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (RawAddLogin(form)) { 587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) changes.push_back(password_manager::PasswordStoreChange( 588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) password_manager::PasswordStoreChange::ADD, form)); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return changes; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool NativeBackendGnome::UpdateLogin( 594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const PasswordForm& form, 595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) password_manager::PasswordStoreChangeList* changes) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Based on LoginDatabase::UpdateLogin(), we search for forms to update by 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // origin_url, username_element, username_value, password_element, and 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // signon_realm. We then compare the result to the updated form. If they 599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // differ in any of the mutable fields, then we remove the original, and 600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // then add the new entry. We'd add the new one first, and then delete the 601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // original, but then the delete might actually delete the newly-added entry! 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 603cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(changes); 604cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) changes->clear(); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod method; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GKRMethod::UpdateLoginSearch, 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&method), 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form, app_string_.c_str())); 610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedVector<autofill::PasswordForm> forms; 611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GnomeKeyringResult result = method.WaitResult(&forms.get()); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != GNOME_KEYRING_RESULT_OK) { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Keyring find failed: " 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << gnome_keyring_result_to_message(result); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool removed = false; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < forms.size(); ++i) { 620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (*forms[i] != form) { 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveLogin(*forms[i]); 622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) removed = true; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!removed) 626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (RawAddLogin(form)) { 629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) password_manager::PasswordStoreChange change( 630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) password_manager::PasswordStoreChange::UPDATE, form); 631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) changes->push_back(change); 632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeBackendGnome::RemoveLogin(const PasswordForm& form) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod method; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GKRMethod::RemoveLogin, 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&method), 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form, app_string_.c_str())); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringResult result = method.WaitResult(); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != GNOME_KEYRING_RESULT_OK) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Warning, not error, because this can sometimes happen due to the user 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // racing with the daemon to delete the password a second time. 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Keyring delete failed: " 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << gnome_keyring_result_to_message(result); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)bool NativeBackendGnome::RemoveLoginsCreatedBetween( 6566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Time delete_begin, 6576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Time delete_end, 6586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) password_manager::PasswordStoreChangeList* changes) { 659f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return RemoveLoginsBetween( 6606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) delete_begin, delete_end, CREATION_TIMESTAMP, changes); 661f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 663f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool NativeBackendGnome::RemoveLoginsSyncedBetween( 664f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Time delete_begin, 665f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Time delete_end, 666f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) password_manager::PasswordStoreChangeList* changes) { 667f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeBackendGnome::GetLogins(const PasswordForm& form, 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordFormList* forms) { 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod method; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GKRMethod::GetLogins, 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&method), 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form, app_string_.c_str())); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringResult result = method.WaitResult(forms); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == GNOME_KEYRING_RESULT_NO_MATCH) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != GNOME_KEYRING_RESULT_OK) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Keyring find failed: " 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << gnome_keyring_result_to_message(result); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeBackendGnome::GetAutofillableLogins(PasswordFormList* forms) { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetLoginsList(forms, true); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeBackendGnome::GetBlacklistLogins(PasswordFormList* forms) { 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetLoginsList(forms, false); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeBackendGnome::GetLoginsList(PasswordFormList* forms, 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool autofillable) { 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t blacklisted_by_user = !autofillable; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod method; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GKRMethod::GetLoginsList, 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&method), 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blacklisted_by_user, app_string_.c_str())); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringResult result = method.WaitResult(forms); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == GNOME_KEYRING_RESULT_NO_MATCH) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != GNOME_KEYRING_RESULT_OK) { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Keyring find failed: " 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << gnome_keyring_result_to_message(result); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeBackendGnome::GetAllLogins(PasswordFormList* forms) { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GKRMethod method; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GKRMethod::GetAllLogins, 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&method), 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_string_.c_str())); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GnomeKeyringResult result = method.WaitResult(forms); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == GNOME_KEYRING_RESULT_NO_MATCH) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != GNOME_KEYRING_RESULT_OK) { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Keyring find failed: " 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << gnome_keyring_result_to_message(result); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 736f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool NativeBackendGnome::GetLoginsBetween(base::Time get_begin, 737f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Time get_end, 738f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) TimestampToCompare date_to_compare, 739f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) PasswordFormList* forms) { 740f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 741f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // We could walk the list and add items as we find them, but it is much 742f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // easier to build the list and then filter the results. 743f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) PasswordFormList all_forms; 744f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!GetAllLogins(&all_forms)) 745f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 746f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 747f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Time autofill::PasswordForm::*date_member = 748f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) date_to_compare == CREATION_TIMESTAMP 749f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ? &autofill::PasswordForm::date_created 750f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : &autofill::PasswordForm::date_synced; 751f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t i = 0; i < all_forms.size(); ++i) { 752f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (get_begin <= all_forms[i]->*date_member && 753f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) (get_end.is_null() || all_forms[i]->*date_member < get_end)) { 754f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) forms->push_back(all_forms[i]); 755f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 756f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) delete all_forms[i]; 757f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 758f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 759f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 760f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 761f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 762f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 763f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool NativeBackendGnome::RemoveLoginsBetween( 764f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Time get_begin, 765f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Time get_end, 766f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) TimestampToCompare date_to_compare, 767f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) password_manager::PasswordStoreChangeList* changes) { 768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 7696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(changes); 7706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) changes->clear(); 771f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // We could walk the list and delete items as we find them, but it is much 772f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // easier to build the list and use RemoveLogin() to delete them. 773f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ScopedVector<autofill::PasswordForm> forms; 774f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms.get())) 775f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 776f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 777f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool ok = true; 778f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t i = 0; i < forms.size(); ++i) { 779f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (RemoveLogin(*forms[i])) { 7806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) changes->push_back(password_manager::PasswordStoreChange( 7816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) password_manager::PasswordStoreChange::REMOVE, *forms[i])); 782f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 783f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ok = false; 784f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 785f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 786f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ok; 787f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 788f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string NativeBackendGnome::GetProfileSpecificAppString() const { 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Originally, the application string was always just "chrome" and used only 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that we had *something* to search for since GNOME Keyring won't search 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for nothing. Now we use it to distinguish passwords for different profiles. 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795