device_cloud_policy_manager_chromeos.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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/common/chrome_content_client.h" 24#include "chrome/common/pref_names.h" 25#include "chromeos/chromeos_constants.h" 26#include "chromeos/chromeos_switches.h" 27#include "chromeos/system/statistics_provider.h" 28#include "components/policy/core/common/cloud/cloud_policy_constants.h" 29#include "components/policy/core/common/cloud/cloud_policy_store.h" 30#include "components/policy/core/common/cloud/device_management_service.h" 31#include "components/policy/core/common/cloud/system_policy_request_context.h" 32#include "content/public/browser/browser_thread.h" 33#include "crypto/sha2.h" 34#include "policy/proto/device_management_backend.pb.h" 35#include "url/gurl.h" 36 37using content::BrowserThread; 38 39namespace em = enterprise_management; 40 41namespace policy { 42 43namespace { 44 45// Overridden no requisition value. 46const char kNoRequisition[] = "none"; 47 48// Overridden no requisition value. 49const char kRemoraRequisition[] = "remora"; 50 51// These are the machine serial number keys that we check in order until we 52// find a non-empty serial number. The VPD spec says the serial number should be 53// in the "serial_number" key for v2+ VPDs. However, legacy devices used a 54// different key to report their serial number, which we fall back to if 55// "serial_number" is not present. 56// 57// Product_S/N is still special-cased due to inconsistencies with serial 58// numbers on Lumpy devices: On these devices, serial_number is identical to 59// Product_S/N with an appended checksum. Unfortunately, the sticker on the 60// packaging doesn't include that checksum either (the sticker on the device 61// does though!). The former sticker is the source of the serial number used by 62// device management service, so we prefer Product_S/N over serial number to 63// match the server. 64// 65// TODO(mnissler): Move serial_number back to the top once the server side uses 66// the correct serial number. 67const char* kMachineInfoSerialNumberKeys[] = { 68 "Product_S/N", // Lumpy/Alex devices 69 "serial_number", // VPD v2+ devices 70 "Product_SN", // Mario 71 "sn", // old ZGB devices (more recent ones use serial_number) 72}; 73 74// Fetches a machine statistic value from StatisticsProvider, returns an empty 75// string on failure. 76std::string GetMachineStatistic(const std::string& key) { 77 std::string value; 78 chromeos::system::StatisticsProvider* provider = 79 chromeos::system::StatisticsProvider::GetInstance(); 80 if (!provider->GetMachineStatistic(key, &value)) 81 return std::string(); 82 83 return value; 84} 85 86// Gets a machine flag from StatisticsProvider, returns the given 87// |default_value| if not present. 88bool GetMachineFlag(const std::string& key, bool default_value) { 89 bool value = default_value; 90 chromeos::system::StatisticsProvider* provider = 91 chromeos::system::StatisticsProvider::GetInstance(); 92 if (!provider->GetMachineFlag(key, &value)) 93 return default_value; 94 95 return value; 96} 97 98} // namespace 99 100const int 101DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyTimeQuantumPower; 102 103const int 104DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyFutureQuanta; 105 106DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS( 107 scoped_ptr<DeviceCloudPolicyStoreChromeOS> store, 108 const scoped_refptr<base::SequencedTaskRunner>& task_runner, 109 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, 110 EnterpriseInstallAttributes* install_attributes) 111 : CloudPolicyManager( 112 PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType, 113 std::string()), 114 store.get(), 115 task_runner, 116 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), 117 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)), 118 device_store_(store.Pass()), 119 background_task_runner_(background_task_runner), 120 install_attributes_(install_attributes), 121 device_management_service_(NULL), 122 local_state_(NULL) {} 123 124DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {} 125 126void DeviceCloudPolicyManagerChromeOS::Connect( 127 PrefService* local_state, 128 DeviceManagementService* device_management_service, 129 scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) { 130 CHECK(!device_management_service_); 131 CHECK(device_management_service); 132 CHECK(local_state); 133 134 local_state_ = local_state; 135 device_management_service_ = device_management_service; 136 device_status_provider_ = device_status_provider.Pass(); 137 138 InitalizeRequisition(); 139 StartIfManaged(); 140} 141 142void DeviceCloudPolicyManagerChromeOS::StartEnrollment( 143 const std::string& auth_token, 144 bool is_auto_enrollment, 145 const AllowedDeviceModes& allowed_device_modes, 146 const EnrollmentCallback& callback) { 147 CHECK(device_management_service_); 148 core()->Disconnect(); 149 150 enrollment_handler_.reset( 151 new EnrollmentHandlerChromeOS( 152 device_store_.get(), install_attributes_, CreateClient(), 153 background_task_runner_, auth_token, 154 install_attributes_->GetDeviceId(), is_auto_enrollment, 155 GetDeviceRequisition(), GetCurrentDeviceStateKey(), 156 allowed_device_modes, 157 base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted, 158 base::Unretained(this), callback))); 159 enrollment_handler_->StartEnrollment(); 160} 161 162void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() { 163 if (enrollment_handler_.get()) { 164 enrollment_handler_.reset(); 165 StartIfManaged(); 166 } 167} 168 169std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const { 170 std::string requisition; 171 const PrefService::Preference* pref = local_state_->FindPreference( 172 prefs::kDeviceEnrollmentRequisition); 173 if (!pref->IsDefaultValue()) 174 pref->GetValue()->GetAsString(&requisition); 175 176 if (requisition == kNoRequisition) 177 requisition.clear(); 178 179 return requisition; 180} 181 182void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition( 183 const std::string& requisition) { 184 if (local_state_) { 185 if (requisition.empty()) { 186 local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition); 187 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart); 188 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit); 189 } else { 190 local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition); 191 if (requisition == kNoRequisition) { 192 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart); 193 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit); 194 } else { 195 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true); 196 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false); 197 } 198 } 199 } 200} 201 202bool DeviceCloudPolicyManagerChromeOS::ShouldAutoStartEnrollment() const { 203 std::string restore_mode = GetRestoreMode(); 204 if (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested || 205 restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced) { 206 return true; 207 } 208 209 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart)) 210 return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart); 211 212 return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false); 213} 214 215bool DeviceCloudPolicyManagerChromeOS::CanExitEnrollment() const { 216 if (GetRestoreMode() == kDeviceStateRestoreModeReEnrollmentEnforced) 217 return false; 218 219 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit)) 220 return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit); 221 222 return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey, 223 true); 224} 225 226std::string 227DeviceCloudPolicyManagerChromeOS::GetForcedEnrollmentDomain() const { 228 const base::DictionaryValue* device_state_dict = 229 local_state_->GetDictionary(prefs::kServerBackedDeviceState); 230 std::string management_domain; 231 device_state_dict->GetString(kDeviceStateManagementDomain, 232 &management_domain); 233 return management_domain; 234} 235 236void DeviceCloudPolicyManagerChromeOS::Shutdown() { 237 CloudPolicyManager::Shutdown(); 238 device_status_provider_.reset(); 239} 240 241void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) { 242 CloudPolicyManager::OnStoreLoaded(store); 243 244 if (!enrollment_handler_.get()) 245 StartIfManaged(); 246} 247 248// static 249void DeviceCloudPolicyManagerChromeOS::RegisterPrefs( 250 PrefRegistrySimple* registry) { 251 registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition, 252 std::string()); 253 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false); 254 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true); 255 registry->RegisterDictionaryPref(prefs::kServerBackedDeviceState); 256} 257 258// static 259std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() { 260 std::string machine_id; 261 chromeos::system::StatisticsProvider* provider = 262 chromeos::system::StatisticsProvider::GetInstance(); 263 for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) { 264 if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i], 265 &machine_id) && 266 !machine_id.empty()) { 267 break; 268 } 269 } 270 271 if (machine_id.empty()) 272 LOG(WARNING) << "Failed to get machine id."; 273 274 return machine_id; 275} 276 277// static 278std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() { 279 return GetMachineStatistic(chromeos::system::kHardwareClassKey); 280} 281 282// static 283std::string DeviceCloudPolicyManagerChromeOS::GetCurrentDeviceStateKey() { 284 std::vector<std::string> state_keys; 285 if (GetDeviceStateKeys(base::Time::Now(), &state_keys) && 286 !state_keys.empty()) { 287 // The key for the current time is always the first one. 288 return state_keys[0]; 289 } 290 291 return std::string(); 292} 293 294scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() { 295 scoped_refptr<net::URLRequestContextGetter> request_context = 296 new SystemPolicyRequestContext( 297 g_browser_process->system_request_context(), GetUserAgent()); 298 299 scoped_ptr<CloudPolicyClient> client( 300 new CloudPolicyClient(GetMachineID(), GetMachineModel(), 301 kPolicyVerificationKeyHash, 302 USER_AFFILIATION_NONE, 303 device_status_provider_.get(), 304 device_management_service_, 305 request_context)); 306 307 // Set state keys to upload immediately after creation so the first policy 308 // fetch submits them to the server. 309 if (chromeos::AutoEnrollmentController::GetMode() == 310 chromeos::AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT) { 311 std::vector<std::string> state_keys; 312 if (GetDeviceStateKeys(base::Time::Now(), &state_keys)) 313 client->SetStateKeysToUpload(state_keys); 314 } 315 316 return client.Pass(); 317} 318 319void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted( 320 const EnrollmentCallback& callback, 321 EnrollmentStatus status) { 322 if (status.status() == EnrollmentStatus::STATUS_SUCCESS) 323 StartConnection(enrollment_handler_->ReleaseClient()); 324 else 325 StartIfManaged(); 326 327 enrollment_handler_.reset(); 328 if (!callback.is_null()) 329 callback.Run(status); 330} 331 332void DeviceCloudPolicyManagerChromeOS::StartIfManaged() { 333 if (device_management_service_ && 334 local_state_ && 335 store()->is_initialized() && 336 store()->has_policy() && 337 !service()) { 338 StartConnection(CreateClient()); 339 } 340} 341 342void DeviceCloudPolicyManagerChromeOS::StartConnection( 343 scoped_ptr<CloudPolicyClient> client_to_connect) { 344 core()->Connect(client_to_connect.Pass()); 345 core()->StartRefreshScheduler(); 346 core()->TrackRefreshDelayPref(local_state_, 347 prefs::kDevicePolicyRefreshRate); 348 attestation_policy_observer_.reset( 349 new chromeos::attestation::AttestationPolicyObserver(client())); 350} 351 352void DeviceCloudPolicyManagerChromeOS::InitalizeRequisition() { 353 // OEM statistics are only loaded when OOBE is not completed. 354 if (chromeos::StartupUtils::IsOobeCompleted()) 355 return; 356 357 const PrefService::Preference* pref = local_state_->FindPreference( 358 prefs::kDeviceEnrollmentRequisition); 359 if (pref->IsDefaultValue()) { 360 std::string requisition = 361 GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey); 362 363 if (!requisition.empty()) { 364 local_state_->SetString(prefs::kDeviceEnrollmentRequisition, 365 requisition); 366 if (requisition == kRemoraRequisition) { 367 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true); 368 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false); 369 } else { 370 local_state_->SetBoolean( 371 prefs::kDeviceEnrollmentAutoStart, 372 GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, 373 false)); 374 local_state_->SetBoolean( 375 prefs::kDeviceEnrollmentCanExit, 376 GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey, 377 false)); 378 } 379 } 380 } 381} 382 383std::string DeviceCloudPolicyManagerChromeOS::GetRestoreMode() const { 384 const base::DictionaryValue* device_state_dict = 385 local_state_->GetDictionary(prefs::kServerBackedDeviceState); 386 std::string restore_mode; 387 device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode); 388 return restore_mode; 389} 390 391// static 392bool DeviceCloudPolicyManagerChromeOS::GetDeviceStateKeys( 393 const base::Time& timestamp, 394 std::vector<std::string>* state_keys) { 395 state_keys->clear(); 396 397 std::string disk_serial_number = 398 GetMachineStatistic(chromeos::system::kDiskSerialNumber); 399 if (disk_serial_number.empty()) { 400 LOG(ERROR) << "Missing disk serial number"; 401 return false; 402 } 403 404 std::string machine_id = GetMachineID(); 405 if (machine_id.empty()) 406 return false; 407 408 // Tolerate missing group code keys, some old devices may not have it. 409 std::string group_code_key = 410 GetMachineStatistic(chromeos::system::kOffersGroupCodeKey); 411 412 // Get the current time in quantized form. 413 int64 quantum_size = GG_INT64_C(1) << kDeviceStateKeyTimeQuantumPower; 414 int64 quantized_time = 415 (timestamp - base::Time::UnixEpoch()).InSeconds() & ~(quantum_size - 1); 416 for (int i = 0; i < kDeviceStateKeyFutureQuanta; ++i) { 417 state_keys->push_back(crypto::SHA256HashString( 418 crypto::SHA256HashString(group_code_key) + 419 crypto::SHA256HashString(disk_serial_number) + 420 crypto::SHA256HashString(machine_id) + 421 crypto::SHA256HashString(base::Int64ToString(quantized_time)))); 422 quantized_time += quantum_size; 423 } 424 425 return true; 426} 427 428} // namespace policy 429