Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(517)

Side by Side Diff: components/os_crypt/key_storage_libsecret.cc

Issue 2441653002: Always unlock all libsecret items in Password Manager and OSCrypt (Closed)
Patch Set: Error handling Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698