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

Side by Side Diff: chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc

Issue 565293003: Revert of Non-plafrom-specific part of an OwnerSettingsService is moved to components/ownership/*. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/threading/thread_checker.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/chromeos/profiles/profile_helper.h"
17 #include "chrome/browser/chromeos/settings/cros_settings.h"
18 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chromeos/dbus/dbus_thread_manager.h"
21 #include "chromeos/tpm_token_loader.h"
22 #include "components/ownership/owner_key_util.h"
23 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/notification_details.h"
26 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/notification_source.h"
28 #include "content/public/common/content_switches.h"
29 #include "crypto/nss_util.h"
30 #include "crypto/nss_util_internal.h"
31 #include "crypto/rsa_private_key.h"
32 #include "crypto/scoped_nss_types.h"
33 #include "crypto/signature_creator.h"
34
35 namespace em = enterprise_management;
36
37 using content::BrowserThread;
38 using ownership::OwnerKeyUtil;
39 using ownership::PrivateKey;
40 using ownership::PublicKey;
41
42 namespace chromeos {
43
44 namespace {
45
46 DeviceSettingsService* g_device_settings_service_for_testing = NULL;
47
48 bool IsOwnerInTests(const std::string& user_id) {
49 if (user_id.empty() ||
50 !CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType) ||
51 !CrosSettings::IsInitialized()) {
52 return false;
53 }
54 const base::Value* value = CrosSettings::Get()->GetPref(kDeviceOwner);
55 if (!value || value->GetType() != base::Value::TYPE_STRING)
56 return false;
57 return static_cast<const base::StringValue*>(value)->GetString() == user_id;
58 }
59
60 void LoadPrivateKeyByPublicKey(
61 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
62 scoped_refptr<PublicKey> public_key,
63 const std::string& username_hash,
64 const base::Callback<void(const scoped_refptr<PublicKey>& public_key,
65 const scoped_refptr<PrivateKey>& private_key)>&
66 callback) {
67 crypto::EnsureNSSInit();
68 crypto::ScopedPK11Slot slot =
69 crypto::GetPublicSlotForChromeOSUser(username_hash);
70 scoped_refptr<PrivateKey> private_key(new PrivateKey(
71 owner_key_util->FindPrivateKeyInSlot(public_key->data(), slot.get())));
72 BrowserThread::PostTask(BrowserThread::UI,
73 FROM_HERE,
74 base::Bind(callback, public_key, private_key));
75 }
76
77 void LoadPrivateKey(
78 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
79 const std::string username_hash,
80 const base::Callback<void(const scoped_refptr<PublicKey>& public_key,
81 const scoped_refptr<PrivateKey>& private_key)>&
82 callback) {
83 std::vector<uint8> public_key_data;
84 scoped_refptr<PublicKey> public_key;
85 if (!owner_key_util->ImportPublicKey(&public_key_data)) {
86 scoped_refptr<PrivateKey> private_key;
87 BrowserThread::PostTask(BrowserThread::UI,
88 FROM_HERE,
89 base::Bind(callback, public_key, private_key));
90 return;
91 }
92 public_key = new PublicKey();
93 public_key->data().swap(public_key_data);
94 bool rv = BrowserThread::PostTask(BrowserThread::IO,
95 FROM_HERE,
96 base::Bind(&LoadPrivateKeyByPublicKey,
97 owner_key_util,
98 public_key,
99 username_hash,
100 callback));
101 if (!rv) {
102 // IO thread doesn't exists in unit tests, but it's safe to use NSS from
103 // BlockingPool in unit tests.
104 LoadPrivateKeyByPublicKey(
105 owner_key_util, public_key, username_hash, callback);
106 }
107 }
108
109 bool DoesPrivateKeyExistAsyncHelper(
110 const scoped_refptr<OwnerKeyUtil>& owner_key_util) {
111 std::vector<uint8> public_key;
112 if (!owner_key_util->ImportPublicKey(&public_key))
113 return false;
114 scoped_ptr<crypto::RSAPrivateKey> key(
115 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
116 bool is_owner = key.get() != NULL;
117 return is_owner;
118 }
119
120 // Checks whether NSS slots with private key are mounted or
121 // not. Responds via |callback|.
122 void DoesPrivateKeyExistAsync(
123 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
124 const OwnerSettingsServiceChromeOS::IsOwnerCallback& callback) {
125 if (!owner_key_util) {
126 callback.Run(false);
127 return;
128 }
129 scoped_refptr<base::TaskRunner> task_runner =
130 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
131 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
132 base::PostTaskAndReplyWithResult(
133 task_runner.get(),
134 FROM_HERE,
135 base::Bind(&DoesPrivateKeyExistAsyncHelper, owner_key_util),
136 callback);
137 }
138
139 DeviceSettingsService* GetDeviceSettingsService() {
140 if (g_device_settings_service_for_testing)
141 return g_device_settings_service_for_testing;
142 return DeviceSettingsService::IsInitialized() ? DeviceSettingsService::Get()
143 : NULL;
144 }
145
146 } // namespace
147
148 OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS(
149 Profile* profile,
150 const scoped_refptr<OwnerKeyUtil>& owner_key_util)
151 : ownership::OwnerSettingsService(owner_key_util),
152 profile_(profile),
153 waiting_for_profile_creation_(true),
154 waiting_for_tpm_token_(true),
155 weak_factory_(this) {
156 if (TPMTokenLoader::IsInitialized()) {
157 TPMTokenLoader::TPMTokenStatus tpm_token_status =
158 TPMTokenLoader::Get()->IsTPMTokenEnabled(
159 base::Bind(&OwnerSettingsServiceChromeOS::OnTPMTokenReady,
160 weak_factory_.GetWeakPtr()));
161 waiting_for_tpm_token_ =
162 tpm_token_status == TPMTokenLoader::TPM_TOKEN_STATUS_UNDETERMINED;
163 }
164
165 if (DBusThreadManager::IsInitialized() &&
166 DBusThreadManager::Get()->GetSessionManagerClient()) {
167 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
168 }
169
170 registrar_.Add(this,
171 chrome::NOTIFICATION_PROFILE_CREATED,
172 content::Source<Profile>(profile_));
173 }
174
175 OwnerSettingsServiceChromeOS::~OwnerSettingsServiceChromeOS() {
176 DCHECK(thread_checker_.CalledOnValidThread());
177 if (DBusThreadManager::IsInitialized() &&
178 DBusThreadManager::Get()->GetSessionManagerClient()) {
179 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
180 }
181 }
182
183 void OwnerSettingsServiceChromeOS::OnTPMTokenReady(
184 bool /* tpm_token_enabled */) {
185 DCHECK(thread_checker_.CalledOnValidThread());
186 waiting_for_tpm_token_ = false;
187
188 // TPMTokenLoader initializes the TPM and NSS database which is necessary to
189 // determine ownership. Force a reload once we know these are initialized.
190 ReloadKeypair();
191 }
192
193 void OwnerSettingsServiceChromeOS::SignAndStorePolicyAsync(
194 scoped_ptr<em::PolicyData> policy,
195 const base::Closure& callback) {
196 DCHECK(thread_checker_.CalledOnValidThread());
197 SignAndStoreSettingsOperation* operation = new SignAndStoreSettingsOperation(
198 base::Bind(&OwnerSettingsServiceChromeOS::HandleCompletedOperation,
199 weak_factory_.GetWeakPtr(),
200 callback),
201 policy.Pass());
202 operation->set_owner_settings_service(weak_factory_.GetWeakPtr());
203 pending_operations_.push_back(operation);
204 if (pending_operations_.front() == operation)
205 StartNextOperation();
206 }
207
208 void OwnerSettingsServiceChromeOS::Observe(
209 int type,
210 const content::NotificationSource& source,
211 const content::NotificationDetails& details) {
212 DCHECK(thread_checker_.CalledOnValidThread());
213 if (type != chrome::NOTIFICATION_PROFILE_CREATED) {
214 NOTREACHED();
215 return;
216 }
217
218 Profile* profile = content::Source<Profile>(source).ptr();
219 if (profile != profile_) {
220 NOTREACHED();
221 return;
222 }
223
224 waiting_for_profile_creation_ = false;
225 ReloadKeypair();
226 }
227
228 void OwnerSettingsServiceChromeOS::OwnerKeySet(bool success) {
229 DCHECK(thread_checker_.CalledOnValidThread());
230 if (success)
231 ReloadKeypair();
232 }
233
234 // static
235 void OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync(
236 const std::string& user_hash,
237 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
238 const IsOwnerCallback& callback) {
239 CHECK(chromeos::LoginState::Get()->IsInSafeMode());
240
241 // Make sure NSS is initialized and NSS DB is loaded for the user before
242 // searching for the owner key.
243 BrowserThread::PostTaskAndReply(
244 BrowserThread::IO,
245 FROM_HERE,
246 base::Bind(base::IgnoreResult(&crypto::InitializeNSSForChromeOSUser),
247 user_hash,
248 ProfileHelper::GetProfilePathByUserIdHash(user_hash)),
249 base::Bind(&DoesPrivateKeyExistAsync, owner_key_util, callback));
250 }
251
252 // static
253 void OwnerSettingsServiceChromeOS::SetDeviceSettingsServiceForTesting(
254 DeviceSettingsService* device_settings_service) {
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
256 g_device_settings_service_for_testing = device_settings_service;
257 }
258
259 void OwnerSettingsServiceChromeOS::OnPostKeypairLoadedActions() {
260 DCHECK(thread_checker_.CalledOnValidThread());
261
262 user_id_ = profile_->GetProfileName();
263 const bool is_owner = IsOwner() || IsOwnerInTests(user_id_);
264 if (is_owner && GetDeviceSettingsService())
265 GetDeviceSettingsService()->InitOwner(user_id_, weak_factory_.GetWeakPtr());
266 }
267
268 void OwnerSettingsServiceChromeOS::ReloadKeypairImpl(const base::Callback<
269 void(const scoped_refptr<PublicKey>& public_key,
270 const scoped_refptr<PrivateKey>& private_key)>& callback) {
271 DCHECK(thread_checker_.CalledOnValidThread());
272
273 if (waiting_for_profile_creation_ || waiting_for_tpm_token_)
274 return;
275 scoped_refptr<base::TaskRunner> task_runner =
276 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
277 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
278 task_runner->PostTask(
279 FROM_HERE,
280 base::Bind(&LoadPrivateKey,
281 owner_key_util_,
282 ProfileHelper::GetUserIdHashFromProfile(profile_),
283 callback));
284 }
285
286 void OwnerSettingsServiceChromeOS::StartNextOperation() {
287 DeviceSettingsService* service = GetDeviceSettingsService();
288 if (!pending_operations_.empty() && service &&
289 service->session_manager_client()) {
290 pending_operations_.front()->Start(
291 service->session_manager_client(), owner_key_util_, public_key_);
292 }
293 }
294
295 void OwnerSettingsServiceChromeOS::HandleCompletedOperation(
296 const base::Closure& callback,
297 SessionManagerOperation* operation,
298 DeviceSettingsService::Status status) {
299 DCHECK_EQ(operation, pending_operations_.front());
300
301 DeviceSettingsService* service = GetDeviceSettingsService();
302 if (status == DeviceSettingsService::STORE_SUCCESS) {
303 service->set_policy_data(operation->policy_data().Pass());
304 service->set_device_settings(operation->device_settings().Pass());
305 }
306
307 if ((operation->public_key() && !public_key_) ||
308 (operation->public_key() && public_key_ &&
309 operation->public_key()->data() != public_key_->data())) {
310 // Public part changed so we need to reload private part too.
311 ReloadKeypair();
312 content::NotificationService::current()->Notify(
313 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
314 content::Source<OwnerSettingsServiceChromeOS>(this),
315 content::NotificationService::NoDetails());
316 }
317 service->OnSignAndStoreOperationCompleted(status);
318 if (!callback.is_null())
319 callback.Run();
320
321 pending_operations_.pop_front();
322 delete operation;
323 StartNextOperation();
324 }
325
326 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698