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

Side by Side Diff: chrome/browser/chromeos/login/session_manager_operation.cc

Issue 10828032: Add DeviceSettingsService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 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
(Empty)
1 // Copyright (c) 2012 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/login/session_manager_operation.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/file_path.h"
10 #include "base/file_util.h"
11 #include "base/message_loop.h"
12 #include "base/stl_util.h"
13 #include "base/task_runner_util.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "base/time.h"
16 #include "chrome/browser/chromeos/login/owner_key_util.h"
17 #include "chrome/browser/policy/cloud_policy_constants.h"
18 #include "chrome/browser/policy/cloud_policy_validator.h"
19 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
20 #include "chrome/browser/policy/proto/device_management_backend.pb.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "crypto/rsa_private_key.h"
23 #include "crypto/signature_creator.h"
24
25 namespace em = enterprise_management;
26
27 namespace chromeos {
28
29 SessionManagerOperation::SessionManagerOperation(
30 scoped_refptr<OwnerKeyUtil> owner_key_util,
31 const Callback& callback)
32 : session_manager_client_(NULL),
33 owner_key_util_(owner_key_util),
34 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
35 callback_(callback),
36 force_key_load_(false),
37 is_loading_(false) {}
38
39 SessionManagerOperation::~SessionManagerOperation() {}
40
41 void SessionManagerOperation::RestartLoad(bool key_changed) {
42 if (key_changed)
43 owner_key_ = NULL;
44
45 if (!is_loading_)
46 return;
47
48 // Abort previous load operations.
49 weak_factory_.InvalidateWeakPtrs();
50 StartLoading();
51 }
52
53 void SessionManagerOperation::StartLoading() {
54 is_loading_ = true;
55 EnsureOwnerKey(base::Bind(&SessionManagerOperation::RetrieveDeviceSettings,
56 weak_factory_.GetWeakPtr()));
57 }
58
59 void SessionManagerOperation::ReportResult(
60 DeviceSettingsService::Status status) {
61 callback_.Run(this, status);
62 }
63
64 void SessionManagerOperation::EnsureOwnerKey(const base::Closure& callback) {
65 if (force_key_load_ ||
66 !owner_key_.get() ||
67 !owner_key_->public_key()) {
68 base::PostTaskAndReplyWithResult(
69 content::BrowserThread::GetBlockingPool(),
70 FROM_HERE,
71 base::Bind(&SessionManagerOperation::LoadOwnerKey,
72 owner_key_util_, owner_key_),
73 base::Bind(&SignAndStoreSettingsOperation::StoreOwnerKey,
74 weak_factory_.GetWeakPtr(), callback));
75 } else {
76 callback.Run();
77 }
78 }
79
80 // static
81 scoped_refptr<OwnerKey> SessionManagerOperation::LoadOwnerKey(
82 scoped_refptr<OwnerKeyUtil> util,
83 scoped_refptr<OwnerKey> current_key) {
84 scoped_ptr<std::vector<uint8> > public_key;
85 scoped_ptr<crypto::RSAPrivateKey> private_key;
86
87 // Keep any already-existing keys.
88 if (current_key.get()) {
89 if (current_key->public_key())
90 public_key.reset(new std::vector<uint8>(*current_key->public_key()));
91 if (current_key->private_key())
92 private_key.reset(current_key->private_key()->Copy());
93 }
94
95 if (!public_key.get() && util->IsPublicKeyPresent()) {
96 public_key.reset(new std::vector<uint8>());
97 if (!util->ImportPublicKey(public_key.get()))
98 LOG(ERROR) << "Failed to load public owner key.";
99 }
100
101 if (public_key.get() && !private_key.get()) {
102 private_key.reset(util->FindPrivateKey(*public_key));
103 if (!private_key.get())
104 VLOG(1) << "Failed to load private owner key.";
105 }
106
107 return new OwnerKey(public_key.Pass(), private_key.Pass());
108 }
109
110 void SessionManagerOperation::StoreOwnerKey(const base::Closure& callback,
111 scoped_refptr<OwnerKey> new_key) {
112 force_key_load_ = false;
113 owner_key_ = new_key;
114
115 if (!owner_key_.get() || !owner_key_->public_key()) {
116 ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
117 return;
118 }
119
120 callback.Run();
121 }
122
123 void SessionManagerOperation::RetrieveDeviceSettings() {
124 session_manager_client()->RetrieveDevicePolicy(
125 base::Bind(&SessionManagerOperation::ValidateDeviceSettings,
126 weak_factory_.GetWeakPtr()));
127 }
128
129 void SessionManagerOperation::ValidateDeviceSettings(
130 const std::string& policy_blob) {
131 scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse());
132 if (policy_blob.empty()) {
133 ReportResult(DeviceSettingsService::STORE_NO_POLICY);
134 return;
135 }
136
137 if (!policy->ParseFromString(policy_blob) ||
138 !policy->IsInitialized()) {
139 ReportResult(DeviceSettingsService::STORE_INVALID_POLICY);
140 return;
141 }
142
143 policy::DeviceCloudPolicyValidator* validator =
144 policy::DeviceCloudPolicyValidator::Create(
145 policy.Pass(),
146 base::Bind(&SessionManagerOperation::ReportValidatorStatus,
147 weak_factory_.GetWeakPtr()));
148
149 // Policy auto-generated by session manager doesn't include a timestamp, so we
150 // need to allow missing timestamps.
151 validator->ValidateAgainstCurrentPolicy(
152 policy_data_.get(),
153 !policy_data_.get() || !policy_data_->has_request_token());
154 validator->ValidatePolicyType(policy::dm_protocol::kChromeDevicePolicyType);
155 validator->ValidatePayload();
156 const std::vector<uint8>* public_key = owner_key_->public_key();
157 validator->ValidateSignature(
158 std::string(reinterpret_cast<const char*>(vector_as_array(public_key)),
159 public_key->size()),
160 false);
161
162 validator->StartValidation();
163 }
164
165 void SessionManagerOperation::ReportValidatorStatus(
166 policy::DeviceCloudPolicyValidator* validator) {
167 DeviceSettingsService::Status status =
168 DeviceSettingsService::STORE_VALIDATION_ERROR;
169 if (validator->success()) {
170 status = DeviceSettingsService::STORE_SUCCESS;
171 policy_data_ = validator->policy_data().Pass();
172 device_settings_ = validator->payload().Pass();
173 } else {
174 LOG(ERROR) << "Policy validation failed: " << validator->status();
175 }
176
177 ReportResult(status);
178 }
179
180 LoadSettingsOperation::LoadSettingsOperation(
181 scoped_refptr<OwnerKeyUtil> owner_key_util,
182 const Callback& callback)
183 : SessionManagerOperation(owner_key_util, callback) {}
184
185 LoadSettingsOperation::~LoadSettingsOperation() {}
186
187 void LoadSettingsOperation::Run() {
188 StartLoading();
189 }
190
191 StoreSettingsOperation::StoreSettingsOperation(
192 scoped_refptr<OwnerKeyUtil> owner_key_util,
193 const Callback& callback,
194 const std::string& policy_blob)
195 : SessionManagerOperation(owner_key_util, callback),
196 policy_blob_(policy_blob),
197 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {}
198
199 StoreSettingsOperation::~StoreSettingsOperation() {}
200
201 void StoreSettingsOperation::Run() {
202 session_manager_client()->StoreDevicePolicy(
203 policy_blob_,
204 base::Bind(&StoreSettingsOperation::HandleStoreResult,
205 weak_factory_.GetWeakPtr()));
206 }
207
208 void StoreSettingsOperation::HandleStoreResult(bool success) {
209 if (!success)
210 ReportResult(DeviceSettingsService::STORE_OPERATION_FAILED);
211 else
212 StartLoading();
213 }
214
215 SignAndStoreSettingsOperation::SignAndStoreSettingsOperation(
216 scoped_refptr<OwnerKeyUtil> owner_key_util,
217 const Callback& callback,
218 scoped_ptr<em::ChromeDeviceSettingsProto> settings,
219 const std::string& username)
220 : SessionManagerOperation(owner_key_util, callback),
221 settings_(settings.Pass()),
222 username_(username),
223 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
224 DCHECK(settings_.get());
225 }
226
227 SignAndStoreSettingsOperation::~SignAndStoreSettingsOperation() {}
228
229 void SignAndStoreSettingsOperation::Run() {
230 EnsureOwnerKey(base::Bind(&SignAndStoreSettingsOperation::StartSigning,
231 weak_factory_.GetWeakPtr()));
232 }
233
234 void SignAndStoreSettingsOperation::StartSigning() {
235 if (!owner_key() || !owner_key()->private_key() || username_.empty()) {
236 ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
237 return;
238 }
239
240 base::PostTaskAndReplyWithResult(
241 content::BrowserThread::GetBlockingPool(),
242 FROM_HERE,
243 base::Bind(&SignAndStoreSettingsOperation::AssembleAndSignPolicy,
244 base::Passed(&settings_), username_, owner_key()),
245 base::Bind(&SignAndStoreSettingsOperation::StoreDeviceSettingsBlob,
246 weak_factory_.GetWeakPtr()));
247 }
248
249 // static
250 std::string SignAndStoreSettingsOperation::AssembleAndSignPolicy(
251 scoped_ptr<em::ChromeDeviceSettingsProto> device_settings,
252 const std::string& username,
253 scoped_refptr<OwnerKey> owner_key) {
254 // Assemble the policy.
255 em::PolicyFetchResponse policy_response;
256 em::PolicyData policy;
257 policy.set_policy_type(policy::dm_protocol::kChromeDevicePolicyType);
258 policy.set_timestamp((base::Time::NowFromSystemTime() -
259 base::Time::UnixEpoch()).InMilliseconds());
260 policy.set_username(username);
261 if (!device_settings->SerializeToString(policy.mutable_policy_value()) ||
262 !policy.SerializeToString(policy_response.mutable_policy_data())) {
263 LOG(ERROR) << "Failed to encode policy payload.";
264 return std::string();
265 }
266
267 // Generate the signature.
268 scoped_ptr<crypto::SignatureCreator> signature_creator(
269 crypto::SignatureCreator::Create(owner_key->private_key()));
270 signature_creator->Update(
271 reinterpret_cast<const uint8*>(policy_response.policy_data().c_str()),
272 policy_response.policy_data().size());
273 std::vector<uint8> signature_bytes;
274 std::string policy_blob;
275 if (!signature_creator->Final(&signature_bytes)) {
276 LOG(ERROR) << "Failed to create policy signature.";
277 return std::string();
278 }
279
280 policy_response.mutable_policy_data_signature()->assign(
281 reinterpret_cast<const char*>(vector_as_array(&signature_bytes)),
282 signature_bytes.size());
283 return policy_response.SerializeAsString();
284 }
285
286 void SignAndStoreSettingsOperation::StoreDeviceSettingsBlob(
287 std::string device_settings_blob) {
288 if (device_settings_blob.empty()) {
289 ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
290 return;
291 }
292
293 session_manager_client()->StoreDevicePolicy(
294 device_settings_blob,
295 base::Bind(&SignAndStoreSettingsOperation::HandleStoreResult,
296 weak_factory_.GetWeakPtr()));
297 }
298
299 void SignAndStoreSettingsOperation::HandleStoreResult(bool success) {
300 if (!success)
301 ReportResult(DeviceSettingsService::STORE_OPERATION_FAILED);
302 else
303 StartLoading();
304 }
305
306 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698