Home | History | Annotate | Download | only in policy
      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/chromeos/attestation/attestation_policy_observer.h"
     16 #include "chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h"
     17 #include "chrome/browser/chromeos/login/startup_utils.h"
     18 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
     19 #include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.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_store.h"
     25 #include "content/public/browser/browser_thread.h"
     26 #include "crypto/sha2.h"
     27 #include "policy/proto/device_management_backend.pb.h"
     28 #include "url/gurl.h"
     29 
     30 using content::BrowserThread;
     31 
     32 namespace em = enterprise_management;
     33 
     34 namespace policy {
     35 
     36 namespace {
     37 
     38 const char kNoRequisition[] = "none";
     39 const char kRemoraRequisition[] = "remora";
     40 const char kSharkRequisition[] = "shark";
     41 
     42 // These are the machine serial number keys that we check in order until we
     43 // find a non-empty serial number. The VPD spec says the serial number should be
     44 // in the "serial_number" key for v2+ VPDs. However, legacy devices used a
     45 // different key to report their serial number, which we fall back to if
     46 // "serial_number" is not present.
     47 //
     48 // Product_S/N is still special-cased due to inconsistencies with serial
     49 // numbers on Lumpy devices: On these devices, serial_number is identical to
     50 // Product_S/N with an appended checksum. Unfortunately, the sticker on the
     51 // packaging doesn't include that checksum either (the sticker on the device
     52 // does though!). The former sticker is the source of the serial number used by
     53 // device management service, so we prefer Product_S/N over serial number to
     54 // match the server.
     55 //
     56 // TODO(mnissler): Move serial_number back to the top once the server side uses
     57 // the correct serial number.
     58 const char* kMachineInfoSerialNumberKeys[] = {
     59   "Product_S/N",    // Lumpy/Alex devices
     60   "serial_number",  // VPD v2+ devices
     61   "Product_SN",     // Mario
     62   "sn",             // old ZGB devices (more recent ones use serial_number)
     63 };
     64 
     65 // Fetches a machine statistic value from StatisticsProvider, returns an empty
     66 // string on failure.
     67 std::string GetMachineStatistic(const std::string& key) {
     68   std::string value;
     69   chromeos::system::StatisticsProvider* provider =
     70       chromeos::system::StatisticsProvider::GetInstance();
     71   if (!provider->GetMachineStatistic(key, &value))
     72     return std::string();
     73 
     74   return value;
     75 }
     76 
     77 // Gets a machine flag from StatisticsProvider, returns the given
     78 // |default_value| if not present.
     79 bool GetMachineFlag(const std::string& key, bool default_value) {
     80   bool value = default_value;
     81   chromeos::system::StatisticsProvider* provider =
     82       chromeos::system::StatisticsProvider::GetInstance();
     83   if (!provider->GetMachineFlag(key, &value))
     84     return default_value;
     85 
     86   return value;
     87 }
     88 
     89 // Checks whether forced re-enrollment is enabled.
     90 bool ForcedReEnrollmentEnabled() {
     91   return chromeos::AutoEnrollmentController::GetMode() ==
     92          chromeos::AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT;
     93 }
     94 
     95 }  // namespace
     96 
     97 DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
     98     scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
     99     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
    100     ServerBackedStateKeysBroker* state_keys_broker)
    101     : CloudPolicyManager(
    102           PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
    103                              std::string()),
    104           store.get(),
    105           task_runner,
    106           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
    107           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)),
    108       device_store_(store.Pass()),
    109       state_keys_broker_(state_keys_broker),
    110       local_state_(NULL) {
    111 }
    112 
    113 DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
    114 
    115 void DeviceCloudPolicyManagerChromeOS::Initialize(PrefService* local_state) {
    116   CHECK(local_state);
    117 
    118   local_state_ = local_state;
    119 
    120   state_keys_update_subscription_ = state_keys_broker_->RegisterUpdateCallback(
    121       base::Bind(&DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated,
    122                  base::Unretained(this)));
    123 
    124   InitializeRequisition();
    125 }
    126 
    127 std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const {
    128   std::string requisition;
    129   const PrefService::Preference* pref = local_state_->FindPreference(
    130       prefs::kDeviceEnrollmentRequisition);
    131   if (!pref->IsDefaultValue())
    132     pref->GetValue()->GetAsString(&requisition);
    133 
    134   if (requisition == kNoRequisition)
    135     requisition.clear();
    136 
    137   return requisition;
    138 }
    139 
    140 void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
    141     const std::string& requisition) {
    142   VLOG(1) << "SetDeviceRequisition " << requisition;
    143   if (local_state_) {
    144     if (requisition.empty()) {
    145       local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
    146       local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
    147       local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
    148     } else {
    149       local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
    150       if (requisition == kNoRequisition) {
    151         local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
    152         local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
    153       } else {
    154         local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
    155         local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
    156       }
    157     }
    158   }
    159 }
    160 
    161 bool DeviceCloudPolicyManagerChromeOS::IsRemoraRequisition() const {
    162   return GetDeviceRequisition() == kRemoraRequisition;
    163 }
    164 
    165 bool DeviceCloudPolicyManagerChromeOS::IsSharkRequisition() const {
    166   return GetDeviceRequisition() == kSharkRequisition;
    167 }
    168 
    169 void DeviceCloudPolicyManagerChromeOS::Shutdown() {
    170   state_keys_update_subscription_.reset();
    171   CloudPolicyManager::Shutdown();
    172 }
    173 
    174 // static
    175 void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
    176     PrefRegistrySimple* registry) {
    177   registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
    178                                std::string());
    179   registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
    180   registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
    181   registry->RegisterDictionaryPref(prefs::kServerBackedDeviceState);
    182 }
    183 
    184 // static
    185 std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
    186   std::string machine_id;
    187   chromeos::system::StatisticsProvider* provider =
    188       chromeos::system::StatisticsProvider::GetInstance();
    189   for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
    190     if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
    191                                       &machine_id) &&
    192         !machine_id.empty()) {
    193       break;
    194     }
    195   }
    196 
    197   if (machine_id.empty())
    198     LOG(WARNING) << "Failed to get machine id.";
    199 
    200   return machine_id;
    201 }
    202 
    203 // static
    204 std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
    205   return GetMachineStatistic(chromeos::system::kHardwareClassKey);
    206 }
    207 
    208 void DeviceCloudPolicyManagerChromeOS::StartConnection(
    209     scoped_ptr<CloudPolicyClient> client_to_connect,
    210     scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) {
    211   CHECK(!service());
    212 
    213   device_status_provider_ = device_status_provider.Pass();
    214 
    215   // Set state keys here so the first policy fetch submits them to the server.
    216   if (ForcedReEnrollmentEnabled())
    217     client_to_connect->SetStateKeysToUpload(state_keys_broker_->state_keys());
    218 
    219   core()->Connect(client_to_connect.Pass());
    220   core()->StartRefreshScheduler();
    221   core()->TrackRefreshDelayPref(local_state_,
    222                                 prefs::kDevicePolicyRefreshRate);
    223   attestation_policy_observer_.reset(
    224       new chromeos::attestation::AttestationPolicyObserver(client()));
    225 }
    226 
    227 void DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated() {
    228   if (client() && ForcedReEnrollmentEnabled())
    229     client()->SetStateKeysToUpload(state_keys_broker_->state_keys());
    230 }
    231 
    232 void DeviceCloudPolicyManagerChromeOS::InitializeRequisition() {
    233   // OEM statistics are only loaded when OOBE is not completed.
    234   if (chromeos::StartupUtils::IsOobeCompleted())
    235     return;
    236 
    237   const PrefService::Preference* pref = local_state_->FindPreference(
    238       prefs::kDeviceEnrollmentRequisition);
    239   if (pref->IsDefaultValue()) {
    240     std::string requisition =
    241         GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
    242 
    243     if (!requisition.empty()) {
    244       local_state_->SetString(prefs::kDeviceEnrollmentRequisition,
    245                               requisition);
    246       if (requisition == kRemoraRequisition ||
    247           requisition == kSharkRequisition) {
    248         local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
    249         local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
    250       } else {
    251         local_state_->SetBoolean(
    252             prefs::kDeviceEnrollmentAutoStart,
    253             GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey,
    254                            false));
    255         local_state_->SetBoolean(
    256             prefs::kDeviceEnrollmentCanExit,
    257             GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
    258                            false));
    259       }
    260     }
    261   }
    262 }
    263 
    264 }  // namespace policy
    265