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