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