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.
5 #include "chromeos/dbus/session_manager_client.h"
7 #include <sys/socket.h>
10 #include "base/callback.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/location.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "base/task_runner_util.h"
18 #include "base/threading/worker_pool.h"
19 #include "chromeos/chromeos_paths.h"
20 #include "chromeos/dbus/blocking_method_caller.h"
21 #include "chromeos/dbus/cryptohome_client.h"
22 #include "crypto/sha2.h"
24 #include "dbus/message.h"
25 #include "dbus/object_path.h"
26 #include "dbus/object_proxy.h"
27 #include "policy/proto/device_management_backend.pb.h"
28 #include "third_party/cros_system_api/dbus/service_constants.h"
34 // Returns a location for |file| that is specific to the given |username|.
35 // These paths will be relative to DIR_USER_POLICY_KEYS, and can be used only
36 // to store stub files.
37 base::FilePath
GetUserFilePath(const std::string
& username
, const char* file
) {
38 base::FilePath keys_path
;
39 if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS
, &keys_path
))
40 return base::FilePath();
41 const std::string sanitized
=
42 CryptohomeClient::GetStubSanitizedUsername(username
);
43 return keys_path
.AppendASCII(sanitized
).AppendASCII(file
);
46 // Helper to asynchronously retrieve a file's content.
47 std::string
GetFileContent(const base::FilePath
& path
) {
50 base::ReadFileToString(path
, &result
);
54 // Helper to write a file in a background thread.
55 void StoreFile(const base::FilePath
& path
, const std::string
& data
) {
56 const int size
= static_cast<int>(data
.size());
58 !base::CreateDirectory(path
.DirName()) ||
59 base::WriteFile(path
, data
.data(), size
) != size
) {
60 LOG(WARNING
) << "Failed to write to " << path
.value();
64 // Creates a pair of file descriptors that form a conduit for trustworthy
65 // transfer of credentials between Chrome and the session_manager
66 void CreateValidCredConduit(dbus::FileDescriptor
* local_auth_fd
,
67 dbus::FileDescriptor
* remote_auth_fd
) {
68 int sockets
[2] = {-1, -1};
69 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sockets
) < 0) {
70 PLOG(ERROR
) << "Failed to create a unix domain socketpair";
74 local_auth_fd
->PutValue(sockets
[0]);
75 local_auth_fd
->CheckValidity();
77 remote_auth_fd
->PutValue(sockets
[1]);
78 remote_auth_fd
->CheckValidity();
83 // The SessionManagerClient implementation used in production.
84 class SessionManagerClientImpl
: public SessionManagerClient
{
86 SessionManagerClientImpl()
87 : session_manager_proxy_(NULL
),
88 screen_is_locked_(false),
89 weak_ptr_factory_(this) {}
91 ~SessionManagerClientImpl() override
{}
93 // SessionManagerClient overrides:
94 void SetStubDelegate(StubDelegate
* delegate
) override
{
95 // Do nothing; this isn't a stub implementation.
98 void AddObserver(Observer
* observer
) override
{
99 observers_
.AddObserver(observer
);
102 void RemoveObserver(Observer
* observer
) override
{
103 observers_
.RemoveObserver(observer
);
106 bool HasObserver(const Observer
* observer
) const override
{
107 return observers_
.HasObserver(observer
);
110 bool IsScreenLocked() const override
{ return screen_is_locked_
; }
112 void EmitLoginPromptVisible() override
{
113 SimpleMethodCallToSessionManager(
114 login_manager::kSessionManagerEmitLoginPromptVisible
);
115 FOR_EACH_OBSERVER(Observer
, observers_
, EmitLoginPromptVisibleCalled());
118 void RestartJob(int pid
, const std::string
& command_line
) override
{
119 dbus::ScopedFileDescriptor
local_auth_fd(new dbus::FileDescriptor());
120 dbus::ScopedFileDescriptor
remote_auth_fd(new dbus::FileDescriptor());
122 // The session_manager provides a new method to replace RestartJob, called
123 // RestartJobWithAuth, that is able to be used correctly within a PID
124 // namespace. To use it, the caller must create a unix domain socket pair
125 // and pass one end over dbus while holding the local end open for the
126 // duration of the call.
127 // Here, we call CreateValidCredConduit() to create the socket pair,
128 // and then pass both ends along to CallRestartJobWithValidFd(), which
129 // takes care of them from there.
130 // NB: PostTaskAndReply ensures that the second callback (which owns the
131 // ScopedFileDescriptor objects) outlives the first, so passing the
132 // bare pointers to CreateValidCredConduit is safe.
133 base::WorkerPool::PostTaskAndReply(
134 FROM_HERE
, base::Bind(&CreateValidCredConduit
, local_auth_fd
.get(),
135 remote_auth_fd
.get()),
136 base::Bind(&SessionManagerClientImpl::CallRestartJobWithValidFd
,
137 weak_ptr_factory_
.GetWeakPtr(), base::Passed(&local_auth_fd
),
138 base::Passed(&remote_auth_fd
), command_line
),
142 void StartSession(const std::string
& user_email
) override
{
143 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
144 login_manager::kSessionManagerStartSession
);
145 dbus::MessageWriter
writer(&method_call
);
146 writer
.AppendString(user_email
);
147 writer
.AppendString(""); // Unique ID is deprecated
148 session_manager_proxy_
->CallMethod(
150 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
151 base::Bind(&SessionManagerClientImpl::OnStartSession
,
152 weak_ptr_factory_
.GetWeakPtr()));
155 void StopSession() override
{
156 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
157 login_manager::kSessionManagerStopSession
);
158 dbus::MessageWriter
writer(&method_call
);
159 writer
.AppendString(""); // Unique ID is deprecated
160 session_manager_proxy_
->CallMethod(
162 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
163 base::Bind(&SessionManagerClientImpl::OnStopSession
,
164 weak_ptr_factory_
.GetWeakPtr()));
167 void StartDeviceWipe() override
{
168 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
169 login_manager::kSessionManagerStartDeviceWipe
);
170 session_manager_proxy_
->CallMethod(
172 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
173 base::Bind(&SessionManagerClientImpl::OnDeviceWipe
,
174 weak_ptr_factory_
.GetWeakPtr()));
177 void RequestLockScreen() override
{
178 SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen
);
181 void NotifyLockScreenShown() override
{
182 SimpleMethodCallToSessionManager(
183 login_manager::kSessionManagerHandleLockScreenShown
);
186 void NotifyLockScreenDismissed() override
{
187 SimpleMethodCallToSessionManager(
188 login_manager::kSessionManagerHandleLockScreenDismissed
);
191 void NotifySupervisedUserCreationStarted() override
{
192 SimpleMethodCallToSessionManager(
193 login_manager::kSessionManagerHandleSupervisedUserCreationStarting
);
196 void NotifySupervisedUserCreationFinished() override
{
197 SimpleMethodCallToSessionManager(
198 login_manager::kSessionManagerHandleSupervisedUserCreationFinished
);
201 void RetrieveActiveSessions(const ActiveSessionsCallback
& callback
) override
{
202 dbus::MethodCall
method_call(
203 login_manager::kSessionManagerInterface
,
204 login_manager::kSessionManagerRetrieveActiveSessions
);
206 session_manager_proxy_
->CallMethod(
208 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
209 base::Bind(&SessionManagerClientImpl::OnRetrieveActiveSessions
,
210 weak_ptr_factory_
.GetWeakPtr(),
211 login_manager::kSessionManagerRetrieveActiveSessions
,
215 void RetrieveDevicePolicy(const RetrievePolicyCallback
& callback
) override
{
216 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
217 login_manager::kSessionManagerRetrievePolicy
);
218 session_manager_proxy_
->CallMethod(
220 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
221 base::Bind(&SessionManagerClientImpl::OnRetrievePolicy
,
222 weak_ptr_factory_
.GetWeakPtr(),
223 login_manager::kSessionManagerRetrievePolicy
,
227 void RetrievePolicyForUser(const std::string
& username
,
228 const RetrievePolicyCallback
& callback
) override
{
229 CallRetrievePolicyByUsername(
230 login_manager::kSessionManagerRetrievePolicyForUser
,
235 std::string
BlockingRetrievePolicyForUser(
236 const std::string
& username
) override
{
237 dbus::MethodCall
method_call(
238 login_manager::kSessionManagerInterface
,
239 login_manager::kSessionManagerRetrievePolicyForUser
);
240 dbus::MessageWriter
writer(&method_call
);
241 writer
.AppendString(username
);
242 scoped_ptr
<dbus::Response
> response
=
243 blocking_method_caller_
->CallMethodAndBlock(&method_call
);
245 ExtractString(login_manager::kSessionManagerRetrievePolicyForUser
,
251 void RetrieveDeviceLocalAccountPolicy(
252 const std::string
& account_name
,
253 const RetrievePolicyCallback
& callback
) override
{
254 CallRetrievePolicyByUsername(
255 login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy
,
260 void StoreDevicePolicy(const std::string
& policy_blob
,
261 const StorePolicyCallback
& callback
) override
{
262 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
263 login_manager::kSessionManagerStorePolicy
);
264 dbus::MessageWriter
writer(&method_call
);
265 // static_cast does not work due to signedness.
266 writer
.AppendArrayOfBytes(
267 reinterpret_cast<const uint8
*>(policy_blob
.data()), policy_blob
.size());
268 session_manager_proxy_
->CallMethod(
270 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
271 base::Bind(&SessionManagerClientImpl::OnStorePolicy
,
272 weak_ptr_factory_
.GetWeakPtr(),
273 login_manager::kSessionManagerStorePolicy
,
277 void StorePolicyForUser(const std::string
& username
,
278 const std::string
& policy_blob
,
279 const StorePolicyCallback
& callback
) override
{
280 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser
,
286 void StoreDeviceLocalAccountPolicy(
287 const std::string
& account_name
,
288 const std::string
& policy_blob
,
289 const StorePolicyCallback
& callback
) override
{
290 CallStorePolicyByUsername(
291 login_manager::kSessionManagerStoreDeviceLocalAccountPolicy
,
297 void SetFlagsForUser(const std::string
& username
,
298 const std::vector
<std::string
>& flags
) override
{
299 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
300 login_manager::kSessionManagerSetFlagsForUser
);
301 dbus::MessageWriter
writer(&method_call
);
302 writer
.AppendString(username
);
303 writer
.AppendArrayOfStrings(flags
);
304 session_manager_proxy_
->CallMethod(
306 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
307 dbus::ObjectProxy::EmptyResponseCallback());
310 void GetServerBackedStateKeys(const StateKeysCallback
& callback
) override
{
311 dbus::MethodCall
method_call(
312 login_manager::kSessionManagerInterface
,
313 login_manager::kSessionManagerGetServerBackedStateKeys
);
315 session_manager_proxy_
->CallMethod(
317 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
318 base::Bind(&SessionManagerClientImpl::OnGetServerBackedStateKeys
,
319 weak_ptr_factory_
.GetWeakPtr(),
324 void Init(dbus::Bus
* bus
) override
{
325 session_manager_proxy_
= bus
->GetObjectProxy(
326 login_manager::kSessionManagerServiceName
,
327 dbus::ObjectPath(login_manager::kSessionManagerServicePath
));
328 blocking_method_caller_
.reset(
329 new BlockingMethodCaller(bus
, session_manager_proxy_
));
331 // Signals emitted on the session manager's interface.
332 session_manager_proxy_
->ConnectToSignal(
333 login_manager::kSessionManagerInterface
,
334 login_manager::kOwnerKeySetSignal
,
335 base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived
,
336 weak_ptr_factory_
.GetWeakPtr()),
337 base::Bind(&SessionManagerClientImpl::SignalConnected
,
338 weak_ptr_factory_
.GetWeakPtr()));
339 session_manager_proxy_
->ConnectToSignal(
340 login_manager::kSessionManagerInterface
,
341 login_manager::kPropertyChangeCompleteSignal
,
342 base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived
,
343 weak_ptr_factory_
.GetWeakPtr()),
344 base::Bind(&SessionManagerClientImpl::SignalConnected
,
345 weak_ptr_factory_
.GetWeakPtr()));
346 session_manager_proxy_
->ConnectToSignal(
347 login_manager::kSessionManagerInterface
,
348 login_manager::kScreenIsLockedSignal
,
349 base::Bind(&SessionManagerClientImpl::ScreenIsLockedReceived
,
350 weak_ptr_factory_
.GetWeakPtr()),
351 base::Bind(&SessionManagerClientImpl::SignalConnected
,
352 weak_ptr_factory_
.GetWeakPtr()));
353 session_manager_proxy_
->ConnectToSignal(
354 login_manager::kSessionManagerInterface
,
355 login_manager::kScreenIsUnlockedSignal
,
356 base::Bind(&SessionManagerClientImpl::ScreenIsUnlockedReceived
,
357 weak_ptr_factory_
.GetWeakPtr()),
358 base::Bind(&SessionManagerClientImpl::SignalConnected
,
359 weak_ptr_factory_
.GetWeakPtr()));
363 // Makes a method call to the session manager with no arguments and no
365 void SimpleMethodCallToSessionManager(const std::string
& method_name
) {
366 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
368 session_manager_proxy_
->CallMethod(
370 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
371 dbus::ObjectProxy::EmptyResponseCallback());
374 // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser.
375 void CallRetrievePolicyByUsername(const std::string
& method_name
,
376 const std::string
& username
,
377 const RetrievePolicyCallback
& callback
) {
378 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
380 dbus::MessageWriter
writer(&method_call
);
381 writer
.AppendString(username
);
382 session_manager_proxy_
->CallMethod(
384 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
386 &SessionManagerClientImpl::OnRetrievePolicy
,
387 weak_ptr_factory_
.GetWeakPtr(),
392 void CallStorePolicyByUsername(const std::string
& method_name
,
393 const std::string
& username
,
394 const std::string
& policy_blob
,
395 const StorePolicyCallback
& callback
) {
396 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
398 dbus::MessageWriter
writer(&method_call
);
399 writer
.AppendString(username
);
400 // static_cast does not work due to signedness.
401 writer
.AppendArrayOfBytes(
402 reinterpret_cast<const uint8
*>(policy_blob
.data()), policy_blob
.size());
403 session_manager_proxy_
->CallMethod(
405 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
407 &SessionManagerClientImpl::OnStorePolicy
,
408 weak_ptr_factory_
.GetWeakPtr(),
413 // Calls RestartJobWithAuth to tell the session manager to restart the
414 // browser using the contents of command_line, authorizing the call
415 // using credentials acquired via remote_auth_fd.
416 // Ownership of local_auth_fd is held for the duration of the dbus call.
417 void CallRestartJobWithValidFd(dbus::ScopedFileDescriptor local_auth_fd
,
418 dbus::ScopedFileDescriptor remote_auth_fd
,
419 const std::string
& command_line
) {
420 dbus::MethodCall
method_call(
421 login_manager::kSessionManagerInterface
,
422 login_manager::kSessionManagerRestartJobWithAuth
);
423 dbus::MessageWriter
writer(&method_call
);
424 writer
.AppendFileDescriptor(*remote_auth_fd
);
425 writer
.AppendString(command_line
);
427 // Ownership of local_auth_fd is passed to the callback that is to be
428 // called on completion of this method call. This keeps the browser end
429 // of the socket-pair alive for the duration of the RPC.
430 session_manager_proxy_
->CallMethod(
431 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
432 base::Bind(&SessionManagerClientImpl::OnRestartJob
,
433 weak_ptr_factory_
.GetWeakPtr(),
434 base::Passed(&local_auth_fd
)));
437 // Called when kSessionManagerRestartJob method is complete.
438 // Now that the call is complete, local_auth_fd can be closed and discarded,
439 // which will happen automatically when it goes out of scope.
440 void OnRestartJob(dbus::ScopedFileDescriptor local_auth_fd
,
441 dbus::Response
* response
) {
442 LOG_IF(ERROR
, !response
)
444 << login_manager::kSessionManagerRestartJob
;
447 // Called when kSessionManagerStartSession method is complete.
448 void OnStartSession(dbus::Response
* response
) {
449 LOG_IF(ERROR
, !response
)
451 << login_manager::kSessionManagerStartSession
;
454 // Called when kSessionManagerStopSession method is complete.
455 void OnStopSession(dbus::Response
* response
) {
456 LOG_IF(ERROR
, !response
)
458 << login_manager::kSessionManagerStopSession
;
461 // Called when kSessionManagerStopSession method is complete.
462 void OnDeviceWipe(dbus::Response
* response
) {
463 LOG_IF(ERROR
, !response
)
465 << login_manager::kSessionManagerStartDeviceWipe
;
468 // Called when kSessionManagerRetrieveActiveSessions method is complete.
469 void OnRetrieveActiveSessions(const std::string
& method_name
,
470 const ActiveSessionsCallback
& callback
,
471 dbus::Response
* response
) {
472 ActiveSessionsMap sessions
;
473 bool success
= false;
475 LOG(ERROR
) << "Failed to call " << method_name
;
476 callback
.Run(sessions
, success
);
480 dbus::MessageReader
reader(response
);
481 dbus::MessageReader
array_reader(NULL
);
483 if (!reader
.PopArray(&array_reader
)) {
484 LOG(ERROR
) << method_name
<< " response is incorrect: "
485 << response
->ToString();
487 while (array_reader
.HasMoreData()) {
488 dbus::MessageReader
dict_entry_reader(NULL
);
491 if (!array_reader
.PopDictEntry(&dict_entry_reader
) ||
492 !dict_entry_reader
.PopString(&key
) ||
493 !dict_entry_reader
.PopString(&value
)) {
494 LOG(ERROR
) << method_name
<< " response is incorrect: "
495 << response
->ToString();
497 sessions
[key
] = value
;
502 callback
.Run(sessions
, success
);
505 void ExtractString(const std::string
& method_name
,
506 dbus::Response
* response
,
507 std::string
* extracted
) {
509 LOG(ERROR
) << "Failed to call " << method_name
;
512 dbus::MessageReader
reader(response
);
513 const uint8
* values
= NULL
;
515 if (!reader
.PopArrayOfBytes(&values
, &length
)) {
516 LOG(ERROR
) << "Invalid response: " << response
->ToString();
519 // static_cast does not work due to signedness.
520 extracted
->assign(reinterpret_cast<const char*>(values
), length
);
523 // Called when kSessionManagerRetrievePolicy or
524 // kSessionManagerRetrievePolicyForUser method is complete.
525 void OnRetrievePolicy(const std::string
& method_name
,
526 const RetrievePolicyCallback
& callback
,
527 dbus::Response
* response
) {
528 std::string serialized_proto
;
529 ExtractString(method_name
, response
, &serialized_proto
);
530 callback
.Run(serialized_proto
);
533 // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser
534 // method is complete.
535 void OnStorePolicy(const std::string
& method_name
,
536 const StorePolicyCallback
& callback
,
537 dbus::Response
* response
) {
538 bool success
= false;
540 LOG(ERROR
) << "Failed to call " << method_name
;
542 dbus::MessageReader
reader(response
);
543 if (!reader
.PopBool(&success
))
544 LOG(ERROR
) << "Invalid response: " << response
->ToString();
546 callback
.Run(success
);
549 // Called when the owner key set signal is received.
550 void OwnerKeySetReceived(dbus::Signal
* signal
) {
551 dbus::MessageReader
reader(signal
);
552 std::string result_string
;
553 if (!reader
.PopString(&result_string
)) {
554 LOG(ERROR
) << "Invalid signal: " << signal
->ToString();
557 const bool success
= StartsWithASCII(result_string
, "success", false);
558 FOR_EACH_OBSERVER(Observer
, observers_
, OwnerKeySet(success
));
561 // Called when the property change complete signal is received.
562 void PropertyChangeCompleteReceived(dbus::Signal
* signal
) {
563 dbus::MessageReader
reader(signal
);
564 std::string result_string
;
565 if (!reader
.PopString(&result_string
)) {
566 LOG(ERROR
) << "Invalid signal: " << signal
->ToString();
569 const bool success
= StartsWithASCII(result_string
, "success", false);
570 FOR_EACH_OBSERVER(Observer
, observers_
, PropertyChangeComplete(success
));
573 void ScreenIsLockedReceived(dbus::Signal
* signal
) {
574 screen_is_locked_
= true;
575 FOR_EACH_OBSERVER(Observer
, observers_
, ScreenIsLocked());
578 void ScreenIsUnlockedReceived(dbus::Signal
* signal
) {
579 screen_is_locked_
= false;
580 FOR_EACH_OBSERVER(Observer
, observers_
, ScreenIsUnlocked());
583 // Called when the object is connected to the signal.
584 void SignalConnected(const std::string
& interface_name
,
585 const std::string
& signal_name
,
587 LOG_IF(ERROR
, !success
) << "Failed to connect to " << signal_name
;
590 // Called when kSessionManagerGetServerBackedStateKeys method is complete.
591 void OnGetServerBackedStateKeys(const StateKeysCallback
& callback
,
592 dbus::Response
* response
) {
593 std::vector
<std::string
> state_keys
;
595 LOG(ERROR
) << "Failed to call "
596 << login_manager::kSessionManagerStartSession
;
598 dbus::MessageReader
reader(response
);
599 dbus::MessageReader
array_reader(NULL
);
601 if (!reader
.PopArray(&array_reader
)) {
602 LOG(ERROR
) << "Bad response: " << response
->ToString();
604 while (array_reader
.HasMoreData()) {
605 const uint8
* data
= NULL
;
607 if (!array_reader
.PopArrayOfBytes(&data
, &size
)) {
608 LOG(ERROR
) << "Bad response: " << response
->ToString();
612 state_keys
.push_back(
613 std::string(reinterpret_cast<const char*>(data
), size
));
618 if (!callback
.is_null())
619 callback
.Run(state_keys
);
623 dbus::ObjectProxy
* session_manager_proxy_
;
624 scoped_ptr
<BlockingMethodCaller
> blocking_method_caller_
;
625 ObserverList
<Observer
> observers_
;
627 // Most recent screen-lock state received from session_manager.
628 bool screen_is_locked_
;
630 // Note: This should remain the last member so it'll be destroyed and
631 // invalidate its weak pointers before any other members are destroyed.
632 base::WeakPtrFactory
<SessionManagerClientImpl
> weak_ptr_factory_
;
634 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl
);
637 // The SessionManagerClient implementation used on Linux desktop,
638 // which does nothing.
639 class SessionManagerClientStubImpl
: public SessionManagerClient
{
641 SessionManagerClientStubImpl() : delegate_(NULL
), screen_is_locked_(false) {}
642 ~SessionManagerClientStubImpl() override
{}
644 // SessionManagerClient overrides
645 void Init(dbus::Bus
* bus
) override
{}
646 void SetStubDelegate(StubDelegate
* delegate
) override
{
647 delegate_
= delegate
;
649 void AddObserver(Observer
* observer
) override
{
650 observers_
.AddObserver(observer
);
652 void RemoveObserver(Observer
* observer
) override
{
653 observers_
.RemoveObserver(observer
);
655 bool HasObserver(const Observer
* observer
) const override
{
656 return observers_
.HasObserver(observer
);
658 bool IsScreenLocked() const override
{ return screen_is_locked_
; }
659 void EmitLoginPromptVisible() override
{}
660 void RestartJob(int pid
, const std::string
& command_line
) override
{}
661 void StartSession(const std::string
& user_email
) override
{}
662 void StopSession() override
{}
663 void NotifySupervisedUserCreationStarted() override
{}
664 void NotifySupervisedUserCreationFinished() override
{}
665 void StartDeviceWipe() override
{}
666 void RequestLockScreen() override
{
668 delegate_
->LockScreenForStub();
670 void NotifyLockScreenShown() override
{
671 screen_is_locked_
= true;
672 FOR_EACH_OBSERVER(Observer
, observers_
, ScreenIsLocked());
674 void NotifyLockScreenDismissed() override
{
675 screen_is_locked_
= false;
676 FOR_EACH_OBSERVER(Observer
, observers_
, ScreenIsUnlocked());
678 void RetrieveActiveSessions(const ActiveSessionsCallback
& callback
) override
{
680 void RetrieveDevicePolicy(const RetrievePolicyCallback
& callback
) override
{
681 base::FilePath owner_key_path
;
682 if (!PathService::Get(chromeos::FILE_OWNER_KEY
, &owner_key_path
)) {
686 base::FilePath device_policy_path
=
687 owner_key_path
.DirName().AppendASCII("stub_device_policy");
688 base::PostTaskAndReplyWithResult(
689 base::WorkerPool::GetTaskRunner(false).get(),
691 base::Bind(&GetFileContent
, device_policy_path
),
694 void RetrievePolicyForUser(const std::string
& username
,
695 const RetrievePolicyCallback
& callback
) override
{
696 base::PostTaskAndReplyWithResult(
697 base::WorkerPool::GetTaskRunner(false).get(),
699 base::Bind(&GetFileContent
, GetUserFilePath(username
, "stub_policy")),
702 std::string
BlockingRetrievePolicyForUser(
703 const std::string
& username
) override
{
704 return GetFileContent(GetUserFilePath(username
, "stub_policy"));
706 void RetrieveDeviceLocalAccountPolicy(
707 const std::string
& account_name
,
708 const RetrievePolicyCallback
& callback
) override
{
709 RetrievePolicyForUser(account_name
, callback
);
711 void StoreDevicePolicy(const std::string
& policy_blob
,
712 const StorePolicyCallback
& callback
) override
{
713 enterprise_management::PolicyFetchResponse response
;
714 base::FilePath owner_key_path
;
715 if (!response
.ParseFromString(policy_blob
) ||
716 !PathService::Get(chromeos::FILE_OWNER_KEY
, &owner_key_path
)) {
721 if (response
.has_new_public_key()) {
722 base::WorkerPool::PostTask(
724 base::Bind(&StoreFile
, owner_key_path
, response
.new_public_key()),
728 // Chrome will attempt to retrieve the device policy right after storing
729 // during enrollment, so make sure it's written before signaling
731 // Note also that the owner key will be written before the device policy,
732 // if it was present in the blob.
733 base::FilePath device_policy_path
=
734 owner_key_path
.DirName().AppendASCII("stub_device_policy");
735 base::WorkerPool::PostTaskAndReply(
737 base::Bind(&StoreFile
, device_policy_path
, policy_blob
),
738 base::Bind(callback
, true),
741 void StorePolicyForUser(const std::string
& username
,
742 const std::string
& policy_blob
,
743 const StorePolicyCallback
& callback
) override
{
744 // The session manager writes the user policy key to a well-known
745 // location. Do the same with the stub impl, so that user policy works and
746 // can be tested on desktop builds.
747 enterprise_management::PolicyFetchResponse response
;
748 if (!response
.ParseFromString(policy_blob
)) {
753 if (response
.has_new_public_key()) {
754 base::FilePath key_path
= GetUserFilePath(username
, "policy.pub");
755 base::WorkerPool::PostTask(
757 base::Bind(&StoreFile
, key_path
, response
.new_public_key()),
761 // This file isn't read directly by Chrome, but is used by this class to
762 // reload the user policy across restarts.
763 base::FilePath stub_policy_path
= GetUserFilePath(username
, "stub_policy");
764 base::WorkerPool::PostTaskAndReply(
766 base::Bind(&StoreFile
, stub_policy_path
, policy_blob
),
767 base::Bind(callback
, true),
770 void StoreDeviceLocalAccountPolicy(
771 const std::string
& account_name
,
772 const std::string
& policy_blob
,
773 const StorePolicyCallback
& callback
) override
{
774 StorePolicyForUser(account_name
, policy_blob
, callback
);
776 void SetFlagsForUser(const std::string
& username
,
777 const std::vector
<std::string
>& flags
) override
{}
779 void GetServerBackedStateKeys(const StateKeysCallback
& callback
) override
{
780 std::vector
<std::string
> state_keys
;
781 for (int i
= 0; i
< 5; ++i
)
782 state_keys
.push_back(crypto::SHA256HashString(base::IntToString(i
)));
784 if (!callback
.is_null())
785 callback
.Run(state_keys
);
789 StubDelegate
* delegate_
; // Weak pointer; may be NULL.
790 ObserverList
<Observer
> observers_
;
791 std::string device_policy_
;
792 bool screen_is_locked_
;
794 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl
);
797 SessionManagerClient::SessionManagerClient() {
800 SessionManagerClient::~SessionManagerClient() {
803 SessionManagerClient
* SessionManagerClient::Create(
804 DBusClientImplementationType type
) {
805 if (type
== REAL_DBUS_CLIENT_IMPLEMENTATION
)
806 return new SessionManagerClientImpl();
807 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION
, type
);
808 return new SessionManagerClientStubImpl();
811 } // namespace chromeos