Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 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/native_backend_libsecret.h" | 5 #include "chrome/browser/password_manager/native_backend_libsecret.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> | |
| 8 #include <stddef.h> | 7 #include <stddef.h> |
| 9 #include <stdint.h> | 8 #include <stdint.h> |
| 10 | 9 |
| 10 #include <libsecret/secret.h> | |
|
Lei Zhang
2016/04/28 21:49:09
I'm curious what this is needed for if "password_m
vabr (Chromium)
2016/04/29 07:36:45
Not interacting with libsecret is the ultimate goa
| |
| 11 | |
| 11 #include <limits> | 12 #include <limits> |
| 12 #include <list> | 13 #include <list> |
| 13 #include <memory> | 14 #include <memory> |
| 14 #include <utility> | 15 #include <utility> |
| 15 #include <vector> | 16 #include <vector> |
| 16 | 17 |
| 17 #include "base/logging.h" | 18 #include "base/logging.h" |
| 18 #include "base/metrics/histogram.h" | 19 #include "base/metrics/histogram.h" |
| 19 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 21 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 22 #include "components/password_manager/core/browser/password_manager_metrics_util .h" | 23 #include "components/password_manager/core/browser/password_manager_metrics_util .h" |
| 23 #include "components/password_manager/core/browser/password_manager_util.h" | 24 #include "components/password_manager/core/browser/password_manager_util.h" |
| 24 #include "url/origin.h" | 25 #include "url/origin.h" |
| 25 | 26 |
| 26 using autofill::PasswordForm; | 27 using autofill::PasswordForm; |
| 27 using base::UTF8ToUTF16; | 28 using base::UTF8ToUTF16; |
| 28 using base::UTF16ToUTF8; | 29 using base::UTF16ToUTF8; |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 const char kEmptyString[] = ""; | 32 const char kEmptyString[] = ""; |
| 32 const int kMaxPossibleTimeTValue = std::numeric_limits<int>::max(); | 33 const int kMaxPossibleTimeTValue = std::numeric_limits<int>::max(); |
| 33 } // namespace | 34 } // namespace |
| 34 | 35 |
| 35 typeof(&::secret_password_store_sync) | |
| 36 LibsecretLoader::secret_password_store_sync; | |
| 37 typeof(&::secret_service_search_sync) | |
| 38 LibsecretLoader::secret_service_search_sync; | |
| 39 typeof(&::secret_password_clear_sync) | |
| 40 LibsecretLoader::secret_password_clear_sync; | |
| 41 typeof(&::secret_item_get_secret) LibsecretLoader::secret_item_get_secret; | |
| 42 typeof(&::secret_value_get_text) LibsecretLoader::secret_value_get_text; | |
| 43 typeof(&::secret_item_get_attributes) | |
| 44 LibsecretLoader::secret_item_get_attributes; | |
| 45 typeof(&::secret_item_load_secret_sync) | |
| 46 LibsecretLoader::secret_item_load_secret_sync; | |
| 47 typeof(&::secret_value_unref) LibsecretLoader::secret_value_unref; | |
| 48 | |
| 49 bool LibsecretLoader::libsecret_loaded = false; | |
| 50 | |
| 51 const LibsecretLoader::FunctionInfo LibsecretLoader::functions[] = { | |
| 52 {"secret_password_store_sync", | |
| 53 reinterpret_cast<void**>(&secret_password_store_sync)}, | |
| 54 {"secret_service_search_sync", | |
| 55 reinterpret_cast<void**>(&secret_service_search_sync)}, | |
| 56 {"secret_password_clear_sync", | |
| 57 reinterpret_cast<void**>(&secret_password_clear_sync)}, | |
| 58 {"secret_item_get_secret", | |
| 59 reinterpret_cast<void**>(&secret_item_get_secret)}, | |
| 60 {"secret_value_get_text", reinterpret_cast<void**>(&secret_value_get_text)}, | |
| 61 {"secret_item_get_attributes", | |
| 62 reinterpret_cast<void**>(&secret_item_get_attributes)}, | |
| 63 {"secret_item_load_secret_sync", | |
| 64 reinterpret_cast<void**>(&secret_item_load_secret_sync)}, | |
| 65 {"secret_value_unref", reinterpret_cast<void**>(&secret_value_unref)}, | |
| 66 {nullptr, nullptr}}; | |
| 67 | |
| 68 bool LibsecretLoader::LoadLibsecret() { | |
| 69 if (libsecret_loaded) | |
| 70 return true; | |
| 71 | |
| 72 void* handle = dlopen("libsecret-1.so.0", RTLD_NOW | RTLD_GLOBAL); | |
| 73 if (!handle) { | |
| 74 // We wanted to use libsecret, but we couldn't load it. Warn, because | |
| 75 // either the user asked for this, or we autodetected it incorrectly. (Or | |
| 76 // the system has broken libraries, which is also good to warn about.) | |
| 77 LOG(WARNING) << "Could not load libsecret-1.so.0: " << dlerror(); | |
| 78 return false; | |
| 79 } | |
| 80 | |
| 81 for (size_t i = 0; functions[i].name; ++i) { | |
| 82 dlerror(); | |
| 83 *functions[i].pointer = dlsym(handle, functions[i].name); | |
| 84 const char* error = dlerror(); | |
| 85 if (error) { | |
| 86 VLOG(1) << "Unable to load symbol " << functions[i].name << ": " << error; | |
| 87 dlclose(handle); | |
| 88 return false; | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 libsecret_loaded = true; | |
| 93 // We leak the library handle. That's OK: this function is called only once. | |
| 94 return true; | |
| 95 } | |
| 96 | |
| 97 namespace { | 36 namespace { |
| 98 | 37 |
| 99 const char kLibsecretAppString[] = "chrome"; | 38 const char kLibsecretAppString[] = "chrome"; |
| 100 | 39 |
| 101 // Schema is analagous to the fields in PasswordForm. | 40 // Schema is analagous to the fields in PasswordForm. |
| 102 const SecretSchema kLibsecretSchema = { | 41 const SecretSchema kLibsecretSchema = { |
| 103 "chrome_libsecret_password_schema", | 42 "chrome_libsecret_password_schema", |
| 104 // We have to use SECRET_SCHEMA_DONT_MATCH_NAME in order to get old | 43 // We have to use SECRET_SCHEMA_DONT_MATCH_NAME in order to get old |
| 105 // passwords stored with gnome_keyring. | 44 // passwords stored with gnome_keyring. |
| 106 SECRET_SCHEMA_DONT_MATCH_NAME, | 45 SECRET_SCHEMA_DONT_MATCH_NAME, |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 bool success = DeserializeFormDataFromBase64String(encoded_form_data, | 147 bool success = DeserializeFormDataFromBase64String(encoded_form_data, |
| 209 &form->form_data); | 148 &form->form_data); |
| 210 password_manager::metrics_util::FormDeserializationStatus status = | 149 password_manager::metrics_util::FormDeserializationStatus status = |
| 211 success ? password_manager::metrics_util::GNOME_SUCCESS | 150 success ? password_manager::metrics_util::GNOME_SUCCESS |
| 212 : password_manager::metrics_util::GNOME_FAILURE; | 151 : password_manager::metrics_util::GNOME_FAILURE; |
| 213 LogFormDataDeserializationStatus(status); | 152 LogFormDataDeserializationStatus(status); |
| 214 } | 153 } |
| 215 return form; | 154 return form; |
| 216 } | 155 } |
| 217 | 156 |
| 218 class LibsecretAttributesBuilder { | |
| 219 public: | |
| 220 LibsecretAttributesBuilder(); | |
| 221 ~LibsecretAttributesBuilder(); | |
| 222 void Append(const std::string& name, const std::string& value); | |
| 223 void Append(const std::string& name, int64_t value); | |
| 224 // GHashTable, its keys and values returned from Get() are destroyed in | |
| 225 // |LibsecretAttributesBuilder| desctructor. | |
| 226 GHashTable* Get() { return attrs_; } | |
| 227 | |
| 228 private: | |
| 229 // |name_values_| is a storage for strings referenced in |attrs_|. | |
| 230 std::list<std::string> name_values_; | |
| 231 GHashTable* attrs_; | |
| 232 }; | |
| 233 | |
| 234 LibsecretAttributesBuilder::LibsecretAttributesBuilder() { | |
| 235 attrs_ = g_hash_table_new_full(g_str_hash, g_str_equal, | |
| 236 nullptr, // no deleter for keys | |
| 237 nullptr); // no deleter for values | |
| 238 } | |
| 239 | |
| 240 LibsecretAttributesBuilder::~LibsecretAttributesBuilder() { | |
| 241 g_hash_table_destroy(attrs_); | |
| 242 } | |
| 243 | |
| 244 void LibsecretAttributesBuilder::Append(const std::string& name, | |
| 245 const std::string& value) { | |
| 246 name_values_.push_back(name); | |
| 247 gpointer name_str = | |
| 248 static_cast<gpointer>(const_cast<char*>(name_values_.back().c_str())); | |
| 249 name_values_.push_back(value); | |
| 250 gpointer value_str = | |
| 251 static_cast<gpointer>(const_cast<char*>(name_values_.back().c_str())); | |
| 252 g_hash_table_insert(attrs_, name_str, value_str); | |
| 253 } | |
| 254 | |
| 255 void LibsecretAttributesBuilder::Append(const std::string& name, | |
| 256 int64_t value) { | |
| 257 Append(name, base::Int64ToString(value)); | |
| 258 } | |
| 259 | |
| 260 // Generates a profile-specific app string based on profile_id_. | 157 // Generates a profile-specific app string based on profile_id_. |
| 261 std::string GetProfileSpecificAppString(LocalProfileId id) { | 158 std::string GetProfileSpecificAppString(LocalProfileId id) { |
| 262 // Originally, the application string was always just "chrome" and used only | 159 // Originally, the application string was always just "chrome" and used only |
| 263 // so that we had *something* to search for since GNOME Keyring won't search | 160 // so that we had *something* to search for since GNOME Keyring won't search |
| 264 // for nothing. Now we use it to distinguish passwords for different profiles. | 161 // for nothing. Now we use it to distinguish passwords for different profiles. |
| 265 return base::StringPrintf("%s-%d", kLibsecretAppString, id); | 162 return base::StringPrintf("%s-%d", kLibsecretAppString, id); |
| 266 } | 163 } |
| 267 | 164 |
| 268 } // namespace | 165 } // namespace |
| 269 | 166 |
| 270 bool LibsecretLoader::LibsecretIsAvailable() { | |
| 271 if (!libsecret_loaded) | |
| 272 return false; | |
| 273 // A dummy query is made to check for availability, because libsecret doesn't | |
| 274 // have a dedicated availability function. For performance reasons, the query | |
| 275 // is meant to return an empty result. | |
| 276 LibsecretAttributesBuilder attrs; | |
| 277 attrs.Append("application", "chrome-string_to_get_empty_result"); | |
| 278 | |
| 279 GError* error = nullptr; | |
| 280 GList* found = secret_service_search_sync(nullptr, // default secret service | |
| 281 &kLibsecretSchema, attrs.Get(), | |
| 282 SECRET_SEARCH_ALL, | |
| 283 nullptr, // no cancellable ojbect | |
| 284 &error); | |
| 285 bool success = (error == nullptr); | |
| 286 if (error) | |
| 287 g_error_free(error); | |
| 288 if (found) | |
| 289 g_list_free(found); | |
| 290 | |
| 291 return success; | |
| 292 } | |
| 293 | |
| 294 NativeBackendLibsecret::NativeBackendLibsecret(LocalProfileId id) | 167 NativeBackendLibsecret::NativeBackendLibsecret(LocalProfileId id) |
| 295 : app_string_(GetProfileSpecificAppString(id)) { | 168 : app_string_(GetProfileSpecificAppString(id)) { |
| 296 } | 169 } |
| 297 | 170 |
| 298 NativeBackendLibsecret::~NativeBackendLibsecret() { | 171 NativeBackendLibsecret::~NativeBackendLibsecret() { |
| 299 } | 172 } |
| 300 | 173 |
| 301 bool NativeBackendLibsecret::Init() { | 174 bool NativeBackendLibsecret::Init() { |
| 302 return LoadLibsecret() && LibsecretIsAvailable(); | 175 return LibsecretLoader::LoadLibsecret() && |
| 176 LibsecretLoader::LibsecretIsAvailable(); | |
| 303 } | 177 } |
| 304 | 178 |
| 305 password_manager::PasswordStoreChangeList NativeBackendLibsecret::AddLogin( | 179 password_manager::PasswordStoreChangeList NativeBackendLibsecret::AddLogin( |
| 306 const PasswordForm& form) { | 180 const PasswordForm& form) { |
| 307 // Based on LoginDatabase::AddLogin(), we search for an existing match based | 181 // Based on LoginDatabase::AddLogin(), we search for an existing match based |
| 308 // on origin_url, username_element, username_value, password_element and | 182 // on origin_url, username_element, username_value, password_element and |
| 309 // signon_realm first, remove that, and then add the new entry. | 183 // signon_realm first, remove that, and then add the new entry. |
| 310 password_manager::PasswordStoreChangeList changes; | 184 password_manager::PasswordStoreChangeList changes; |
| 311 ScopedVector<autofill::PasswordForm> forms; | 185 ScopedVector<autofill::PasswordForm> forms; |
| 312 if (!AddUpdateLoginSearch(form, &forms)) | 186 if (!AddUpdateLoginSearch(form, &forms)) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 return true; | 240 return true; |
| 367 } | 241 } |
| 368 return false; | 242 return false; |
| 369 } | 243 } |
| 370 | 244 |
| 371 bool NativeBackendLibsecret::RemoveLogin( | 245 bool NativeBackendLibsecret::RemoveLogin( |
| 372 const autofill::PasswordForm& form, | 246 const autofill::PasswordForm& form, |
| 373 password_manager::PasswordStoreChangeList* changes) { | 247 password_manager::PasswordStoreChangeList* changes) { |
| 374 DCHECK(changes); | 248 DCHECK(changes); |
| 375 GError* error = nullptr; | 249 GError* error = nullptr; |
| 376 if (secret_password_clear_sync( | 250 if (LibsecretLoader::secret_password_clear_sync( |
| 377 &kLibsecretSchema, nullptr, &error, | 251 &kLibsecretSchema, nullptr, &error, "origin_url", |
| 378 "origin_url", form.origin.spec().c_str(), | 252 form.origin.spec().c_str(), "username_element", |
| 379 "username_element", UTF16ToUTF8(form.username_element).c_str(), | 253 UTF16ToUTF8(form.username_element).c_str(), "username_value", |
| 380 "username_value", UTF16ToUTF8(form.username_value).c_str(), | 254 UTF16ToUTF8(form.username_value).c_str(), "password_element", |
| 381 "password_element", UTF16ToUTF8(form.password_element).c_str(), | 255 UTF16ToUTF8(form.password_element).c_str(), "signon_realm", |
| 382 "signon_realm", form.signon_realm.c_str(), | 256 form.signon_realm.c_str(), "application", app_string_.c_str(), |
| 383 "application", app_string_.c_str(), nullptr)) { | 257 nullptr)) { |
| 384 changes->push_back(password_manager::PasswordStoreChange( | 258 changes->push_back(password_manager::PasswordStoreChange( |
| 385 password_manager::PasswordStoreChange::REMOVE, form)); | 259 password_manager::PasswordStoreChange::REMOVE, form)); |
| 386 } | 260 } |
| 387 | 261 |
| 388 if (error) { | 262 if (error) { |
| 389 LOG(ERROR) << "Libsecret delete failed: " << error->message; | 263 LOG(ERROR) << "Libsecret delete failed: " << error->message; |
| 390 g_error_free(error); | 264 g_error_free(error); |
| 391 return false; | 265 return false; |
| 392 } | 266 } |
| 393 return true; | 267 return true; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 436 ScopedVector<autofill::PasswordForm>* forms) { | 310 ScopedVector<autofill::PasswordForm>* forms) { |
| 437 LibsecretAttributesBuilder attrs; | 311 LibsecretAttributesBuilder attrs; |
| 438 attrs.Append("origin_url", lookup_form.origin.spec()); | 312 attrs.Append("origin_url", lookup_form.origin.spec()); |
| 439 attrs.Append("username_element", UTF16ToUTF8(lookup_form.username_element)); | 313 attrs.Append("username_element", UTF16ToUTF8(lookup_form.username_element)); |
| 440 attrs.Append("username_value", UTF16ToUTF8(lookup_form.username_value)); | 314 attrs.Append("username_value", UTF16ToUTF8(lookup_form.username_value)); |
| 441 attrs.Append("password_element", UTF16ToUTF8(lookup_form.password_element)); | 315 attrs.Append("password_element", UTF16ToUTF8(lookup_form.password_element)); |
| 442 attrs.Append("signon_realm", lookup_form.signon_realm); | 316 attrs.Append("signon_realm", lookup_form.signon_realm); |
| 443 attrs.Append("application", app_string_); | 317 attrs.Append("application", app_string_); |
| 444 | 318 |
| 445 GError* error = nullptr; | 319 GError* error = nullptr; |
| 446 GList* found = secret_service_search_sync(nullptr, // default secret service | 320 GList* found = LibsecretLoader::secret_service_search_sync( |
| 447 &kLibsecretSchema, attrs.Get(), | 321 nullptr, // default secret service |
| 448 SECRET_SEARCH_ALL, | 322 &kLibsecretSchema, attrs.Get(), SECRET_SEARCH_ALL, |
| 449 nullptr, // no cancellable ojbect | 323 nullptr, // no cancellable ojbect |
| 450 &error); | 324 &error); |
| 451 if (error) { | 325 if (error) { |
| 452 LOG(ERROR) << "Unable to get logins " << error->message; | 326 LOG(ERROR) << "Unable to get logins " << error->message; |
| 453 g_error_free(error); | 327 g_error_free(error); |
| 454 if (found) | 328 if (found) |
| 455 g_list_free(found); | 329 g_list_free(found); |
| 456 return false; | 330 return false; |
| 457 } | 331 } |
| 458 | 332 |
| 459 *forms = ConvertFormList(found, &lookup_form); | 333 *forms = ConvertFormList(found, &lookup_form); |
| 460 return true; | 334 return true; |
| 461 } | 335 } |
| 462 | 336 |
| 463 bool NativeBackendLibsecret::RawAddLogin(const PasswordForm& form) { | 337 bool NativeBackendLibsecret::RawAddLogin(const PasswordForm& form) { |
| 464 int64_t date_created = form.date_created.ToInternalValue(); | 338 int64_t date_created = form.date_created.ToInternalValue(); |
| 465 // If we are asked to save a password with 0 date, use the current time. | 339 // If we are asked to save a password with 0 date, use the current time. |
| 466 // We don't want to actually save passwords as though on January 1, 1601. | 340 // We don't want to actually save passwords as though on January 1, 1601. |
| 467 if (!date_created) | 341 if (!date_created) |
| 468 date_created = base::Time::Now().ToInternalValue(); | 342 date_created = base::Time::Now().ToInternalValue(); |
| 469 int64_t date_synced = form.date_synced.ToInternalValue(); | 343 int64_t date_synced = form.date_synced.ToInternalValue(); |
| 470 std::string form_data; | 344 std::string form_data; |
| 471 SerializeFormDataToBase64String(form.form_data, &form_data); | 345 SerializeFormDataToBase64String(form.form_data, &form_data); |
| 472 GError* error = nullptr; | 346 GError* error = nullptr; |
| 473 // clang-format off | 347 // clang-format off |
| 474 secret_password_store_sync( | 348 LibsecretLoader::secret_password_store_sync( |
| 475 &kLibsecretSchema, | 349 &kLibsecretSchema, |
| 476 nullptr, // Default collection. | 350 nullptr, // Default collection. |
| 477 form.origin.spec().c_str(), // Display name. | 351 form.origin.spec().c_str(), // Display name. |
| 478 UTF16ToUTF8(form.password_value).c_str(), | 352 UTF16ToUTF8(form.password_value).c_str(), |
| 479 nullptr, // no cancellable ojbect | 353 nullptr, // no cancellable ojbect |
| 480 &error, | 354 &error, |
| 481 "origin_url", form.origin.spec().c_str(), | 355 "origin_url", form.origin.spec().c_str(), |
| 482 "action_url", form.action.spec().c_str(), | 356 "action_url", form.action.spec().c_str(), |
| 483 "username_element", UTF16ToUTF8(form.username_element).c_str(), | 357 "username_element", UTF16ToUTF8(form.username_element).c_str(), |
| 484 "username_value", UTF16ToUTF8(form.username_value).c_str(), | 358 "username_value", UTF16ToUTF8(form.username_value).c_str(), |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 539 if (options != ALL_LOGINS) | 413 if (options != ALL_LOGINS) |
| 540 attrs.Append("blacklisted_by_user", options == BLACKLISTED_LOGINS); | 414 attrs.Append("blacklisted_by_user", options == BLACKLISTED_LOGINS); |
| 541 if (lookup_form && | 415 if (lookup_form && |
| 542 !password_manager::ShouldPSLDomainMatchingApply( | 416 !password_manager::ShouldPSLDomainMatchingApply( |
| 543 password_manager::GetRegistryControlledDomain( | 417 password_manager::GetRegistryControlledDomain( |
| 544 GURL(lookup_form->signon_realm))) && | 418 GURL(lookup_form->signon_realm))) && |
| 545 lookup_form->scheme != PasswordForm::SCHEME_HTML) | 419 lookup_form->scheme != PasswordForm::SCHEME_HTML) |
| 546 attrs.Append("signon_realm", lookup_form->signon_realm); | 420 attrs.Append("signon_realm", lookup_form->signon_realm); |
| 547 | 421 |
| 548 GError* error = nullptr; | 422 GError* error = nullptr; |
| 549 GList* found = secret_service_search_sync(nullptr, // default secret service | 423 GList* found = LibsecretLoader::secret_service_search_sync( |
| 550 &kLibsecretSchema, attrs.Get(), | 424 nullptr, // default secret service |
| 551 SECRET_SEARCH_ALL, | 425 &kLibsecretSchema, attrs.Get(), SECRET_SEARCH_ALL, |
| 552 nullptr, // no cancellable ojbect | 426 nullptr, // no cancellable ojbect |
| 553 &error); | 427 &error); |
| 554 if (error) { | 428 if (error) { |
| 555 LOG(ERROR) << "Unable to get logins " << error->message; | 429 LOG(ERROR) << "Unable to get logins " << error->message; |
| 556 g_error_free(error); | 430 g_error_free(error); |
| 557 if (found) | 431 if (found) |
| 558 g_list_free(found); | 432 g_list_free(found); |
| 559 return false; | 433 return false; |
| 560 } | 434 } |
| 561 | 435 |
| 562 *forms = ConvertFormList(found, lookup_form); | 436 *forms = ConvertFormList(found, lookup_form); |
| 563 if (lookup_form) | 437 if (lookup_form) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 for (GList* element = g_list_first(found); element != nullptr; | 513 for (GList* element = g_list_first(found); element != nullptr; |
| 640 element = g_list_next(element)) { | 514 element = g_list_next(element)) { |
| 641 SecretItem* secretItem = static_cast<SecretItem*>(element->data); | 515 SecretItem* secretItem = static_cast<SecretItem*>(element->data); |
| 642 LibsecretLoader::secret_item_load_secret_sync(secretItem, nullptr, &error); | 516 LibsecretLoader::secret_item_load_secret_sync(secretItem, nullptr, &error); |
| 643 if (error) { | 517 if (error) { |
| 644 LOG(ERROR) << "Unable to load secret item" << error->message; | 518 LOG(ERROR) << "Unable to load secret item" << error->message; |
| 645 g_error_free(error); | 519 g_error_free(error); |
| 646 error = nullptr; | 520 error = nullptr; |
| 647 continue; | 521 continue; |
| 648 } | 522 } |
| 649 GHashTable* attrs = secret_item_get_attributes(secretItem); | 523 GHashTable* attrs = LibsecretLoader::secret_item_get_attributes(secretItem); |
| 650 std::unique_ptr<PasswordForm> form(FormOutOfAttributes(attrs)); | 524 std::unique_ptr<PasswordForm> form(FormOutOfAttributes(attrs)); |
| 651 g_hash_table_unref(attrs); | 525 g_hash_table_unref(attrs); |
| 652 if (form) { | 526 if (form) { |
| 653 if (lookup_form && form->signon_realm != lookup_form->signon_realm) { | 527 if (lookup_form && form->signon_realm != lookup_form->signon_realm) { |
| 654 if (lookup_form->scheme != PasswordForm::SCHEME_HTML || | 528 if (lookup_form->scheme != PasswordForm::SCHEME_HTML || |
| 655 form->scheme != PasswordForm::SCHEME_HTML) | 529 form->scheme != PasswordForm::SCHEME_HTML) |
| 656 continue; | 530 continue; |
| 657 // This is not an exact match, we try PSL matching and federated match. | 531 // This is not an exact match, we try PSL matching and federated match. |
| 658 if (allow_psl_match && | 532 if (allow_psl_match && |
| 659 password_manager::IsPublicSuffixDomainMatch( | 533 password_manager::IsPublicSuffixDomainMatch( |
| 660 form->signon_realm, lookup_form->signon_realm)) { | 534 form->signon_realm, lookup_form->signon_realm)) { |
| 661 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND; | 535 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND; |
| 662 form->is_public_suffix_match = true; | 536 form->is_public_suffix_match = true; |
| 663 } else if (!form->federation_origin.unique() && | 537 } else if (!form->federation_origin.unique() && |
| 664 password_manager::IsFederatedMatch(form->signon_realm, | 538 password_manager::IsFederatedMatch(form->signon_realm, |
| 665 lookup_form->origin)) { | 539 lookup_form->origin)) { |
| 666 } else { | 540 } else { |
| 667 continue; | 541 continue; |
| 668 } | 542 } |
| 669 } | 543 } |
| 670 SecretValue* secretValue = secret_item_get_secret(secretItem); | 544 SecretValue* secretValue = |
| 545 LibsecretLoader::secret_item_get_secret(secretItem); | |
| 671 if (secretValue) { | 546 if (secretValue) { |
| 672 form->password_value = UTF8ToUTF16(secret_value_get_text(secretValue)); | 547 form->password_value = |
| 673 secret_value_unref(secretValue); | 548 UTF8ToUTF16(LibsecretLoader::secret_value_get_text(secretValue)); |
| 549 LibsecretLoader::secret_value_unref(secretValue); | |
| 674 } else { | 550 } else { |
| 675 LOG(WARNING) << "Unable to access password from list element!"; | 551 LOG(WARNING) << "Unable to access password from list element!"; |
| 676 } | 552 } |
| 677 forms.push_back(std::move(form)); | 553 forms.push_back(std::move(form)); |
| 678 } else { | 554 } else { |
| 679 VLOG(1) << "Could not initialize PasswordForm from attributes!"; | 555 VLOG(1) << "Could not initialize PasswordForm from attributes!"; |
| 680 } | 556 } |
| 681 } | 557 } |
| 682 | 558 |
| 683 if (lookup_form) { | 559 if (lookup_form) { |
| 684 UMA_HISTOGRAM_ENUMERATION("PasswordManager.PslDomainMatchTriggering", | 560 UMA_HISTOGRAM_ENUMERATION("PasswordManager.PslDomainMatchTriggering", |
| 685 allow_psl_match | 561 allow_psl_match |
| 686 ? psl_domain_match_metric | 562 ? psl_domain_match_metric |
| 687 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, | 563 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, |
| 688 password_manager::PSL_DOMAIN_MATCH_COUNT); | 564 password_manager::PSL_DOMAIN_MATCH_COUNT); |
| 689 } | 565 } |
| 690 g_list_free(found); | 566 g_list_free(found); |
| 691 return forms; | 567 return forms; |
| 692 } | 568 } |
| OLD | NEW |