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

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

Powered by Google App Engine
This is Rietveld 408576698