Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / policy / device_cloud_policy_store_chromeos.cc
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/logging.h"
9 #include "base/metrics/histogram.h"
10 #include "base/sequenced_task_runner.h"
11 #include "chrome/browser/chromeos/login/startup_utils.h"
12 #include "chrome/browser/chromeos/policy/device_policy_decoder_chromeos.h"
13 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
14 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
15 #include "components/ownership/owner_key_util.h"
16 #include "policy/proto/device_management_backend.pb.h"
17
18 namespace em = enterprise_management;
19
20 namespace policy {
21
22 DeviceCloudPolicyStoreChromeOS::DeviceCloudPolicyStoreChromeOS(
23     chromeos::DeviceSettingsService* device_settings_service,
24     EnterpriseInstallAttributes* install_attributes,
25     scoped_refptr<base::SequencedTaskRunner> background_task_runner)
26     : device_settings_service_(device_settings_service),
27       install_attributes_(install_attributes),
28       background_task_runner_(background_task_runner),
29       enrollment_validation_done_(false),
30       weak_factory_(this) {
31   device_settings_service_->AddObserver(this);
32 }
33
34 DeviceCloudPolicyStoreChromeOS::~DeviceCloudPolicyStoreChromeOS() {
35   device_settings_service_->RemoveObserver(this);
36 }
37
38 void DeviceCloudPolicyStoreChromeOS::Store(
39     const em::PolicyFetchResponse& policy) {
40   // Cancel all pending requests.
41   weak_factory_.InvalidateWeakPtrs();
42
43   scoped_refptr<ownership::PublicKey> public_key(
44       device_settings_service_->GetPublicKey());
45   if (!install_attributes_->IsEnterpriseDevice() ||
46       !device_settings_service_->policy_data() || !public_key.get() ||
47       !public_key->is_loaded()) {
48     status_ = STATUS_BAD_STATE;
49     NotifyStoreError();
50     return;
51   }
52
53   scoped_ptr<DeviceCloudPolicyValidator> validator(CreateValidator(policy));
54   validator->ValidateSignature(public_key->as_string(),
55                                GetPolicyVerificationKey(),
56                                install_attributes_->GetDomain(),
57                                true);
58   validator->ValidateAgainstCurrentPolicy(
59       device_settings_service_->policy_data(),
60       CloudPolicyValidatorBase::TIMESTAMP_REQUIRED,
61       CloudPolicyValidatorBase::DM_TOKEN_REQUIRED);
62   validator.release()->StartValidation(
63       base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
64                  weak_factory_.GetWeakPtr()));
65 }
66
67 void DeviceCloudPolicyStoreChromeOS::Load() {
68   device_settings_service_->Load();
69 }
70
71 void DeviceCloudPolicyStoreChromeOS::InstallInitialPolicy(
72     const em::PolicyFetchResponse& policy) {
73   // Cancel all pending requests.
74   weak_factory_.InvalidateWeakPtrs();
75
76   if (!install_attributes_->IsEnterpriseDevice() &&
77       device_settings_service_->status() !=
78           chromeos::DeviceSettingsService::STORE_NO_POLICY) {
79     status_ = STATUS_BAD_STATE;
80     NotifyStoreError();
81     return;
82   }
83
84   scoped_ptr<DeviceCloudPolicyValidator> validator(CreateValidator(policy));
85   validator->ValidateInitialKey(GetPolicyVerificationKey(),
86                                 install_attributes_->GetDomain());
87   validator.release()->StartValidation(
88       base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
89                  weak_factory_.GetWeakPtr()));
90 }
91
92 void DeviceCloudPolicyStoreChromeOS::OwnershipStatusChanged() {
93   // Nothing to do.
94 }
95
96 void DeviceCloudPolicyStoreChromeOS::DeviceSettingsUpdated() {
97   if (!weak_factory_.HasWeakPtrs())
98     UpdateFromService();
99 }
100
101 scoped_ptr<DeviceCloudPolicyValidator>
102     DeviceCloudPolicyStoreChromeOS::CreateValidator(
103         const em::PolicyFetchResponse& policy) {
104   scoped_ptr<DeviceCloudPolicyValidator> validator(
105       DeviceCloudPolicyValidator::Create(
106           scoped_ptr<em::PolicyFetchResponse>(
107               new em::PolicyFetchResponse(policy)),
108           background_task_runner_));
109   validator->ValidateDomain(install_attributes_->GetDomain());
110   validator->ValidatePolicyType(dm_protocol::kChromeDevicePolicyType);
111   validator->ValidatePayload();
112   return validator.Pass();
113 }
114
115 void DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated(
116     DeviceCloudPolicyValidator* validator) {
117   if (!validator->success()) {
118     status_ = STATUS_VALIDATION_ERROR;
119     validation_status_ = validator->status();
120     NotifyStoreError();
121     return;
122   }
123
124   device_settings_service_->Store(
125       validator->policy().Pass(),
126       base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyStored,
127                  weak_factory_.GetWeakPtr()));
128 }
129
130 void DeviceCloudPolicyStoreChromeOS::OnPolicyStored() {
131   UpdateFromService();
132 }
133
134 void DeviceCloudPolicyStoreChromeOS::UpdateFromService() {
135   if (!install_attributes_->IsEnterpriseDevice()) {
136     status_ = STATUS_BAD_STATE;
137     NotifyStoreError();
138     return;
139   }
140
141   // Once per session, validate internal consistency of enrollment state (DM
142   // token must be present on enrolled devices) and in case of failure set flag
143   // to indicate that recovery is required.
144   const chromeos::DeviceSettingsService::Status status =
145       device_settings_service_->status();
146   switch (status) {
147     case chromeos::DeviceSettingsService::STORE_SUCCESS:
148     case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE:
149     case chromeos::DeviceSettingsService::STORE_NO_POLICY:
150     case chromeos::DeviceSettingsService::STORE_INVALID_POLICY:
151     case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR: {
152       if (!enrollment_validation_done_) {
153         enrollment_validation_done_ = true;
154         const bool has_dm_token =
155             status == chromeos::DeviceSettingsService::STORE_SUCCESS &&
156             device_settings_service_->policy_data() &&
157             device_settings_service_->policy_data()->has_request_token();
158
159         // At the time LoginDisplayHostImpl decides whether enrollment flow is
160         // to be started, policy hasn't been read yet.  To work around this,
161         // once the need for recovery is detected upon policy load, a flag is
162         // stored in prefs which is accessed by LoginDisplayHostImpl early
163         // during (next) boot.
164         if (!has_dm_token) {
165           LOG(ERROR) << "Device policy read on enrolled device yields "
166                      << "no DM token! Status: " << status << ".";
167           chromeos::StartupUtils::MarkEnrollmentRecoveryRequired();
168         }
169         UMA_HISTOGRAM_BOOLEAN("Enterprise.EnrolledPolicyHasDMToken",
170                               has_dm_token);
171       }
172       break;
173     }
174     case chromeos::DeviceSettingsService::STORE_POLICY_ERROR:
175     case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED:
176     case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
177       // Do nothing for write errors or transient read errors.
178       break;
179   }
180
181   switch (status) {
182     case chromeos::DeviceSettingsService::STORE_SUCCESS: {
183       status_ = STATUS_OK;
184       policy_.reset(new em::PolicyData());
185       if (device_settings_service_->policy_data())
186         policy_->MergeFrom(*device_settings_service_->policy_data());
187
188       PolicyMap new_policy_map;
189       if (is_managed()) {
190         DecodeDevicePolicy(*device_settings_service_->device_settings(),
191                            &new_policy_map, install_attributes_);
192       }
193       policy_map_.Swap(&new_policy_map);
194
195       NotifyStoreLoaded();
196       return;
197     }
198     case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE:
199       status_ = STATUS_BAD_STATE;
200       break;
201     case chromeos::DeviceSettingsService::STORE_POLICY_ERROR:
202     case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED:
203       status_ = STATUS_STORE_ERROR;
204       break;
205     case chromeos::DeviceSettingsService::STORE_NO_POLICY:
206     case chromeos::DeviceSettingsService::STORE_INVALID_POLICY:
207     case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR:
208     case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
209       status_ = STATUS_LOAD_ERROR;
210       break;
211   }
212
213   NotifyStoreError();
214 }
215
216 }  // namespace policy