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 "chrome/browser/chrome_notification_types.h" 12 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" 13 #include "chrome/browser/chromeos/settings/owner_key_util.h" 14 #include "chrome/browser/chromeos/settings/session_manager_operation.h" 15 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/notification_service.h" 17 #include "content/public/browser/notification_source.h" 18 #include "crypto/rsa_private_key.h" 19 #include "policy/proto/device_management_backend.pb.h" 20 21 namespace em = enterprise_management; 22 23 namespace { 24 25 // Delay between load retries when there was a validation error. 26 // NOTE: This code is here to mitigate clock loss on some devices where policy 27 // loads will fail with a validation error caused by RTC clock bing reset when 28 // the battery is drained. 29 int kLoadRetryDelayMs = 1000 * 5; 30 // Maximal number of retries before we give up. Calculated to allow for 10 min 31 // of retry time. 32 int kMaxLoadRetries = (1000 * 60 * 10) / kLoadRetryDelayMs; 33 34 } // namespace 35 36 namespace chromeos { 37 38 OwnerKey::OwnerKey(scoped_ptr<std::vector<uint8> > public_key, 39 scoped_ptr<crypto::RSAPrivateKey> private_key) 40 : public_key_(public_key.Pass()), 41 private_key_(private_key.Pass()) {} 42 43 OwnerKey::~OwnerKey() {} 44 45 DeviceSettingsService::Observer::~Observer() {} 46 47 static DeviceSettingsService* g_device_settings_service = NULL; 48 49 // static 50 void DeviceSettingsService::Initialize() { 51 CHECK(!g_device_settings_service); 52 g_device_settings_service = new DeviceSettingsService(); 53 } 54 55 // static 56 bool DeviceSettingsService::IsInitialized() { 57 return g_device_settings_service; 58 } 59 60 // static 61 void DeviceSettingsService::Shutdown() { 62 DCHECK(g_device_settings_service); 63 delete g_device_settings_service; 64 g_device_settings_service = NULL; 65 } 66 67 // static 68 DeviceSettingsService* DeviceSettingsService::Get() { 69 CHECK(g_device_settings_service); 70 return g_device_settings_service; 71 } 72 73 DeviceSettingsService::DeviceSettingsService() 74 : session_manager_client_(NULL), 75 weak_factory_(this), 76 store_status_(STORE_SUCCESS), 77 certificates_loaded_(false), 78 owner_key_loaded_with_certificates_(false), 79 load_retries_left_(kMaxLoadRetries) { 80 if (CertLoader::IsInitialized()) { 81 certificates_loaded_ = CertLoader::Get()->certificates_loaded(); 82 CertLoader::Get()->AddObserver(this); 83 } 84 } 85 86 DeviceSettingsService::~DeviceSettingsService() { 87 DCHECK(pending_operations_.empty()); 88 if (CertLoader::IsInitialized()) 89 CertLoader::Get()->RemoveObserver(this); 90 } 91 92 void DeviceSettingsService::SetSessionManager( 93 SessionManagerClient* session_manager_client, 94 scoped_refptr<OwnerKeyUtil> owner_key_util) { 95 DCHECK(session_manager_client); 96 DCHECK(owner_key_util.get()); 97 DCHECK(!session_manager_client_); 98 DCHECK(!owner_key_util_.get()); 99 100 session_manager_client_ = session_manager_client; 101 owner_key_util_ = owner_key_util; 102 103 session_manager_client_->AddObserver(this); 104 105 StartNextOperation(); 106 } 107 108 void DeviceSettingsService::UnsetSessionManager() { 109 STLDeleteContainerPointers(pending_operations_.begin(), 110 pending_operations_.end()); 111 pending_operations_.clear(); 112 113 if (session_manager_client_) 114 session_manager_client_->RemoveObserver(this); 115 session_manager_client_ = NULL; 116 owner_key_util_ = NULL; 117 } 118 119 scoped_refptr<OwnerKey> DeviceSettingsService::GetOwnerKey() { 120 return owner_key_; 121 } 122 123 void DeviceSettingsService::Load() { 124 EnqueueLoad(false); 125 } 126 127 void DeviceSettingsService::SignAndStore( 128 scoped_ptr<em::ChromeDeviceSettingsProto> new_settings, 129 const base::Closure& callback) { 130 Enqueue( 131 new SignAndStoreSettingsOperation( 132 base::Bind(&DeviceSettingsService::HandleCompletedOperation, 133 weak_factory_.GetWeakPtr(), 134 callback), 135 new_settings.Pass(), 136 username_)); 137 } 138 139 void DeviceSettingsService::Store(scoped_ptr<em::PolicyFetchResponse> policy, 140 const base::Closure& callback) { 141 Enqueue( 142 new StoreSettingsOperation( 143 base::Bind(&DeviceSettingsService::HandleCompletedOperation, 144 weak_factory_.GetWeakPtr(), 145 callback), 146 policy.Pass())); 147 } 148 149 DeviceSettingsService::OwnershipStatus 150 DeviceSettingsService::GetOwnershipStatus() { 151 if (owner_key_.get()) 152 return owner_key_->public_key() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; 153 154 return OWNERSHIP_UNKNOWN; 155 } 156 157 void DeviceSettingsService::GetOwnershipStatusAsync( 158 const OwnershipStatusCallback& callback) { 159 if (owner_key_.get()) { 160 // If there is a key, report status immediately. 161 base::MessageLoop::current()->PostTask( 162 FROM_HERE, 163 base::Bind( 164 callback, 165 owner_key_->public_key() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE)); 166 } else { 167 // If the key hasn't been loaded yet, enqueue the callback to be fired when 168 // the next SessionManagerOperation completes. If no operation is pending, 169 // start a load operation to fetch the key and report the result. 170 pending_ownership_status_callbacks_.push_back(callback); 171 if (pending_operations_.empty()) 172 EnqueueLoad(false); 173 } 174 } 175 176 bool DeviceSettingsService::HasPrivateOwnerKey() { 177 return owner_key_.get() && owner_key_->private_key(); 178 } 179 180 void DeviceSettingsService::IsCurrentUserOwnerAsync( 181 const IsCurrentUserOwnerCallback& callback) { 182 if (owner_key_loaded_with_certificates_) { 183 // If the current owner key was loaded while the certificates were loaded, 184 // or the certificate loader is not initialized, in which case the private 185 // key cannot be set, report status immediately. 186 base::MessageLoop::current()->PostTask( 187 FROM_HERE, 188 base::Bind(callback, HasPrivateOwnerKey())); 189 } else { 190 // If the key hasn't been loaded with the known certificates, enqueue the 191 // callback to be fired when the next SessionManagerOperation completes in 192 // an environment where the certificates are loaded. There is no need to 193 // start a new operation, as the reload operation will be started when the 194 // certificates are loaded. 195 pending_is_current_user_owner_callbacks_.push_back(callback); 196 } 197 } 198 199 void DeviceSettingsService::SetUsername(const std::string& username) { 200 username_ = username; 201 202 // The private key may have become available, so force a key reload. 203 owner_key_ = NULL; 204 EnsureReload(true); 205 } 206 207 const std::string& DeviceSettingsService::GetUsername() const { 208 return username_; 209 } 210 211 void DeviceSettingsService::AddObserver(Observer* observer) { 212 observers_.AddObserver(observer); 213 } 214 215 void DeviceSettingsService::RemoveObserver(Observer* observer) { 216 observers_.RemoveObserver(observer); 217 } 218 219 void DeviceSettingsService::OwnerKeySet(bool success) { 220 if (!success) { 221 LOG(ERROR) << "Owner key change failed."; 222 return; 223 } 224 225 owner_key_ = NULL; 226 EnsureReload(true); 227 } 228 229 void DeviceSettingsService::PropertyChangeComplete(bool success) { 230 if (!success) { 231 LOG(ERROR) << "Policy update failed."; 232 return; 233 } 234 235 EnsureReload(false); 236 } 237 238 void DeviceSettingsService::OnCertificatesLoaded( 239 const net::CertificateList& cert_list, 240 bool initial_load) { 241 certificates_loaded_ = true; 242 // CertLoader initializes the TPM and NSS database which is necessary to 243 // determine ownership. Force a reload once we know these are initialized. 244 EnsureReload(true); 245 } 246 247 void DeviceSettingsService::Enqueue(SessionManagerOperation* operation) { 248 pending_operations_.push_back(operation); 249 if (pending_operations_.front() == operation) 250 StartNextOperation(); 251 } 252 253 void DeviceSettingsService::EnqueueLoad(bool force_key_load) { 254 SessionManagerOperation* operation = 255 new LoadSettingsOperation( 256 base::Bind(&DeviceSettingsService::HandleCompletedOperation, 257 weak_factory_.GetWeakPtr(), 258 base::Closure())); 259 operation->set_force_key_load(force_key_load); 260 Enqueue(operation); 261 } 262 263 void DeviceSettingsService::EnsureReload(bool force_key_load) { 264 if (!pending_operations_.empty()) 265 pending_operations_.front()->RestartLoad(force_key_load); 266 else 267 EnqueueLoad(force_key_load); 268 } 269 270 void DeviceSettingsService::StartNextOperation() { 271 if (!pending_operations_.empty() && 272 session_manager_client_ && 273 owner_key_util_.get()) { 274 pending_operations_.front()->Start(session_manager_client_, 275 owner_key_util_, owner_key_); 276 } 277 } 278 279 void DeviceSettingsService::HandleCompletedOperation( 280 const base::Closure& callback, 281 SessionManagerOperation* operation, 282 Status status) { 283 DCHECK_EQ(operation, pending_operations_.front()); 284 store_status_ = status; 285 286 OwnershipStatus ownership_status = OWNERSHIP_UNKNOWN; 287 bool is_owner = false; 288 scoped_refptr<OwnerKey> new_key(operation->owner_key()); 289 if (new_key.get()) { 290 ownership_status = 291 new_key->public_key() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; 292 is_owner = (new_key->private_key() != NULL); 293 } else { 294 NOTREACHED() << "Failed to determine key status."; 295 } 296 297 bool new_owner_key = false; 298 if (owner_key_.get() != new_key.get()) { 299 owner_key_ = new_key; 300 new_owner_key = true; 301 } 302 303 if (status == STORE_SUCCESS) { 304 policy_data_ = operation->policy_data().Pass(); 305 device_settings_ = operation->device_settings().Pass(); 306 load_retries_left_ = kMaxLoadRetries; 307 } else if (status != STORE_KEY_UNAVAILABLE) { 308 LOG(ERROR) << "Session manager operation failed: " << status; 309 // Validation errors can be temprary if the rtc has went on holiday for a 310 // short while. So we will retry such loads for up to 10 minutes. 311 if (status == STORE_TEMP_VALIDATION_ERROR) { 312 if (load_retries_left_ > 0) { 313 load_retries_left_--; 314 LOG(ERROR) << "A re-load has been scheduled due to a validation error."; 315 content::BrowserThread::PostDelayedTask( 316 content::BrowserThread::UI, 317 FROM_HERE, 318 base::Bind(&DeviceSettingsService::Load, base::Unretained(this)), 319 base::TimeDelta::FromMilliseconds(kLoadRetryDelayMs)); 320 } 321 } 322 } 323 324 if (new_owner_key) { 325 FOR_EACH_OBSERVER(Observer, observers_, OwnershipStatusChanged()); 326 content::NotificationService::current()->Notify( 327 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, 328 content::Source<DeviceSettingsService>(this), 329 content::NotificationService::NoDetails()); 330 } 331 332 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); 333 334 std::vector<OwnershipStatusCallback> callbacks; 335 callbacks.swap(pending_ownership_status_callbacks_); 336 for (std::vector<OwnershipStatusCallback>::iterator iter(callbacks.begin()); 337 iter != callbacks.end(); ++iter) { 338 iter->Run(ownership_status); 339 } 340 341 if (certificates_loaded_) { 342 owner_key_loaded_with_certificates_ = true; 343 std::vector<IsCurrentUserOwnerCallback> is_owner_callbacks; 344 is_owner_callbacks.swap(pending_is_current_user_owner_callbacks_); 345 for (std::vector<IsCurrentUserOwnerCallback>::iterator iter( 346 is_owner_callbacks.begin()); 347 iter != is_owner_callbacks.end(); ++iter) { 348 iter->Run(is_owner); 349 } 350 } 351 352 // The completion callback happens after the notification so clients can 353 // filter self-triggered updates. 354 if (!callback.is_null()) 355 callback.Run(); 356 357 // Only remove the pending operation here, so new operations triggered by any 358 // of the callbacks above are queued up properly. 359 pending_operations_.pop_front(); 360 delete operation; 361 362 StartNextOperation(); 363 } 364 365 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() { 366 DeviceSettingsService::Initialize(); 367 } 368 369 ScopedTestDeviceSettingsService::~ScopedTestDeviceSettingsService() { 370 DeviceSettingsService::Shutdown(); 371 } 372 373 } // namespace chromeos 374