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