OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/settings/device_settings_service.h" | 5 #include "chrome/browser/chromeos/settings/device_settings_service.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
12 #include "chrome/browser/chrome_notification_types.h" | 12 #include "chrome/browser/chrome_notification_types.h" |
13 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" | |
14 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" | 13 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" |
15 #include "chrome/browser/chromeos/settings/session_manager_operation.h" | 14 #include "chrome/browser/chromeos/settings/session_manager_operation.h" |
16 #include "components/ownership/owner_key_util.h" | 15 #include "components/ownership/owner_key_util.h" |
17 #include "components/policy/core/common/cloud/cloud_policy_constants.h" | 16 #include "components/policy/core/common/cloud/cloud_policy_constants.h" |
18 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/browser/notification_service.h" | 18 #include "content/public/browser/notification_service.h" |
20 #include "content/public/browser/notification_source.h" | 19 #include "content/public/browser/notification_source.h" |
21 #include "crypto/rsa_private_key.h" | 20 #include "crypto/rsa_private_key.h" |
22 | 21 |
23 namespace em = enterprise_management; | 22 namespace em = enterprise_management; |
24 | 23 |
25 using ownership::OwnerKeyUtil; | 24 using ownership::OwnerKeyUtil; |
26 using ownership::PublicKey; | 25 using ownership::PublicKey; |
27 | 26 |
28 namespace { | 27 namespace { |
29 | 28 |
30 // Delay between load retries when there was a validation error. | 29 // Delay between load retries when there was a validation error. |
31 // NOTE: This code is here to mitigate clock loss on some devices where policy | 30 // NOTE: This code is here to mitigate clock loss on some devices where policy |
32 // loads will fail with a validation error caused by RTC clock being reset when | 31 // loads will fail with a validation error caused by RTC clock being reset when |
33 // the battery is drained. | 32 // the battery is drained. |
34 int kLoadRetryDelayMs = 1000 * 5; | 33 int kLoadRetryDelayMs = 1000 * 5; |
35 // Maximal number of retries before we give up. Calculated to allow for 10 min | 34 // Maximal number of retries before we give up. Calculated to allow for 10 min |
36 // of retry time. | 35 // of retry time. |
37 int kMaxLoadRetries = (1000 * 60 * 10) / kLoadRetryDelayMs; | 36 int kMaxLoadRetries = (1000 * 60 * 10) / kLoadRetryDelayMs; |
38 | 37 |
| 38 // Assembles PolicyData based on |settings|, |policy_data| and |
| 39 // |user_id|. |
| 40 scoped_ptr<em::PolicyData> AssemblePolicy( |
| 41 const std::string& user_id, |
| 42 const em::PolicyData* policy_data, |
| 43 const em::ChromeDeviceSettingsProto* settings) { |
| 44 scoped_ptr<em::PolicyData> policy(new em::PolicyData()); |
| 45 if (policy_data) { |
| 46 // Preserve management settings. |
| 47 if (policy_data->has_management_mode()) |
| 48 policy->set_management_mode(policy_data->management_mode()); |
| 49 if (policy_data->has_request_token()) |
| 50 policy->set_request_token(policy_data->request_token()); |
| 51 if (policy_data->has_device_id()) |
| 52 policy->set_device_id(policy_data->device_id()); |
| 53 } else { |
| 54 // If there's no previous policy data, this is the first time the device |
| 55 // setting is set. We set the management mode to NOT_MANAGED initially. |
| 56 policy->set_management_mode(em::PolicyData::NOT_MANAGED); |
| 57 } |
| 58 policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType); |
| 59 policy->set_timestamp( |
| 60 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds()); |
| 61 policy->set_username(user_id); |
| 62 if (!settings->SerializeToString(policy->mutable_policy_value())) |
| 63 return scoped_ptr<em::PolicyData>(); |
| 64 |
| 65 return policy.Pass(); |
| 66 } |
| 67 |
39 // Returns true if it is okay to transfer from the current mode to the new | 68 // Returns true if it is okay to transfer from the current mode to the new |
40 // mode. This function should be called in SetManagementMode(). | 69 // mode. This function should be called in SetManagementMode(). |
41 bool CheckManagementModeTransition(em::PolicyData::ManagementMode current_mode, | 70 bool CheckManagementModeTransition(em::PolicyData::ManagementMode current_mode, |
42 em::PolicyData::ManagementMode new_mode) { | 71 em::PolicyData::ManagementMode new_mode) { |
43 // Mode is not changed. | 72 // Mode is not changed. |
44 if (current_mode == new_mode) | 73 if (current_mode == new_mode) |
45 return true; | 74 return true; |
46 | 75 |
47 switch (current_mode) { | 76 switch (current_mode) { |
48 case em::PolicyData::NOT_MANAGED: | 77 case em::PolicyData::NOT_MANAGED: |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 | 144 |
116 session_manager_client_ = session_manager_client; | 145 session_manager_client_ = session_manager_client; |
117 owner_key_util_ = owner_key_util; | 146 owner_key_util_ = owner_key_util; |
118 | 147 |
119 session_manager_client_->AddObserver(this); | 148 session_manager_client_->AddObserver(this); |
120 | 149 |
121 StartNextOperation(); | 150 StartNextOperation(); |
122 } | 151 } |
123 | 152 |
124 void DeviceSettingsService::UnsetSessionManager() { | 153 void DeviceSettingsService::UnsetSessionManager() { |
| 154 STLDeleteContainerPointers(pending_operations_.begin(), |
| 155 pending_operations_.end()); |
125 pending_operations_.clear(); | 156 pending_operations_.clear(); |
126 | 157 |
127 if (session_manager_client_) | 158 if (session_manager_client_) |
128 session_manager_client_->RemoveObserver(this); | 159 session_manager_client_->RemoveObserver(this); |
129 session_manager_client_ = NULL; | 160 session_manager_client_ = NULL; |
130 owner_key_util_ = NULL; | 161 owner_key_util_ = NULL; |
131 } | 162 } |
132 | 163 |
133 scoped_refptr<PublicKey> DeviceSettingsService::GetPublicKey() { | 164 scoped_refptr<PublicKey> DeviceSettingsService::GetPublicKey() { |
134 return public_key_; | 165 return public_key_; |
135 } | 166 } |
136 | 167 |
137 void DeviceSettingsService::Load() { | 168 void DeviceSettingsService::Load() { |
138 EnqueueLoad(false); | 169 EnqueueLoad(false); |
139 } | 170 } |
140 | 171 |
141 void DeviceSettingsService::SignAndStore( | 172 void DeviceSettingsService::SignAndStore( |
142 scoped_ptr<em::ChromeDeviceSettingsProto> new_settings, | 173 scoped_ptr<em::ChromeDeviceSettingsProto> new_settings, |
143 const base::Closure& callback) { | 174 const base::Closure& callback) { |
| 175 if (!owner_settings_service_) { |
| 176 HandleError(STORE_KEY_UNAVAILABLE, callback); |
| 177 return; |
| 178 } |
144 scoped_ptr<em::PolicyData> policy = | 179 scoped_ptr<em::PolicyData> policy = |
145 OwnerSettingsServiceChromeOS::AssemblePolicy( | 180 AssemblePolicy(GetUsername(), policy_data(), new_settings.get()); |
146 GetUsername(), policy_data(), new_settings.get()); | 181 if (!policy) { |
147 EnqueueSignAndStore(policy.Pass(), callback); | 182 HandleError(STORE_POLICY_ERROR, callback); |
| 183 return; |
| 184 } |
| 185 |
| 186 owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback); |
148 } | 187 } |
149 | 188 |
150 void DeviceSettingsService::SetManagementSettings( | 189 void DeviceSettingsService::SetManagementSettings( |
151 em::PolicyData::ManagementMode management_mode, | 190 em::PolicyData::ManagementMode management_mode, |
152 const std::string& request_token, | 191 const std::string& request_token, |
153 const std::string& device_id, | 192 const std::string& device_id, |
154 const base::Closure& callback) { | 193 const base::Closure& callback) { |
155 if (!owner_settings_service_) { | 194 if (!owner_settings_service_) { |
156 HandleError(STORE_KEY_UNAVAILABLE, callback); | 195 HandleError(STORE_KEY_UNAVAILABLE, callback); |
157 return; | 196 return; |
158 } | 197 } |
159 | 198 |
160 em::PolicyData::ManagementMode current_mode = em::PolicyData::NOT_MANAGED; | 199 em::PolicyData::ManagementMode current_mode = em::PolicyData::NOT_MANAGED; |
161 if (policy_data() && policy_data()->has_management_mode()) | 200 if (policy_data() && policy_data()->has_management_mode()) |
162 current_mode = policy_data()->management_mode(); | 201 current_mode = policy_data()->management_mode(); |
163 | 202 |
164 if (!CheckManagementModeTransition(current_mode, management_mode)) { | 203 if (!CheckManagementModeTransition(current_mode, management_mode)) { |
165 LOG(ERROR) << "Invalid management mode transition: current mode = " | 204 LOG(ERROR) << "Invalid management mode transition: current mode = " |
166 << current_mode << ", new mode = " << management_mode; | 205 << current_mode << ", new mode = " << management_mode; |
167 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); | 206 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); |
168 return; | 207 return; |
169 } | 208 } |
170 | 209 |
171 scoped_ptr<em::PolicyData> policy = | 210 scoped_ptr<em::PolicyData> policy = |
172 OwnerSettingsServiceChromeOS::AssemblePolicy( | 211 AssemblePolicy(GetUsername(), policy_data(), device_settings()); |
173 GetUsername(), policy_data(), device_settings()); | |
174 if (!policy) { | 212 if (!policy) { |
175 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); | 213 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); |
176 return; | 214 return; |
177 } | 215 } |
178 | 216 |
179 policy->set_management_mode(management_mode); | 217 policy->set_management_mode(management_mode); |
180 policy->set_request_token(request_token); | 218 policy->set_request_token(request_token); |
181 policy->set_device_id(device_id); | 219 policy->set_device_id(device_id); |
182 | 220 |
183 EnqueueSignAndStore(policy.Pass(), callback); | 221 owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback); |
184 } | 222 } |
185 | 223 |
186 void DeviceSettingsService::Store(scoped_ptr<em::PolicyFetchResponse> policy, | 224 void DeviceSettingsService::Store(scoped_ptr<em::PolicyFetchResponse> policy, |
187 const base::Closure& callback) { | 225 const base::Closure& callback) { |
188 Enqueue(linked_ptr<SessionManagerOperation>(new StoreSettingsOperation( | 226 Enqueue( |
189 base::Bind(&DeviceSettingsService::HandleCompletedOperation, | 227 new StoreSettingsOperation( |
190 weak_factory_.GetWeakPtr(), | 228 base::Bind(&DeviceSettingsService::HandleCompletedOperation, |
191 callback), | 229 weak_factory_.GetWeakPtr(), |
192 policy.Pass()))); | 230 callback), |
| 231 policy.Pass())); |
193 } | 232 } |
194 | 233 |
195 DeviceSettingsService::OwnershipStatus | 234 DeviceSettingsService::OwnershipStatus |
196 DeviceSettingsService::GetOwnershipStatus() { | 235 DeviceSettingsService::GetOwnershipStatus() { |
197 if (public_key_.get()) | 236 if (public_key_.get()) |
198 return public_key_->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; | 237 return public_key_->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; |
199 return OWNERSHIP_UNKNOWN; | 238 return OWNERSHIP_UNKNOWN; |
200 } | 239 } |
201 | 240 |
202 void DeviceSettingsService::GetOwnershipStatusAsync( | 241 void DeviceSettingsService::GetOwnershipStatusAsync( |
(...skipping 27 matching lines...) Expand all Loading... |
230 username_ = username; | 269 username_ = username; |
231 owner_settings_service_ = owner_settings_service; | 270 owner_settings_service_ = owner_settings_service; |
232 | 271 |
233 EnsureReload(true); | 272 EnsureReload(true); |
234 } | 273 } |
235 | 274 |
236 const std::string& DeviceSettingsService::GetUsername() const { | 275 const std::string& DeviceSettingsService::GetUsername() const { |
237 return username_; | 276 return username_; |
238 } | 277 } |
239 | 278 |
240 ownership::OwnerSettingsService* | |
241 DeviceSettingsService::GetOwnerSettingsService() const { | |
242 return owner_settings_service_.get(); | |
243 } | |
244 | |
245 void DeviceSettingsService::AddObserver(Observer* observer) { | 279 void DeviceSettingsService::AddObserver(Observer* observer) { |
246 observers_.AddObserver(observer); | 280 observers_.AddObserver(observer); |
247 } | 281 } |
248 | 282 |
249 void DeviceSettingsService::RemoveObserver(Observer* observer) { | 283 void DeviceSettingsService::RemoveObserver(Observer* observer) { |
250 observers_.RemoveObserver(observer); | 284 observers_.RemoveObserver(observer); |
251 } | 285 } |
252 | 286 |
253 void DeviceSettingsService::OwnerKeySet(bool success) { | 287 void DeviceSettingsService::OwnerKeySet(bool success) { |
254 if (!success) { | 288 if (!success) { |
255 LOG(ERROR) << "Owner key change failed."; | 289 LOG(ERROR) << "Owner key change failed."; |
256 return; | 290 return; |
257 } | 291 } |
258 | 292 |
259 public_key_ = NULL; | 293 public_key_ = NULL; |
260 EnsureReload(true); | 294 EnsureReload(true); |
261 } | 295 } |
262 | 296 |
263 void DeviceSettingsService::PropertyChangeComplete(bool success) { | 297 void DeviceSettingsService::PropertyChangeComplete(bool success) { |
264 if (!success) { | 298 if (!success) { |
265 LOG(ERROR) << "Policy update failed."; | 299 LOG(ERROR) << "Policy update failed."; |
266 return; | 300 return; |
267 } | 301 } |
268 | 302 |
269 EnsureReload(false); | 303 EnsureReload(false); |
270 } | 304 } |
271 | 305 |
272 void DeviceSettingsService::Enqueue( | 306 void DeviceSettingsService::Enqueue(SessionManagerOperation* operation) { |
273 const linked_ptr<SessionManagerOperation>& operation) { | |
274 pending_operations_.push_back(operation); | 307 pending_operations_.push_back(operation); |
275 if (pending_operations_.front().get() == operation.get()) | 308 if (pending_operations_.front() == operation) |
276 StartNextOperation(); | 309 StartNextOperation(); |
277 } | 310 } |
278 | 311 |
279 void DeviceSettingsService::EnqueueLoad(bool force_key_load) { | 312 void DeviceSettingsService::EnqueueLoad(bool force_key_load) { |
280 linked_ptr<SessionManagerOperation> operation(new LoadSettingsOperation( | 313 SessionManagerOperation* operation = |
281 base::Bind(&DeviceSettingsService::HandleCompletedOperation, | 314 new LoadSettingsOperation( |
282 weak_factory_.GetWeakPtr(), | 315 base::Bind(&DeviceSettingsService::HandleCompletedOperation, |
283 base::Closure()))); | 316 weak_factory_.GetWeakPtr(), |
| 317 base::Closure())); |
284 operation->set_force_key_load(force_key_load); | 318 operation->set_force_key_load(force_key_load); |
285 operation->set_username(username_); | 319 operation->set_username(username_); |
286 operation->set_owner_settings_service(owner_settings_service_); | 320 operation->set_owner_settings_service(owner_settings_service_); |
287 Enqueue(operation); | 321 Enqueue(operation); |
288 } | 322 } |
289 | |
290 void DeviceSettingsService::EnqueueSignAndStore( | |
291 scoped_ptr<enterprise_management::PolicyData> policy, | |
292 const base::Closure& callback) { | |
293 linked_ptr<SessionManagerOperation> operation( | |
294 new SignAndStoreSettingsOperation( | |
295 base::Bind(&DeviceSettingsService::HandleCompletedOperation, | |
296 weak_factory_.GetWeakPtr(), | |
297 callback), | |
298 policy.Pass())); | |
299 operation->set_owner_settings_service(owner_settings_service_); | |
300 Enqueue(operation); | |
301 } | |
302 | 323 |
303 void DeviceSettingsService::EnsureReload(bool force_key_load) { | 324 void DeviceSettingsService::EnsureReload(bool force_key_load) { |
304 if (!pending_operations_.empty()) { | 325 if (!pending_operations_.empty()) { |
305 pending_operations_.front()->set_username(username_); | 326 pending_operations_.front()->set_username(username_); |
306 pending_operations_.front()->set_owner_settings_service( | 327 pending_operations_.front()->set_owner_settings_service( |
307 owner_settings_service_); | 328 owner_settings_service_); |
308 pending_operations_.front()->RestartLoad(force_key_load); | 329 pending_operations_.front()->RestartLoad(force_key_load); |
309 } else { | 330 } else { |
310 EnqueueLoad(force_key_load); | 331 EnqueueLoad(force_key_load); |
311 } | 332 } |
312 } | 333 } |
313 | 334 |
314 void DeviceSettingsService::StartNextOperation() { | 335 void DeviceSettingsService::StartNextOperation() { |
315 if (!pending_operations_.empty() && session_manager_client_ && | 336 if (!pending_operations_.empty() && |
| 337 session_manager_client_ && |
316 owner_key_util_.get()) { | 338 owner_key_util_.get()) { |
317 pending_operations_.front()->Start( | 339 pending_operations_.front()->Start( |
318 session_manager_client_, owner_key_util_, public_key_); | 340 session_manager_client_, owner_key_util_, public_key_); |
319 } | 341 } |
320 } | 342 } |
321 | 343 |
322 void DeviceSettingsService::HandleCompletedOperation( | 344 void DeviceSettingsService::HandleCompletedOperation( |
323 const base::Closure& callback, | 345 const base::Closure& callback, |
324 SessionManagerOperation* operation, | 346 SessionManagerOperation* operation, |
325 Status status) { | 347 Status status) { |
326 DCHECK_EQ(operation, pending_operations_.front().get()); | 348 DCHECK_EQ(operation, pending_operations_.front()); |
327 store_status_ = status; | 349 store_status_ = status; |
328 | 350 |
329 OwnershipStatus ownership_status = OWNERSHIP_UNKNOWN; | 351 OwnershipStatus ownership_status = OWNERSHIP_UNKNOWN; |
330 scoped_refptr<PublicKey> new_key(operation->public_key()); | 352 scoped_refptr<PublicKey> new_key(operation->public_key()); |
331 if (new_key.get()) { | 353 if (new_key.get()) { |
332 ownership_status = new_key->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; | 354 ownership_status = new_key->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; |
333 } else { | 355 } else { |
334 NOTREACHED() << "Failed to determine key status."; | 356 NOTREACHED() << "Failed to determine key status."; |
335 } | 357 } |
336 | 358 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 } | 405 } |
384 | 406 |
385 // The completion callback happens after the notification so clients can | 407 // The completion callback happens after the notification so clients can |
386 // filter self-triggered updates. | 408 // filter self-triggered updates. |
387 if (!callback.is_null()) | 409 if (!callback.is_null()) |
388 callback.Run(); | 410 callback.Run(); |
389 | 411 |
390 // Only remove the pending operation here, so new operations triggered by any | 412 // Only remove the pending operation here, so new operations triggered by any |
391 // of the callbacks above are queued up properly. | 413 // of the callbacks above are queued up properly. |
392 pending_operations_.pop_front(); | 414 pending_operations_.pop_front(); |
| 415 delete operation; |
393 | 416 |
394 StartNextOperation(); | 417 StartNextOperation(); |
395 } | 418 } |
396 | 419 |
397 void DeviceSettingsService::HandleError(Status status, | 420 void DeviceSettingsService::HandleError(Status status, |
398 const base::Closure& callback) { | 421 const base::Closure& callback) { |
399 store_status_ = status; | 422 store_status_ = status; |
400 | 423 |
401 LOG(ERROR) << "Session manager operation failed: " << status; | 424 LOG(ERROR) << "Session manager operation failed: " << status; |
402 | 425 |
403 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); | 426 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); |
404 | 427 |
405 // The completion callback happens after the notification so clients can | 428 // The completion callback happens after the notification so clients can |
406 // filter self-triggered updates. | 429 // filter self-triggered updates. |
407 if (!callback.is_null()) | 430 if (!callback.is_null()) |
408 callback.Run(); | 431 callback.Run(); |
409 } | 432 } |
410 | 433 |
| 434 void DeviceSettingsService::OnSignAndStoreOperationCompleted(Status status) { |
| 435 store_status_ = status; |
| 436 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); |
| 437 } |
| 438 |
411 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() { | 439 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() { |
412 DeviceSettingsService::Initialize(); | 440 DeviceSettingsService::Initialize(); |
413 } | 441 } |
414 | 442 |
415 ScopedTestDeviceSettingsService::~ScopedTestDeviceSettingsService() { | 443 ScopedTestDeviceSettingsService::~ScopedTestDeviceSettingsService() { |
416 // Clean pending operations. | 444 // Clean pending operations. |
417 DeviceSettingsService::Get()->UnsetSessionManager(); | 445 DeviceSettingsService::Get()->UnsetSessionManager(); |
418 DeviceSettingsService::Shutdown(); | 446 DeviceSettingsService::Shutdown(); |
419 } | 447 } |
420 | 448 |
421 } // namespace chromeos | 449 } // namespace chromeos |
OLD | NEW |