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