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

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

Issue 399613003: SignAndStore method is moved out from DeviceSettingsService to OwnerSettingsService. It's still cal… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix. Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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/chromeos/ownership/owner_settings_service.h" 5 #include "chrome/browser/chromeos/ownership/owner_settings_service.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/chromeos/login/users/user.h" 12 #include "chrome/browser/chromeos/login/users/user.h"
13 #include "chrome/browser/chromeos/login/users/user_manager.h" 13 #include "chrome/browser/chromeos/login/users/user_manager.h"
14 #include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" 14 #include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h"
15 #include "chrome/browser/chromeos/profiles/profile_helper.h" 15 #include "chrome/browser/chromeos/profiles/profile_helper.h"
16 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
18 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
17 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/notification_details.h" 20 #include "content/public/browser/notification_details.h"
21 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/notification_source.h" 22 #include "content/public/browser/notification_source.h"
20 #include "crypto/nss_util.h" 23 #include "crypto/nss_util.h"
21 #include "crypto/nss_util_internal.h" 24 #include "crypto/nss_util_internal.h"
22 #include "crypto/rsa_private_key.h" 25 #include "crypto/rsa_private_key.h"
23 #include "crypto/scoped_nss_types.h" 26 #include "crypto/scoped_nss_types.h"
24 #include "crypto/signature_creator.h" 27 #include "crypto/signature_creator.h"
25 28
26 namespace em = enterprise_management; 29 namespace em = enterprise_management;
27 30
28 using content::BrowserThread; 31 using content::BrowserThread;
29 32
30 namespace chromeos { 33 namespace chromeos {
31 34
32 namespace { 35 namespace {
33 36
34 scoped_refptr<OwnerKeyUtil>* g_owner_key_util_for_testing = NULL; 37 scoped_refptr<OwnerKeyUtil>* g_owner_key_util_for_testing = NULL;
35 DeviceSettingsService* g_device_settings_service_for_testing = NULL; 38 DeviceSettingsService* g_device_settings_service_for_testing = NULL;
36 39
40 // Assembles PolicyData based on |settings|, |policy_data| and
41 // |user_id|.
42 scoped_ptr<em::PolicyData> AssemblePolicy(
43 const std::string& user_id,
44 const em::PolicyData* policy_data,
45 const em::ChromeDeviceSettingsProto* settings) {
46 scoped_ptr<em::PolicyData> policy(new em::PolicyData());
47 if (policy_data) {
48 // Preserve management settings.
49 if (policy_data->has_management_mode())
50 policy->set_management_mode(policy_data->management_mode());
51 if (policy_data->has_request_token())
52 policy->set_request_token(policy_data->request_token());
53 if (policy_data->has_device_id())
54 policy->set_device_id(policy_data->device_id());
55 } else {
56 // If there's no previous policy data, this is the first time the device
57 // setting is set. We set the management mode to NOT_MANAGED initially.
58 policy->set_management_mode(em::PolicyData::NOT_MANAGED);
59 }
60 policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType);
61 policy->set_timestamp(
62 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds());
63 policy->set_username(user_id);
64 if (!settings->SerializeToString(policy->mutable_policy_value()))
65 return scoped_ptr<em::PolicyData>();
66
67 return policy.Pass();
68 }
69
37 std::string AssembleAndSignPolicy(scoped_ptr<em::PolicyData> policy, 70 std::string AssembleAndSignPolicy(scoped_ptr<em::PolicyData> policy,
38 crypto::RSAPrivateKey* private_key) { 71 crypto::RSAPrivateKey* private_key) {
39 // Assemble the policy. 72 // Assemble the policy.
40 em::PolicyFetchResponse policy_response; 73 em::PolicyFetchResponse policy_response;
41 if (!policy->SerializeToString(policy_response.mutable_policy_data())) { 74 if (!policy->SerializeToString(policy_response.mutable_policy_data())) {
42 LOG(ERROR) << "Failed to encode policy payload."; 75 LOG(ERROR) << "Failed to encode policy payload.";
43 return std::string(); 76 return std::string();
44 } 77 }
45 78
46 // Generate the signature. 79 // Generate the signature.
(...skipping 10 matching lines...) Expand all
57 } 90 }
58 91
59 policy_response.mutable_policy_data_signature()->assign( 92 policy_response.mutable_policy_data_signature()->assign(
60 reinterpret_cast<const char*>(vector_as_array(&signature_bytes)), 93 reinterpret_cast<const char*>(vector_as_array(&signature_bytes)),
61 signature_bytes.size()); 94 signature_bytes.size());
62 return policy_response.SerializeAsString(); 95 return policy_response.SerializeAsString();
63 } 96 }
64 97
65 void LoadPrivateKeyByPublicKey( 98 void LoadPrivateKeyByPublicKey(
66 const scoped_refptr<OwnerKeyUtil>& owner_key_util, 99 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
67 const std::vector<uint8>& public_key, 100 scoped_refptr<PublicKey> public_key,
68 const std::string& username_hash, 101 const std::string& username_hash,
69 const base::Callback<void(scoped_ptr<crypto::RSAPrivateKey>)>& callback) { 102 const base::Callback<void(scoped_refptr<PublicKey> public_key,
103 scoped_refptr<PrivateKey> private_key)>&
104 callback) {
70 crypto::EnsureNSSInit(); 105 crypto::EnsureNSSInit();
71 crypto::ScopedPK11Slot slot = 106 crypto::ScopedPK11Slot slot =
72 crypto::GetPublicSlotForChromeOSUser(username_hash); 107 crypto::GetPublicSlotForChromeOSUser(username_hash);
73 scoped_ptr<crypto::RSAPrivateKey> key( 108 scoped_refptr<PrivateKey> private_key(new PrivateKey(
74 owner_key_util->FindPrivateKeyInSlot(public_key, slot.get())); 109 owner_key_util->FindPrivateKeyInSlot(public_key->data(), slot.get())));
75 BrowserThread::PostTask( 110 BrowserThread::PostTask(BrowserThread::UI,
76 BrowserThread::UI, FROM_HERE, base::Bind(callback, base::Passed(&key))); 111 FROM_HERE,
112 base::Bind(callback, public_key, private_key));
77 } 113 }
78 114
79 void LoadPrivateKey( 115 void LoadPrivateKey(const scoped_refptr<OwnerKeyUtil>& owner_key_util,
80 const scoped_refptr<OwnerKeyUtil>& owner_key_util, 116 const std::string username_hash,
81 const std::string username_hash, 117 const base::Callback<void(
82 const base::Callback<void(scoped_ptr<crypto::RSAPrivateKey>)>& callback) { 118 scoped_refptr<PublicKey> public_key,
83 std::vector<uint8> public_key; 119 scoped_refptr<PrivateKey> private_key)>& callback) {
84 if (!owner_key_util->ImportPublicKey(&public_key)) { 120 std::vector<uint8> public_key_data;
85 scoped_ptr<crypto::RSAPrivateKey> result; 121 scoped_refptr<PublicKey> public_key;
122 if (!owner_key_util->ImportPublicKey(&public_key_data)) {
123 scoped_refptr<PrivateKey> private_key;
86 BrowserThread::PostTask(BrowserThread::UI, 124 BrowserThread::PostTask(BrowserThread::UI,
87 FROM_HERE, 125 FROM_HERE,
88 base::Bind(callback, base::Passed(&result))); 126 base::Bind(callback, public_key, private_key));
89 return; 127 return;
90 } 128 }
129 public_key = new PublicKey();
130 public_key->data().swap(public_key_data);
91 bool rv = BrowserThread::PostTask(BrowserThread::IO, 131 bool rv = BrowserThread::PostTask(BrowserThread::IO,
92 FROM_HERE, 132 FROM_HERE,
93 base::Bind(&LoadPrivateKeyByPublicKey, 133 base::Bind(&LoadPrivateKeyByPublicKey,
94 owner_key_util, 134 owner_key_util,
95 public_key, 135 public_key,
96 username_hash, 136 username_hash,
97 callback)); 137 callback));
98 if (!rv) { 138 if (!rv) {
99 // IO thread doesn't exists in unit tests, but it's safe to use NSS from 139 // IO thread doesn't exists in unit tests, but it's safe to use NSS from
100 // BlockingPool in unit tests. 140 // BlockingPool in unit tests.
(...skipping 26 matching lines...) Expand all
127 content::BrowserThread::GetBlockingPool() 167 content::BrowserThread::GetBlockingPool()
128 ->GetTaskRunnerWithShutdownBehavior( 168 ->GetTaskRunnerWithShutdownBehavior(
129 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 169 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
130 base::PostTaskAndReplyWithResult( 170 base::PostTaskAndReplyWithResult(
131 task_runner.get(), 171 task_runner.get(),
132 FROM_HERE, 172 FROM_HERE,
133 base::Bind(&DoesPrivateKeyExistAsyncHelper, owner_key_util), 173 base::Bind(&DoesPrivateKeyExistAsyncHelper, owner_key_util),
134 callback); 174 callback);
135 } 175 }
136 176
177 // Returns the current management mode.
178 em::PolicyData::ManagementMode GetManagementMode(
179 DeviceSettingsService* service) {
180 if (!service) {
181 LOG(ERROR) << "DeviceSettingsService is not initialized";
182 return em::PolicyData::NOT_MANAGED;
183 }
184
185 const em::PolicyData* policy_data = service->policy_data();
186 if (policy_data && policy_data->has_management_mode())
187 return policy_data->management_mode();
188 return em::PolicyData::NOT_MANAGED;
189 }
190
191 // Returns true if it is okay to transfer from the current mode to the new
192 // mode. This function should be called in SetManagementMode().
193 bool CheckManagementModeTransition(em::PolicyData::ManagementMode current_mode,
194 em::PolicyData::ManagementMode new_mode) {
195 // Mode is not changed.
196 if (current_mode == new_mode)
197 return true;
198
199 switch (current_mode) {
200 case em::PolicyData::NOT_MANAGED:
201 // For consumer management enrollment.
202 return new_mode == em::PolicyData::CONSUMER_MANAGED;
203
204 case em::PolicyData::ENTERPRISE_MANAGED:
205 // Management mode cannot be set when it is currently ENTERPRISE_MANAGED.
206 return false;
207
208 case em::PolicyData::CONSUMER_MANAGED:
209 // For consumer management unenrollment.
210 return new_mode == em::PolicyData::NOT_MANAGED;
211 }
212
213 NOTREACHED();
214 return false;
215 }
216
137 } // namespace 217 } // namespace
138 218
139 OwnerSettingsService::OwnerSettingsService(Profile* profile) 219 OwnerSettingsService::OwnerSettingsService(Profile* profile)
140 : profile_(profile), 220 : profile_(profile),
141 owner_key_util_(OwnerKeyUtil::Create()), 221 owner_key_util_(OwnerKeyUtil::Create()),
142 waiting_for_profile_creation_(true), 222 waiting_for_profile_creation_(true),
143 waiting_for_tpm_token_(true), 223 waiting_for_tpm_token_(true),
144 weak_factory_(this) { 224 weak_factory_(this) {
145 if (TPMTokenLoader::IsInitialized()) { 225 if (TPMTokenLoader::IsInitialized()) {
146 waiting_for_tpm_token_ = !TPMTokenLoader::Get()->IsTPMTokenReady(); 226 waiting_for_tpm_token_ = !TPMTokenLoader::Get()->IsTPMTokenReady();
(...skipping 20 matching lines...) Expand all
167 DCHECK(thread_checker_.CalledOnValidThread()); 247 DCHECK(thread_checker_.CalledOnValidThread());
168 if (private_key_) { 248 if (private_key_) {
169 base::MessageLoop::current()->PostTask(FROM_HERE, 249 base::MessageLoop::current()->PostTask(FROM_HERE,
170 base::Bind(callback, IsOwner())); 250 base::Bind(callback, IsOwner()));
171 } else { 251 } else {
172 pending_is_owner_callbacks_.push_back(callback); 252 pending_is_owner_callbacks_.push_back(callback);
173 } 253 }
174 } 254 }
175 255
176 bool OwnerSettingsService::AssembleAndSignPolicyAsync( 256 bool OwnerSettingsService::AssembleAndSignPolicyAsync(
177 scoped_ptr<enterprise_management::PolicyData> policy, 257 scoped_ptr<em::PolicyData> policy,
178 const AssembleAndSignPolicyCallback& callback) { 258 const AssembleAndSignPolicyCallback& callback) {
179 DCHECK(thread_checker_.CalledOnValidThread()); 259 DCHECK(thread_checker_.CalledOnValidThread());
180 if (!IsOwner()) 260 if (!IsOwner())
181 return false; 261 return false;
182 base::PostTaskAndReplyWithResult( 262 base::PostTaskAndReplyWithResult(
183 BrowserThread::GetBlockingPool(), 263 BrowserThread::GetBlockingPool(),
184 FROM_HERE, 264 FROM_HERE,
185 base::Bind( 265 base::Bind(
186 &AssembleAndSignPolicy, base::Passed(&policy), private_key_->key()), 266 &AssembleAndSignPolicy, base::Passed(&policy), private_key_->key()),
187 callback); 267 callback);
188 return true; 268 return true;
189 } 269 }
190 270
271 void OwnerSettingsService::SignAndStoreAsync(
272 scoped_ptr<em::ChromeDeviceSettingsProto> settings,
273 const base::Closure& callback) {
274 DCHECK(thread_checker_.CalledOnValidThread());
275 scoped_ptr<em::PolicyData> policy = AssemblePolicy(
276 user_id_, GetDeviceSettingsService()->policy_data(), settings.get());
277 if (!policy) {
278 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback);
279 return;
280 }
281
282 EnqueueSignAndStore(policy.Pass(), callback);
283 }
284
285 void OwnerSettingsService::SetManagementSettingsAsync(
286 em::PolicyData::ManagementMode management_mode,
287 const std::string& request_token,
288 const std::string& device_id,
289 const base::Closure& callback) {
290 em::PolicyData::ManagementMode current_mode =
291 GetManagementMode(GetDeviceSettingsService());
292 if (!CheckManagementModeTransition(current_mode, management_mode)) {
293 LOG(ERROR) << "Invalid management mode transition: current mode = "
294 << current_mode << ", new mode = " << management_mode;
295 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback);
296 return;
297 }
298
299 DeviceSettingsService* service = GetDeviceSettingsService();
300 scoped_ptr<em::PolicyData> policy = AssemblePolicy(
301 user_id_, service->policy_data(), service->device_settings());
302 if (!policy) {
303 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback);
304 return;
305 }
306
307 policy->set_management_mode(management_mode);
308 policy->set_request_token(request_token);
309 policy->set_device_id(device_id);
310
311 EnqueueSignAndStore(policy.Pass(), callback);
312 }
313
191 void OwnerSettingsService::Observe( 314 void OwnerSettingsService::Observe(
192 int type, 315 int type,
193 const content::NotificationSource& source, 316 const content::NotificationSource& source,
194 const content::NotificationDetails& details) { 317 const content::NotificationDetails& details) {
195 DCHECK(thread_checker_.CalledOnValidThread()); 318 DCHECK(thread_checker_.CalledOnValidThread());
196 if (type != chrome::NOTIFICATION_PROFILE_CREATED) { 319 if (type != chrome::NOTIFICATION_PROFILE_CREATED) {
197 NOTREACHED(); 320 NOTREACHED();
198 return; 321 return;
199 } 322 }
200 323
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 task_runner->PostTask( 391 task_runner->PostTask(
269 FROM_HERE, 392 FROM_HERE,
270 base::Bind(&LoadPrivateKey, 393 base::Bind(&LoadPrivateKey,
271 GetOwnerKeyUtil(), 394 GetOwnerKeyUtil(),
272 ProfileHelper::GetUserIdHashFromProfile(profile_), 395 ProfileHelper::GetUserIdHashFromProfile(profile_),
273 base::Bind(&OwnerSettingsService::OnPrivateKeyLoaded, 396 base::Bind(&OwnerSettingsService::OnPrivateKeyLoaded,
274 weak_factory_.GetWeakPtr()))); 397 weak_factory_.GetWeakPtr())));
275 } 398 }
276 399
277 void OwnerSettingsService::OnPrivateKeyLoaded( 400 void OwnerSettingsService::OnPrivateKeyLoaded(
278 scoped_ptr<crypto::RSAPrivateKey> private_key) { 401 scoped_refptr<PublicKey> public_key,
402 scoped_refptr<PrivateKey> private_key) {
279 DCHECK(thread_checker_.CalledOnValidThread()); 403 DCHECK(thread_checker_.CalledOnValidThread());
280 private_key_ = new PrivateKey(private_key.release()); 404 public_key_ = public_key;
405 private_key_ = private_key;
281 406
282 const std::string& user_id = profile_->GetProfileName(); 407 user_id_ = profile_->GetProfileName();
283 if (user_id == OwnerSettingsServiceFactory::GetInstance()->GetUsername()) 408 if (user_id_ == OwnerSettingsServiceFactory::GetInstance()->GetUsername())
284 GetDeviceSettingsService()->InitOwner(user_id, weak_factory_.GetWeakPtr()); 409 GetDeviceSettingsService()->InitOwner(user_id_, weak_factory_.GetWeakPtr());
285 410
286 std::vector<IsOwnerCallback> is_owner_callbacks; 411 std::vector<IsOwnerCallback> is_owner_callbacks;
287 is_owner_callbacks.swap(pending_is_owner_callbacks_); 412 is_owner_callbacks.swap(pending_is_owner_callbacks_);
288 const bool is_owner = private_key_.get() && private_key_->key(); 413 const bool is_owner = private_key_.get() && private_key_->key();
289 for (std::vector<IsOwnerCallback>::iterator it(is_owner_callbacks.begin()); 414 for (std::vector<IsOwnerCallback>::iterator it(is_owner_callbacks.begin());
290 it != is_owner_callbacks.end(); 415 it != is_owner_callbacks.end();
291 ++it) { 416 ++it) {
292 it->Run(is_owner); 417 it->Run(is_owner);
293 } 418 }
294 } 419 }
295 420
421 void OwnerSettingsService::EnqueueSignAndStore(
422 scoped_ptr<em::PolicyData> policy,
423 const base::Closure& callback) {
424 SignAndStoreSettingsOperation* operation = new SignAndStoreSettingsOperation(
425 base::Bind(&OwnerSettingsService::HandleCompletedOperation,
426 weak_factory_.GetWeakPtr(),
427 callback),
428 policy.Pass());
429 operation->set_delegate(weak_factory_.GetWeakPtr());
430 pending_operations_.push_back(operation);
431 if (pending_operations_.front() == operation)
432 StartNextOperation();
433 }
434
435 void OwnerSettingsService::StartNextOperation() {
436 DeviceSettingsService* service = GetDeviceSettingsService();
437 if (!pending_operations_.empty() && service &&
438 service->session_manager_client()) {
439 pending_operations_.front()->Start(
440 service->session_manager_client(), GetOwnerKeyUtil(), public_key_);
441 }
442 }
443
444 void OwnerSettingsService::HandleCompletedOperation(
445 const base::Closure& callback,
446 SessionManagerOperation* operation,
447 DeviceSettingsService::Status status) {
448 DCHECK_EQ(operation, pending_operations_.front());
449
450 DeviceSettingsService* service = GetDeviceSettingsService();
451 if (status == DeviceSettingsService::STORE_SUCCESS) {
452 service->set_policy_data(operation->policy_data().Pass());
453 service->set_device_settings(operation->device_settings().Pass());
454 }
455
456 if ((operation->public_key() && !public_key_) ||
457 (operation->public_key() && public_key_ &&
458 operation->public_key()->data() != public_key_->data())) {
459 // Public part changed so we need to reload private part too.
460 ReloadPrivateKey();
461 content::NotificationService::current()->Notify(
462 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
463 content::Source<OwnerSettingsService>(this),
464 content::NotificationService::NoDetails());
465 }
466 service->OnSignAndStoreOperationCompleted(status);
467 if (!callback.is_null())
468 callback.Run();
469
470 pending_operations_.pop_front();
471 delete operation;
472 StartNextOperation();
473 }
474
475 void OwnerSettingsService::HandleError(DeviceSettingsService::Status status,
476 const base::Closure& callback) {
477 LOG(ERROR) << "Session manager operation failed: " << status;
478 GetDeviceSettingsService()->OnSignAndStoreOperationCompleted(status);
479 if (!callback.is_null())
480 callback.Run();
481 }
482
296 scoped_refptr<OwnerKeyUtil> OwnerSettingsService::GetOwnerKeyUtil() { 483 scoped_refptr<OwnerKeyUtil> OwnerSettingsService::GetOwnerKeyUtil() {
297 DCHECK(thread_checker_.CalledOnValidThread()); 484 DCHECK(thread_checker_.CalledOnValidThread());
298 if (g_owner_key_util_for_testing) 485 if (g_owner_key_util_for_testing)
299 return *g_owner_key_util_for_testing; 486 return *g_owner_key_util_for_testing;
300 return owner_key_util_; 487 return owner_key_util_;
301 } 488 }
302 489
303 DeviceSettingsService* OwnerSettingsService::GetDeviceSettingsService() { 490 DeviceSettingsService* OwnerSettingsService::GetDeviceSettingsService() {
304 DCHECK(thread_checker_.CalledOnValidThread()); 491 DCHECK(thread_checker_.CalledOnValidThread());
305 if (g_device_settings_service_for_testing) 492 if (g_device_settings_service_for_testing)
306 return g_device_settings_service_for_testing; 493 return g_device_settings_service_for_testing;
307 if (DeviceSettingsService::IsInitialized()) 494 if (DeviceSettingsService::IsInitialized())
308 return DeviceSettingsService::Get(); 495 return DeviceSettingsService::Get();
309 return NULL; 496 return NULL;
310 } 497 }
311 498
312 } // namespace chromeos 499 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/ownership/owner_settings_service.h ('k') | chrome/browser/chromeos/settings/device_settings_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698