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, extract a SecretValue, asserting that there was only | |
37 // one result. | |
38 SecretValue* ToSingleSecret(GList* secret_items) { | |
39 GList* first = g_list_first(secret_items); | |
40 if (g_list_next(first) != nullptr) { | |
41 LOG(ERROR) << "OSCrypt found more than one encryption keys."; | |
vasilii
2016/10/21 14:10:07
Seems like you use VLOG everywhere?
cfroussios
2016/10/21 17:56:35
Done.
| |
42 } | |
43 SecretItem* secret_item = static_cast<SecretItem*>(first->data); | |
44 g_list_free(secret_items); | |
vasilii
2016/10/21 14:10:07
Doesn't it destroy SecretItem* too?
cfroussios
2016/10/21 17:56:35
There is no method to free a SecretItem.
https://d
vasilii
2016/10/24 10:41:14
The concern was that secret_item_get_secret(secret
cfroussios
2016/10/24 11:25:55
Yes, I forgot to complete my point that if doesn't
| |
45 return LibsecretLoader::secret_item_get_secret(secret_item); | |
46 } | |
47 | |
36 } // namespace | 48 } // namespace |
37 | 49 |
38 std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() { | 50 std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() { |
39 std::string password; | 51 std::string password; |
40 base::Base64Encode(base::RandBytesAsString(16), &password); | 52 base::Base64Encode(base::RandBytesAsString(16), &password); |
41 GError* error = nullptr; | 53 GError* error = nullptr; |
42 bool success = LibsecretLoader::secret_password_store_sync( | 54 bool success = LibsecretLoader::secret_password_store_sync( |
43 &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(), | 55 &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(), |
44 nullptr, &error, "application", kApplicationName, nullptr); | 56 nullptr, &error, "application", kApplicationName, nullptr); |
45 if (error || !success) { | 57 if (error || !success) { |
46 VLOG(1) << "Libsecret lookup failed: " << error->message; | 58 VLOG(1) << "Libsecret lookup failed: " << error->message; |
47 return std::string(); | 59 return std::string(); |
48 } | 60 } |
49 | 61 |
50 VLOG(1) << "OSCrypt generated a new password."; | 62 VLOG(1) << "OSCrypt generated a new password."; |
51 return password; | 63 return password; |
52 } | 64 } |
53 | 65 |
54 std::string KeyStorageLibsecret::GetKey() { | 66 std::string KeyStorageLibsecret::GetKey() { |
55 GError* error = nullptr; | 67 GError* error = nullptr; |
56 LibsecretAttributesBuilder attrs; | 68 LibsecretAttributesBuilder attrs; |
57 attrs.Append("application", kApplicationName); | 69 attrs.Append("application", kApplicationName); |
58 SecretValue* password_libsecret = LibsecretLoader::secret_service_lookup_sync( | 70 GList* search_results = LibsecretLoader::secret_service_search_sync( |
59 nullptr, &kKeystoreSchemaV2, attrs.Get(), nullptr, &error); | 71 nullptr /* default secret service */, &kKeystoreSchemaV2, attrs.Get(), |
72 static_cast<SecretSearchFlags>(SECRET_SEARCH_UNLOCK | | |
73 SECRET_SEARCH_LOAD_SECRETS), | |
74 nullptr, &error); | |
75 if (error) { | |
76 g_error_free(error); | |
77 return std::string(); | |
78 } | |
79 SecretValue* password_libsecret = ToSingleSecret(search_results); | |
60 if (error) { | 80 if (error) { |
vasilii
2016/10/21 14:10:07
if (error) again?
cfroussios
2016/10/21 17:56:35
Done.
| |
61 VLOG(1) << "Libsecret lookup failed: " << error->message; | 81 VLOG(1) << "Libsecret lookup failed: " << error->message; |
62 g_error_free(error); | 82 g_error_free(error); |
63 return std::string(); | 83 return std::string(); |
64 } | 84 } |
65 if (!password_libsecret) { | 85 if (!password_libsecret) { |
66 std::string password = Migrate(); | 86 std::string password = Migrate(); |
67 if (!password.empty()) | 87 if (!password.empty()) |
68 return password; | 88 return password; |
69 return AddRandomPasswordInLibsecret(); | 89 return AddRandomPasswordInLibsecret(); |
70 } | 90 } |
71 std::string password( | 91 std::string password( |
72 LibsecretLoader::secret_value_get_text(password_libsecret)); | 92 LibsecretLoader::secret_value_get_text(password_libsecret)); |
73 LibsecretLoader::secret_value_unref(password_libsecret); | 93 LibsecretLoader::secret_value_unref(password_libsecret); |
74 return password; | 94 return password; |
75 } | 95 } |
76 | 96 |
77 bool KeyStorageLibsecret::Init() { | 97 bool KeyStorageLibsecret::Init() { |
78 return LibsecretLoader::EnsureLibsecretLoaded(); | 98 return LibsecretLoader::EnsureLibsecretLoaded(); |
79 } | 99 } |
80 | 100 |
81 std::string KeyStorageLibsecret::Migrate() { | 101 std::string KeyStorageLibsecret::Migrate() { |
82 GError* error = nullptr; | 102 GError* error = nullptr; |
83 LibsecretAttributesBuilder attrs; | 103 LibsecretAttributesBuilder attrs; |
84 | 104 |
85 // Detect old entry. | 105 // Detect old entry. |
86 SecretValue* password_libsecret = LibsecretLoader::secret_service_lookup_sync( | 106 GList* search_results = LibsecretLoader::secret_service_search_sync( |
87 nullptr, &kKeystoreSchemaV1, attrs.Get(), nullptr, &error); | 107 nullptr /* default secret service */, &kKeystoreSchemaV1, attrs.Get(), |
88 if (error || !password_libsecret) | 108 static_cast<SecretSearchFlags>(SECRET_SEARCH_UNLOCK | |
109 SECRET_SEARCH_LOAD_SECRETS), | |
110 nullptr, &error); | |
111 if (error || !search_results) { | |
vasilii
2016/10/21 14:10:07
Why the identical logic above checks just |error|.
cfroussios
2016/10/21 17:56:35
I intended to flatten the nulls in ToSingleSecret(
| |
112 g_error_free(error); | |
vasilii
2016/10/21 14:10:07
is it ok to free 0?
cfroussios
2016/10/21 17:56:35
They check that it's not null.
https://github.com/
| |
113 return std::string(); | |
114 } | |
115 SecretValue* password_libsecret = ToSingleSecret(search_results); | |
116 if (!password_libsecret) | |
89 return std::string(); | 117 return std::string(); |
90 | 118 |
91 VLOG(1) << "OSCrypt detected a deprecated password in Libsecret."; | 119 VLOG(1) << "OSCrypt detected a deprecated password in Libsecret."; |
92 std::string password( | 120 std::string password( |
93 LibsecretLoader::secret_value_get_text(password_libsecret)); | 121 LibsecretLoader::secret_value_get_text(password_libsecret)); |
122 LibsecretLoader::secret_value_unref(password_libsecret); | |
94 | 123 |
95 // Create new entry. | 124 // Create new entry. |
96 bool success = LibsecretLoader::secret_password_store_sync( | 125 bool success = LibsecretLoader::secret_password_store_sync( |
97 &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(), | 126 &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(), |
98 nullptr, &error, "application", kApplicationName, nullptr); | 127 nullptr, &error, "application", kApplicationName, nullptr); |
99 if (error || !success) | 128 if (error || !success) { |
129 g_error_free(error); | |
100 return std::string(); | 130 return std::string(); |
131 } | |
101 | 132 |
102 // Delete old entry. | 133 // Delete old entry. |
103 // Even if deletion failed, we have to use the password that we created. | 134 // Even if deletion failed, we have to use the password that we created. |
104 success = LibsecretLoader::secret_password_clear_sync( | 135 success = LibsecretLoader::secret_password_clear_sync( |
105 &kKeystoreSchemaV1, nullptr, &error, nullptr); | 136 &kKeystoreSchemaV1, nullptr, &error, nullptr); |
137 if (error) | |
138 g_error_free(error); | |
106 | 139 |
107 VLOG(1) << "OSCrypt migrated from deprecated password."; | 140 VLOG(1) << "OSCrypt migrated from deprecated password."; |
108 | 141 |
109 return password; | 142 return password; |
110 } | 143 } |
OLD | NEW |