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