• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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"
36 #include "url/gurl.h"
37 
38 using content::BrowserThread;
39 
40 namespace em = enterprise_management;
41 
42 namespace policy {
43 
44 namespace {
45 
46 // Overridden no requisition value.
47 const char kNoRequisition[] = "none";
48 
49 // Overridden no requisition value.
50 const char kRemoraRequisition[] = "remora";
51 
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.
57 //
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
64 // match the server.
65 //
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)
73 };
74 
75 // Fetches a machine statistic value from StatisticsProvider, returns an empty
76 // string on failure.
GetMachineStatistic(const std::string & key)77 std::string GetMachineStatistic(const std::string& key) {
78   std::string value;
79   chromeos::system::StatisticsProvider* provider =
80       chromeos::system::StatisticsProvider::GetInstance();
81   if (!provider->GetMachineStatistic(key, &value))
82     return std::string();
83 
84   return value;
85 }
86 
87 // Gets a machine flag from StatisticsProvider, returns the given
88 // |default_value| if not present.
GetMachineFlag(const std::string & key,bool default_value)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))
94     return default_value;
95 
96   return value;
97 }
98 
99 // Checks whether forced re-enrollment is enabled.
ForcedReEnrollmentEnabled()100 bool ForcedReEnrollmentEnabled() {
101   return chromeos::AutoEnrollmentController::GetMode() ==
102          chromeos::AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT;
103 }
104 
105 }  // namespace
106 
DeviceCloudPolicyManagerChromeOS(scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,const scoped_refptr<base::SequencedTaskRunner> & task_runner,const scoped_refptr<base::SequencedTaskRunner> & background_task_runner,EnterpriseInstallAttributes * install_attributes,ServerBackedStateKeysBroker * state_keys_broker)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,
115                              std::string()),
116           store.get(),
117           task_runner,
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),
125       local_state_(NULL) {
126 }
127 
~DeviceCloudPolicyManagerChromeOS()128 DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
129 
Connect(PrefService * local_state,DeviceManagementService * device_management_service,scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider)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);
136   CHECK(local_state);
137 
138   local_state_ = local_state;
139   device_management_service_ = device_management_service;
140   device_status_provider_ = device_status_provider.Pass();
141 
142   state_keys_update_subscription_ = state_keys_broker_->RegisterUpdateCallback(
143       base::Bind(&DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated,
144                  base::Unretained(this)));
145 
146   InitializeRequisition();
147   StartIfManaged();
148 }
149 
StartEnrollment(const std::string & auth_token,bool is_auto_enrollment,const AllowedDeviceModes & allowed_device_modes,const EnrollmentCallback & callback)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();
158 
159   enrollment_handler_.reset(new EnrollmentHandlerChromeOS(
160       device_store_.get(),
161       install_attributes_,
162       state_keys_broker_,
163       CreateClient(),
164       background_task_runner_,
165       auth_token,
166       install_attributes_->GetDeviceId(),
167       is_auto_enrollment,
168       GetDeviceRequisition(),
169       allowed_device_modes,
170       base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
171                  base::Unretained(this),
172                  callback)));
173   enrollment_handler_->StartEnrollment();
174 }
175 
CancelEnrollment()176 void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() {
177   if (enrollment_handler_) {
178     enrollment_handler_.reset();
179     StartIfManaged();
180   }
181 }
182 
GetDeviceRequisition() const183 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);
189 
190   if (requisition == kNoRequisition)
191     requisition.clear();
192 
193   return requisition;
194 }
195 
SetDeviceRequisition(const std::string & requisition)196 void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
197     const std::string& requisition) {
198   if (local_state_) {
199     if (requisition.empty()) {
200       local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
201       local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
202       local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
203     } else {
204       local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
205       if (requisition == kNoRequisition) {
206         local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
207         local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
208       } else {
209         local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
210         local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
211       }
212     }
213   }
214 }
215 
ShouldAutoStartEnrollment() const216 bool DeviceCloudPolicyManagerChromeOS::ShouldAutoStartEnrollment() const {
217   std::string restore_mode = GetRestoreMode();
218   if (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested ||
219       restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced) {
220     return true;
221   }
222 
223   if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart))
224     return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart);
225 
226   return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false);
227 }
228 
ShouldRecoverEnrollment() const229 bool DeviceCloudPolicyManagerChromeOS::ShouldRecoverEnrollment() const {
230   if (install_attributes_->IsEnterpriseDevice() &&
231       chromeos::StartupUtils::IsEnrollmentRecoveryRequired()) {
232     LOG(WARNING) << "Enrollment recovery required according to pref.";
233     if (!DeviceCloudPolicyManagerChromeOS::GetMachineID().empty())
234       return true;
235     LOG(WARNING) << "Postponing recovery because machine id is missing.";
236   }
237   return false;
238 }
239 
240 std::string
GetEnrollmentRecoveryDomain() const241 DeviceCloudPolicyManagerChromeOS::GetEnrollmentRecoveryDomain() const {
242   return install_attributes_->GetDomain();
243 }
244 
CanExitEnrollment() const245 bool DeviceCloudPolicyManagerChromeOS::CanExitEnrollment() const {
246   if (GetRestoreMode() == kDeviceStateRestoreModeReEnrollmentEnforced)
247     return false;
248 
249   if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit))
250     return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit);
251 
252   return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
253                         true);
254 }
255 
256 std::string
GetForcedEnrollmentDomain() const257 DeviceCloudPolicyManagerChromeOS::GetForcedEnrollmentDomain() const {
258   const base::DictionaryValue* device_state_dict =
259       local_state_->GetDictionary(prefs::kServerBackedDeviceState);
260   std::string management_domain;
261   device_state_dict->GetString(kDeviceStateManagementDomain,
262                                &management_domain);
263   return management_domain;
264 }
265 
Shutdown()266 void DeviceCloudPolicyManagerChromeOS::Shutdown() {
267   state_keys_update_subscription_.reset();
268   CloudPolicyManager::Shutdown();
269   device_status_provider_.reset();
270 }
271 
OnStoreLoaded(CloudPolicyStore * store)272 void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
273   CloudPolicyManager::OnStoreLoaded(store);
274   StartIfManaged();
275 }
276 
277 // static
RegisterPrefs(PrefRegistrySimple * registry)278 void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
279     PrefRegistrySimple* registry) {
280   registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
281                                std::string());
282   registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
283   registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
284   registry->RegisterDictionaryPref(prefs::kServerBackedDeviceState);
285 }
286 
287 // static
GetMachineID()288 std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
289   std::string machine_id;
290   chromeos::system::StatisticsProvider* provider =
291       chromeos::system::StatisticsProvider::GetInstance();
292   for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
293     if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
294                                       &machine_id) &&
295         !machine_id.empty()) {
296       break;
297     }
298   }
299 
300   if (machine_id.empty())
301     LOG(WARNING) << "Failed to get machine id.";
302 
303   return machine_id;
304 }
305 
306 // static
GetMachineModel()307 std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
308   return GetMachineStatistic(chromeos::system::kHardwareClassKey);
309 }
310 
CreateClient()311 scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
312   scoped_refptr<net::URLRequestContextGetter> request_context =
313       new SystemPolicyRequestContext(
314           g_browser_process->system_request_context(), GetUserAgent());
315 
316   scoped_ptr<CloudPolicyClient> client(
317       new CloudPolicyClient(GetMachineID(), GetMachineModel(),
318                             kPolicyVerificationKeyHash,
319                             USER_AFFILIATION_NONE,
320                             device_status_provider_.get(),
321                             device_management_service_,
322                             request_context));
323 
324   return client.Pass();
325 }
326 
EnrollmentCompleted(const EnrollmentCallback & callback,EnrollmentStatus status)327 void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted(
328     const EnrollmentCallback& callback,
329     EnrollmentStatus status) {
330   if (status.status() == EnrollmentStatus::STATUS_SUCCESS)
331     StartConnection(enrollment_handler_->ReleaseClient());
332   else
333     StartIfManaged();
334 
335   enrollment_handler_.reset();
336   if (!callback.is_null())
337     callback.Run(status);
338 }
339 
StartIfManaged()340 void DeviceCloudPolicyManagerChromeOS::StartIfManaged() {
341   if (device_management_service_ &&
342       local_state_ &&
343       store()->is_initialized() &&
344       store()->has_policy() &&
345       !device_store_->policy()->request_token().empty() &&
346       !state_keys_broker_->pending() &&
347       !enrollment_handler_ &&
348       !service()) {
349     StartConnection(CreateClient());
350   }
351 }
352 
StartConnection(scoped_ptr<CloudPolicyClient> client_to_connect)353 void DeviceCloudPolicyManagerChromeOS::StartConnection(
354     scoped_ptr<CloudPolicyClient> client_to_connect) {
355   // Set state keys here so the first policy fetch submits them to the server.
356   if (ForcedReEnrollmentEnabled())
357     client_to_connect->SetStateKeysToUpload(state_keys_broker_->state_keys());
358 
359   core()->Connect(client_to_connect.Pass());
360   core()->StartRefreshScheduler();
361   core()->TrackRefreshDelayPref(local_state_,
362                                 prefs::kDevicePolicyRefreshRate);
363   attestation_policy_observer_.reset(
364       new chromeos::attestation::AttestationPolicyObserver(client()));
365 }
366 
OnStateKeysUpdated()367 void DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated() {
368   if (client()) {
369     if (ForcedReEnrollmentEnabled())
370       client()->SetStateKeysToUpload(state_keys_broker_->state_keys());
371   } else {
372     StartIfManaged();
373   }
374 }
375 
InitializeRequisition()376 void DeviceCloudPolicyManagerChromeOS::InitializeRequisition() {
377   // OEM statistics are only loaded when OOBE is not completed.
378   if (chromeos::StartupUtils::IsOobeCompleted())
379     return;
380 
381   const PrefService::Preference* pref = local_state_->FindPreference(
382       prefs::kDeviceEnrollmentRequisition);
383   if (pref->IsDefaultValue()) {
384     std::string requisition =
385         GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
386 
387     if (!requisition.empty()) {
388       local_state_->SetString(prefs::kDeviceEnrollmentRequisition,
389                               requisition);
390       if (requisition == kRemoraRequisition) {
391         local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
392         local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
393       } else {
394         local_state_->SetBoolean(
395             prefs::kDeviceEnrollmentAutoStart,
396             GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey,
397                            false));
398         local_state_->SetBoolean(
399             prefs::kDeviceEnrollmentCanExit,
400             GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
401                            false));
402       }
403     }
404   }
405 }
406 
GetRestoreMode() const407 std::string DeviceCloudPolicyManagerChromeOS::GetRestoreMode() const {
408   const base::DictionaryValue* device_state_dict =
409       local_state_->GetDictionary(prefs::kServerBackedDeviceState);
410   std::string restore_mode;
411   device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode);
412   return restore_mode;
413 }
414 
415 }  // namespace policy
416