OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/os_crypt/key_storage_libsecret.h" | 5 #include "components/os_crypt/key_storage_libsecret.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "components/os_crypt/libsecret_util_linux.h" | 10 #include "components/os_crypt/libsecret_util_linux.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
26 }}; | 26 }}; |
27 | 27 |
28 const SecretSchema kKeystoreSchemaV2 = { | 28 const SecretSchema kKeystoreSchemaV2 = { |
29 "chrome_libsecret_os_crypt_password_v2", | 29 "chrome_libsecret_os_crypt_password_v2", |
30 SECRET_SCHEMA_DONT_MATCH_NAME, | 30 SECRET_SCHEMA_DONT_MATCH_NAME, |
31 { | 31 { |
32 {"application", SECRET_SCHEMA_ATTRIBUTE_STRING}, | 32 {"application", SECRET_SCHEMA_ATTRIBUTE_STRING}, |
33 {nullptr, SECRET_SCHEMA_ATTRIBUTE_STRING}, | 33 {nullptr, SECRET_SCHEMA_ATTRIBUTE_STRING}, |
34 }}; | 34 }}; |
35 | 35 |
36 // From a search result, extracts a SecretValue, asserting that there was at | |
37 // most one result. Returns nullptr if there are no results. | |
38 SecretValue* ToSingleSecret(GList* secret_items) { | |
39 GList* first = g_list_first(secret_items); | |
40 if (first == nullptr) | |
41 return nullptr; | |
42 if (g_list_next(first) != nullptr) { | |
43 VLOG(1) << "OSCrypt found more than one encryption keys."; | |
44 } | |
45 SecretItem* secret_item = static_cast<SecretItem*>(first->data); | |
46 SecretValue* secret_value = | |
47 LibsecretLoader::secret_item_get_secret(secret_item); | |
48 g_list_free(secret_items); | |
49 return secret_value; | |
50 } | |
51 | |
36 } // namespace | 52 } // namespace |
37 | 53 |
38 std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() { | 54 std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() { |
39 std::string password; | 55 std::string password; |
40 base::Base64Encode(base::RandBytesAsString(16), &password); | 56 base::Base64Encode(base::RandBytesAsString(16), &password); |
41 GError* error = nullptr; | 57 GError* error = nullptr; |
42 bool success = LibsecretLoader::secret_password_store_sync( | 58 bool success = LibsecretLoader::secret_password_store_sync( |
43 &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(), | 59 &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(), |
44 nullptr, &error, "application", kApplicationName, nullptr); | 60 nullptr, &error, "application", kApplicationName, nullptr); |
45 if (error || !success) { | 61 if (error) { |
46 VLOG(1) << "Libsecret lookup failed: " << error->message; | 62 VLOG(1) << "Libsecret lookup failed: " << error->message; |
63 g_error_free(error); | |
47 return std::string(); | 64 return std::string(); |
48 } | 65 } |
66 if (!success) { | |
67 VLOG(1) << "Libsecret lookup failed."; | |
vasilii
2016/10/24 12:56:00
indent 2 spaces.
cfroussios
2016/10/24 13:12:30
Done.
| |
68 return std::string(); | |
69 } | |
49 | 70 |
50 VLOG(1) << "OSCrypt generated a new password."; | 71 VLOG(1) << "OSCrypt generated a new password."; |
51 return password; | 72 return password; |
52 } | 73 } |
53 | 74 |
54 std::string KeyStorageLibsecret::GetKey() { | 75 std::string KeyStorageLibsecret::GetKey() { |
55 GError* error = nullptr; | 76 GError* error = nullptr; |
56 LibsecretAttributesBuilder attrs; | 77 LibsecretAttributesBuilder attrs; |
57 attrs.Append("application", kApplicationName); | 78 attrs.Append("application", kApplicationName); |
58 SecretValue* password_libsecret = LibsecretLoader::secret_service_lookup_sync( | 79 GList* search_results = LibsecretLoader::secret_service_search_sync( |
59 nullptr, &kKeystoreSchemaV2, attrs.Get(), nullptr, &error); | 80 nullptr /* default secret service */, &kKeystoreSchemaV2, attrs.Get(), |
81 static_cast<SecretSearchFlags>(SECRET_SEARCH_UNLOCK | | |
82 SECRET_SEARCH_LOAD_SECRETS), | |
83 nullptr, &error); | |
60 if (error) { | 84 if (error) { |
61 VLOG(1) << "Libsecret lookup failed: " << error->message; | 85 VLOG(1) << "Libsecret lookup failed: " << error->message; |
62 g_error_free(error); | 86 g_error_free(error); |
63 return std::string(); | 87 return std::string(); |
64 } | 88 } |
89 SecretValue* password_libsecret = ToSingleSecret(search_results); | |
65 if (!password_libsecret) { | 90 if (!password_libsecret) { |
66 std::string password = Migrate(); | 91 std::string password = Migrate(); |
67 if (!password.empty()) | 92 if (!password.empty()) |
68 return password; | 93 return password; |
69 return AddRandomPasswordInLibsecret(); | 94 return AddRandomPasswordInLibsecret(); |
70 } | 95 } |
71 std::string password( | 96 std::string password( |
72 LibsecretLoader::secret_value_get_text(password_libsecret)); | 97 LibsecretLoader::secret_value_get_text(password_libsecret)); |
73 LibsecretLoader::secret_value_unref(password_libsecret); | 98 LibsecretLoader::secret_value_unref(password_libsecret); |
74 return password; | 99 return password; |
75 } | 100 } |
76 | 101 |
77 bool KeyStorageLibsecret::Init() { | 102 bool KeyStorageLibsecret::Init() { |
78 return LibsecretLoader::EnsureLibsecretLoaded(); | 103 return LibsecretLoader::EnsureLibsecretLoaded(); |
79 } | 104 } |
80 | 105 |
81 std::string KeyStorageLibsecret::Migrate() { | 106 std::string KeyStorageLibsecret::Migrate() { |
82 GError* error = nullptr; | 107 GError* error = nullptr; |
83 LibsecretAttributesBuilder attrs; | 108 LibsecretAttributesBuilder attrs; |
84 | 109 |
85 // Detect old entry. | 110 // Detect old entry. |
86 SecretValue* password_libsecret = LibsecretLoader::secret_service_lookup_sync( | 111 GList* search_results = LibsecretLoader::secret_service_search_sync( |
87 nullptr, &kKeystoreSchemaV1, attrs.Get(), nullptr, &error); | 112 nullptr /* default secret service */, &kKeystoreSchemaV1, attrs.Get(), |
88 if (error || !password_libsecret) | 113 static_cast<SecretSearchFlags>(SECRET_SEARCH_UNLOCK | |
114 SECRET_SEARCH_LOAD_SECRETS), | |
115 nullptr, &error); | |
116 if (error) { | |
117 g_error_free(error); | |
118 g_list_free(search_results); | |
119 return std::string(); | |
120 } | |
121 SecretValue* password_libsecret = ToSingleSecret(search_results); | |
122 if (!password_libsecret) | |
89 return std::string(); | 123 return std::string(); |
90 | 124 |
91 VLOG(1) << "OSCrypt detected a deprecated password in Libsecret."; | 125 VLOG(1) << "OSCrypt detected a deprecated password in Libsecret."; |
92 std::string password( | 126 std::string password( |
93 LibsecretLoader::secret_value_get_text(password_libsecret)); | 127 LibsecretLoader::secret_value_get_text(password_libsecret)); |
128 LibsecretLoader::secret_value_unref(password_libsecret); | |
94 | 129 |
95 // Create new entry. | 130 // Create new entry. |
96 bool success = LibsecretLoader::secret_password_store_sync( | 131 bool success = LibsecretLoader::secret_password_store_sync( |
97 &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(), | 132 &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(), |
98 nullptr, &error, "application", kApplicationName, nullptr); | 133 nullptr, &error, "application", kApplicationName, nullptr); |
99 if (error || !success) | 134 if (error) { |
135 VLOG(1) << "Failed to store migrated password. " << error->message; | |
136 g_error_free(error); | |
100 return std::string(); | 137 return std::string(); |
138 } | |
139 if (!success) { | |
140 VLOG(1) << "Failed to store migrated password."; | |
141 return std::string(); | |
142 } | |
101 | 143 |
102 // Delete old entry. | 144 // Delete old entry. |
103 // Even if deletion failed, we have to use the password that we created. | 145 // Even if deletion failed, we have to use the password that we created. |
104 success = LibsecretLoader::secret_password_clear_sync( | 146 success = LibsecretLoader::secret_password_clear_sync( |
105 &kKeystoreSchemaV1, nullptr, &error, nullptr); | 147 &kKeystoreSchemaV1, nullptr, &error, nullptr); |
148 if (error) { | |
149 VLOG(1) << "OSCrypt failed to delete deprecated password. " | |
150 << error->message; | |
151 g_error_free(error); | |
152 } | |
106 | 153 |
107 VLOG(1) << "OSCrypt migrated from deprecated password."; | 154 VLOG(1) << "OSCrypt migrated from deprecated password."; |
108 | 155 |
109 return password; | 156 return password; |
110 } | 157 } |
OLD | NEW |