device_cloud_policy_manager_chromeos.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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_manager_chromeos.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/prefs/pref_registry_simple.h"
10#include "base/prefs/pref_service.h"
11#include "chrome/browser/browser_process.h"
12#include "chrome/browser/chromeos/attestation/attestation_policy_observer.h"
13#include "chrome/browser/chromeos/login/startup_utils.h"
14#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
15#include "chrome/browser/chromeos/policy/enrollment_handler_chromeos.h"
16#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
17#include "chrome/common/pref_names.h"
18#include "chromeos/chromeos_constants.h"
19#include "chromeos/system/statistics_provider.h"
20#include "components/policy/core/common/cloud/cloud_policy_constants.h"
21#include "components/policy/core/common/cloud/cloud_policy_store.h"
22#include "components/policy/core/common/cloud/device_management_service.h"
23#include "components/policy/core/common/cloud/system_policy_request_context.h"
24#include "content/public/browser/browser_thread.h"
25#include "content/public/common/content_client.h"
26#include "policy/proto/device_management_backend.pb.h"
27#include "url/gurl.h"
28
29using content::BrowserThread;
30
31namespace em = enterprise_management;
32
33namespace policy {
34
35namespace {
36
37// MachineInfo key names.
38const char kMachineInfoSystemHwqual[] = "hardware_class";
39
40// These are the machine serial number keys that we check in order until we
41// find a non-empty serial number. The VPD spec says the serial number should be
42// in the "serial_number" key for v2+ VPDs. However, legacy devices used a
43// different keys to report their serial number, which we fall back to if
44// "serial_number" is not present.
45//
46// Product_S/N is still special-cased due to inconsistencies with serial
47// numbers on Lumpy devices: On these devices, serial_number is identical to
48// Product_S/N with an appended checksum. Unfortunately, the sticker on the
49// packaging doesn't include that checksum either (the sticker on the device
50// does though!). The former sticker is the source of the serial number used by
51// device management service, so we prefer Product_S/N over serial number to
52// match the server.
53//
54// TODO(mnissler): Move serial_number back to the top once the server side uses
55// the correct serial number.
56const char* kMachineInfoSerialNumberKeys[] = {
57  "Product_S/N",    // Lumpy/Alex devices
58  "serial_number",  // VPD v2+ devices
59  "Product_SN",     // Mario
60  "sn",             // old ZGB devices (more recent ones use serial_number)
61};
62
63// Fetches a machine statistic value from StatisticsProvider, returns an empty
64// string on failure.
65std::string GetMachineStatistic(const std::string& key) {
66  std::string value;
67  chromeos::system::StatisticsProvider* provider =
68      chromeos::system::StatisticsProvider::GetInstance();
69  if (!provider->GetMachineStatistic(key, &value))
70    return std::string();
71
72  return value;
73}
74
75// Gets a machine flag from StatisticsProvider, returns the given
76// |default_value| if not present.
77bool GetMachineFlag(const std::string& key, bool default_value) {
78  bool value = default_value;
79  chromeos::system::StatisticsProvider* provider =
80      chromeos::system::StatisticsProvider::GetInstance();
81  if (!provider->GetMachineFlag(key, &value))
82    return default_value;
83
84  return value;
85}
86
87}  // namespace
88
89DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
90    scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
91    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
92    const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
93    EnterpriseInstallAttributes* install_attributes)
94    : CloudPolicyManager(
95          PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
96                             std::string()),
97          store.get(),
98          task_runner,
99          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
100          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)),
101      device_store_(store.Pass()),
102      background_task_runner_(background_task_runner),
103      install_attributes_(install_attributes),
104      device_management_service_(NULL),
105      local_state_(NULL) {}
106
107DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
108
109void DeviceCloudPolicyManagerChromeOS::Connect(
110    PrefService* local_state,
111    DeviceManagementService* device_management_service,
112    scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) {
113  CHECK(!device_management_service_);
114  CHECK(device_management_service);
115  CHECK(local_state);
116
117  local_state_ = local_state;
118  device_management_service_ = device_management_service;
119  device_status_provider_ = device_status_provider.Pass();
120
121  StartIfManaged();
122}
123
124void DeviceCloudPolicyManagerChromeOS::StartEnrollment(
125    const std::string& auth_token,
126    bool is_auto_enrollment,
127    const AllowedDeviceModes& allowed_device_modes,
128    const EnrollmentCallback& callback) {
129  CHECK(device_management_service_);
130  core()->Disconnect();
131
132  enrollment_handler_.reset(
133      new EnrollmentHandlerChromeOS(
134          device_store_.get(), install_attributes_, CreateClient(),
135          background_task_runner_, auth_token,
136          install_attributes_->GetDeviceId(), is_auto_enrollment,
137          GetDeviceRequisition(), allowed_device_modes,
138          base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
139                     base::Unretained(this), callback)));
140  enrollment_handler_->StartEnrollment();
141}
142
143void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() {
144  if (enrollment_handler_.get()) {
145    enrollment_handler_.reset();
146    StartIfManaged();
147  }
148}
149
150std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const {
151  std::string requisition;
152  const PrefService::Preference* pref = local_state_->FindPreference(
153      prefs::kDeviceEnrollmentRequisition);
154  if (pref->IsDefaultValue() && !chromeos::StartupUtils::IsOobeCompleted()) {
155    // OEM statistics are only loaded when OOBE is not completed.
156    requisition =
157        GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
158  } else {
159    pref->GetValue()->GetAsString(&requisition);
160  }
161
162  return requisition;
163}
164
165void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
166    const std::string& requisition) {
167  if (local_state_) {
168    if (requisition.empty()) {
169      local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
170      local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
171      local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
172    } else {
173      local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
174      local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
175      local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
176    }
177  }
178}
179
180bool DeviceCloudPolicyManagerChromeOS::ShouldAutoStartEnrollment() const {
181  if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart))
182    return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart);
183
184  return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false);
185}
186
187bool DeviceCloudPolicyManagerChromeOS::CanExitEnrollment() const {
188  if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit))
189    return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit);
190
191  return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
192                        true);
193}
194
195void DeviceCloudPolicyManagerChromeOS::Shutdown() {
196  CloudPolicyManager::Shutdown();
197  device_status_provider_.reset();
198}
199
200void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
201  CloudPolicyManager::OnStoreLoaded(store);
202
203  if (!enrollment_handler_.get())
204    StartIfManaged();
205}
206
207// static
208void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
209    PrefRegistrySimple* registry) {
210  registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
211                               std::string());
212  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
213  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
214}
215
216// static
217std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
218  std::string machine_id;
219  chromeos::system::StatisticsProvider* provider =
220      chromeos::system::StatisticsProvider::GetInstance();
221  for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
222    if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
223                                      &machine_id) &&
224        !machine_id.empty()) {
225      break;
226    }
227  }
228
229  if (machine_id.empty())
230    LOG(WARNING) << "Failed to get machine id.";
231
232  return machine_id;
233}
234
235// static
236std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
237  return GetMachineStatistic(kMachineInfoSystemHwqual);
238}
239
240std::string DeviceCloudPolicyManagerChromeOS::GetRobotAccountId() {
241  const enterprise_management::PolicyData* policy = device_store_->policy();
242  return policy ? policy->service_account_identity() : std::string();
243}
244
245scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
246  scoped_refptr<net::URLRequestContextGetter> request_context =
247      new SystemPolicyRequestContext(
248          g_browser_process->system_request_context(),
249          content::GetUserAgent(GURL(
250              device_management_service_->GetServerUrl())));
251
252  return make_scoped_ptr(
253      new CloudPolicyClient(GetMachineID(), GetMachineModel(),
254                            USER_AFFILIATION_NONE,
255                            device_status_provider_.get(),
256                            device_management_service_,
257                            request_context));
258}
259
260void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted(
261    const EnrollmentCallback& callback,
262    EnrollmentStatus status) {
263  if (status.status() == EnrollmentStatus::STATUS_SUCCESS) {
264    core()->Connect(enrollment_handler_->ReleaseClient());
265    core()->StartRefreshScheduler();
266    core()->TrackRefreshDelayPref(local_state_,
267                                  prefs::kDevicePolicyRefreshRate);
268    attestation_policy_observer_.reset(
269        new chromeos::attestation::AttestationPolicyObserver(client()));
270  } else {
271    StartIfManaged();
272  }
273
274  enrollment_handler_.reset();
275  if (!callback.is_null())
276    callback.Run(status);
277}
278
279void DeviceCloudPolicyManagerChromeOS::StartIfManaged() {
280  if (device_management_service_ &&
281      local_state_ &&
282      store()->is_initialized() &&
283      store()->is_managed() &&
284      !service()) {
285    core()->Connect(CreateClient());
286    core()->StartRefreshScheduler();
287    core()->TrackRefreshDelayPref(local_state_,
288                                  prefs::kDevicePolicyRefreshRate);
289    attestation_policy_observer_.reset(
290        new chromeos::attestation::AttestationPolicyObserver(client()));
291  }
292}
293
294}  // namespace policy
295