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/common/chrome_content_client.h"
24 #include "chrome/common/pref_names.h"
25 #include "chromeos/chromeos_constants.h"
26 #include "chromeos/chromeos_switches.h"
27 #include "chromeos/system/statistics_provider.h"
28 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
29 #include "components/policy/core/common/cloud/cloud_policy_store.h"
30 #include "components/policy/core/common/cloud/device_management_service.h"
31 #include "components/policy/core/common/cloud/system_policy_request_context.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "crypto/sha2.h"
34 #include "policy/proto/device_management_backend.pb.h"
37 using content::BrowserThread;
39 namespace em = enterprise_management;
45 // Overridden no requisition value.
46 const char kNoRequisition[] = "none";
48 // Overridden no requisition value.
49 const char kRemoraRequisition[] = "remora";
51 // These are the machine serial number keys that we check in order until we
52 // find a non-empty serial number. The VPD spec says the serial number should be
53 // in the "serial_number" key for v2+ VPDs. However, legacy devices used a
54 // different key to report their serial number, which we fall back to if
55 // "serial_number" is not present.
57 // Product_S/N is still special-cased due to inconsistencies with serial
58 // numbers on Lumpy devices: On these devices, serial_number is identical to
59 // Product_S/N with an appended checksum. Unfortunately, the sticker on the
60 // packaging doesn't include that checksum either (the sticker on the device
61 // does though!). The former sticker is the source of the serial number used by
62 // device management service, so we prefer Product_S/N over serial number to
65 // TODO(mnissler): Move serial_number back to the top once the server side uses
66 // the correct serial number.
67 const char* kMachineInfoSerialNumberKeys[] = {
68 "Product_S/N", // Lumpy/Alex devices
69 "serial_number", // VPD v2+ devices
70 "Product_SN", // Mario
71 "sn", // old ZGB devices (more recent ones use serial_number)
74 // Fetches a machine statistic value from StatisticsProvider, returns an empty
76 std::string GetMachineStatistic(const std::string& key) {
78 chromeos::system::StatisticsProvider* provider =
79 chromeos::system::StatisticsProvider::GetInstance();
80 if (!provider->GetMachineStatistic(key, &value))
86 // Gets a machine flag from StatisticsProvider, returns the given
87 // |default_value| if not present.
88 bool GetMachineFlag(const std::string& key, bool default_value) {
89 bool value = default_value;
90 chromeos::system::StatisticsProvider* provider =
91 chromeos::system::StatisticsProvider::GetInstance();
92 if (!provider->GetMachineFlag(key, &value))
101 DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyTimeQuantumPower;
104 DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyFutureQuanta;
106 DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
107 scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
108 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
109 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
110 EnterpriseInstallAttributes* install_attributes)
111 : CloudPolicyManager(
112 PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
116 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
117 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)),
118 device_store_(store.Pass()),
119 background_task_runner_(background_task_runner),
120 install_attributes_(install_attributes),
121 device_management_service_(NULL),
122 local_state_(NULL) {}
124 DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
126 void DeviceCloudPolicyManagerChromeOS::Connect(
127 PrefService* local_state,
128 DeviceManagementService* device_management_service,
129 scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) {
130 CHECK(!device_management_service_);
131 CHECK(device_management_service);
134 local_state_ = local_state;
135 device_management_service_ = device_management_service;
136 device_status_provider_ = device_status_provider.Pass();
138 InitalizeRequisition();
142 void DeviceCloudPolicyManagerChromeOS::StartEnrollment(
143 const std::string& auth_token,
144 bool is_auto_enrollment,
145 const AllowedDeviceModes& allowed_device_modes,
146 const EnrollmentCallback& callback) {
147 CHECK(device_management_service_);
148 core()->Disconnect();
150 enrollment_handler_.reset(
151 new EnrollmentHandlerChromeOS(
152 device_store_.get(), install_attributes_, CreateClient(),
153 background_task_runner_, auth_token,
154 install_attributes_->GetDeviceId(), is_auto_enrollment,
155 GetDeviceRequisition(), GetCurrentDeviceStateKey(),
156 allowed_device_modes,
157 base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
158 base::Unretained(this), callback)));
159 enrollment_handler_->StartEnrollment();
162 void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() {
163 if (enrollment_handler_.get()) {
164 enrollment_handler_.reset();
169 std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const {
170 std::string requisition;
171 const PrefService::Preference* pref = local_state_->FindPreference(
172 prefs::kDeviceEnrollmentRequisition);
173 if (!pref->IsDefaultValue())
174 pref->GetValue()->GetAsString(&requisition);
176 if (requisition == kNoRequisition)
182 void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
183 const std::string& requisition) {
185 if (requisition.empty()) {
186 local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
187 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
188 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
190 local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
191 if (requisition == kNoRequisition) {
192 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
193 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
195 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
196 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
202 bool DeviceCloudPolicyManagerChromeOS::ShouldAutoStartEnrollment() const {
203 std::string restore_mode = GetRestoreMode();
204 if (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested ||
205 restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced) {
209 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart))
210 return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart);
212 return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false);
215 bool DeviceCloudPolicyManagerChromeOS::CanExitEnrollment() const {
216 if (GetRestoreMode() == kDeviceStateRestoreModeReEnrollmentEnforced)
219 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit))
220 return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit);
222 return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
227 DeviceCloudPolicyManagerChromeOS::GetForcedEnrollmentDomain() const {
228 const base::DictionaryValue* device_state_dict =
229 local_state_->GetDictionary(prefs::kServerBackedDeviceState);
230 std::string management_domain;
231 device_state_dict->GetString(kDeviceStateManagementDomain,
233 return management_domain;
236 void DeviceCloudPolicyManagerChromeOS::Shutdown() {
237 CloudPolicyManager::Shutdown();
238 device_status_provider_.reset();
241 void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
242 CloudPolicyManager::OnStoreLoaded(store);
244 if (!enrollment_handler_.get())
249 void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
250 PrefRegistrySimple* registry) {
251 registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
253 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
254 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
255 registry->RegisterDictionaryPref(prefs::kServerBackedDeviceState);
259 std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
260 std::string machine_id;
261 chromeos::system::StatisticsProvider* provider =
262 chromeos::system::StatisticsProvider::GetInstance();
263 for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
264 if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
266 !machine_id.empty()) {
271 if (machine_id.empty())
272 LOG(WARNING) << "Failed to get machine id.";
278 std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
279 return GetMachineStatistic(chromeos::system::kHardwareClassKey);
283 std::string DeviceCloudPolicyManagerChromeOS::GetCurrentDeviceStateKey() {
284 std::vector<std::string> state_keys;
285 if (GetDeviceStateKeys(base::Time::Now(), &state_keys) &&
286 !state_keys.empty()) {
287 // The key for the current time is always the first one.
288 return state_keys[0];
291 return std::string();
294 scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
295 scoped_refptr<net::URLRequestContextGetter> request_context =
296 new SystemPolicyRequestContext(
297 g_browser_process->system_request_context(), GetUserAgent());
299 scoped_ptr<CloudPolicyClient> client(
300 new CloudPolicyClient(GetMachineID(), GetMachineModel(),
301 kPolicyVerificationKeyHash,
302 USER_AFFILIATION_NONE,
303 device_status_provider_.get(),
304 device_management_service_,
307 // Set state keys to upload immediately after creation so the first policy
308 // fetch submits them to the server.
309 if (chromeos::AutoEnrollmentController::GetMode() ==
310 chromeos::AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT) {
311 std::vector<std::string> state_keys;
312 if (GetDeviceStateKeys(base::Time::Now(), &state_keys))
313 client->SetStateKeysToUpload(state_keys);
316 return client.Pass();
319 void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted(
320 const EnrollmentCallback& callback,
321 EnrollmentStatus status) {
322 if (status.status() == EnrollmentStatus::STATUS_SUCCESS)
323 StartConnection(enrollment_handler_->ReleaseClient());
327 enrollment_handler_.reset();
328 if (!callback.is_null())
329 callback.Run(status);
332 void DeviceCloudPolicyManagerChromeOS::StartIfManaged() {
333 if (device_management_service_ &&
335 store()->is_initialized() &&
336 store()->has_policy() &&
338 StartConnection(CreateClient());
342 void DeviceCloudPolicyManagerChromeOS::StartConnection(
343 scoped_ptr<CloudPolicyClient> client_to_connect) {
344 core()->Connect(client_to_connect.Pass());
345 core()->StartRefreshScheduler();
346 core()->TrackRefreshDelayPref(local_state_,
347 prefs::kDevicePolicyRefreshRate);
348 attestation_policy_observer_.reset(
349 new chromeos::attestation::AttestationPolicyObserver(client()));
352 void DeviceCloudPolicyManagerChromeOS::InitalizeRequisition() {
353 // OEM statistics are only loaded when OOBE is not completed.
354 if (chromeos::StartupUtils::IsOobeCompleted())
357 const PrefService::Preference* pref = local_state_->FindPreference(
358 prefs::kDeviceEnrollmentRequisition);
359 if (pref->IsDefaultValue()) {
360 std::string requisition =
361 GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
363 if (!requisition.empty()) {
364 local_state_->SetString(prefs::kDeviceEnrollmentRequisition,
366 if (requisition == kRemoraRequisition) {
367 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
368 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
370 local_state_->SetBoolean(
371 prefs::kDeviceEnrollmentAutoStart,
372 GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey,
374 local_state_->SetBoolean(
375 prefs::kDeviceEnrollmentCanExit,
376 GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
383 std::string DeviceCloudPolicyManagerChromeOS::GetRestoreMode() const {
384 const base::DictionaryValue* device_state_dict =
385 local_state_->GetDictionary(prefs::kServerBackedDeviceState);
386 std::string restore_mode;
387 device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode);
392 bool DeviceCloudPolicyManagerChromeOS::GetDeviceStateKeys(
393 const base::Time& timestamp,
394 std::vector<std::string>* state_keys) {
397 std::string disk_serial_number =
398 GetMachineStatistic(chromeos::system::kDiskSerialNumber);
399 if (disk_serial_number.empty()) {
400 LOG(ERROR) << "Missing disk serial number";
404 std::string machine_id = GetMachineID();
405 if (machine_id.empty())
408 // Tolerate missing group code keys, some old devices may not have it.
409 std::string group_code_key =
410 GetMachineStatistic(chromeos::system::kOffersGroupCodeKey);
412 // Get the current time in quantized form.
413 int64 quantum_size = GG_INT64_C(1) << kDeviceStateKeyTimeQuantumPower;
414 int64 quantized_time =
415 (timestamp - base::Time::UnixEpoch()).InSeconds() & ~(quantum_size - 1);
416 for (int i = 0; i < kDeviceStateKeyFutureQuanta; ++i) {
417 state_keys->push_back(crypto::SHA256HashString(
418 crypto::SHA256HashString(group_code_key) +
419 crypto::SHA256HashString(disk_serial_number) +
420 crypto::SHA256HashString(machine_id) +
421 crypto::SHA256HashString(base::Int64ToString(quantized_time))));
422 quantized_time += quantum_size;
428 } // namespace policy