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