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/settings/device_settings_service.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/stl_util.h" 11 #include "base/time/time.h" 12 #include "chrome/browser/chrome_notification_types.h" 13 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" 14 #include "chrome/browser/chromeos/settings/session_manager_operation.h" 15 #include "components/ownership/owner_key_util.h" 16 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/notification_service.h" 19 #include "content/public/browser/notification_source.h" 20 #include "crypto/rsa_private_key.h" 21 22 namespace em = enterprise_management; 23 24 using ownership::OwnerKeyUtil; 25 using ownership::PublicKey; 26 27 namespace { 28 29 // Delay between load retries when there was a validation error. 30 // NOTE: This code is here to mitigate clock loss on some devices where policy 31 // loads will fail with a validation error caused by RTC clock being reset when 32 // the battery is drained. 33 int kLoadRetryDelayMs = 1000 * 5; 34 // Maximal number of retries before we give up. Calculated to allow for 10 min 35 // of retry time. 36 int kMaxLoadRetries = (1000 * 60 * 10) / kLoadRetryDelayMs; 37 38 // Assembles PolicyData based on |settings|, |policy_data| and 39 // |user_id|. 40 scoped_ptr<em::PolicyData> AssemblePolicy( 41 const std::string& user_id, 42 const em::PolicyData* policy_data, 43 const em::ChromeDeviceSettingsProto* settings) { 44 scoped_ptr<em::PolicyData> policy(new em::PolicyData()); 45 if (policy_data) { 46 // Preserve management settings. 47 if (policy_data->has_management_mode()) 48 policy->set_management_mode(policy_data->management_mode()); 49 if (policy_data->has_request_token()) 50 policy->set_request_token(policy_data->request_token()); 51 if (policy_data->has_device_id()) 52 policy->set_device_id(policy_data->device_id()); 53 } else { 54 // If there's no previous policy data, this is the first time the device 55 // setting is set. We set the management mode to NOT_MANAGED initially. 56 policy->set_management_mode(em::PolicyData::NOT_MANAGED); 57 } 58 policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType); 59 policy->set_timestamp( 60 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds()); 61 policy->set_username(user_id); 62 if (!settings->SerializeToString(policy->mutable_policy_value())) 63 return scoped_ptr<em::PolicyData>(); 64 65 return policy.Pass(); 66 } 67 68 // Returns true if it is okay to transfer from the current mode to the new 69 // mode. This function should be called in SetManagementMode(). 70 bool CheckManagementModeTransition(em::PolicyData::ManagementMode current_mode, 71 em::PolicyData::ManagementMode new_mode) { 72 // Mode is not changed. 73 if (current_mode == new_mode) 74 return true; 75 76 switch (current_mode) { 77 case em::PolicyData::NOT_MANAGED: 78 // For consumer management enrollment. 79 return new_mode == em::PolicyData::CONSUMER_MANAGED; 80 81 case em::PolicyData::ENTERPRISE_MANAGED: 82 // Management mode cannot be set when it is currently ENTERPRISE_MANAGED. 83 return false; 84 85 case em::PolicyData::CONSUMER_MANAGED: 86 // For consumer management unenrollment. 87 return new_mode == em::PolicyData::NOT_MANAGED; 88 } 89 90 NOTREACHED(); 91 return false; 92 } 93 94 } // namespace 95 96 namespace chromeos { 97 98 DeviceSettingsService::Observer::~Observer() {} 99 100 static DeviceSettingsService* g_device_settings_service = NULL; 101 102 // static 103 void DeviceSettingsService::Initialize() { 104 CHECK(!g_device_settings_service); 105 g_device_settings_service = new DeviceSettingsService(); 106 } 107 108 // static 109 bool DeviceSettingsService::IsInitialized() { 110 return g_device_settings_service; 111 } 112 113 // static 114 void DeviceSettingsService::Shutdown() { 115 DCHECK(g_device_settings_service); 116 delete g_device_settings_service; 117 g_device_settings_service = NULL; 118 } 119 120 // static 121 DeviceSettingsService* DeviceSettingsService::Get() { 122 CHECK(g_device_settings_service); 123 return g_device_settings_service; 124 } 125 126 DeviceSettingsService::DeviceSettingsService() 127 : session_manager_client_(NULL), 128 store_status_(STORE_SUCCESS), 129 load_retries_left_(kMaxLoadRetries), 130 weak_factory_(this) { 131 } 132 133 DeviceSettingsService::~DeviceSettingsService() { 134 DCHECK(pending_operations_.empty()); 135 } 136 137 void DeviceSettingsService::SetSessionManager( 138 SessionManagerClient* session_manager_client, 139 scoped_refptr<OwnerKeyUtil> owner_key_util) { 140 DCHECK(session_manager_client); 141 DCHECK(owner_key_util.get()); 142 DCHECK(!session_manager_client_); 143 DCHECK(!owner_key_util_.get()); 144 145 session_manager_client_ = session_manager_client; 146 owner_key_util_ = owner_key_util; 147 148 session_manager_client_->AddObserver(this); 149 150 StartNextOperation(); 151 } 152 153 void DeviceSettingsService::UnsetSessionManager() { 154 STLDeleteContainerPointers(pending_operations_.begin(), 155 pending_operations_.end()); 156 pending_operations_.clear(); 157 158 if (session_manager_client_) 159 session_manager_client_->RemoveObserver(this); 160 session_manager_client_ = NULL; 161 owner_key_util_ = NULL; 162 } 163 164 scoped_refptr<PublicKey> DeviceSettingsService::GetPublicKey() { 165 return public_key_; 166 } 167 168 void DeviceSettingsService::Load() { 169 EnqueueLoad(false); 170 } 171 172 void DeviceSettingsService::SignAndStore( 173 scoped_ptr<em::ChromeDeviceSettingsProto> new_settings, 174 const base::Closure& callback) { 175 if (!owner_settings_service_) { 176 HandleError(STORE_KEY_UNAVAILABLE, callback); 177 return; 178 } 179 scoped_ptr<em::PolicyData> policy = 180 AssemblePolicy(GetUsername(), policy_data(), new_settings.get()); 181 if (!policy) { 182 HandleError(STORE_POLICY_ERROR, callback); 183 return; 184 } 185 186 owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback); 187 } 188 189 void DeviceSettingsService::SetManagementSettings( 190 em::PolicyData::ManagementMode management_mode, 191 const std::string& request_token, 192 const std::string& device_id, 193 const base::Closure& callback) { 194 if (!owner_settings_service_) { 195 HandleError(STORE_KEY_UNAVAILABLE, callback); 196 return; 197 } 198 199 em::PolicyData::ManagementMode current_mode = em::PolicyData::NOT_MANAGED; 200 if (policy_data() && policy_data()->has_management_mode()) 201 current_mode = policy_data()->management_mode(); 202 203 if (!CheckManagementModeTransition(current_mode, management_mode)) { 204 LOG(ERROR) << "Invalid management mode transition: current mode = " 205 << current_mode << ", new mode = " << management_mode; 206 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); 207 return; 208 } 209 210 scoped_ptr<em::PolicyData> policy = 211 AssemblePolicy(GetUsername(), policy_data(), device_settings()); 212 if (!policy) { 213 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); 214 return; 215 } 216 217 policy->set_management_mode(management_mode); 218 policy->set_request_token(request_token); 219 policy->set_device_id(device_id); 220 221 owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback); 222 } 223 224 void DeviceSettingsService::Store(scoped_ptr<em::PolicyFetchResponse> policy, 225 const base::Closure& callback) { 226 Enqueue( 227 new StoreSettingsOperation( 228 base::Bind(&DeviceSettingsService::HandleCompletedOperation, 229 weak_factory_.GetWeakPtr(), 230 callback), 231 policy.Pass())); 232 } 233 234 DeviceSettingsService::OwnershipStatus 235 DeviceSettingsService::GetOwnershipStatus() { 236 if (public_key_.get()) 237 return public_key_->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; 238 return OWNERSHIP_UNKNOWN; 239 } 240 241 void DeviceSettingsService::GetOwnershipStatusAsync( 242 const OwnershipStatusCallback& callback) { 243 if (public_key_.get()) { 244 // If there is a key, report status immediately. 245 base::MessageLoop::current()->PostTask( 246 FROM_HERE, base::Bind(callback, GetOwnershipStatus())); 247 } else { 248 // If the key hasn't been loaded yet, enqueue the callback to be fired when 249 // the next SessionManagerOperation completes. If no operation is pending, 250 // start a load operation to fetch the key and report the result. 251 pending_ownership_status_callbacks_.push_back(callback); 252 if (pending_operations_.empty()) 253 EnqueueLoad(false); 254 } 255 } 256 257 bool DeviceSettingsService::HasPrivateOwnerKey() { 258 return owner_settings_service_ && owner_settings_service_->IsOwner(); 259 } 260 261 void DeviceSettingsService::InitOwner( 262 const std::string& username, 263 const base::WeakPtr<ownership::OwnerSettingsService>& 264 owner_settings_service) { 265 // When InitOwner() is called twice with the same |username| it's 266 // worth to reload settings since owner key may become available. 267 if (!username_.empty() && username_ != username) 268 return; 269 username_ = username; 270 owner_settings_service_ = owner_settings_service; 271 272 EnsureReload(true); 273 } 274 275 const std::string& DeviceSettingsService::GetUsername() const { 276 return username_; 277 } 278 279 void DeviceSettingsService::AddObserver(Observer* observer) { 280 observers_.AddObserver(observer); 281 } 282 283 void DeviceSettingsService::RemoveObserver(Observer* observer) { 284 observers_.RemoveObserver(observer); 285 } 286 287 void DeviceSettingsService::OwnerKeySet(bool success) { 288 if (!success) { 289 LOG(ERROR) << "Owner key change failed."; 290 return; 291 } 292 293 public_key_ = NULL; 294 EnsureReload(true); 295 } 296 297 void DeviceSettingsService::PropertyChangeComplete(bool success) { 298 if (!success) { 299 LOG(ERROR) << "Policy update failed."; 300 return; 301 } 302 303 EnsureReload(false); 304 } 305 306 void DeviceSettingsService::Enqueue(SessionManagerOperation* operation) { 307 pending_operations_.push_back(operation); 308 if (pending_operations_.front() == operation) 309 StartNextOperation(); 310 } 311 312 void DeviceSettingsService::EnqueueLoad(bool force_key_load) { 313 SessionManagerOperation* operation = 314 new LoadSettingsOperation( 315 base::Bind(&DeviceSettingsService::HandleCompletedOperation, 316 weak_factory_.GetWeakPtr(), 317 base::Closure())); 318 operation->set_force_key_load(force_key_load); 319 operation->set_username(username_); 320 operation->set_owner_settings_service(owner_settings_service_); 321 Enqueue(operation); 322 } 323 324 void DeviceSettingsService::EnsureReload(bool force_key_load) { 325 if (!pending_operations_.empty()) { 326 pending_operations_.front()->set_username(username_); 327 pending_operations_.front()->set_owner_settings_service( 328 owner_settings_service_); 329 pending_operations_.front()->RestartLoad(force_key_load); 330 } else { 331 EnqueueLoad(force_key_load); 332 } 333 } 334 335 void DeviceSettingsService::StartNextOperation() { 336 if (!pending_operations_.empty() && 337 session_manager_client_ && 338 owner_key_util_.get()) { 339 pending_operations_.front()->Start( 340 session_manager_client_, owner_key_util_, public_key_); 341 } 342 } 343 344 void DeviceSettingsService::HandleCompletedOperation( 345 const base::Closure& callback, 346 SessionManagerOperation* operation, 347 Status status) { 348 DCHECK_EQ(operation, pending_operations_.front()); 349 store_status_ = status; 350 351 OwnershipStatus ownership_status = OWNERSHIP_UNKNOWN; 352 scoped_refptr<PublicKey> new_key(operation->public_key()); 353 if (new_key.get()) { 354 ownership_status = new_key->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; 355 } else { 356 NOTREACHED() << "Failed to determine key status."; 357 } 358 359 bool new_owner_key = false; 360 if (public_key_.get() != new_key.get()) { 361 public_key_ = new_key; 362 new_owner_key = true; 363 } 364 365 if (status == STORE_SUCCESS) { 366 policy_data_ = operation->policy_data().Pass(); 367 device_settings_ = operation->device_settings().Pass(); 368 load_retries_left_ = kMaxLoadRetries; 369 } else if (status != STORE_KEY_UNAVAILABLE) { 370 LOG(ERROR) << "Session manager operation failed: " << status; 371 // Validation errors can be temporary if the rtc has gone on holiday for a 372 // short while. So we will retry such loads for up to 10 minutes. 373 if (status == STORE_TEMP_VALIDATION_ERROR) { 374 if (load_retries_left_ > 0) { 375 load_retries_left_--; 376 LOG(ERROR) << "A re-load has been scheduled due to a validation error."; 377 content::BrowserThread::PostDelayedTask( 378 content::BrowserThread::UI, 379 FROM_HERE, 380 base::Bind(&DeviceSettingsService::Load, base::Unretained(this)), 381 base::TimeDelta::FromMilliseconds(kLoadRetryDelayMs)); 382 } else { 383 // Once we've given up retrying, the validation error is not temporary 384 // anymore. 385 store_status_ = STORE_VALIDATION_ERROR; 386 } 387 } 388 } 389 390 if (new_owner_key) { 391 FOR_EACH_OBSERVER(Observer, observers_, OwnershipStatusChanged()); 392 content::NotificationService::current()->Notify( 393 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, 394 content::Source<DeviceSettingsService>(this), 395 content::NotificationService::NoDetails()); 396 } 397 398 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); 399 400 std::vector<OwnershipStatusCallback> callbacks; 401 callbacks.swap(pending_ownership_status_callbacks_); 402 for (std::vector<OwnershipStatusCallback>::iterator iter(callbacks.begin()); 403 iter != callbacks.end(); ++iter) { 404 iter->Run(ownership_status); 405 } 406 407 // The completion callback happens after the notification so clients can 408 // filter self-triggered updates. 409 if (!callback.is_null()) 410 callback.Run(); 411 412 // Only remove the pending operation here, so new operations triggered by any 413 // of the callbacks above are queued up properly. 414 pending_operations_.pop_front(); 415 delete operation; 416 417 StartNextOperation(); 418 } 419 420 void DeviceSettingsService::HandleError(Status status, 421 const base::Closure& callback) { 422 store_status_ = status; 423 424 LOG(ERROR) << "Session manager operation failed: " << status; 425 426 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); 427 428 // The completion callback happens after the notification so clients can 429 // filter self-triggered updates. 430 if (!callback.is_null()) 431 callback.Run(); 432 } 433 434 void DeviceSettingsService::OnSignAndStoreOperationCompleted(Status status) { 435 store_status_ = status; 436 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); 437 } 438 439 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() { 440 DeviceSettingsService::Initialize(); 441 } 442 443 ScopedTestDeviceSettingsService::~ScopedTestDeviceSettingsService() { 444 // Clean pending operations. 445 DeviceSettingsService::Get()->UnsetSessionManager(); 446 DeviceSettingsService::Shutdown(); 447 } 448 449 } // namespace chromeos 450