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