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 |
| 11 #include <limits> | 10 #include <limits> |
| 12 #include <list> | 11 #include <list> |
| 13 #include <memory> | 12 #include <memory> |
| 14 #include <utility> | 13 #include <utility> |
| 15 #include <vector> | 14 #include <vector> |
| 16 | 15 |
| 16 #include <libsecret/secret.h> | |
| 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 // Generates a profile-specific app string based on profile_id_. | 199 // Generates a profile-specific app string based on profile_id_. |
| 261 std::string GetProfileSpecificAppString(LocalProfileId id) { | 200 std::string GetProfileSpecificAppString(LocalProfileId id) { |
| 262 // Originally, the application string was always just "chrome" and used only | 201 // 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 | 202 // 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. | 203 // for nothing. Now we use it to distinguish passwords for different profiles. |
| 265 return base::StringPrintf("%s-%d", kLibsecretAppString, id); | 204 return base::StringPrintf("%s-%d", kLibsecretAppString, id); |
| 266 } | 205 } |
| 267 | 206 |
| 268 } // namespace | 207 } // namespace |
| 269 | 208 |
| 270 bool LibsecretLoader::LibsecretIsAvailable() { | 209 bool LibsecretLoader::LibsecretIsAvailable() { |
|
vabr (Chromium)
2016/04/28 12:44:25
Move this implementation to os_crypt as well.
cfroussios
2016/04/28 14:33:43
Done.
| |
| 271 if (!libsecret_loaded) | 210 if (!libsecret_loaded) |
| 272 return false; | 211 return false; |
| 273 // A dummy query is made to check for availability, because libsecret doesn't | 212 // A dummy query is made to check for availability, because libsecret doesn't |
| 274 // have a dedicated availability function. For performance reasons, the query | 213 // have a dedicated availability function. For performance reasons, the query |
| 275 // is meant to return an empty result. | 214 // is meant to return an empty result. |
| 276 LibsecretAttributesBuilder attrs; | 215 LibsecretAttributesBuilder attrs; |
| 277 attrs.Append("application", "chrome-string_to_get_empty_result"); | 216 attrs.Append("application", "chrome-string_to_get_empty_result"); |
| 278 | 217 |
| 279 GError* error = nullptr; | 218 GError* error = nullptr; |
| 280 GList* found = secret_service_search_sync(nullptr, // default secret service | 219 GList* found = secret_service_search_sync(nullptr, // default secret service |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 683 if (lookup_form) { | 622 if (lookup_form) { |
| 684 UMA_HISTOGRAM_ENUMERATION("PasswordManager.PslDomainMatchTriggering", | 623 UMA_HISTOGRAM_ENUMERATION("PasswordManager.PslDomainMatchTriggering", |
| 685 allow_psl_match | 624 allow_psl_match |
| 686 ? psl_domain_match_metric | 625 ? psl_domain_match_metric |
| 687 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, | 626 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, |
| 688 password_manager::PSL_DOMAIN_MATCH_COUNT); | 627 password_manager::PSL_DOMAIN_MATCH_COUNT); |
| 689 } | 628 } |
| 690 g_list_free(found); | 629 g_list_free(found); |
| 691 return forms; | 630 return forms; |
| 692 } | 631 } |
| OLD | NEW |