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