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 #include "chromeos/dbus/session_manager_client.h"
6
7 #include <map>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/file_util.h"
12 #include "base/files/file_path.h"
13 #include "base/location.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_util.h"
16 #include "base/threading/worker_pool.h"
17 #include "chromeos/chromeos_paths.h"
18 #include "chromeos/dbus/blocking_method_caller.h"
19 #include "chromeos/dbus/cryptohome_client.h"
20 #include "dbus/bus.h"
21 #include "dbus/message.h"
22 #include "dbus/object_path.h"
23 #include "dbus/object_proxy.h"
24 #include "third_party/cros_system_api/dbus/service_constants.h"
25
26 namespace chromeos {
27
28 // The SessionManagerClient implementation used in production.
29 class SessionManagerClientImpl : public SessionManagerClient {
30 public:
SessionManagerClientImpl()31 SessionManagerClientImpl()
32 : session_manager_proxy_(NULL),
33 weak_ptr_factory_(this) {}
34
~SessionManagerClientImpl()35 virtual ~SessionManagerClientImpl() {
36 }
37
38 // SessionManagerClient overrides:
AddObserver(Observer * observer)39 virtual void AddObserver(Observer* observer) OVERRIDE {
40 observers_.AddObserver(observer);
41 }
42
RemoveObserver(Observer * observer)43 virtual void RemoveObserver(Observer* observer) OVERRIDE {
44 observers_.RemoveObserver(observer);
45 }
46
HasObserver(Observer * observer)47 virtual bool HasObserver(Observer* observer) OVERRIDE {
48 return observers_.HasObserver(observer);
49 }
50
EmitLoginPromptReady()51 virtual void EmitLoginPromptReady() OVERRIDE {
52 SimpleMethodCallToSessionManager(
53 login_manager::kSessionManagerEmitLoginPromptReady);
54 }
55
EmitLoginPromptVisible()56 virtual void EmitLoginPromptVisible() OVERRIDE {
57 SimpleMethodCallToSessionManager(
58 login_manager::kSessionManagerEmitLoginPromptVisible);
59 FOR_EACH_OBSERVER(Observer, observers_, EmitLoginPromptVisibleCalled());
60 }
61
RestartJob(int pid,const std::string & command_line)62 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {
63 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
64 login_manager::kSessionManagerRestartJob);
65 dbus::MessageWriter writer(&method_call);
66 writer.AppendInt32(pid);
67 writer.AppendString(command_line);
68 session_manager_proxy_->CallMethod(
69 &method_call,
70 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
71 base::Bind(&SessionManagerClientImpl::OnRestartJob,
72 weak_ptr_factory_.GetWeakPtr()));
73 }
74
StartSession(const std::string & user_email)75 virtual void StartSession(const std::string& user_email) OVERRIDE {
76 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
77 login_manager::kSessionManagerStartSession);
78 dbus::MessageWriter writer(&method_call);
79 writer.AppendString(user_email);
80 writer.AppendString(""); // Unique ID is deprecated
81 session_manager_proxy_->CallMethod(
82 &method_call,
83 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
84 base::Bind(&SessionManagerClientImpl::OnStartSession,
85 weak_ptr_factory_.GetWeakPtr()));
86 }
87
StopSession()88 virtual void StopSession() OVERRIDE {
89 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
90 login_manager::kSessionManagerStopSession);
91 dbus::MessageWriter writer(&method_call);
92 writer.AppendString(""); // Unique ID is deprecated
93 session_manager_proxy_->CallMethod(
94 &method_call,
95 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
96 base::Bind(&SessionManagerClientImpl::OnStopSession,
97 weak_ptr_factory_.GetWeakPtr()));
98 }
99
StartDeviceWipe()100 virtual void StartDeviceWipe() OVERRIDE {
101 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
102 login_manager::kSessionManagerStartDeviceWipe);
103 session_manager_proxy_->CallMethod(
104 &method_call,
105 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
106 base::Bind(&SessionManagerClientImpl::OnDeviceWipe,
107 weak_ptr_factory_.GetWeakPtr()));
108 }
109
RequestLockScreen()110 virtual void RequestLockScreen() OVERRIDE {
111 SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen);
112 }
113
NotifyLockScreenShown()114 virtual void NotifyLockScreenShown() OVERRIDE {
115 SimpleMethodCallToSessionManager(
116 login_manager::kSessionManagerHandleLockScreenShown);
117 }
118
NotifyLockScreenDismissed()119 virtual void NotifyLockScreenDismissed() OVERRIDE {
120 SimpleMethodCallToSessionManager(
121 login_manager::kSessionManagerHandleLockScreenDismissed);
122 }
123
RetrieveActiveSessions(const ActiveSessionsCallback & callback)124 virtual void RetrieveActiveSessions(
125 const ActiveSessionsCallback& callback) OVERRIDE {
126 dbus::MethodCall method_call(
127 login_manager::kSessionManagerInterface,
128 login_manager::kSessionManagerRetrieveActiveSessions);
129
130 session_manager_proxy_->CallMethod(
131 &method_call,
132 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
133 base::Bind(&SessionManagerClientImpl::OnRetrieveActiveSessions,
134 weak_ptr_factory_.GetWeakPtr(),
135 login_manager::kSessionManagerRetrieveActiveSessions,
136 callback));
137 }
138
RetrieveDevicePolicy(const RetrievePolicyCallback & callback)139 virtual void RetrieveDevicePolicy(
140 const RetrievePolicyCallback& callback) OVERRIDE {
141 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
142 login_manager::kSessionManagerRetrievePolicy);
143 session_manager_proxy_->CallMethod(
144 &method_call,
145 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
146 base::Bind(&SessionManagerClientImpl::OnRetrievePolicy,
147 weak_ptr_factory_.GetWeakPtr(),
148 login_manager::kSessionManagerRetrievePolicy,
149 callback));
150 }
151
RetrievePolicyForUser(const std::string & username,const RetrievePolicyCallback & callback)152 virtual void RetrievePolicyForUser(
153 const std::string& username,
154 const RetrievePolicyCallback& callback) OVERRIDE {
155 CallRetrievePolicyByUsername(
156 login_manager::kSessionManagerRetrievePolicyForUser,
157 username,
158 callback);
159 }
160
BlockingRetrievePolicyForUser(const std::string & username)161 virtual std::string BlockingRetrievePolicyForUser(
162 const std::string& username) OVERRIDE {
163 dbus::MethodCall method_call(
164 login_manager::kSessionManagerInterface,
165 login_manager::kSessionManagerRetrievePolicyForUser);
166 dbus::MessageWriter writer(&method_call);
167 writer.AppendString(username);
168 scoped_ptr<dbus::Response> response =
169 blocking_method_caller_->CallMethodAndBlock(&method_call);
170 std::string policy;
171 ExtractString(login_manager::kSessionManagerRetrievePolicyForUser,
172 response.get(),
173 &policy);
174 return policy;
175 }
176
RetrieveDeviceLocalAccountPolicy(const std::string & account_name,const RetrievePolicyCallback & callback)177 virtual void RetrieveDeviceLocalAccountPolicy(
178 const std::string& account_name,
179 const RetrievePolicyCallback& callback) OVERRIDE {
180 CallRetrievePolicyByUsername(
181 login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy,
182 account_name,
183 callback);
184 }
185
StoreDevicePolicy(const std::string & policy_blob,const StorePolicyCallback & callback)186 virtual void StoreDevicePolicy(const std::string& policy_blob,
187 const StorePolicyCallback& callback) OVERRIDE {
188 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
189 login_manager::kSessionManagerStorePolicy);
190 dbus::MessageWriter writer(&method_call);
191 // static_cast does not work due to signedness.
192 writer.AppendArrayOfBytes(
193 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
194 session_manager_proxy_->CallMethod(
195 &method_call,
196 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
197 base::Bind(&SessionManagerClientImpl::OnStorePolicy,
198 weak_ptr_factory_.GetWeakPtr(),
199 login_manager::kSessionManagerStorePolicy,
200 callback));
201 }
202
StorePolicyForUser(const std::string & username,const std::string & policy_blob,const std::string & ignored_policy_key,const StorePolicyCallback & callback)203 virtual void StorePolicyForUser(
204 const std::string& username,
205 const std::string& policy_blob,
206 const std::string& ignored_policy_key,
207 const StorePolicyCallback& callback) OVERRIDE {
208 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser,
209 username,
210 policy_blob,
211 callback);
212 }
213
StoreDeviceLocalAccountPolicy(const std::string & account_name,const std::string & policy_blob,const StorePolicyCallback & callback)214 virtual void StoreDeviceLocalAccountPolicy(
215 const std::string& account_name,
216 const std::string& policy_blob,
217 const StorePolicyCallback& callback) OVERRIDE {
218 CallStorePolicyByUsername(
219 login_manager::kSessionManagerStoreDeviceLocalAccountPolicy,
220 account_name,
221 policy_blob,
222 callback);
223 }
224
SetFlagsForUser(const std::string & username,const std::vector<std::string> & flags)225 virtual void SetFlagsForUser(const std::string& username,
226 const std::vector<std::string>& flags) OVERRIDE {
227 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
228 login_manager::kSessionManagerSetFlagsForUser);
229 dbus::MessageWriter writer(&method_call);
230 writer.AppendString(username);
231 writer.AppendArrayOfStrings(flags);
232 session_manager_proxy_->CallMethod(
233 &method_call,
234 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
235 dbus::ObjectProxy::EmptyResponseCallback());
236 }
237
238 protected:
Init(dbus::Bus * bus)239 virtual void Init(dbus::Bus* bus) OVERRIDE {
240 session_manager_proxy_ = bus->GetObjectProxy(
241 login_manager::kSessionManagerServiceName,
242 dbus::ObjectPath(login_manager::kSessionManagerServicePath));
243 blocking_method_caller_.reset(
244 new BlockingMethodCaller(bus, session_manager_proxy_));
245
246 // Signals emitted on Chromium's interface. Many of these ought to be
247 // method calls instead.
248 session_manager_proxy_->ConnectToSignal(
249 chromium::kChromiumInterface,
250 chromium::kOwnerKeySetSignal,
251 base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived,
252 weak_ptr_factory_.GetWeakPtr()),
253 base::Bind(&SessionManagerClientImpl::SignalConnected,
254 weak_ptr_factory_.GetWeakPtr()));
255 session_manager_proxy_->ConnectToSignal(
256 chromium::kChromiumInterface,
257 chromium::kPropertyChangeCompleteSignal,
258 base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived,
259 weak_ptr_factory_.GetWeakPtr()),
260 base::Bind(&SessionManagerClientImpl::SignalConnected,
261 weak_ptr_factory_.GetWeakPtr()));
262 session_manager_proxy_->ConnectToSignal(
263 chromium::kChromiumInterface,
264 chromium::kLockScreenSignal,
265 base::Bind(&SessionManagerClientImpl::ScreenLockReceived,
266 weak_ptr_factory_.GetWeakPtr()),
267 base::Bind(&SessionManagerClientImpl::SignalConnected,
268 weak_ptr_factory_.GetWeakPtr()));
269 session_manager_proxy_->ConnectToSignal(
270 chromium::kChromiumInterface,
271 chromium::kLivenessRequestedSignal,
272 base::Bind(&SessionManagerClientImpl::LivenessRequestedReceived,
273 weak_ptr_factory_.GetWeakPtr()),
274 base::Bind(&SessionManagerClientImpl::SignalConnected,
275 weak_ptr_factory_.GetWeakPtr()));
276
277 // Signals emitted on the session manager's interface.
278 session_manager_proxy_->ConnectToSignal(
279 login_manager::kSessionManagerInterface,
280 login_manager::kScreenIsLockedSignal,
281 base::Bind(&SessionManagerClientImpl::ScreenIsLockedReceived,
282 weak_ptr_factory_.GetWeakPtr()),
283 base::Bind(&SessionManagerClientImpl::SignalConnected,
284 weak_ptr_factory_.GetWeakPtr()));
285 session_manager_proxy_->ConnectToSignal(
286 login_manager::kSessionManagerInterface,
287 login_manager::kScreenIsUnlockedSignal,
288 base::Bind(&SessionManagerClientImpl::ScreenIsUnlockedReceived,
289 weak_ptr_factory_.GetWeakPtr()),
290 base::Bind(&SessionManagerClientImpl::SignalConnected,
291 weak_ptr_factory_.GetWeakPtr()));
292 }
293
294 private:
295 // Makes a method call to the session manager with no arguments and no
296 // response.
SimpleMethodCallToSessionManager(const std::string & method_name)297 void SimpleMethodCallToSessionManager(const std::string& method_name) {
298 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
299 method_name);
300 session_manager_proxy_->CallMethod(
301 &method_call,
302 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
303 dbus::ObjectProxy::EmptyResponseCallback());
304 }
305
306 // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser.
CallRetrievePolicyByUsername(const std::string & method_name,const std::string & username,const RetrievePolicyCallback & callback)307 void CallRetrievePolicyByUsername(const std::string& method_name,
308 const std::string& username,
309 const RetrievePolicyCallback& callback) {
310 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
311 method_name);
312 dbus::MessageWriter writer(&method_call);
313 writer.AppendString(username);
314 session_manager_proxy_->CallMethod(
315 &method_call,
316 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
317 base::Bind(
318 &SessionManagerClientImpl::OnRetrievePolicy,
319 weak_ptr_factory_.GetWeakPtr(),
320 method_name,
321 callback));
322 }
323
CallStorePolicyByUsername(const std::string & method_name,const std::string & username,const std::string & policy_blob,const StorePolicyCallback & callback)324 void CallStorePolicyByUsername(const std::string& method_name,
325 const std::string& username,
326 const std::string& policy_blob,
327 const StorePolicyCallback& callback) {
328 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
329 method_name);
330 dbus::MessageWriter writer(&method_call);
331 writer.AppendString(username);
332 // static_cast does not work due to signedness.
333 writer.AppendArrayOfBytes(
334 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
335 session_manager_proxy_->CallMethod(
336 &method_call,
337 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
338 base::Bind(
339 &SessionManagerClientImpl::OnStorePolicy,
340 weak_ptr_factory_.GetWeakPtr(),
341 method_name,
342 callback));
343 }
344
345 // Called when kSessionManagerRestartJob method is complete.
OnRestartJob(dbus::Response * response)346 void OnRestartJob(dbus::Response* response) {
347 LOG_IF(ERROR, !response)
348 << "Failed to call "
349 << login_manager::kSessionManagerRestartJob;
350 }
351
352 // Called when kSessionManagerStartSession method is complete.
OnStartSession(dbus::Response * response)353 void OnStartSession(dbus::Response* response) {
354 LOG_IF(ERROR, !response)
355 << "Failed to call "
356 << login_manager::kSessionManagerStartSession;
357 }
358
359 // Called when kSessionManagerStopSession method is complete.
OnStopSession(dbus::Response * response)360 void OnStopSession(dbus::Response* response) {
361 LOG_IF(ERROR, !response)
362 << "Failed to call "
363 << login_manager::kSessionManagerStopSession;
364 }
365
366 // Called when kSessionManagerStopSession method is complete.
OnDeviceWipe(dbus::Response * response)367 void OnDeviceWipe(dbus::Response* response) {
368 LOG_IF(ERROR, !response)
369 << "Failed to call "
370 << login_manager::kSessionManagerStartDeviceWipe;
371 }
372
373 // Called when kSessionManagerRetrieveActiveSessions method is complete.
OnRetrieveActiveSessions(const std::string & method_name,const ActiveSessionsCallback & callback,dbus::Response * response)374 void OnRetrieveActiveSessions(const std::string& method_name,
375 const ActiveSessionsCallback& callback,
376 dbus::Response* response) {
377 ActiveSessionsMap sessions;
378 bool success = false;
379 if (!response) {
380 LOG(ERROR) << "Failed to call " << method_name;
381 callback.Run(sessions, success);
382 return;
383 }
384
385 dbus::MessageReader reader(response);
386 dbus::MessageReader array_reader(NULL);
387
388 if (!reader.PopArray(&array_reader)) {
389 LOG(ERROR) << method_name << " response is incorrect: "
390 << response->ToString();
391 } else {
392 while (array_reader.HasMoreData()) {
393 dbus::MessageReader dict_entry_reader(NULL);
394 std::string key;
395 std::string value;
396 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
397 !dict_entry_reader.PopString(&key) ||
398 !dict_entry_reader.PopString(&value)) {
399 LOG(ERROR) << method_name << " response is incorrect: "
400 << response->ToString();
401 } else {
402 sessions[key] = value;
403 }
404 }
405 success = true;
406 }
407 callback.Run(sessions, success);
408 }
409
ExtractString(const std::string & method_name,dbus::Response * response,std::string * extracted)410 void ExtractString(const std::string& method_name,
411 dbus::Response* response,
412 std::string* extracted) {
413 if (!response) {
414 LOG(ERROR) << "Failed to call " << method_name;
415 return;
416 }
417 dbus::MessageReader reader(response);
418 uint8* values = NULL;
419 size_t length = 0;
420 if (!reader.PopArrayOfBytes(&values, &length)) {
421 LOG(ERROR) << "Invalid response: " << response->ToString();
422 return;
423 }
424 // static_cast does not work due to signedness.
425 extracted->assign(reinterpret_cast<char*>(values), length);
426 }
427
428 // Called when kSessionManagerRetrievePolicy or
429 // kSessionManagerRetrievePolicyForUser method is complete.
OnRetrievePolicy(const std::string & method_name,const RetrievePolicyCallback & callback,dbus::Response * response)430 void OnRetrievePolicy(const std::string& method_name,
431 const RetrievePolicyCallback& callback,
432 dbus::Response* response) {
433 std::string serialized_proto;
434 ExtractString(method_name, response, &serialized_proto);
435 callback.Run(serialized_proto);
436 }
437
438 // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser
439 // method is complete.
OnStorePolicy(const std::string & method_name,const StorePolicyCallback & callback,dbus::Response * response)440 void OnStorePolicy(const std::string& method_name,
441 const StorePolicyCallback& callback,
442 dbus::Response* response) {
443 bool success = false;
444 if (!response) {
445 LOG(ERROR) << "Failed to call " << method_name;
446 } else {
447 dbus::MessageReader reader(response);
448 if (!reader.PopBool(&success))
449 LOG(ERROR) << "Invalid response: " << response->ToString();
450 }
451 callback.Run(success);
452 }
453
454 // Called when the owner key set signal is received.
OwnerKeySetReceived(dbus::Signal * signal)455 void OwnerKeySetReceived(dbus::Signal* signal) {
456 dbus::MessageReader reader(signal);
457 std::string result_string;
458 if (!reader.PopString(&result_string)) {
459 LOG(ERROR) << "Invalid signal: " << signal->ToString();
460 return;
461 }
462 const bool success = StartsWithASCII(result_string, "success", false);
463 FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success));
464 }
465
466 // Called when the property change complete signal is received.
PropertyChangeCompleteReceived(dbus::Signal * signal)467 void PropertyChangeCompleteReceived(dbus::Signal* signal) {
468 dbus::MessageReader reader(signal);
469 std::string result_string;
470 if (!reader.PopString(&result_string)) {
471 LOG(ERROR) << "Invalid signal: " << signal->ToString();
472 return;
473 }
474 const bool success = StartsWithASCII(result_string, "success", false);
475 FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success));
476 }
477
ScreenLockReceived(dbus::Signal * signal)478 void ScreenLockReceived(dbus::Signal* signal) {
479 FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
480 }
481
LivenessRequestedReceived(dbus::Signal * signal)482 void LivenessRequestedReceived(dbus::Signal* signal) {
483 SimpleMethodCallToSessionManager(
484 login_manager::kSessionManagerHandleLivenessConfirmed);
485 }
486
ScreenIsLockedReceived(dbus::Signal * signal)487 void ScreenIsLockedReceived(dbus::Signal* signal) {
488 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
489 }
490
ScreenIsUnlockedReceived(dbus::Signal * signal)491 void ScreenIsUnlockedReceived(dbus::Signal* signal) {
492 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
493 }
494
495 // Called when the object is connected to the signal.
SignalConnected(const std::string & interface_name,const std::string & signal_name,bool success)496 void SignalConnected(const std::string& interface_name,
497 const std::string& signal_name,
498 bool success) {
499 LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
500 }
501
502 dbus::ObjectProxy* session_manager_proxy_;
503 scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
504 ObserverList<Observer> observers_;
505
506 // Note: This should remain the last member so it'll be destroyed and
507 // invalidate its weak pointers before any other members are destroyed.
508 base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;
509
510 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
511 };
512
513 // The SessionManagerClient implementation used on Linux desktop,
514 // which does nothing.
515 class SessionManagerClientStubImpl : public SessionManagerClient {
516 public:
SessionManagerClientStubImpl()517 SessionManagerClientStubImpl() {}
~SessionManagerClientStubImpl()518 virtual ~SessionManagerClientStubImpl() {}
519
520 // SessionManagerClient overrides
Init(dbus::Bus * bus)521 virtual void Init(dbus::Bus* bus) OVERRIDE {
522 // Make sure that there are no keys left over from a previous browser run.
523 base::FilePath user_policy_key_dir;
524 if (PathService::Get(chromeos::DIR_USER_POLICY_KEYS,
525 &user_policy_key_dir)) {
526 base::WorkerPool::PostTask(
527 FROM_HERE,
528 base::Bind(base::IgnoreResult(&base::DeleteFile),
529 user_policy_key_dir, true),
530 false);
531 }
532 }
533
AddObserver(Observer * observer)534 virtual void AddObserver(Observer* observer) OVERRIDE {
535 observers_.AddObserver(observer);
536 }
RemoveObserver(Observer * observer)537 virtual void RemoveObserver(Observer* observer) OVERRIDE {
538 observers_.RemoveObserver(observer);
539 }
HasObserver(Observer * observer)540 virtual bool HasObserver(Observer* observer) OVERRIDE {
541 return observers_.HasObserver(observer);
542 }
EmitLoginPromptReady()543 virtual void EmitLoginPromptReady() OVERRIDE {}
EmitLoginPromptVisible()544 virtual void EmitLoginPromptVisible() OVERRIDE {}
RestartJob(int pid,const std::string & command_line)545 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {}
StartSession(const std::string & user_email)546 virtual void StartSession(const std::string& user_email) OVERRIDE {}
StopSession()547 virtual void StopSession() OVERRIDE {}
StartDeviceWipe()548 virtual void StartDeviceWipe() OVERRIDE {}
RequestLockScreen()549 virtual void RequestLockScreen() OVERRIDE {
550 FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
551 }
NotifyLockScreenShown()552 virtual void NotifyLockScreenShown() OVERRIDE {
553 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
554 }
NotifyLockScreenDismissed()555 virtual void NotifyLockScreenDismissed() OVERRIDE {
556 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
557 }
RetrieveActiveSessions(const ActiveSessionsCallback & callback)558 virtual void RetrieveActiveSessions(
559 const ActiveSessionsCallback& callback) OVERRIDE {}
RetrieveDevicePolicy(const RetrievePolicyCallback & callback)560 virtual void RetrieveDevicePolicy(
561 const RetrievePolicyCallback& callback) OVERRIDE {
562 callback.Run(device_policy_);
563 }
RetrievePolicyForUser(const std::string & username,const RetrievePolicyCallback & callback)564 virtual void RetrievePolicyForUser(
565 const std::string& username,
566 const RetrievePolicyCallback& callback) OVERRIDE {
567 callback.Run(user_policies_[username]);
568 }
BlockingRetrievePolicyForUser(const std::string & username)569 virtual std::string BlockingRetrievePolicyForUser(
570 const std::string& username) OVERRIDE {
571 return user_policies_[username];
572 }
RetrieveDeviceLocalAccountPolicy(const std::string & account_name,const RetrievePolicyCallback & callback)573 virtual void RetrieveDeviceLocalAccountPolicy(
574 const std::string& account_name,
575 const RetrievePolicyCallback& callback) OVERRIDE {
576 callback.Run(user_policies_[account_name]);
577 }
StoreDevicePolicy(const std::string & policy_blob,const StorePolicyCallback & callback)578 virtual void StoreDevicePolicy(const std::string& policy_blob,
579 const StorePolicyCallback& callback) OVERRIDE {
580 device_policy_ = policy_blob;
581 callback.Run(true);
582 }
StorePolicyForUser(const std::string & username,const std::string & policy_blob,const std::string & policy_key,const StorePolicyCallback & callback)583 virtual void StorePolicyForUser(
584 const std::string& username,
585 const std::string& policy_blob,
586 const std::string& policy_key,
587 const StorePolicyCallback& callback) OVERRIDE {
588 if (policy_key.empty()) {
589 user_policies_[username] = policy_blob;
590 callback.Run(true);
591 return;
592 }
593 // The session manager writes the user policy key to a well-known
594 // location. Do the same with the stub impl, so that user policy works and
595 // can be tested on desktop builds.
596 // TODO(joaodasilva): parse the PolicyFetchResponse in |policy_blob| to get
597 // the policy key directly, after moving the policy protobufs to a top-level
598 // directory. The |policy_key| argument to this method can then be removed.
599 // http://crbug.com/240269
600 base::FilePath key_path;
601 if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &key_path)) {
602 callback.Run(false);
603 return;
604 }
605 const std::string sanitized =
606 CryptohomeClient::GetStubSanitizedUsername(username);
607 key_path = key_path.AppendASCII(sanitized).AppendASCII("policy.pub");
608 // Assume that the key write is successful.
609 user_policies_[username] = policy_blob;
610 base::WorkerPool::PostTaskAndReply(
611 FROM_HERE,
612 base::Bind(&SessionManagerClientStubImpl::StoreFileInBackground,
613 key_path, policy_key),
614 base::Bind(callback, true),
615 false);
616 }
StoreDeviceLocalAccountPolicy(const std::string & account_name,const std::string & policy_blob,const StorePolicyCallback & callback)617 virtual void StoreDeviceLocalAccountPolicy(
618 const std::string& account_name,
619 const std::string& policy_blob,
620 const StorePolicyCallback& callback) OVERRIDE {
621 user_policies_[account_name] = policy_blob;
622 callback.Run(true);
623 }
SetFlagsForUser(const std::string & username,const std::vector<std::string> & flags)624 virtual void SetFlagsForUser(const std::string& username,
625 const std::vector<std::string>& flags) OVERRIDE {
626 }
627
StoreFileInBackground(const base::FilePath & path,const std::string & data)628 static void StoreFileInBackground(const base::FilePath& path,
629 const std::string& data) {
630 const int size = static_cast<int>(data.size());
631 if (!base::CreateDirectory(path.DirName()) ||
632 file_util::WriteFile(path, data.data(), size) != size) {
633 LOG(WARNING) << "Failed to write policy key to " << path.value();
634 }
635 }
636
637 private:
638 ObserverList<Observer> observers_;
639 std::string device_policy_;
640 std::map<std::string, std::string> user_policies_;
641
642 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
643 };
644
SessionManagerClient()645 SessionManagerClient::SessionManagerClient() {
646 }
647
~SessionManagerClient()648 SessionManagerClient::~SessionManagerClient() {
649 }
650
Create(DBusClientImplementationType type)651 SessionManagerClient* SessionManagerClient::Create(
652 DBusClientImplementationType type) {
653 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
654 return new SessionManagerClientImpl();
655 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
656 return new SessionManagerClientStubImpl();
657 }
658
659 } // namespace chromeos
660