| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/password_manager/password_store_gnome.h" | 5 #include "chrome/browser/password_manager/password_store_gnome.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/task.h" | 11 #include "base/task.h" |
| 12 #include "base/time.h" | 12 #include "base/time.h" |
| 13 #include "base/utf_string_conversions.h" |
| 13 | 14 |
| 14 using std::map; | 15 using std::map; |
| 15 using std::string; | 16 using std::string; |
| 16 using std::vector; | 17 using std::vector; |
| 18 using webkit_glue::PasswordForm; |
| 19 |
| 20 #define GNOME_KEYRING_APPLICATION_CHROME "chrome" |
| 17 | 21 |
| 18 // Schema is analagous to the fields in PasswordForm. | 22 // Schema is analagous to the fields in PasswordForm. |
| 19 const GnomeKeyringPasswordSchema PasswordStoreGnome::kGnomeSchema = { | 23 const GnomeKeyringPasswordSchema PasswordStoreGnome::kGnomeSchema = { |
| 20 GNOME_KEYRING_ITEM_GENERIC_SECRET, { | 24 GNOME_KEYRING_ITEM_GENERIC_SECRET, { |
| 21 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 25 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 22 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 26 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 23 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 27 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 24 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 28 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 25 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 29 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 26 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 30 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 27 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 31 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 28 { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 32 { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 29 { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 33 { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 30 { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 34 { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 31 { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 35 { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 32 { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 36 { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 37 // This field is always "chrome" so that we can search for it. |
| 38 { "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 33 { NULL } | 39 { NULL } |
| 34 } | 40 } |
| 35 }; | 41 }; |
| 36 | 42 |
| 37 PasswordStoreGnome::PasswordStoreGnome() { | 43 PasswordStoreGnome::PasswordStoreGnome(LoginDatabase* login_db, |
| 44 Profile* profile, |
| 45 WebDataService* web_data_service) { |
| 38 } | 46 } |
| 39 | 47 |
| 40 PasswordStoreGnome::~PasswordStoreGnome() { | 48 PasswordStoreGnome::~PasswordStoreGnome() { |
| 41 } | 49 } |
| 42 | 50 |
| 43 bool PasswordStoreGnome::Init() { | 51 bool PasswordStoreGnome::Init() { |
| 44 return PasswordStore::Init() && gnome_keyring_is_available(); | 52 return PasswordStore::Init() && gnome_keyring_is_available(); |
| 45 } | 53 } |
| 46 | 54 |
| 47 void PasswordStoreGnome::AddLoginImpl(const PasswordForm& form) { | 55 void PasswordStoreGnome::AddLoginImpl(const PasswordForm& form) { |
| 48 AutoLock l(gnome_keyring_lock_); | 56 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
| 49 GnomeKeyringResult result = gnome_keyring_store_password_sync( | 57 AddLoginHelper(form, base::Time::Now()); |
| 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 } | 58 } |
| 74 | 59 |
| 75 void PasswordStoreGnome::UpdateLoginImpl(const PasswordForm& form) { | 60 void PasswordStoreGnome::UpdateLoginImpl(const PasswordForm& form) { |
| 76 AddLoginImpl(form); // Add & Update are the same in gnome keyring. | 61 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by |
| 62 // origin_url, username_element, username_value, password_element, and |
| 63 // signon_realm. We then compare the result to the updated form. If they |
| 64 // differ in any of the action, password_value, ssl_valid, or preferred |
| 65 // fields, then we add a new login with those fields updated and only delete |
| 66 // the original on success. |
| 67 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
| 68 GList* found = NULL; |
| 69 // Search gnome keyring for matching passwords. |
| 70 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( |
| 71 GNOME_KEYRING_ITEM_GENERIC_SECRET, |
| 72 &found, |
| 73 "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 74 form.origin.spec().c_str(), |
| 75 "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 76 UTF16ToUTF8(form.username_element).c_str(), |
| 77 "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 78 UTF16ToUTF8(form.username_value).c_str(), |
| 79 "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 80 UTF16ToUTF8(form.password_element).c_str(), |
| 81 "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 82 form.signon_realm.c_str(), |
| 83 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 84 GNOME_KEYRING_APPLICATION_CHROME, |
| 85 NULL); |
| 86 vector<PasswordForm*> forms; |
| 87 if (result == GNOME_KEYRING_RESULT_OK) { |
| 88 FillFormVector(found, &forms); |
| 89 for (size_t i = 0; i < forms.size(); ++i) { |
| 90 if (forms[i]->action != form.action || |
| 91 forms[i]->password_value != form.password_value || |
| 92 forms[i]->ssl_valid != form.ssl_valid || |
| 93 forms[i]->preferred != form.preferred) { |
| 94 PasswordForm updated = *forms[i]; |
| 95 updated.action = form.action; |
| 96 updated.password_value = form.password_value; |
| 97 updated.ssl_valid = form.ssl_valid; |
| 98 updated.preferred = form.preferred; |
| 99 if (AddLoginHelper(updated, updated.date_created)) |
| 100 RemoveLoginImpl(*forms[i]); |
| 101 } |
| 102 delete forms[i]; |
| 103 } |
| 104 } else { |
| 105 LOG(ERROR) << "Keyring find failed: " |
| 106 << gnome_keyring_result_to_message(result); |
| 107 } |
| 77 } | 108 } |
| 78 | 109 |
| 79 void PasswordStoreGnome::RemoveLoginImpl(const PasswordForm& form) { | 110 void PasswordStoreGnome::RemoveLoginImpl(const PasswordForm& form) { |
| 80 AutoLock l(gnome_keyring_lock_); | 111 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
| 112 // We find forms using the same fields as LoginDatabase::RemoveLogin(). |
| 81 GnomeKeyringResult result = gnome_keyring_delete_password_sync( | 113 GnomeKeyringResult result = gnome_keyring_delete_password_sync( |
| 82 &kGnomeSchema, | 114 &kGnomeSchema, |
| 83 "origin_url", form.origin.spec().c_str(), | 115 "origin_url", form.origin.spec().c_str(), |
| 84 "action_url", form.action.spec().c_str(), | 116 "action_url", form.action.spec().c_str(), |
| 85 "username_element", form.username_element.c_str(), | 117 "username_element", UTF16ToUTF8(form.username_element).c_str(), |
| 86 "username_value", form.username_value.c_str(), | 118 "username_value", UTF16ToUTF8(form.username_value).c_str(), |
| 87 "password_element", form.password_element.c_str(), | 119 "password_element", UTF16ToUTF8(form.password_element).c_str(), |
| 88 "submit_element", form.submit_element.c_str(), | 120 "submit_element", UTF16ToUTF8(form.submit_element).c_str(), |
| 121 "signon_realm", form.signon_realm.c_str(), |
| 122 NULL); |
| 123 if (result != GNOME_KEYRING_RESULT_OK) { |
| 124 LOG(ERROR) << "Keyring delete failed: " |
| 125 << gnome_keyring_result_to_message(result); |
| 126 } |
| 127 } |
| 128 |
| 129 void PasswordStoreGnome::RemoveLoginsCreatedBetweenImpl( |
| 130 const base::Time& delete_begin, |
| 131 const base::Time& delete_end) { |
| 132 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
| 133 GList* found = NULL; |
| 134 // Search GNOME keyring for all passwords, then delete the ones in the range. |
| 135 // We need to search for something, otherwise we get no results - so we search |
| 136 // for the fixed application string. |
| 137 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( |
| 138 GNOME_KEYRING_ITEM_GENERIC_SECRET, |
| 139 &found, |
| 140 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 141 GNOME_KEYRING_APPLICATION_CHROME, |
| 142 NULL); |
| 143 if (result == GNOME_KEYRING_RESULT_OK) { |
| 144 // We could walk the list and delete items as we find them, but it is much |
| 145 // easier to build the vector and use RemoveLoginImpl() to delete them. |
| 146 vector<PasswordForm*> forms; |
| 147 FillFormVector(found, &forms); |
| 148 for (size_t i = 0; i < forms.size(); ++i) { |
| 149 if (delete_begin <= forms[i]->date_created && |
| 150 (delete_end.is_null() || forms[i]->date_created < delete_end)) { |
| 151 RemoveLoginImpl(*forms[i]); |
| 152 } |
| 153 delete forms[i]; |
| 154 } |
| 155 } else if (result != GNOME_KEYRING_RESULT_NO_MATCH) { |
| 156 LOG(ERROR) << "Keyring find failed: " |
| 157 << gnome_keyring_result_to_message(result); |
| 158 } |
| 159 } |
| 160 |
| 161 void PasswordStoreGnome::GetLoginsImpl(GetLoginsRequest* request, |
| 162 const PasswordForm& form) { |
| 163 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
| 164 GList* found = NULL; |
| 165 // Search gnome keyring for matching passwords. |
| 166 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( |
| 167 GNOME_KEYRING_ITEM_GENERIC_SECRET, |
| 168 &found, |
| 169 "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 170 form.signon_realm.c_str(), |
| 171 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 172 GNOME_KEYRING_APPLICATION_CHROME, |
| 173 NULL); |
| 174 vector<PasswordForm*> forms; |
| 175 if (result == GNOME_KEYRING_RESULT_OK) { |
| 176 FillFormVector(found, &forms); |
| 177 } else if (result != GNOME_KEYRING_RESULT_NO_MATCH) { |
| 178 LOG(ERROR) << "Keyring find failed: " |
| 179 << gnome_keyring_result_to_message(result); |
| 180 } |
| 181 NotifyConsumer(request, forms); |
| 182 } |
| 183 |
| 184 void PasswordStoreGnome::GetAutofillableLoginsImpl( |
| 185 GetLoginsRequest* request) { |
| 186 std::vector<PasswordForm*> forms; |
| 187 FillAutofillableLogins(&forms); |
| 188 NotifyConsumer(request, forms); |
| 189 } |
| 190 |
| 191 void PasswordStoreGnome::GetBlacklistLoginsImpl( |
| 192 GetLoginsRequest* request) { |
| 193 std::vector<PasswordForm*> forms; |
| 194 FillBlacklistLogins(&forms); |
| 195 NotifyConsumer(request, forms); |
| 196 } |
| 197 |
| 198 bool PasswordStoreGnome::FillAutofillableLogins( |
| 199 std::vector<PasswordForm*>* forms) { |
| 200 return FillSomeLogins(true, forms); |
| 201 } |
| 202 |
| 203 bool PasswordStoreGnome::FillBlacklistLogins( |
| 204 std::vector<PasswordForm*>* forms) { |
| 205 return FillSomeLogins(false, forms); |
| 206 } |
| 207 |
| 208 bool PasswordStoreGnome::AddLoginHelper(const PasswordForm& form, |
| 209 const base::Time& date_created) { |
| 210 GnomeKeyringResult result = gnome_keyring_store_password_sync( |
| 211 &kGnomeSchema, |
| 212 NULL, // Default keyring. |
| 213 form.origin.spec().c_str(), // Display name. |
| 214 UTF16ToUTF8(form.password_value).c_str(), |
| 215 "origin_url", form.origin.spec().c_str(), |
| 216 "action_url", form.action.spec().c_str(), |
| 217 "username_element", UTF16ToUTF8(form.username_element).c_str(), |
| 218 "username_value", UTF16ToUTF8(form.username_value).c_str(), |
| 219 "password_element", UTF16ToUTF8(form.password_element).c_str(), |
| 220 "submit_element", UTF16ToUTF8(form.submit_element).c_str(), |
| 89 "signon_realm", form.signon_realm.c_str(), | 221 "signon_realm", form.signon_realm.c_str(), |
| 90 "ssl_valid", form.ssl_valid, | 222 "ssl_valid", form.ssl_valid, |
| 91 "preferred", form.preferred, | 223 "preferred", form.preferred, |
| 92 "date_created", Int64ToString(form.date_created.ToTimeT()).c_str(), | 224 "date_created", Int64ToString(date_created.ToTimeT()).c_str(), |
| 93 "blacklisted_by_user", form.blacklisted_by_user, | 225 "blacklisted_by_user", form.blacklisted_by_user, |
| 94 "scheme", form.scheme, | 226 "scheme", form.scheme, |
| 95 NULL); | 227 "application", GNOME_KEYRING_APPLICATION_CHROME, |
| 228 NULL); |
| 229 |
| 96 if (result != GNOME_KEYRING_RESULT_OK) { | 230 if (result != GNOME_KEYRING_RESULT_OK) { |
| 97 LOG(ERROR) << "Keyring delete failed: " | 231 LOG(ERROR) << "Keyring save failed: " |
| 98 << gnome_keyring_result_to_message(result); | 232 << gnome_keyring_result_to_message(result); |
| 99 } | 233 return false; |
| 100 } | 234 } |
| 101 | 235 return true; |
| 102 void PasswordStoreGnome::GetLoginsImpl(GetLoginsRequest* request) { | 236 } |
| 103 AutoLock l(gnome_keyring_lock_); | 237 |
| 104 GList* found = NULL; | 238 bool PasswordStoreGnome::FillSomeLogins( |
| 239 bool autofillable, |
| 240 std::vector<PasswordForm*>* forms) { |
| 241 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); |
| 242 GList* found = NULL; |
| 243 uint32_t blacklisted_by_user = !autofillable; |
| 105 // Search gnome keyring for matching passwords. | 244 // Search gnome keyring for matching passwords. |
| 106 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( | 245 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( |
| 107 GNOME_KEYRING_ITEM_GENERIC_SECRET, | 246 GNOME_KEYRING_ITEM_GENERIC_SECRET, |
| 108 &found, | 247 &found, |
| 109 "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | 248 "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32, |
| 110 request->form.signon_realm.c_str(), | 249 blacklisted_by_user, |
| 111 NULL); | 250 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, |
| 112 vector<PasswordForm*> forms; | 251 GNOME_KEYRING_APPLICATION_CHROME, |
| 113 if (result == GNOME_KEYRING_RESULT_NO_MATCH) { | 252 NULL); |
| 114 NotifyConsumer(request, forms); | 253 if (result == GNOME_KEYRING_RESULT_OK) { |
| 115 return; | 254 FillFormVector(found, forms); |
| 116 } else if (result != GNOME_KEYRING_RESULT_OK) { | 255 } else if (result != GNOME_KEYRING_RESULT_NO_MATCH) { |
| 117 LOG(ERROR) << "Keyring find failed: " | 256 LOG(ERROR) << "Keyring find failed: " |
| 118 << gnome_keyring_result_to_message(result); | 257 << gnome_keyring_result_to_message(result); |
| 119 NotifyConsumer(request, forms); | 258 return false; |
| 120 return; | 259 } |
| 121 } | 260 return true; |
| 122 | 261 } |
| 123 // Parse all the results from the returned GList into a | 262 |
| 124 // vector<PasswordForm*>. PasswordForms are allocated on the heap. These | 263 void PasswordStoreGnome::FillFormVector(GList* found, |
| 125 // will be deleted by the consumer. | 264 std::vector<PasswordForm*>* forms) { |
| 126 GList* element = g_list_first(found); | 265 GList* element = g_list_first(found); |
| 127 while (element != NULL) { | 266 while (element != NULL) { |
| 128 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); | 267 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); |
| 129 char* password = data->secret; | 268 char* password = data->secret; |
| 130 | 269 |
| 131 GnomeKeyringAttributeList* attributes = data->attributes; | 270 GnomeKeyringAttributeList* attributes = data->attributes; |
| 132 // Read the string & int attributes into the appropriate map. | 271 // Read the string and int attributes into the appropriate map. |
| 133 map<string, string> string_attribute_map; | 272 map<string, string> string_attribute_map; |
| 134 map<string, uint32> uint_attribute_map; | 273 map<string, uint32> uint_attribute_map; |
| 135 for (unsigned int i = 0; i < attributes->len; ++i) { | 274 for (unsigned int i = 0; i < attributes->len; ++i) { |
| 136 GnomeKeyringAttribute attribute = | 275 GnomeKeyringAttribute attribute = |
| 137 gnome_keyring_attribute_list_index(attributes, i); | 276 gnome_keyring_attribute_list_index(attributes, i); |
| 138 if (attribute.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) { | 277 if (attribute.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) { |
| 139 string_attribute_map[string(attribute.name)] = | 278 string_attribute_map[string(attribute.name)] = |
| 140 string(attribute.value.string); | 279 string(attribute.value.string); |
| 141 } else if (attribute.type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) { | 280 } else if (attribute.type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) { |
| 142 uint_attribute_map[string(attribute.name)] = attribute.value.integer; | 281 uint_attribute_map[string(attribute.name)] = attribute.value.integer; |
| 143 } | 282 } |
| 144 } | 283 } |
| 145 | 284 |
| 146 PasswordForm* form = new PasswordForm(); | 285 PasswordForm* form = new PasswordForm(); |
| 147 form->origin = GURL(string_attribute_map["origin_url"]); | 286 form->origin = GURL(string_attribute_map["origin_url"]); |
| 148 form->action = GURL(string_attribute_map["action_url"]); | 287 form->action = GURL(string_attribute_map["action_url"]); |
| 149 form->username_element = | 288 form->username_element = |
| 150 ASCIIToWide(string(string_attribute_map["username_element"])); | 289 UTF8ToUTF16(string(string_attribute_map["username_element"])); |
| 151 form->username_value = | 290 form->username_value = |
| 152 ASCIIToWide(string(string_attribute_map["username_value"])); | 291 UTF8ToUTF16(string(string_attribute_map["username_value"])); |
| 153 form->password_element = | 292 form->password_element = |
| 154 ASCIIToWide(string(string_attribute_map["password_element"])); | 293 UTF8ToUTF16(string(string_attribute_map["password_element"])); |
| 155 form->password_value = ASCIIToWide(string(password)); | 294 form->password_value = UTF8ToUTF16(string(password)); |
| 156 form->submit_element = | 295 form->submit_element = |
| 157 ASCIIToWide(string(string_attribute_map["submit_element"])); | 296 UTF8ToUTF16(string(string_attribute_map["submit_element"])); |
| 158 form->signon_realm = uint_attribute_map["signon_realm"]; | 297 form->signon_realm = string_attribute_map["signon_realm"]; |
| 159 form->ssl_valid = uint_attribute_map["ssl_valid"]; | 298 form->ssl_valid = uint_attribute_map["ssl_valid"]; |
| 160 form->preferred = uint_attribute_map["preferred"]; | 299 form->preferred = uint_attribute_map["preferred"]; |
| 161 string date = string_attribute_map["date_created"]; | 300 string date = string_attribute_map["date_created"]; |
| 162 int64 date_created = 0; | 301 int64 date_created = 0; |
| 163 DCHECK(StringToInt64(date, &date_created) && date_created != 0); | 302 bool date_ok = StringToInt64(date, &date_created); |
| 303 DCHECK(date_ok); |
| 304 DCHECK(date_created != 0); |
| 164 form->date_created = base::Time::FromTimeT(date_created); | 305 form->date_created = base::Time::FromTimeT(date_created); |
| 165 form->blacklisted_by_user = uint_attribute_map["blacklisted_by_user"]; | 306 form->blacklisted_by_user = uint_attribute_map["blacklisted_by_user"]; |
| 166 form->scheme = | 307 form->scheme = static_cast<PasswordForm::Scheme>( |
| 167 static_cast<PasswordForm::Scheme>(uint_attribute_map["scheme"]); | 308 uint_attribute_map["scheme"]); |
| 168 | 309 |
| 169 forms.push_back(form); | 310 forms->push_back(form); |
| 170 | 311 |
| 171 element = g_list_next(element); | 312 element = g_list_next(element); |
| 172 } | 313 } |
| 173 gnome_keyring_found_list_free(found); | 314 gnome_keyring_found_list_free(found); |
| 174 found = NULL; | |
| 175 | |
| 176 NotifyConsumer(request, forms); | |
| 177 } | 315 } |
| OLD | NEW |