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 #ifndef CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_SERVICE_H_
      6 #define CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_SERVICE_H_
      7 
      8 #include <deque>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/callback.h"
     14 #include "base/compiler_specific.h"
     15 #include "base/memory/ref_counted.h"
     16 #include "base/memory/scoped_ptr.h"
     17 #include "base/observer_list.h"
     18 #include "chromeos/dbus/session_manager_client.h"
     19 #include "components/policy/core/common/cloud/cloud_policy_validator.h"
     20 #include "crypto/scoped_nss_types.h"
     21 #include "policy/proto/device_management_backend.pb.h"
     22 
     23 namespace crypto {
     24 class RSAPrivateKey;
     25 }
     26 
     27 namespace enterprise_management {
     28 class ChromeDeviceSettingsProto;
     29 }
     30 
     31 namespace chromeos {
     32 
     33 class OwnerKeyUtil;
     34 class PublicKey;
     35 class SessionManagerOperation;
     36 
     37 // Deals with the low-level interface to Chromium OS device settings. Device
     38 // settings are stored in a protobuf that's protected by a cryptographic
     39 // signature generated by a key in the device owner's possession. Key and
     40 // settings are brokered by the session_manager daemon.
     41 //
     42 // The purpose of DeviceSettingsService is to keep track of the current key and
     43 // settings blob. For reading and writing device settings, use CrosSettings
     44 // instead, which provides a high-level interface that allows for manipulation
     45 // of individual settings.
     46 //
     47 // DeviceSettingsService generates notifications for key and policy update
     48 // events so interested parties can reload state as appropriate.
     49 class DeviceSettingsService : public SessionManagerClient::Observer {
     50  public:
     51   // Indicates ownership status of the device.
     52   enum OwnershipStatus {
     53     // Listed in upgrade order.
     54     OWNERSHIP_UNKNOWN = 0,
     55     OWNERSHIP_NONE,
     56     OWNERSHIP_TAKEN
     57   };
     58 
     59   typedef base::Callback<void(OwnershipStatus)> OwnershipStatusCallback;
     60 
     61   // Status codes for Store().
     62   enum Status {
     63     STORE_SUCCESS,
     64     STORE_KEY_UNAVAILABLE,       // Owner key not yet configured.
     65     STORE_POLICY_ERROR,          // Failure constructing the settings blob.
     66     STORE_OPERATION_FAILED,      // IPC to session_manager daemon failed.
     67     STORE_NO_POLICY,             // No settings blob present.
     68     STORE_INVALID_POLICY,        // Invalid settings blob.
     69     STORE_VALIDATION_ERROR,      // Unrecoverable policy validation failure.
     70     STORE_TEMP_VALIDATION_ERROR, // Temporary policy validation failure.
     71   };
     72 
     73   // Observer interface.
     74   class Observer {
     75    public:
     76     virtual ~Observer();
     77 
     78     // Indicates device ownership status changes.
     79     virtual void OwnershipStatusChanged() = 0;
     80 
     81     // Gets call after updates to the device settings.
     82     virtual void DeviceSettingsUpdated() = 0;
     83   };
     84 
     85   class PrivateKeyDelegate {
     86    public:
     87     typedef base::Callback<void(bool is_owner)> IsOwnerCallback;
     88     typedef base::Callback<void(std::string policy_blob)>
     89         AssembleAndSignPolicyCallback;
     90 
     91     virtual ~PrivateKeyDelegate() {}
     92 
     93     // Returns whether current user is owner or not. When this method
     94     // is called too early, incorrect result can be returned because
     95     // private key loading may be in progress.
     96     virtual bool IsOwner() = 0;
     97 
     98     // Determines whether current user is owner or not, responds via
     99     // |callback|.
    100     virtual void IsOwnerAsync(const IsOwnerCallback& callback) = 0;
    101 
    102     // Assembles and signs |policy|, responds via |callback|.
    103     virtual bool AssembleAndSignPolicyAsync(
    104         scoped_ptr<enterprise_management::PolicyData> policy,
    105         const AssembleAndSignPolicyCallback& callback) = 0;
    106   };
    107 
    108   // Manage singleton instance.
    109   static void Initialize();
    110   static bool IsInitialized();
    111   static void Shutdown();
    112   static DeviceSettingsService* Get();
    113 
    114   // Creates a device settings service instance. This is meant for unit tests,
    115   // production code uses the singleton returned by Get() above.
    116   DeviceSettingsService();
    117   virtual ~DeviceSettingsService();
    118 
    119   // To be called on startup once threads are initialized and DBus is ready.
    120   void SetSessionManager(SessionManagerClient* session_manager_client,
    121                          scoped_refptr<OwnerKeyUtil> owner_key_util);
    122 
    123   // Prevents the service from making further calls to session_manager_client
    124   // and stops any pending operations.
    125   void UnsetSessionManager();
    126 
    127   // Returns the currently active device settings. Returns NULL if the device
    128   // settings have not been retrieved from session_manager yet.
    129   const enterprise_management::PolicyData* policy_data() {
    130     return policy_data_.get();
    131   }
    132   const enterprise_management::ChromeDeviceSettingsProto*
    133       device_settings() const {
    134     return device_settings_.get();
    135   }
    136 
    137   // Returns the currently used owner key.
    138   scoped_refptr<PublicKey> GetPublicKey();
    139 
    140   // Returns the status generated by the last operation.
    141   Status status() {
    142     return store_status_;
    143   }
    144 
    145   // Triggers an attempt to pull the public half of the owner key from disk and
    146   // load the device settings.
    147   void Load();
    148 
    149   // Signs |settings| with the private half of the owner key and sends the
    150   // resulting policy blob to session manager for storage. The result of the
    151   // operation is reported through |callback|. If successful, the updated device
    152   // settings are present in policy_data() and device_settings() when the
    153   // callback runs.
    154   void SignAndStore(
    155       scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> new_settings,
    156       const base::Closure& callback);
    157 
    158   // Sets the management related settings in PolicyData. Note that if
    159   // |management_mode| is NOT_MANAGED, |request_token| and |device_id| should be
    160   // empty strings.
    161   void SetManagementSettings(
    162       enterprise_management::PolicyData::ManagementMode management_mode,
    163       const std::string& request_token,
    164       const std::string& device_id,
    165       const base::Closure& callback);
    166 
    167   // Stores a policy blob to session_manager. The result of the operation is
    168   // reported through |callback|. If successful, the updated device settings are
    169   // present in policy_data() and device_settings() when the callback runs.
    170   void Store(scoped_ptr<enterprise_management::PolicyFetchResponse> policy,
    171              const base::Closure& callback);
    172 
    173   // Returns the ownership status. May return OWNERSHIP_UNKNOWN if the disk
    174   // hasn't been checked yet.
    175   OwnershipStatus GetOwnershipStatus();
    176 
    177   // Determines the ownership status and reports the result to |callback|. This
    178   // is guaranteed to never return OWNERSHIP_UNKNOWN.
    179   void GetOwnershipStatusAsync(const OwnershipStatusCallback& callback);
    180 
    181   // Checks whether we have the private owner key.
    182   bool HasPrivateOwnerKey();
    183 
    184   // Sets the identity of the user that's interacting with the service. This is
    185   // relevant only for writing settings through SignAndStore().
    186   void InitOwner(const std::string& username,
    187                  const base::WeakPtr<PrivateKeyDelegate>& delegate);
    188   const std::string& GetUsername() const;
    189 
    190   // Adds an observer.
    191   void AddObserver(Observer* observer);
    192   // Removes an observer.
    193   void RemoveObserver(Observer* observer);
    194 
    195   // SessionManagerClient::Observer:
    196   virtual void OwnerKeySet(bool success) OVERRIDE;
    197   virtual void PropertyChangeComplete(bool success) OVERRIDE;
    198 
    199  private:
    200   // Enqueues a new operation. Takes ownership of |operation| and starts it
    201   // right away if there is no active operation currently.
    202   void Enqueue(SessionManagerOperation* operation);
    203 
    204   // Enqueues a load operation.
    205   void EnqueueLoad(bool force_key_load);
    206 
    207   void EnqueueSignAndStore(scoped_ptr<enterprise_management::PolicyData> policy,
    208                            const base::Closure& callback);
    209 
    210   // Makes sure there's a reload operation so changes to the settings (and key,
    211   // in case force_key_load is set) are getting picked up.
    212   void EnsureReload(bool force_key_load);
    213 
    214   // Runs the next pending operation.
    215   void StartNextOperation();
    216 
    217   // Updates status, policy data and owner key from a finished operation.
    218   // Starts the next pending operation if available.
    219   void HandleCompletedOperation(const base::Closure& callback,
    220                                 SessionManagerOperation* operation,
    221                                 Status status);
    222 
    223   // Updates status and invokes the callback immediately.
    224   void HandleError(Status status, const base::Closure& callback);
    225 
    226   // Assembles PolicyData based on |settings| and the current |policy_data_|
    227   // and |username_|.
    228   scoped_ptr<enterprise_management::PolicyData> AssemblePolicy(
    229       const enterprise_management::ChromeDeviceSettingsProto& settings) const;
    230 
    231   // Returns the current management mode.
    232   enterprise_management::PolicyData::ManagementMode GetManagementMode() const;
    233 
    234   // Returns true if it is okay to transfer from the current mode to the new
    235   // mode. This function should be called in SetManagementMode().
    236   bool CheckManagementModeTransition(
    237       enterprise_management::PolicyData::ManagementMode new_mode) const;
    238 
    239   SessionManagerClient* session_manager_client_;
    240   scoped_refptr<OwnerKeyUtil> owner_key_util_;
    241 
    242   Status store_status_;
    243 
    244   std::vector<OwnershipStatusCallback> pending_ownership_status_callbacks_;
    245 
    246   std::string username_;
    247   scoped_refptr<PublicKey> public_key_;
    248   base::WeakPtr<PrivateKeyDelegate> delegate_;
    249 
    250   scoped_ptr<enterprise_management::PolicyData> policy_data_;
    251   scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> device_settings_;
    252 
    253   // The queue of pending operations. The first operation on the queue is
    254   // currently active; it gets removed and destroyed once it completes.
    255   std::deque<SessionManagerOperation*> pending_operations_;
    256 
    257   ObserverList<Observer, true> observers_;
    258 
    259   // For recoverable load errors how many retries are left before we give up.
    260   int load_retries_left_;
    261 
    262   base::WeakPtrFactory<DeviceSettingsService> weak_factory_;
    263 
    264   DISALLOW_COPY_AND_ASSIGN(DeviceSettingsService);
    265 };
    266 
    267 // Helper class for tests. Initializes the DeviceSettingsService singleton on
    268 // construction and tears it down again on destruction.
    269 class ScopedTestDeviceSettingsService {
    270  public:
    271   ScopedTestDeviceSettingsService();
    272   ~ScopedTestDeviceSettingsService();
    273 
    274  private:
    275   DISALLOW_COPY_AND_ASSIGN(ScopedTestDeviceSettingsService);
    276 };
    277 
    278 }  // namespace chromeos
    279 
    280 #endif  // CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_SERVICE_H_
    281