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