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.
5 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.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 "components/policy/core/common/cloud/cloud_policy_constants.h"
17 #include "policy/proto/device_management_backend.pb.h"
19 namespace em
= enterprise_management
;
23 DeviceCloudPolicyStoreChromeOS::DeviceCloudPolicyStoreChromeOS(
24 chromeos::DeviceSettingsService
* device_settings_service
,
25 EnterpriseInstallAttributes
* install_attributes
,
26 scoped_refptr
<base::SequencedTaskRunner
> background_task_runner
)
27 : device_settings_service_(device_settings_service
),
28 install_attributes_(install_attributes
),
29 background_task_runner_(background_task_runner
),
30 enrollment_validation_done_(false),
32 device_settings_service_
->AddObserver(this);
35 DeviceCloudPolicyStoreChromeOS::~DeviceCloudPolicyStoreChromeOS() {
36 device_settings_service_
->RemoveObserver(this);
39 void DeviceCloudPolicyStoreChromeOS::Store(
40 const em::PolicyFetchResponse
& policy
) {
41 // Cancel all pending requests.
42 weak_factory_
.InvalidateWeakPtrs();
44 scoped_refptr
<ownership::PublicKey
> public_key(
45 device_settings_service_
->GetPublicKey());
46 if (!install_attributes_
->IsEnterpriseDevice() ||
47 !device_settings_service_
->policy_data() || !public_key
.get() ||
48 !public_key
->is_loaded()) {
49 status_
= STATUS_BAD_STATE
;
54 scoped_ptr
<DeviceCloudPolicyValidator
> validator(CreateValidator(policy
));
55 validator
->ValidateSignature(public_key
->as_string(),
56 GetPolicyVerificationKey(),
57 install_attributes_
->GetDomain(),
59 validator
->ValidateAgainstCurrentPolicy(
60 device_settings_service_
->policy_data(),
61 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED
,
62 CloudPolicyValidatorBase::DM_TOKEN_REQUIRED
);
63 validator
.release()->StartValidation(
64 base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated
,
65 weak_factory_
.GetWeakPtr()));
68 void DeviceCloudPolicyStoreChromeOS::Load() {
69 device_settings_service_
->Load();
72 void DeviceCloudPolicyStoreChromeOS::InstallInitialPolicy(
73 const em::PolicyFetchResponse
& policy
) {
74 // Cancel all pending requests.
75 weak_factory_
.InvalidateWeakPtrs();
77 if (!install_attributes_
->IsEnterpriseDevice()) {
78 status_
= STATUS_BAD_STATE
;
83 scoped_ptr
<DeviceCloudPolicyValidator
> validator(CreateValidator(policy
));
84 validator
->ValidateInitialKey(GetPolicyVerificationKey(),
85 install_attributes_
->GetDomain());
86 validator
.release()->StartValidation(
87 base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated
,
88 weak_factory_
.GetWeakPtr()));
91 void DeviceCloudPolicyStoreChromeOS::OwnershipStatusChanged() {
95 void DeviceCloudPolicyStoreChromeOS::DeviceSettingsUpdated() {
96 if (!weak_factory_
.HasWeakPtrs())
100 void DeviceCloudPolicyStoreChromeOS::OnDeviceSettingsServiceShutdown() {
101 device_settings_service_
= nullptr;
104 scoped_ptr
<DeviceCloudPolicyValidator
>
105 DeviceCloudPolicyStoreChromeOS::CreateValidator(
106 const em::PolicyFetchResponse
& policy
) {
107 scoped_ptr
<DeviceCloudPolicyValidator
> validator(
108 DeviceCloudPolicyValidator::Create(
109 scoped_ptr
<em::PolicyFetchResponse
>(
110 new em::PolicyFetchResponse(policy
)),
111 background_task_runner_
));
112 validator
->ValidateDomain(install_attributes_
->GetDomain());
113 validator
->ValidatePolicyType(dm_protocol::kChromeDevicePolicyType
);
114 validator
->ValidatePayload();
115 return validator
.Pass();
118 void DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated(
119 DeviceCloudPolicyValidator
* validator
) {
120 if (!validator
->success()) {
121 status_
= STATUS_VALIDATION_ERROR
;
122 validation_status_
= validator
->status();
127 device_settings_service_
->Store(
128 validator
->policy().Pass(),
129 base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyStored
,
130 weak_factory_
.GetWeakPtr()));
133 void DeviceCloudPolicyStoreChromeOS::OnPolicyStored() {
137 void DeviceCloudPolicyStoreChromeOS::UpdateFromService() {
138 const em::PolicyData
* policy_data
= device_settings_service_
->policy_data();
139 const chromeos::DeviceSettingsService::Status status
=
140 device_settings_service_
->status();
142 const bool is_enterprise_managed
= install_attributes_
->IsEnterpriseDevice();
143 bool is_or_was_consumer_managed
= false;
145 const ManagementMode management_mode
= GetManagementMode(*policy_data
);
146 if (management_mode
== MANAGEMENT_MODE_CONSUMER_MANAGED
||
147 (management_mode
== MANAGEMENT_MODE_LOCAL_OWNER
&&
149 GetManagementMode(*policy()) == MANAGEMENT_MODE_CONSUMER_MANAGED
)) {
150 // The device is consumer-managed, or was consumer-managed and is now
152 is_or_was_consumer_managed
= true;
156 if (!is_enterprise_managed
&& !is_or_was_consumer_managed
) {
157 status_
= STATUS_BAD_STATE
;
162 // For enterprise devices, once per session, validate internal consistency of
163 // enrollment state (DM token must be present on enrolled devices) and in case
164 // of failure set flag to indicate that recovery is required.
165 if (is_enterprise_managed
) {
167 case chromeos::DeviceSettingsService::STORE_SUCCESS
:
168 case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE
:
169 case chromeos::DeviceSettingsService::STORE_NO_POLICY
:
170 case chromeos::DeviceSettingsService::STORE_INVALID_POLICY
:
171 case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR
: {
172 if (!enrollment_validation_done_
) {
173 enrollment_validation_done_
= true;
174 const bool has_dm_token
=
175 status
== chromeos::DeviceSettingsService::STORE_SUCCESS
&&
177 policy_data
->has_request_token();
179 // At the time LoginDisplayHostImpl decides whether enrollment flow is
180 // to be started, policy hasn't been read yet. To work around this,
181 // once the need for recovery is detected upon policy load, a flag is
182 // stored in prefs which is accessed by LoginDisplayHostImpl early
183 // during (next) boot.
185 LOG(ERROR
) << "Device policy read on enrolled device yields "
186 << "no DM token! Status: " << status
<< ".";
187 chromeos::StartupUtils::MarkEnrollmentRecoveryRequired();
189 UMA_HISTOGRAM_BOOLEAN("Enterprise.EnrolledPolicyHasDMToken",
194 case chromeos::DeviceSettingsService::STORE_POLICY_ERROR
:
195 case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED
:
196 case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR
:
197 // Do nothing for write errors or transient read errors.
203 case chromeos::DeviceSettingsService::STORE_SUCCESS
: {
205 policy_
.reset(new em::PolicyData());
207 policy_
->MergeFrom(*policy_data
);
209 PolicyMap new_policy_map
;
210 if (is_enterprise_managed
&& is_managed()) {
211 DecodeDevicePolicy(*device_settings_service_
->device_settings(),
214 policy_map_
.Swap(&new_policy_map
);
219 case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE
:
220 status_
= STATUS_BAD_STATE
;
222 case chromeos::DeviceSettingsService::STORE_POLICY_ERROR
:
223 case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED
:
224 status_
= STATUS_STORE_ERROR
;
226 case chromeos::DeviceSettingsService::STORE_NO_POLICY
:
227 case chromeos::DeviceSettingsService::STORE_INVALID_POLICY
:
228 case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR
:
229 case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR
:
230 status_
= STATUS_LOAD_ERROR
;
237 } // namespace policy