device_settings_service.h revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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
23namespace crypto {
24class RSAPrivateKey;
25}
26
27namespace enterprise_management {
28class ChromeDeviceSettingsProto;
29}
30
31namespace chromeos {
32
33class OwnerKeyUtil;
34class PublicKey;
35class 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.
49class 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.
269class 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