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_manager_chromeos.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/port.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chromeos/attestation/attestation_policy_observer.h"
17 #include "chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h"
18 #include "chrome/browser/chromeos/login/startup_utils.h"
19 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
20 #include "chrome/browser/chromeos/policy/enrollment_handler_chromeos.h"
21 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
22 #include "chrome/browser/chromeos/policy/server_backed_device_state.h"
23 #include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.h"
24 #include "chrome/common/chrome_content_client.h"
25 #include "chrome/common/pref_names.h"
26 #include "chromeos/chromeos_constants.h"
27 #include "chromeos/chromeos_switches.h"
28 #include "chromeos/system/statistics_provider.h"
29 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
30 #include "components/policy/core/common/cloud/cloud_policy_store.h"
31 #include "components/policy/core/common/cloud/device_management_service.h"
32 #include "components/policy/core/common/cloud/system_policy_request_context.h"
33 #include "content/public/browser/browser_thread.h"
34 #include "crypto/sha2.h"
35 #include "policy/proto/device_management_backend.pb.h"
38 using content::BrowserThread;
40 namespace em = enterprise_management;
46 // Overridden no requisition value.
47 const char kNoRequisition[] = "none";
49 // Overridden no requisition value.
50 const char kRemoraRequisition[] = "remora";
52 // These are the machine serial number keys that we check in order until we
53 // find a non-empty serial number. The VPD spec says the serial number should be
54 // in the "serial_number" key for v2+ VPDs. However, legacy devices used a
55 // different key to report their serial number, which we fall back to if
56 // "serial_number" is not present.
58 // Product_S/N is still special-cased due to inconsistencies with serial
59 // numbers on Lumpy devices: On these devices, serial_number is identical to
60 // Product_S/N with an appended checksum. Unfortunately, the sticker on the
61 // packaging doesn't include that checksum either (the sticker on the device
62 // does though!). The former sticker is the source of the serial number used by
63 // device management service, so we prefer Product_S/N over serial number to
66 // TODO(mnissler): Move serial_number back to the top once the server side uses
67 // the correct serial number.
68 const char* kMachineInfoSerialNumberKeys[] = {
69 "Product_S/N", // Lumpy/Alex devices
70 "serial_number", // VPD v2+ devices
71 "Product_SN", // Mario
72 "sn", // old ZGB devices (more recent ones use serial_number)
75 // Fetches a machine statistic value from StatisticsProvider, returns an empty
77 std::string GetMachineStatistic(const std::string& key) {
79 chromeos::system::StatisticsProvider* provider =
80 chromeos::system::StatisticsProvider::GetInstance();
81 if (!provider->GetMachineStatistic(key, &value))
87 // Gets a machine flag from StatisticsProvider, returns the given
88 // |default_value| if not present.
89 bool GetMachineFlag(const std::string& key, bool default_value) {
90 bool value = default_value;
91 chromeos::system::StatisticsProvider* provider =
92 chromeos::system::StatisticsProvider::GetInstance();
93 if (!provider->GetMachineFlag(key, &value))
99 // Checks whether forced re-enrollment is enabled.
100 bool ForcedReEnrollmentEnabled() {
101 return chromeos::AutoEnrollmentController::GetMode() ==
102 chromeos::AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT;
107 DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
108 scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
109 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
110 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
111 EnterpriseInstallAttributes* install_attributes,
112 ServerBackedStateKeysBroker* state_keys_broker)
113 : CloudPolicyManager(
114 PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
118 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
119 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)),
120 device_store_(store.Pass()),
121 background_task_runner_(background_task_runner),
122 install_attributes_(install_attributes),
123 state_keys_broker_(state_keys_broker),
124 device_management_service_(NULL),
128 DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
130 void DeviceCloudPolicyManagerChromeOS::Connect(
131 PrefService* local_state,
132 DeviceManagementService* device_management_service,
133 scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) {
134 CHECK(!device_management_service_);
135 CHECK(device_management_service);
138 local_state_ = local_state;
139 device_management_service_ = device_management_service;
140 device_status_provider_ = device_status_provider.Pass();
142 state_keys_update_subscription_ = state_keys_broker_->RegisterUpdateCallback(
143 base::Bind(&DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated,
144 base::Unretained(this)));
146 InitializeRequisition();
150 void DeviceCloudPolicyManagerChromeOS::StartEnrollment(
151 const std::string& auth_token,
152 bool is_auto_enrollment,
153 const AllowedDeviceModes& allowed_device_modes,
154 const EnrollmentCallback& callback) {
155 CHECK(device_management_service_);
156 CHECK(!enrollment_handler_);
157 core()->Disconnect();
159 enrollment_handler_.reset(new EnrollmentHandlerChromeOS(
164 background_task_runner_,
166 install_attributes_->GetDeviceId(),
168 GetDeviceRequisition(),
169 allowed_device_modes,
170 base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
171 base::Unretained(this),
173 enrollment_handler_->StartEnrollment();
176 void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() {
177 if (enrollment_handler_) {
178 enrollment_handler_.reset();
183 std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const {
184 std::string requisition;
185 const PrefService::Preference* pref = local_state_->FindPreference(
186 prefs::kDeviceEnrollmentRequisition);
187 if (!pref->IsDefaultValue())
188 pref->GetValue()->GetAsString(&requisition);
190 if (requisition == kNoRequisition)
196 void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
197 const std::string& requisition) {
199 if (requisition.empty()) {
200 local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
201 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
202 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
204 local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
205 if (requisition == kNoRequisition) {
206 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
207 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
209 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
210 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
216 bool DeviceCloudPolicyManagerChromeOS::ShouldAutoStartEnrollment() const {
217 std::string restore_mode = GetRestoreMode();
218 if (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested ||
219 restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced) {
223 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart))
224 return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart);
226 return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false);
229 bool DeviceCloudPolicyManagerChromeOS::CanExitEnrollment() const {
230 if (GetRestoreMode() == kDeviceStateRestoreModeReEnrollmentEnforced)
233 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit))
234 return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit);
236 return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
241 DeviceCloudPolicyManagerChromeOS::GetForcedEnrollmentDomain() const {
242 const base::DictionaryValue* device_state_dict =
243 local_state_->GetDictionary(prefs::kServerBackedDeviceState);
244 std::string management_domain;
245 device_state_dict->GetString(kDeviceStateManagementDomain,
247 return management_domain;
250 void DeviceCloudPolicyManagerChromeOS::Shutdown() {
251 state_keys_update_subscription_.reset();
252 CloudPolicyManager::Shutdown();
253 device_status_provider_.reset();
256 void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
257 CloudPolicyManager::OnStoreLoaded(store);
262 void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
263 PrefRegistrySimple* registry) {
264 registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
266 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
267 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
268 registry->RegisterDictionaryPref(prefs::kServerBackedDeviceState);
272 std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
273 std::string machine_id;
274 chromeos::system::StatisticsProvider* provider =
275 chromeos::system::StatisticsProvider::GetInstance();
276 for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
277 if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
279 !machine_id.empty()) {
284 if (machine_id.empty())
285 LOG(WARNING) << "Failed to get machine id.";
291 std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
292 return GetMachineStatistic(chromeos::system::kHardwareClassKey);
295 scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
296 scoped_refptr<net::URLRequestContextGetter> request_context =
297 new SystemPolicyRequestContext(
298 g_browser_process->system_request_context(), GetUserAgent());
300 scoped_ptr<CloudPolicyClient> client(
301 new CloudPolicyClient(GetMachineID(), GetMachineModel(),
302 kPolicyVerificationKeyHash,
303 USER_AFFILIATION_NONE,
304 device_status_provider_.get(),
305 device_management_service_,
308 return client.Pass();
311 void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted(
312 const EnrollmentCallback& callback,
313 EnrollmentStatus status) {
314 if (status.status() == EnrollmentStatus::STATUS_SUCCESS)
315 StartConnection(enrollment_handler_->ReleaseClient());
319 enrollment_handler_.reset();
320 if (!callback.is_null())
321 callback.Run(status);
324 void DeviceCloudPolicyManagerChromeOS::StartIfManaged() {
325 if (device_management_service_ &&
327 store()->is_initialized() &&
328 store()->has_policy() &&
329 !state_keys_broker_->pending() &&
330 !enrollment_handler_ &&
332 StartConnection(CreateClient());
336 void DeviceCloudPolicyManagerChromeOS::StartConnection(
337 scoped_ptr<CloudPolicyClient> client_to_connect) {
338 // Set state keys here so the first policy fetch submits them to the server.
339 if (ForcedReEnrollmentEnabled())
340 client_to_connect->SetStateKeysToUpload(state_keys_broker_->state_keys());
342 core()->Connect(client_to_connect.Pass());
343 core()->StartRefreshScheduler();
344 core()->TrackRefreshDelayPref(local_state_,
345 prefs::kDevicePolicyRefreshRate);
346 attestation_policy_observer_.reset(
347 new chromeos::attestation::AttestationPolicyObserver(client()));
350 void DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated() {
352 if (ForcedReEnrollmentEnabled())
353 client()->SetStateKeysToUpload(state_keys_broker_->state_keys());
359 void DeviceCloudPolicyManagerChromeOS::InitializeRequisition() {
360 // OEM statistics are only loaded when OOBE is not completed.
361 if (chromeos::StartupUtils::IsOobeCompleted())
364 const PrefService::Preference* pref = local_state_->FindPreference(
365 prefs::kDeviceEnrollmentRequisition);
366 if (pref->IsDefaultValue()) {
367 std::string requisition =
368 GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
370 if (!requisition.empty()) {
371 local_state_->SetString(prefs::kDeviceEnrollmentRequisition,
373 if (requisition == kRemoraRequisition) {
374 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
375 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
377 local_state_->SetBoolean(
378 prefs::kDeviceEnrollmentAutoStart,
379 GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey,
381 local_state_->SetBoolean(
382 prefs::kDeviceEnrollmentCanExit,
383 GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
390 std::string DeviceCloudPolicyManagerChromeOS::GetRestoreMode() const {
391 const base::DictionaryValue* device_state_dict =
392 local_state_->GetDictionary(prefs::kServerBackedDeviceState);
393 std::string restore_mode;
394 device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode);
398 } // namespace policy