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