| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/password_manager/password_store_gnome.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "base/string_util.h" | |
| 11 #include "base/task.h" | |
| 12 #include "base/time.h" | |
| 13 | |
| 14 using std::map; | |
| 15 using std::string; | |
| 16 using std::vector; | |
| 17 | |
| 18 // Schema is analagous to the fields in PasswordForm. | |
| 19 const GnomeKeyringPasswordSchema PasswordStoreGnome::kGnomeSchema = { | |
| 20 GNOME_KEYRING_ITEM_GENERIC_SECRET, { | |
| 21 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
| 22 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
| 23 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
| 24 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
| 25 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
| 26 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
| 27 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
| 28 { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | |
| 29 { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | |
| 30 { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
| 31 { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | |
| 32 { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | |
| 33 { NULL } | |
| 34 } | |
| 35 }; | |
| 36 | |
| 37 PasswordStoreGnome::PasswordStoreGnome() { | |
| 38 } | |
| 39 | |
| 40 PasswordStoreGnome::~PasswordStoreGnome() { | |
| 41 } | |
| 42 | |
| 43 bool PasswordStoreGnome::Init() { | |
| 44 return PasswordStore::Init() && gnome_keyring_is_available(); | |
| 45 } | |
| 46 | |
| 47 void PasswordStoreGnome::AddLoginImpl(const PasswordForm& form) { | |
| 48 AutoLock l(gnome_keyring_lock_); | |
| 49 GnomeKeyringResult result = gnome_keyring_store_password_sync( | |
| 50 &kGnomeSchema, | |
| 51 NULL, // Default keyring. | |
| 52 // TODO(johnmaguire@google.com): Localise this. | |
| 53 "Form password stored by Chrome", | |
| 54 WideToASCII(form.password_value).c_str(), | |
| 55 "origin_url", form.origin.spec().c_str(), | |
| 56 "action_url", form.action.spec().c_str(), | |
| 57 "username_element", form.username_element.c_str(), | |
| 58 "username_value", form.username_value.c_str(), | |
| 59 "password_element", form.password_element.c_str(), | |
| 60 "submit_element", form.submit_element.c_str(), | |
| 61 "signon_realm", form.signon_realm.c_str(), | |
| 62 "ssl_valid", form.ssl_valid, | |
| 63 "preferred", form.preferred, | |
| 64 "date_created", Int64ToString(base::Time::Now().ToTimeT()).c_str(), | |
| 65 "blacklisted_by_user", form.blacklisted_by_user, | |
| 66 "scheme", form.scheme, | |
| 67 NULL); | |
| 68 | |
| 69 if (result != GNOME_KEYRING_RESULT_OK) { | |
| 70 LOG(ERROR) << "Keyring save failed: " | |
| 71 << gnome_keyring_result_to_message(result); | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 void PasswordStoreGnome::UpdateLoginImpl(const PasswordForm& form) { | |
| 76 AddLoginImpl(form); // Add & Update are the same in gnome keyring. | |
| 77 } | |
| 78 | |
| 79 void PasswordStoreGnome::RemoveLoginImpl(const PasswordForm& form) { | |
| 80 AutoLock l(gnome_keyring_lock_); | |
| 81 GnomeKeyringResult result = gnome_keyring_delete_password_sync( | |
| 82 &kGnomeSchema, | |
| 83 "origin_url", form.origin.spec().c_str(), | |
| 84 "action_url", form.action.spec().c_str(), | |
| 85 "username_element", form.username_element.c_str(), | |
| 86 "username_value", form.username_value.c_str(), | |
| 87 "password_element", form.password_element.c_str(), | |
| 88 "submit_element", form.submit_element.c_str(), | |
| 89 "signon_realm", form.signon_realm.c_str(), | |
| 90 "ssl_valid", form.ssl_valid, | |
| 91 "preferred", form.preferred, | |
| 92 "date_created", Int64ToString(form.date_created.ToTimeT()).c_str(), | |
| 93 "blacklisted_by_user", form.blacklisted_by_user, | |
| 94 "scheme", form.scheme, | |
| 95 NULL); | |
| 96 if (result != GNOME_KEYRING_RESULT_OK) { | |
| 97 LOG(ERROR) << "Keyring delete failed: " | |
| 98 << gnome_keyring_result_to_message(result); | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 void PasswordStoreGnome::GetLoginsImpl(GetLoginsRequest* request) { | |
| 103 AutoLock l(gnome_keyring_lock_); | |
| 104 GList* found = NULL; | |
| 105 // Search gnome keyring for matching passwords. | |
| 106 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( | |
| 107 GNOME_KEYRING_ITEM_GENERIC_SECRET, | |
| 108 &found, | |
| 109 "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | |
| 110 request->form.signon_realm.c_str(), | |
| 111 NULL); | |
| 112 vector<PasswordForm*> forms; | |
| 113 if (result == GNOME_KEYRING_RESULT_NO_MATCH) { | |
| 114 NotifyConsumer(request, forms); | |
| 115 return; | |
| 116 } else if (result != GNOME_KEYRING_RESULT_OK) { | |
| 117 LOG(ERROR) << "Keyring find failed: " | |
| 118 << gnome_keyring_result_to_message(result); | |
| 119 NotifyConsumer(request, forms); | |
| 120 return; | |
| 121 } | |
| 122 | |
| 123 // Parse all the results from the returned GList into a | |
| 124 // vector<PasswordForm*>. PasswordForms are allocated on the heap. These | |
| 125 // will be deleted by the consumer. | |
| 126 GList* element = g_list_first(found); | |
| 127 while (element != NULL) { | |
| 128 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); | |
| 129 char* password = data->secret; | |
| 130 | |
| 131 GnomeKeyringAttributeList* attributes = data->attributes; | |
| 132 // Read the string & int attributes into the appropriate map. | |
| 133 map<string, string> string_attribute_map; | |
| 134 map<string, uint32> uint_attribute_map; | |
| 135 for (unsigned int i = 0; i < attributes->len; ++i) { | |
| 136 GnomeKeyringAttribute attribute = | |
| 137 gnome_keyring_attribute_list_index(attributes, i); | |
| 138 if (attribute.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) { | |
| 139 string_attribute_map[string(attribute.name)] = | |
| 140 string(attribute.value.string); | |
| 141 } else if (attribute.type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) { | |
| 142 uint_attribute_map[string(attribute.name)] = attribute.value.integer; | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 PasswordForm* form = new PasswordForm(); | |
| 147 form->origin = GURL(string_attribute_map["origin_url"]); | |
| 148 form->action = GURL(string_attribute_map["action_url"]); | |
| 149 form->username_element = | |
| 150 ASCIIToWide(string(string_attribute_map["username_element"])); | |
| 151 form->username_value = | |
| 152 ASCIIToWide(string(string_attribute_map["username_value"])); | |
| 153 form->password_element = | |
| 154 ASCIIToWide(string(string_attribute_map["password_element"])); | |
| 155 form->password_value = ASCIIToWide(string(password)); | |
| 156 form->submit_element = | |
| 157 ASCIIToWide(string(string_attribute_map["submit_element"])); | |
| 158 form->signon_realm = uint_attribute_map["signon_realm"]; | |
| 159 form->ssl_valid = uint_attribute_map["ssl_valid"]; | |
| 160 form->preferred = uint_attribute_map["preferred"]; | |
| 161 string date = string_attribute_map["date_created"]; | |
| 162 int64 date_created = 0; | |
| 163 DCHECK(StringToInt64(date, &date_created) && date_created != 0); | |
| 164 form->date_created = base::Time::FromTimeT(date_created); | |
| 165 form->blacklisted_by_user = uint_attribute_map["blacklisted_by_user"]; | |
| 166 form->scheme = | |
| 167 static_cast<PasswordForm::Scheme>(uint_attribute_map["scheme"]); | |
| 168 | |
| 169 forms.push_back(form); | |
| 170 | |
| 171 element = g_list_next(element); | |
| 172 } | |
| 173 gnome_keyring_found_list_free(found); | |
| 174 found = NULL; | |
| 175 | |
| 176 NotifyConsumer(request, forms); | |
| 177 } | |
| OLD | NEW |