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/settings/owner_key_util.h" 13 #include "chrome/browser/chromeos/settings/session_manager_operation.h" 14 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" 15 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" 16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/notification_service.h" 18 #include "content/public/browser/notification_source.h" 19 #include "crypto/rsa_private_key.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 load_retries_left_(kMaxLoadRetries) { 78 if (CertLoader::IsInitialized()) 79 CertLoader::Get()->AddObserver(this); 80 } 81 82 DeviceSettingsService::~DeviceSettingsService() { 83 DCHECK(pending_operations_.empty()); 84 if (CertLoader::IsInitialized()) 85 CertLoader::Get()->RemoveObserver(this); 86 } 87 88 void DeviceSettingsService::SetSessionManager( 89 SessionManagerClient* session_manager_client, 90 scoped_refptr<OwnerKeyUtil> owner_key_util) { 91 DCHECK(session_manager_client); 92 DCHECK(owner_key_util.get()); 93 DCHECK(!session_manager_client_); 94 DCHECK(!owner_key_util_.get()); 95 96 session_manager_client_ = session_manager_client; 97 owner_key_util_ = owner_key_util; 98 99 session_manager_client_->AddObserver(this); 100 101 StartNextOperation(); 102 } 103 104 void DeviceSettingsService::UnsetSessionManager() { 105 STLDeleteContainerPointers(pending_operations_.begin(), 106 pending_operations_.end()); 107 pending_operations_.clear(); 108 109 if (session_manager_client_) 110 session_manager_client_->RemoveObserver(this); 111 session_manager_client_ = NULL; 112 owner_key_util_ = NULL; 113 } 114 115 scoped_refptr<OwnerKey> DeviceSettingsService::GetOwnerKey() { 116 return owner_key_; 117 } 118 119 void DeviceSettingsService::Load() { 120 EnqueueLoad(false); 121 } 122 123 void DeviceSettingsService::SignAndStore( 124 scoped_ptr<em::ChromeDeviceSettingsProto> new_settings, 125 const base::Closure& callback) { 126 Enqueue( 127 new SignAndStoreSettingsOperation( 128 base::Bind(&DeviceSettingsService::HandleCompletedOperation, 129 weak_factory_.GetWeakPtr(), 130 callback), 131 new_settings.Pass(), 132 username_)); 133 } 134 135 void DeviceSettingsService::Store(scoped_ptr<em::PolicyFetchResponse> policy, 136 const base::Closure& callback) { 137 Enqueue( 138 new StoreSettingsOperation( 139 base::Bind(&DeviceSettingsService::HandleCompletedOperation, 140 weak_factory_.GetWeakPtr(), 141 callback), 142 policy.Pass())); 143 } 144 145 DeviceSettingsService::OwnershipStatus 146 DeviceSettingsService::GetOwnershipStatus() { 147 if (owner_key_.get()) 148 return owner_key_->public_key() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; 149 150 return OWNERSHIP_UNKNOWN; 151 } 152 153 void DeviceSettingsService::GetOwnershipStatusAsync( 154 const OwnershipStatusCallback& callback) { 155 if (owner_key_.get()) { 156 // If there is a key, report status immediately. 157 base::MessageLoop::current()->PostTask( 158 FROM_HERE, 159 base::Bind(callback, 160 owner_key_->public_key() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE, 161 owner_key_->private_key() != NULL)); 162 } else { 163 // If the key hasn't been loaded yet, enqueue the callback to be fired when 164 // the next SessionManagerOperation completes. If no operation is pending, 165 // start a load operation to fetch the key and report the result. 166 pending_ownership_status_callbacks_.push_back(callback); 167 if (pending_operations_.empty()) 168 EnqueueLoad(false); 169 } 170 } 171 172 bool DeviceSettingsService::HasPrivateOwnerKey() { 173 return owner_key_.get() && owner_key_->private_key(); 174 } 175 176 void DeviceSettingsService::SetUsername(const std::string& username) { 177 username_ = username; 178 179 // The private key may have become available, so force a key reload. 180 owner_key_ = NULL; 181 EnsureReload(true); 182 } 183 184 const std::string& DeviceSettingsService::GetUsername() const { 185 return username_; 186 } 187 188 void DeviceSettingsService::AddObserver(Observer* observer) { 189 observers_.AddObserver(observer); 190 } 191 192 void DeviceSettingsService::RemoveObserver(Observer* observer) { 193 observers_.RemoveObserver(observer); 194 } 195 196 void DeviceSettingsService::OwnerKeySet(bool success) { 197 if (!success) { 198 LOG(ERROR) << "Owner key change failed."; 199 return; 200 } 201 202 owner_key_ = NULL; 203 EnsureReload(true); 204 } 205 206 void DeviceSettingsService::PropertyChangeComplete(bool success) { 207 if (!success) { 208 LOG(ERROR) << "Policy update failed."; 209 return; 210 } 211 212 EnsureReload(false); 213 } 214 215 void DeviceSettingsService::OnCertificatesLoaded( 216 const net::CertificateList& cert_list, 217 bool initial_load) { 218 // CertLoader initializes the TPM and NSS database which is necessary to 219 // determine ownership. Force a reload once we know these are initialized. 220 EnsureReload(true); 221 } 222 223 void DeviceSettingsService::Enqueue(SessionManagerOperation* operation) { 224 pending_operations_.push_back(operation); 225 if (pending_operations_.front() == operation) 226 StartNextOperation(); 227 } 228 229 void DeviceSettingsService::EnqueueLoad(bool force_key_load) { 230 SessionManagerOperation* operation = 231 new LoadSettingsOperation( 232 base::Bind(&DeviceSettingsService::HandleCompletedOperation, 233 weak_factory_.GetWeakPtr(), 234 base::Closure())); 235 operation->set_force_key_load(force_key_load); 236 Enqueue(operation); 237 } 238 239 void DeviceSettingsService::EnsureReload(bool force_key_load) { 240 if (!pending_operations_.empty()) 241 pending_operations_.front()->RestartLoad(force_key_load); 242 else 243 EnqueueLoad(force_key_load); 244 } 245 246 void DeviceSettingsService::StartNextOperation() { 247 if (!pending_operations_.empty() && 248 session_manager_client_ && 249 owner_key_util_.get()) { 250 pending_operations_.front()->Start(session_manager_client_, 251 owner_key_util_, owner_key_); 252 } 253 } 254 255 void DeviceSettingsService::HandleCompletedOperation( 256 const base::Closure& callback, 257 SessionManagerOperation* operation, 258 Status status) { 259 DCHECK_EQ(operation, pending_operations_.front()); 260 store_status_ = status; 261 262 OwnershipStatus ownership_status = OWNERSHIP_UNKNOWN; 263 bool is_owner = false; 264 scoped_refptr<OwnerKey> new_key(operation->owner_key()); 265 if (new_key.get()) { 266 ownership_status = 267 new_key->public_key() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; 268 is_owner = (new_key->private_key() != NULL); 269 } else { 270 NOTREACHED() << "Failed to determine key status."; 271 } 272 273 bool new_owner_key = false; 274 if (owner_key_.get() != new_key.get()) { 275 owner_key_ = new_key; 276 new_owner_key = true; 277 } 278 279 if (status == STORE_SUCCESS) { 280 policy_data_ = operation->policy_data().Pass(); 281 device_settings_ = operation->device_settings().Pass(); 282 load_retries_left_ = kMaxLoadRetries; 283 } else if (status != STORE_KEY_UNAVAILABLE) { 284 LOG(ERROR) << "Session manager operation failed: " << status; 285 // Validation errors can be temprary if the rtc has went on holiday for a 286 // short while. So we will retry such loads for up to 10 minutes. 287 if (status == STORE_TEMP_VALIDATION_ERROR) { 288 if (load_retries_left_ > 0) { 289 load_retries_left_--; 290 LOG(ERROR) << "A re-load has been scheduled due to a validation error."; 291 content::BrowserThread::PostDelayedTask( 292 content::BrowserThread::UI, 293 FROM_HERE, 294 base::Bind(&DeviceSettingsService::Load, base::Unretained(this)), 295 base::TimeDelta::FromMilliseconds(kLoadRetryDelayMs)); 296 } 297 } 298 } 299 300 if (new_owner_key) { 301 FOR_EACH_OBSERVER(Observer, observers_, OwnershipStatusChanged()); 302 content::NotificationService::current()->Notify( 303 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, 304 content::Source<DeviceSettingsService>(this), 305 content::NotificationService::NoDetails()); 306 } 307 308 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); 309 310 std::vector<OwnershipStatusCallback> callbacks; 311 callbacks.swap(pending_ownership_status_callbacks_); 312 for (std::vector<OwnershipStatusCallback>::iterator iter(callbacks.begin()); 313 iter != callbacks.end(); ++iter) { 314 iter->Run(ownership_status, is_owner); 315 } 316 317 // The completion callback happens after the notification so clients can 318 // filter self-triggered updates. 319 if (!callback.is_null()) 320 callback.Run(); 321 322 // Only remove the pending operation here, so new operations triggered by any 323 // of the callbacks above are queued up properly. 324 pending_operations_.pop_front(); 325 delete operation; 326 327 StartNextOperation(); 328 } 329 330 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() { 331 DeviceSettingsService::Initialize(); 332 } 333 334 ScopedTestDeviceSettingsService::~ScopedTestDeviceSettingsService() { 335 DeviceSettingsService::Shutdown(); 336 } 337 338 } // namespace chromeos 339