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/prefs/pref_registry_simple.h"
11 #include "base/prefs/pref_service.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/attestation/attestation_policy_observer.h"
14 #include "chrome/browser/chromeos/login/startup_utils.h"
15 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
16 #include "chrome/browser/chromeos/policy/enrollment_handler_chromeos.h"
17 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
18 #include "chrome/browser/chromeos/policy/server_backed_device_state.h"
19 #include "chrome/common/chrome_content_client.h"
20 #include "chrome/common/pref_names.h"
21 #include "chromeos/chromeos_constants.h"
22 #include "chromeos/chromeos_switches.h"
23 #include "chromeos/system/statistics_provider.h"
24 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
25 #include "components/policy/core/common/cloud/cloud_policy_store.h"
26 #include "components/policy/core/common/cloud/device_management_service.h"
27 #include "components/policy/core/common/cloud/system_policy_request_context.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "crypto/sha2.h"
30 #include "policy/proto/device_management_backend.pb.h"
33 using content::BrowserThread;
35 namespace em = enterprise_management;
41 // Overridden no requisition value.
42 const char kNoRequisition[] = "none";
44 // Overridden no requisition value.
45 const char kRemoraRequisition[] = "remora";
47 // MachineInfo key names.
48 const char kMachineInfoSystemHwqual[] = "hardware_class";
50 // These are the machine serial number keys that we check in order until we
51 // find a non-empty serial number. The VPD spec says the serial number should be
52 // in the "serial_number" key for v2+ VPDs. However, legacy devices used a
53 // different keys to report their serial number, which we fall back to if
54 // "serial_number" is not present.
56 // Product_S/N is still special-cased due to inconsistencies with serial
57 // numbers on Lumpy devices: On these devices, serial_number is identical to
58 // Product_S/N with an appended checksum. Unfortunately, the sticker on the
59 // packaging doesn't include that checksum either (the sticker on the device
60 // does though!). The former sticker is the source of the serial number used by
61 // device management service, so we prefer Product_S/N over serial number to
64 // TODO(mnissler): Move serial_number back to the top once the server side uses
65 // the correct serial number.
66 const char* kMachineInfoSerialNumberKeys[] = {
67 "Product_S/N", // Lumpy/Alex devices
68 "serial_number", // VPD v2+ devices
69 "Product_SN", // Mario
70 "sn", // old ZGB devices (more recent ones use serial_number)
73 // Fetches a machine statistic value from StatisticsProvider, returns an empty
75 std::string GetMachineStatistic(const std::string& key) {
77 chromeos::system::StatisticsProvider* provider =
78 chromeos::system::StatisticsProvider::GetInstance();
79 if (!provider->GetMachineStatistic(key, &value))
85 // Gets a machine flag from StatisticsProvider, returns the given
86 // |default_value| if not present.
87 bool GetMachineFlag(const std::string& key, bool default_value) {
88 bool value = default_value;
89 chromeos::system::StatisticsProvider* provider =
90 chromeos::system::StatisticsProvider::GetInstance();
91 if (!provider->GetMachineFlag(key, &value))
99 DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
100 scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
101 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
102 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
103 EnterpriseInstallAttributes* install_attributes)
104 : CloudPolicyManager(
105 PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
109 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
110 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)),
111 device_store_(store.Pass()),
112 background_task_runner_(background_task_runner),
113 install_attributes_(install_attributes),
114 device_management_service_(NULL),
115 local_state_(NULL) {}
117 DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
119 void DeviceCloudPolicyManagerChromeOS::Connect(
120 PrefService* local_state,
121 DeviceManagementService* device_management_service,
122 scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) {
123 CHECK(!device_management_service_);
124 CHECK(device_management_service);
127 local_state_ = local_state;
128 device_management_service_ = device_management_service;
129 device_status_provider_ = device_status_provider.Pass();
131 InitalizeRequisition();
135 void DeviceCloudPolicyManagerChromeOS::StartEnrollment(
136 const std::string& auth_token,
137 bool is_auto_enrollment,
138 const AllowedDeviceModes& allowed_device_modes,
139 const EnrollmentCallback& callback) {
140 CHECK(device_management_service_);
141 core()->Disconnect();
143 enrollment_handler_.reset(
144 new EnrollmentHandlerChromeOS(
145 device_store_.get(), install_attributes_, CreateClient(),
146 background_task_runner_, auth_token,
147 install_attributes_->GetDeviceId(), is_auto_enrollment,
148 GetDeviceRequisition(), GetDeviceStateKey(), allowed_device_modes,
149 base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
150 base::Unretained(this), callback)));
151 enrollment_handler_->StartEnrollment();
154 void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() {
155 if (enrollment_handler_.get()) {
156 enrollment_handler_.reset();
161 std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const {
162 std::string requisition;
163 const PrefService::Preference* pref = local_state_->FindPreference(
164 prefs::kDeviceEnrollmentRequisition);
165 if (!pref->IsDefaultValue())
166 pref->GetValue()->GetAsString(&requisition);
168 if (requisition == kNoRequisition)
174 void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
175 const std::string& requisition) {
177 if (requisition.empty()) {
178 local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
179 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
180 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
182 local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
183 if (requisition == kNoRequisition) {
184 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
185 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
187 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
188 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
194 bool DeviceCloudPolicyManagerChromeOS::ShouldAutoStartEnrollment() const {
195 std::string restore_mode = GetRestoreMode();
196 if (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested ||
197 restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced) {
201 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart))
202 return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart);
204 return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false);
207 bool DeviceCloudPolicyManagerChromeOS::CanExitEnrollment() const {
208 if (GetRestoreMode() == kDeviceStateRestoreModeReEnrollmentEnforced)
211 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit))
212 return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit);
214 return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
219 DeviceCloudPolicyManagerChromeOS::GetForcedEnrollmentDomain() const {
220 const base::DictionaryValue* device_state_dict =
221 local_state_->GetDictionary(prefs::kServerBackedDeviceState);
222 std::string management_domain;
223 device_state_dict->GetString(kDeviceStateManagementDomain,
225 return management_domain;
228 void DeviceCloudPolicyManagerChromeOS::Shutdown() {
229 CloudPolicyManager::Shutdown();
230 device_status_provider_.reset();
233 void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
234 CloudPolicyManager::OnStoreLoaded(store);
236 if (!enrollment_handler_.get())
241 void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
242 PrefRegistrySimple* registry) {
243 registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
245 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
246 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
247 registry->RegisterDictionaryPref(prefs::kServerBackedDeviceState);
251 std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
252 std::string machine_id;
253 chromeos::system::StatisticsProvider* provider =
254 chromeos::system::StatisticsProvider::GetInstance();
255 for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
256 if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
258 !machine_id.empty()) {
263 if (machine_id.empty())
264 LOG(WARNING) << "Failed to get machine id.";
270 std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
271 return GetMachineStatistic(kMachineInfoSystemHwqual);
275 std::string DeviceCloudPolicyManagerChromeOS::GetDeviceStateKey() {
276 // TODO(mnissler): Figure out which stable device identifiers should be used
277 // here and update the code. See http://crbug.com/352599.
278 std::string group_code_key =
279 GetMachineStatistic(chromeos::system::kOffersGroupCodeKey);
280 return crypto::SHA256HashString(group_code_key + GetMachineID());
283 scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
284 scoped_refptr<net::URLRequestContextGetter> request_context =
285 new SystemPolicyRequestContext(
286 g_browser_process->system_request_context(), GetUserAgent());
288 scoped_ptr<CloudPolicyClient> client(
289 new CloudPolicyClient(GetMachineID(), GetMachineModel(),
290 kPolicyVerificationKeyHash,
291 USER_AFFILIATION_NONE,
292 device_status_provider_.get(),
293 device_management_service_,
296 // Set state keys to upload immediately after creation so the first policy
297 // fetch submits them to the server.
298 if (CommandLine::ForCurrentProcess()->HasSwitch(
299 chromeos::switches::kEnterpriseEnableForcedReEnrollment)) {
300 std::vector<std::string> state_keys;
301 state_keys.push_back(GetDeviceStateKey());
302 client->SetStateKeysToUpload(state_keys);
305 return client.Pass();
308 void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted(
309 const EnrollmentCallback& callback,
310 EnrollmentStatus status) {
311 if (status.status() == EnrollmentStatus::STATUS_SUCCESS)
312 StartConnection(enrollment_handler_->ReleaseClient());
316 enrollment_handler_.reset();
317 if (!callback.is_null())
318 callback.Run(status);
321 void DeviceCloudPolicyManagerChromeOS::StartIfManaged() {
322 if (device_management_service_ &&
324 store()->is_initialized() &&
325 store()->has_policy() &&
327 StartConnection(CreateClient());
331 void DeviceCloudPolicyManagerChromeOS::StartConnection(
332 scoped_ptr<CloudPolicyClient> client_to_connect) {
333 core()->Connect(client_to_connect.Pass());
334 core()->StartRefreshScheduler();
335 core()->TrackRefreshDelayPref(local_state_,
336 prefs::kDevicePolicyRefreshRate);
337 attestation_policy_observer_.reset(
338 new chromeos::attestation::AttestationPolicyObserver(client()));
341 void DeviceCloudPolicyManagerChromeOS::InitalizeRequisition() {
342 // OEM statistics are only loaded when OOBE is not completed.
343 if (chromeos::StartupUtils::IsOobeCompleted())
346 const PrefService::Preference* pref = local_state_->FindPreference(
347 prefs::kDeviceEnrollmentRequisition);
348 if (pref->IsDefaultValue()) {
349 std::string requisition =
350 GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
352 if (!requisition.empty()) {
353 local_state_->SetString(prefs::kDeviceEnrollmentRequisition,
355 if (requisition == kRemoraRequisition) {
356 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
357 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
359 local_state_->SetBoolean(
360 prefs::kDeviceEnrollmentAutoStart,
361 GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey,
363 local_state_->SetBoolean(
364 prefs::kDeviceEnrollmentCanExit,
365 GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
372 std::string DeviceCloudPolicyManagerChromeOS::GetRestoreMode() const {
373 const base::DictionaryValue* device_state_dict =
374 local_state_->GetDictionary(prefs::kServerBackedDeviceState);
375 std::string restore_mode;
376 device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode);
380 } // namespace policy