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 "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