15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/session_manager_operation.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/net/nss_context.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/ownership/owner_key_util.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/rsa_private_key.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/signature_creator.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing ownership::OwnerKeyUtil;
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing ownership::PublicKey;
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionManagerOperation::SessionManagerOperation(const Callback& callback)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : session_manager_client_(NULL),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_(callback),
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      force_key_load_(false),
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      is_loading_(false),
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_factory_(this) {}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionManagerOperation::~SessionManagerOperation() {}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SessionManagerOperation::Start(
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SessionManagerClient* session_manager_client,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<OwnerKeyUtil> owner_key_util,
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_refptr<PublicKey> public_key) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session_manager_client_ = session_manager_client;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  owner_key_util_ = owner_key_util;
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  public_key_ = public_key;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Run();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SessionManagerOperation::RestartLoad(bool key_changed) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key_changed)
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    public_key_ = NULL;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_loading_)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Abort previous load operations.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Mark as not loading to start loading again.
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  is_loading_ = false;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartLoading();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SessionManagerOperation::StartLoading() {
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (is_loading_)
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_loading_ = true;
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EnsurePublicKey(base::Bind(&SessionManagerOperation::RetrieveDeviceSettings,
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             weak_factory_.GetWeakPtr()));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SessionManagerOperation::ReportResult(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceSettingsService::Status status) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_.Run(this, status);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SessionManagerOperation::EnsurePublicKey(const base::Closure& callback) {
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (force_key_load_ || !public_key_.get() || !public_key_->is_loaded()) {
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_refptr<base::TaskRunner> task_runner =
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        content::BrowserThread::GetBlockingPool()
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            ->GetTaskRunnerWithShutdownBehavior(
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PostTaskAndReplyWithResult(
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        task_runner.get(),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&SessionManagerOperation::LoadPublicKey,
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   owner_key_util_,
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   public_key_),
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&SessionManagerOperation::StorePublicKey,
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   weak_factory_.GetWeakPtr(),
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   callback));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_refptr<PublicKey> SessionManagerOperation::LoadPublicKey(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<OwnerKeyUtil> util,
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_refptr<PublicKey> current_key) {
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<PublicKey> public_key(new PublicKey());
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Keep already-existing public key.
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (current_key.get() && current_key->is_loaded()) {
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    public_key->data() = current_key->data();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!public_key->is_loaded() && util->IsPublicKeyPresent()) {
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!util->ImportPublicKey(&public_key->data()))
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      LOG(ERROR) << "Failed to load public owner key.";
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return public_key;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SessionManagerOperation::StorePublicKey(const base::Closure& callback,
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             scoped_refptr<PublicKey> new_key) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  force_key_load_ = false;
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  public_key_ = new_key;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!public_key_.get() || !public_key_->is_loaded()) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.Run();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SessionManagerOperation::RetrieveDeviceSettings() {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session_manager_client()->RetrieveDevicePolicy(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&SessionManagerOperation::ValidateDeviceSettings,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SessionManagerOperation::ValidateDeviceSettings(
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& policy_blob) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy_blob.empty()) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportResult(DeviceSettingsService::STORE_NO_POLICY);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!policy->ParseFromString(policy_blob) ||
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy->IsInitialized()) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportResult(DeviceSettingsService::STORE_INVALID_POLICY);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::SequencedWorkerPool* pool =
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      content::BrowserThread::GetBlockingPool();
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<base::SequencedTaskRunner> background_task_runner =
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      pool->GetSequencedTaskRunnerWithShutdownBehavior(
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          pool->GetSequenceToken(),
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy::DeviceCloudPolicyValidator* validator =
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      policy::DeviceCloudPolicyValidator::Create(policy.Pass(),
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                 background_task_runner);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Policy auto-generated by session manager doesn't include a timestamp, so
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the timestamp shouldn't be verified in that case.
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Additionally, offline devices can get their clock set backwards in time
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // under some hardware conditions; checking the timestamp now could likely
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // find a value in the future, and prevent the user from signing-in or
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // starting guest mode. Tlsdate will eventually fix the clock when the device
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // is back online, but the network configuration may come from device ONC.
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // To prevent all of these issues the timestamp is just not verified when
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // loading the device policy from the cache. Note that the timestamp is still
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // verified during enrollment and when a new policy is fetched from the
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // server.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  validator->ValidateAgainstCurrentPolicy(
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy_data_.get(),
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      policy::CloudPolicyValidatorBase::TIMESTAMP_NOT_REQUIRED,
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy::CloudPolicyValidatorBase::DM_TOKEN_NOT_REQUIRED);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  validator->ValidatePolicyType(policy::dm_protocol::kChromeDevicePolicyType);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  validator->ValidatePayload();
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We don't check the DMServer verification key below, because the signing
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // key is validated when it is installed.
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  validator->ValidateSignature(public_key_->as_string(),
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               std::string(),  // No key validation check.
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               std::string(),
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               false);
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  validator->StartValidation(
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SessionManagerOperation::ReportValidatorStatus,
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SessionManagerOperation::ReportValidatorStatus(
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    policy::DeviceCloudPolicyValidator* validator) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeviceSettingsService::Status status =
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DeviceSettingsService::STORE_VALIDATION_ERROR;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (validator->success()) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status = DeviceSettingsService::STORE_SUCCESS;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    policy_data_ = validator->policy_data().Pass();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_settings_ = validator->payload().Pass();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Policy validation failed: " << validator->status();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Those are mostly caused by RTC loss and are recoverable.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (validator->status() ==
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        policy::DeviceCloudPolicyValidator::VALIDATION_BAD_TIMESTAMP) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status = DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReportResult(status);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadSettingsOperation::LoadSettingsOperation(const Callback& callback)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SessionManagerOperation(callback) {}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadSettingsOperation::~LoadSettingsOperation() {}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoadSettingsOperation::Run() {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartLoading();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StoreSettingsOperation::StoreSettingsOperation(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Callback& callback,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<em::PolicyFetchResponse> policy)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SessionManagerOperation(callback),
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy_(policy.Pass()),
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StoreSettingsOperation::~StoreSettingsOperation() {}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StoreSettingsOperation::Run() {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session_manager_client()->StoreDevicePolicy(
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy_->SerializeAsString(),
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&StoreSettingsOperation::HandleStoreResult,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StoreSettingsOperation::HandleStoreResult(bool success) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportResult(DeviceSettingsService::STORE_OPERATION_FAILED);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartLoading();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SignAndStoreSettingsOperation::SignAndStoreSettingsOperation(
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Callback& callback,
2440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<em::PolicyData> new_policy)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SessionManagerOperation(callback),
2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new_policy_(new_policy.Pass()),
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(new_policy_);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SignAndStoreSettingsOperation::~SignAndStoreSettingsOperation() {}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SignAndStoreSettingsOperation::Run() {
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!owner_settings_service_) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  owner_settings_service_->IsOwnerAsync(
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SignAndStoreSettingsOperation::StartSigning,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SignAndStoreSettingsOperation::StartSigning(bool is_owner) {
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!owner_settings_service_ || !is_owner) {
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool rv = owner_settings_service_->AssembleAndSignPolicyAsync(
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      content::BrowserThread::GetBlockingPool(),
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new_policy_.Pass(),
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SignAndStoreSettingsOperation::StoreDeviceSettingsBlob,
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!rv) {
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SignAndStoreSettingsOperation::StoreDeviceSettingsBlob(
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string device_settings_blob) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (device_settings_blob.empty()) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportResult(DeviceSettingsService::STORE_POLICY_ERROR);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session_manager_client()->StoreDevicePolicy(
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_blob,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&SignAndStoreSettingsOperation::HandleStoreResult,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SignAndStoreSettingsOperation::HandleStoreResult(bool success) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportResult(DeviceSettingsService::STORE_OPERATION_FAILED);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartLoading();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
301