device_cloud_policy_store_chromeos.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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/policy/device_cloud_policy_store_chromeos.h"
6
7#include "base/bind.h"
8#include "base/sequenced_task_runner.h"
9#include "chrome/browser/chromeos/policy/device_policy_decoder_chromeos.h"
10#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
11#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
12#include "policy/proto/device_management_backend.pb.h"
13
14namespace em = enterprise_management;
15
16namespace policy {
17
18DeviceCloudPolicyStoreChromeOS::DeviceCloudPolicyStoreChromeOS(
19    chromeos::DeviceSettingsService* device_settings_service,
20    EnterpriseInstallAttributes* install_attributes,
21    scoped_refptr<base::SequencedTaskRunner> background_task_runner)
22    : device_settings_service_(device_settings_service),
23      install_attributes_(install_attributes),
24      background_task_runner_(background_task_runner),
25      weak_factory_(this) {
26  device_settings_service_->AddObserver(this);
27}
28
29DeviceCloudPolicyStoreChromeOS::~DeviceCloudPolicyStoreChromeOS() {
30  device_settings_service_->RemoveObserver(this);
31}
32
33void DeviceCloudPolicyStoreChromeOS::Store(
34    const em::PolicyFetchResponse& policy) {
35  // Cancel all pending requests.
36  weak_factory_.InvalidateWeakPtrs();
37
38  scoped_refptr<chromeos::OwnerKey> owner_key(
39      device_settings_service_->GetOwnerKey());
40  if (!install_attributes_->IsEnterpriseDevice() ||
41      !device_settings_service_->policy_data() || !owner_key.get() ||
42      !owner_key->public_key()) {
43    status_ = STATUS_BAD_STATE;
44    NotifyStoreError();
45    return;
46  }
47
48  scoped_ptr<DeviceCloudPolicyValidator> validator(CreateValidator(policy));
49  validator->ValidateSignature(*owner_key->public_key(), true);
50  validator->ValidateAgainstCurrentPolicy(
51      device_settings_service_->policy_data(),
52      CloudPolicyValidatorBase::TIMESTAMP_REQUIRED,
53      CloudPolicyValidatorBase::DM_TOKEN_REQUIRED);
54  validator.release()->StartValidation(
55      base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
56                 weak_factory_.GetWeakPtr()));
57}
58
59void DeviceCloudPolicyStoreChromeOS::Load() {
60  device_settings_service_->Load();
61}
62
63void DeviceCloudPolicyStoreChromeOS::InstallInitialPolicy(
64    const em::PolicyFetchResponse& policy) {
65  // Cancel all pending requests.
66  weak_factory_.InvalidateWeakPtrs();
67
68  if (!install_attributes_->IsEnterpriseDevice() &&
69      device_settings_service_->status() !=
70          chromeos::DeviceSettingsService::STORE_NO_POLICY) {
71    status_ = STATUS_BAD_STATE;
72    NotifyStoreError();
73    return;
74  }
75
76  scoped_ptr<DeviceCloudPolicyValidator> validator(CreateValidator(policy));
77  validator->ValidateInitialKey();
78  validator.release()->StartValidation(
79      base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
80                 weak_factory_.GetWeakPtr()));
81}
82
83void DeviceCloudPolicyStoreChromeOS::OwnershipStatusChanged() {
84  // Nothing to do.
85}
86
87void DeviceCloudPolicyStoreChromeOS::DeviceSettingsUpdated() {
88  if (!weak_factory_.HasWeakPtrs())
89    UpdateFromService();
90}
91
92scoped_ptr<DeviceCloudPolicyValidator>
93    DeviceCloudPolicyStoreChromeOS::CreateValidator(
94        const em::PolicyFetchResponse& policy) {
95  scoped_ptr<DeviceCloudPolicyValidator> validator(
96      DeviceCloudPolicyValidator::Create(
97          scoped_ptr<em::PolicyFetchResponse>(
98              new em::PolicyFetchResponse(policy)),
99          background_task_runner_));
100  validator->ValidateDomain(install_attributes_->GetDomain());
101  validator->ValidatePolicyType(dm_protocol::kChromeDevicePolicyType);
102  validator->ValidatePayload();
103  return validator.Pass();
104}
105
106void DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated(
107    DeviceCloudPolicyValidator* validator) {
108  if (!validator->success()) {
109    status_ = STATUS_VALIDATION_ERROR;
110    validation_status_ = validator->status();
111    NotifyStoreError();
112    return;
113  }
114
115  device_settings_service_->Store(
116      validator->policy().Pass(),
117      base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyStored,
118                 weak_factory_.GetWeakPtr()));
119}
120
121void DeviceCloudPolicyStoreChromeOS::OnPolicyStored() {
122  UpdateFromService();
123}
124
125void DeviceCloudPolicyStoreChromeOS::UpdateFromService() {
126  if (!install_attributes_->IsEnterpriseDevice()) {
127    status_ = STATUS_BAD_STATE;
128    NotifyStoreError();
129    return;
130  }
131
132  switch (device_settings_service_->status()) {
133    case chromeos::DeviceSettingsService::STORE_SUCCESS: {
134      status_ = STATUS_OK;
135      policy_.reset(new em::PolicyData());
136      if (device_settings_service_->policy_data())
137        policy_->MergeFrom(*device_settings_service_->policy_data());
138
139      PolicyMap new_policy_map;
140      if (is_managed()) {
141        DecodeDevicePolicy(*device_settings_service_->device_settings(),
142                           &new_policy_map, install_attributes_);
143      }
144      policy_map_.Swap(&new_policy_map);
145
146      NotifyStoreLoaded();
147      return;
148    }
149    case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE:
150      status_ = STATUS_BAD_STATE;
151      break;
152    case chromeos::DeviceSettingsService::STORE_POLICY_ERROR:
153    case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED:
154      status_ = STATUS_STORE_ERROR;
155      break;
156    case chromeos::DeviceSettingsService::STORE_NO_POLICY:
157    case chromeos::DeviceSettingsService::STORE_INVALID_POLICY:
158    case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR:
159    case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
160      status_ = STATUS_LOAD_ERROR;
161      break;
162  }
163
164  NotifyStoreError();
165}
166
167}  // namespace policy
168