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
|
// 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/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/policy/cloud_policy_validator.h"
#include "chromeos/dbus/session_manager_client.h"
namespace base {
template <typename T> struct DefaultLazyInstanceTraits;
}
namespace crypto {
class RSAPrivateKey;
}
namespace enterprise_management {
class ChromeDeviceSettingsProto;
class PolicyData;
class PolicyFetchResponse;
}
namespace chromeos {
class OwnerKeyUtil;
class SessionManagerOperation;
// Keeps the public and private halves of the owner key. Both may be missing,
// but if the private key is present, the public half will be as well. This
// class is immutable and refcounted in order to allow safe access from any
// thread.
class OwnerKey : public base::RefCountedThreadSafe<OwnerKey> {
public:
OwnerKey(scoped_ptr<std::vector<uint8> > public_key,
scoped_ptr<crypto::RSAPrivateKey> private_key);
const std::vector<uint8>* public_key() {
return public_key_.get();
}
crypto::RSAPrivateKey* private_key() {
return private_key_.get();
}
private:
friend class base::RefCountedThreadSafe<OwnerKey>;
~OwnerKey();
scoped_ptr<std::vector<uint8> > public_key_;
scoped_ptr<crypto::RSAPrivateKey> private_key_;
DISALLOW_COPY_AND_ASSIGN(OwnerKey);
};
// 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, bool)> 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, // 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;
};
// Creates a device settings service instance. This is meant for unit tests,
// production code uses the singleton returned by Get() below.
DeviceSettingsService();
~DeviceSettingsService();
// Returns the singleton instance.
static DeviceSettingsService* Get();
// To be called on startup once threads are initialized and DBus is ready.
void Initialize(SessionManagerClient* session_manager_client,
scoped_refptr<OwnerKeyUtil> owner_key_util);
// Prevents the service from making further calls to session_manager_client
// and stops any pending operations.
void Shutdown();
// 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<OwnerKey> GetOwnerKey();
// 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);
// 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 SetUsername(const std::string& username);
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:
// 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);
SessionManagerClient* session_manager_client_;
scoped_refptr<OwnerKeyUtil> owner_key_util_;
base::WeakPtrFactory<DeviceSettingsService> weak_factory_;
Status store_status_;
std::vector<OwnershipStatusCallback> pending_ownership_status_callbacks_;
std::string username_;
scoped_refptr<OwnerKey> owner_key_;
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_;
DISALLOW_COPY_AND_ASSIGN(DeviceSettingsService);
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_SERVICE_H_
|