Home | History | Annotate | Download | only in settings
      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