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...
134 // you have to grab pointers to the contents of {local,remote}_auth_fd
135 // _before_ they're acted on by base::Passed() below. Passing ownership
136 // of the ScopedFileDescriptor objects to the callback actually nulls
137 // out the storage inside the local instances. Since there are
138 // no guarantees about the order of evaluation of arguments in a
139 // function call, merely having them appear earlier among the args
140 // to PostTaskAndReply() is not enough. Relying on this crashed on
142 base::Closure create_credentials_conduit_closure
= base::Bind(
143 &CreateValidCredConduit
, local_auth_fd
.get(), remote_auth_fd
.get());
145 base::WorkerPool::PostTaskAndReply(
146 FROM_HERE
, create_credentials_conduit_closure
,
147 base::Bind(&SessionManagerClientImpl::CallRestartJobWithValidFd
,
148 weak_ptr_factory_
.GetWeakPtr(), base::Passed(&local_auth_fd
),
149 base::Passed(&remote_auth_fd
), command_line
),
153 void StartSession(const std::string
& user_email
) override
{
154 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
155 login_manager::kSessionManagerStartSession
);
156 dbus::MessageWriter
writer(&method_call
);
157 writer
.AppendString(user_email
);
158 writer
.AppendString(""); // Unique ID is deprecated
159 session_manager_proxy_
->CallMethod(
161 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
162 base::Bind(&SessionManagerClientImpl::OnStartSession
,
163 weak_ptr_factory_
.GetWeakPtr()));
166 void StopSession() override
{
167 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
168 login_manager::kSessionManagerStopSession
);
169 dbus::MessageWriter
writer(&method_call
);
170 writer
.AppendString(""); // Unique ID is deprecated
171 session_manager_proxy_
->CallMethod(
173 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
174 base::Bind(&SessionManagerClientImpl::OnStopSession
,
175 weak_ptr_factory_
.GetWeakPtr()));
178 void StartDeviceWipe() override
{
179 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
180 login_manager::kSessionManagerStartDeviceWipe
);
181 session_manager_proxy_
->CallMethod(
183 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
184 base::Bind(&SessionManagerClientImpl::OnDeviceWipe
,
185 weak_ptr_factory_
.GetWeakPtr()));
188 void RequestLockScreen() override
{
189 SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen
);
192 void NotifyLockScreenShown() override
{
193 SimpleMethodCallToSessionManager(
194 login_manager::kSessionManagerHandleLockScreenShown
);
197 void NotifyLockScreenDismissed() override
{
198 SimpleMethodCallToSessionManager(
199 login_manager::kSessionManagerHandleLockScreenDismissed
);
202 void NotifySupervisedUserCreationStarted() override
{
203 SimpleMethodCallToSessionManager(
204 login_manager::kSessionManagerHandleSupervisedUserCreationStarting
);
207 void NotifySupervisedUserCreationFinished() override
{
208 SimpleMethodCallToSessionManager(
209 login_manager::kSessionManagerHandleSupervisedUserCreationFinished
);
212 void RetrieveActiveSessions(const ActiveSessionsCallback
& callback
) override
{
213 dbus::MethodCall
method_call(
214 login_manager::kSessionManagerInterface
,
215 login_manager::kSessionManagerRetrieveActiveSessions
);
217 session_manager_proxy_
->CallMethod(
219 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
220 base::Bind(&SessionManagerClientImpl::OnRetrieveActiveSessions
,
221 weak_ptr_factory_
.GetWeakPtr(),
222 login_manager::kSessionManagerRetrieveActiveSessions
,
226 void RetrieveDevicePolicy(const RetrievePolicyCallback
& callback
) override
{
227 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
228 login_manager::kSessionManagerRetrievePolicy
);
229 session_manager_proxy_
->CallMethod(
231 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
232 base::Bind(&SessionManagerClientImpl::OnRetrievePolicy
,
233 weak_ptr_factory_
.GetWeakPtr(),
234 login_manager::kSessionManagerRetrievePolicy
,
238 void RetrievePolicyForUser(const std::string
& username
,
239 const RetrievePolicyCallback
& callback
) override
{
240 CallRetrievePolicyByUsername(
241 login_manager::kSessionManagerRetrievePolicyForUser
,
246 std::string
BlockingRetrievePolicyForUser(
247 const std::string
& username
) override
{
248 dbus::MethodCall
method_call(
249 login_manager::kSessionManagerInterface
,
250 login_manager::kSessionManagerRetrievePolicyForUser
);
251 dbus::MessageWriter
writer(&method_call
);
252 writer
.AppendString(username
);
253 scoped_ptr
<dbus::Response
> response
=
254 blocking_method_caller_
->CallMethodAndBlock(&method_call
);
256 ExtractString(login_manager::kSessionManagerRetrievePolicyForUser
,
262 void RetrieveDeviceLocalAccountPolicy(
263 const std::string
& account_name
,
264 const RetrievePolicyCallback
& callback
) override
{
265 CallRetrievePolicyByUsername(
266 login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy
,
271 void StoreDevicePolicy(const std::string
& policy_blob
,
272 const StorePolicyCallback
& callback
) override
{
273 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
274 login_manager::kSessionManagerStorePolicy
);
275 dbus::MessageWriter
writer(&method_call
);
276 // static_cast does not work due to signedness.
277 writer
.AppendArrayOfBytes(
278 reinterpret_cast<const uint8
*>(policy_blob
.data()), policy_blob
.size());
279 session_manager_proxy_
->CallMethod(
281 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
282 base::Bind(&SessionManagerClientImpl::OnStorePolicy
,
283 weak_ptr_factory_
.GetWeakPtr(),
284 login_manager::kSessionManagerStorePolicy
,
288 void StorePolicyForUser(const std::string
& username
,
289 const std::string
& policy_blob
,
290 const StorePolicyCallback
& callback
) override
{
291 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser
,
297 void StoreDeviceLocalAccountPolicy(
298 const std::string
& account_name
,
299 const std::string
& policy_blob
,
300 const StorePolicyCallback
& callback
) override
{
301 CallStorePolicyByUsername(
302 login_manager::kSessionManagerStoreDeviceLocalAccountPolicy
,
308 void SetFlagsForUser(const std::string
& username
,
309 const std::vector
<std::string
>& flags
) override
{
310 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
311 login_manager::kSessionManagerSetFlagsForUser
);
312 dbus::MessageWriter
writer(&method_call
);
313 writer
.AppendString(username
);
314 writer
.AppendArrayOfStrings(flags
);
315 session_manager_proxy_
->CallMethod(
317 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
318 dbus::ObjectProxy::EmptyResponseCallback());
321 void GetServerBackedStateKeys(const StateKeysCallback
& callback
) override
{
322 dbus::MethodCall
method_call(
323 login_manager::kSessionManagerInterface
,
324 login_manager::kSessionManagerGetServerBackedStateKeys
);
326 session_manager_proxy_
->CallMethod(
328 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
329 base::Bind(&SessionManagerClientImpl::OnGetServerBackedStateKeys
,
330 weak_ptr_factory_
.GetWeakPtr(),
335 void Init(dbus::Bus
* bus
) override
{
336 session_manager_proxy_
= bus
->GetObjectProxy(
337 login_manager::kSessionManagerServiceName
,
338 dbus::ObjectPath(login_manager::kSessionManagerServicePath
));
339 blocking_method_caller_
.reset(
340 new BlockingMethodCaller(bus
, session_manager_proxy_
));
342 // Signals emitted on the session manager's interface.
343 session_manager_proxy_
->ConnectToSignal(
344 login_manager::kSessionManagerInterface
,
345 login_manager::kOwnerKeySetSignal
,
346 base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived
,
347 weak_ptr_factory_
.GetWeakPtr()),
348 base::Bind(&SessionManagerClientImpl::SignalConnected
,
349 weak_ptr_factory_
.GetWeakPtr()));
350 session_manager_proxy_
->ConnectToSignal(
351 login_manager::kSessionManagerInterface
,
352 login_manager::kPropertyChangeCompleteSignal
,
353 base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived
,
354 weak_ptr_factory_
.GetWeakPtr()),
355 base::Bind(&SessionManagerClientImpl::SignalConnected
,
356 weak_ptr_factory_
.GetWeakPtr()));
357 session_manager_proxy_
->ConnectToSignal(
358 login_manager::kSessionManagerInterface
,
359 login_manager::kScreenIsLockedSignal
,
360 base::Bind(&SessionManagerClientImpl::ScreenIsLockedReceived
,
361 weak_ptr_factory_
.GetWeakPtr()),
362 base::Bind(&SessionManagerClientImpl::SignalConnected
,
363 weak_ptr_factory_
.GetWeakPtr()));
364 session_manager_proxy_
->ConnectToSignal(
365 login_manager::kSessionManagerInterface
,
366 login_manager::kScreenIsUnlockedSignal
,
367 base::Bind(&SessionManagerClientImpl::ScreenIsUnlockedReceived
,
368 weak_ptr_factory_
.GetWeakPtr()),
369 base::Bind(&SessionManagerClientImpl::SignalConnected
,
370 weak_ptr_factory_
.GetWeakPtr()));
374 // Makes a method call to the session manager with no arguments and no
376 void SimpleMethodCallToSessionManager(const std::string
& method_name
) {
377 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
379 session_manager_proxy_
->CallMethod(
381 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
382 dbus::ObjectProxy::EmptyResponseCallback());
385 // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser.
386 void CallRetrievePolicyByUsername(const std::string
& method_name
,
387 const std::string
& username
,
388 const RetrievePolicyCallback
& callback
) {
389 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
391 dbus::MessageWriter
writer(&method_call
);
392 writer
.AppendString(username
);
393 session_manager_proxy_
->CallMethod(
395 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
397 &SessionManagerClientImpl::OnRetrievePolicy
,
398 weak_ptr_factory_
.GetWeakPtr(),
403 void CallStorePolicyByUsername(const std::string
& method_name
,
404 const std::string
& username
,
405 const std::string
& policy_blob
,
406 const StorePolicyCallback
& callback
) {
407 dbus::MethodCall
method_call(login_manager::kSessionManagerInterface
,
409 dbus::MessageWriter
writer(&method_call
);
410 writer
.AppendString(username
);
411 // static_cast does not work due to signedness.
412 writer
.AppendArrayOfBytes(
413 reinterpret_cast<const uint8
*>(policy_blob
.data()), policy_blob
.size());
414 session_manager_proxy_
->CallMethod(
416 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
418 &SessionManagerClientImpl::OnStorePolicy
,
419 weak_ptr_factory_
.GetWeakPtr(),
424 // Calls RestartJobWithAuth to tell the session manager to restart the
425 // browser using the contents of command_line, authorizing the call
426 // using credentials acquired via remote_auth_fd.
427 // Ownership of local_auth_fd is held for the duration of the dbus call.
428 void CallRestartJobWithValidFd(dbus::ScopedFileDescriptor local_auth_fd
,
429 dbus::ScopedFileDescriptor remote_auth_fd
,
430 const std::string
& command_line
) {
431 dbus::MethodCall
method_call(
432 login_manager::kSessionManagerInterface
,
433 login_manager::kSessionManagerRestartJobWithAuth
);
434 dbus::MessageWriter
writer(&method_call
);
435 writer
.AppendFileDescriptor(*remote_auth_fd
);
436 writer
.AppendString(command_line
);
438 // Ownership of local_auth_fd is passed to the callback that is to be
439 // called on completion of this method call. This keeps the browser end
440 // of the socket-pair alive for the duration of the RPC.
441 session_manager_proxy_
->CallMethod(
442 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
443 base::Bind(&SessionManagerClientImpl::OnRestartJob
,
444 weak_ptr_factory_
.GetWeakPtr(),
445 base::Passed(&local_auth_fd
)));
448 // Called when kSessionManagerRestartJob method is complete.
449 // Now that the call is complete, local_auth_fd can be closed and discarded,
450 // which will happen automatically when it goes out of scope.
451 void OnRestartJob(dbus::ScopedFileDescriptor local_auth_fd
,
452 dbus::Response
* response
) {
453 LOG_IF(ERROR
, !response
)
455 << login_manager::kSessionManagerRestartJob
;
458 // Called when kSessionManagerStartSession method is complete.
459 void OnStartSession(dbus::Response
* response
) {
460 LOG_IF(ERROR
, !response
)
462 << login_manager::kSessionManagerStartSession
;
465 // Called when kSessionManagerStopSession method is complete.
466 void OnStopSession(dbus::Response
* response
) {
467 LOG_IF(ERROR
, !response
)
469 << login_manager::kSessionManagerStopSession
;
472 // Called when kSessionManagerStopSession method is complete.
473 void OnDeviceWipe(dbus::Response
* response
) {
474 LOG_IF(ERROR
, !response
)
476 << login_manager::kSessionManagerStartDeviceWipe
;
479 // Called when kSessionManagerRetrieveActiveSessions method is complete.
480 void OnRetrieveActiveSessions(const std::string
& method_name
,
481 const ActiveSessionsCallback
& callback
,
482 dbus::Response
* response
) {
483 ActiveSessionsMap sessions
;
484 bool success
= false;
486 LOG(ERROR
) << "Failed to call " << method_name
;
487 callback
.Run(sessions
, success
);
491 dbus::MessageReader
reader(response
);
492 dbus::MessageReader
array_reader(NULL
);
494 if (!reader
.PopArray(&array_reader
)) {
495 LOG(ERROR
) << method_name
<< " response is incorrect: "
496 << response
->ToString();
498 while (array_reader
.HasMoreData()) {
499 dbus::MessageReader
dict_entry_reader(NULL
);
502 if (!array_reader
.PopDictEntry(&dict_entry_reader
) ||
503 !dict_entry_reader
.PopString(&key
) ||
504 !dict_entry_reader
.PopString(&value
)) {
505 LOG(ERROR
) << method_name
<< " response is incorrect: "
506 << response
->ToString();
508 sessions
[key
] = value
;
513 callback
.Run(sessions
, success
);
516 void ExtractString(const std::string
& method_name
,
517 dbus::Response
* response
,
518 std::string
* extracted
) {
520 LOG(ERROR
) << "Failed to call " << method_name
;
523 dbus::MessageReader
reader(response
);
524 const uint8
* values
= NULL
;
526 if (!reader
.PopArrayOfBytes(&values
, &length
)) {
527 LOG(ERROR
) << "Invalid response: " << response
->ToString();
530 // static_cast does not work due to signedness.
531 extracted
->assign(reinterpret_cast<const char*>(values
), length
);
534 // Called when kSessionManagerRetrievePolicy or
535 // kSessionManagerRetrievePolicyForUser method is complete.
536 void OnRetrievePolicy(const std::string
& method_name
,
537 const RetrievePolicyCallback
& callback
,
538 dbus::Response
* response
) {
539 std::string serialized_proto
;
540 ExtractString(method_name
, response
, &serialized_proto
);
541 callback
.Run(serialized_proto
);
544 // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser
545 // method is complete.
546 void OnStorePolicy(const std::string
& method_name
,
547 const StorePolicyCallback
& callback
,
548 dbus::Response
* response
) {
549 bool success
= false;
551 LOG(ERROR
) << "Failed to call " << method_name
;
553 dbus::MessageReader
reader(response
);
554 if (!reader
.PopBool(&success
))
555 LOG(ERROR
) << "Invalid response: " << response
->ToString();
557 callback
.Run(success
);
560 // Called when the owner key set signal is received.
561 void OwnerKeySetReceived(dbus::Signal
* signal
) {
562 dbus::MessageReader
reader(signal
);
563 std::string result_string
;
564 if (!reader
.PopString(&result_string
)) {
565 LOG(ERROR
) << "Invalid signal: " << signal
->ToString();
568 const bool success
= base::StartsWith(result_string
, "success",
569 base::CompareCase::INSENSITIVE_ASCII
);
570 FOR_EACH_OBSERVER(Observer
, observers_
, OwnerKeySet(success
));
573 // Called when the property change complete signal is received.
574 void PropertyChangeCompleteReceived(dbus::Signal
* signal
) {
575 dbus::MessageReader
reader(signal
);
576 std::string result_string
;
577 if (!reader
.PopString(&result_string
)) {
578 LOG(ERROR
) << "Invalid signal: " << signal
->ToString();
581 const bool success
= base::StartsWith(result_string
, "success",
582 base::CompareCase::INSENSITIVE_ASCII
);
583 FOR_EACH_OBSERVER(Observer
, observers_
, PropertyChangeComplete(success
));
586 void ScreenIsLockedReceived(dbus::Signal
* signal
) {
587 screen_is_locked_
= true;
588 FOR_EACH_OBSERVER(Observer
, observers_
, ScreenIsLocked());
591 void ScreenIsUnlockedReceived(dbus::Signal
* signal
) {
592 screen_is_locked_
= false;
593 FOR_EACH_OBSERVER(Observer
, observers_
, ScreenIsUnlocked());
596 // Called when the object is connected to the signal.
597 void SignalConnected(const std::string
& interface_name
,
598 const std::string
& signal_name
,
600 LOG_IF(ERROR
, !success
) << "Failed to connect to " << signal_name
;
603 // Called when kSessionManagerGetServerBackedStateKeys method is complete.
604 void OnGetServerBackedStateKeys(const StateKeysCallback
& callback
,
605 dbus::Response
* response
) {
606 std::vector
<std::string
> state_keys
;
608 LOG(ERROR
) << "Failed to call "
609 << login_manager::kSessionManagerGetServerBackedStateKeys
;
611 dbus::MessageReader
reader(response
);
612 dbus::MessageReader
array_reader(NULL
);
614 if (!reader
.PopArray(&array_reader
)) {
615 LOG(ERROR
) << "Bad response: " << response
->ToString();
617 while (array_reader
.HasMoreData()) {
618 const uint8
* data
= NULL
;
620 if (!array_reader
.PopArrayOfBytes(&data
, &size
)) {
621 LOG(ERROR
) << "Bad response: " << response
->ToString();
625 state_keys
.push_back(
626 std::string(reinterpret_cast<const char*>(data
), size
));
631 if (!callback
.is_null())
632 callback
.Run(state_keys
);
636 dbus::ObjectProxy
* session_manager_proxy_
;
637 scoped_ptr
<BlockingMethodCaller
> blocking_method_caller_
;
638 base::ObserverList
<Observer
> observers_
;
640 // Most recent screen-lock state received from session_manager.
641 bool screen_is_locked_
;
643 // Note: This should remain the last member so it'll be destroyed and
644 // invalidate its weak pointers before any other members are destroyed.
645 base::WeakPtrFactory
<SessionManagerClientImpl
> weak_ptr_factory_
;
647 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl
);
650 // The SessionManagerClient implementation used on Linux desktop,
651 // which does nothing.
652 class SessionManagerClientStubImpl
: public SessionManagerClient
{
654 SessionManagerClientStubImpl() : delegate_(NULL
), screen_is_locked_(false) {}
655 ~SessionManagerClientStubImpl() override
{}
657 // SessionManagerClient overrides
658 void Init(dbus::Bus
* bus
) override
{}
659 void SetStubDelegate(StubDelegate
* delegate
) override
{
660 delegate_
= delegate
;
662 void AddObserver(Observer
* observer
) override
{
663 observers_
.AddObserver(observer
);
665 void RemoveObserver(Observer
* observer
) override
{
666 observers_
.RemoveObserver(observer
);
668 bool HasObserver(const Observer
* observer
) const override
{
669 return observers_
.HasObserver(observer
);
671 bool IsScreenLocked() const override
{ return screen_is_locked_
; }
672 void EmitLoginPromptVisible() override
{}
673 void RestartJob(int pid
, const std::string
& command_line
) override
{}
674 void StartSession(const std::string
& user_email
) override
{}
675 void StopSession() override
{}
676 void NotifySupervisedUserCreationStarted() override
{}
677 void NotifySupervisedUserCreationFinished() override
{}
678 void StartDeviceWipe() override
{}
679 void RequestLockScreen() override
{
681 delegate_
->LockScreenForStub();
683 void NotifyLockScreenShown() override
{
684 screen_is_locked_
= true;
685 FOR_EACH_OBSERVER(Observer
, observers_
, ScreenIsLocked());
687 void NotifyLockScreenDismissed() override
{
688 screen_is_locked_
= false;
689 FOR_EACH_OBSERVER(Observer
, observers_
, ScreenIsUnlocked());
691 void RetrieveActiveSessions(const ActiveSessionsCallback
& callback
) override
{
693 void RetrieveDevicePolicy(const RetrievePolicyCallback
& callback
) override
{
694 base::FilePath owner_key_path
;
695 if (!PathService::Get(chromeos::FILE_OWNER_KEY
, &owner_key_path
)) {
699 base::FilePath device_policy_path
=
700 owner_key_path
.DirName().AppendASCII("stub_device_policy");
701 base::PostTaskAndReplyWithResult(
702 base::WorkerPool::GetTaskRunner(false).get(),
704 base::Bind(&GetFileContent
, device_policy_path
),
707 void RetrievePolicyForUser(const std::string
& username
,
708 const RetrievePolicyCallback
& callback
) override
{
709 base::PostTaskAndReplyWithResult(
710 base::WorkerPool::GetTaskRunner(false).get(),
712 base::Bind(&GetFileContent
, GetUserFilePath(username
, "stub_policy")),
715 std::string
BlockingRetrievePolicyForUser(
716 const std::string
& username
) override
{
717 return GetFileContent(GetUserFilePath(username
, "stub_policy"));
719 void RetrieveDeviceLocalAccountPolicy(
720 const std::string
& account_name
,
721 const RetrievePolicyCallback
& callback
) override
{
722 RetrievePolicyForUser(account_name
, callback
);
724 void StoreDevicePolicy(const std::string
& policy_blob
,
725 const StorePolicyCallback
& callback
) override
{
726 enterprise_management::PolicyFetchResponse response
;
727 base::FilePath owner_key_path
;
728 if (!response
.ParseFromString(policy_blob
) ||
729 !PathService::Get(chromeos::FILE_OWNER_KEY
, &owner_key_path
)) {
734 if (response
.has_new_public_key()) {
735 base::WorkerPool::PostTask(
737 base::Bind(&StoreFile
, owner_key_path
, response
.new_public_key()),
741 // Chrome will attempt to retrieve the device policy right after storing
742 // during enrollment, so make sure it's written before signaling
744 // Note also that the owner key will be written before the device policy,
745 // if it was present in the blob.
746 base::FilePath device_policy_path
=
747 owner_key_path
.DirName().AppendASCII("stub_device_policy");
748 base::WorkerPool::PostTaskAndReply(
750 base::Bind(&StoreFile
, device_policy_path
, policy_blob
),
751 base::Bind(callback
, true),
754 void StorePolicyForUser(const std::string
& username
,
755 const std::string
& policy_blob
,
756 const StorePolicyCallback
& callback
) override
{
757 // The session manager writes the user policy key to a well-known
758 // location. Do the same with the stub impl, so that user policy works and
759 // can be tested on desktop builds.
760 enterprise_management::PolicyFetchResponse response
;
761 if (!response
.ParseFromString(policy_blob
)) {
766 if (response
.has_new_public_key()) {
767 base::FilePath key_path
= GetUserFilePath(username
, "policy.pub");
768 base::WorkerPool::PostTask(
770 base::Bind(&StoreFile
, key_path
, response
.new_public_key()),
774 // This file isn't read directly by Chrome, but is used by this class to
775 // reload the user policy across restarts.
776 base::FilePath stub_policy_path
= GetUserFilePath(username
, "stub_policy");
777 base::WorkerPool::PostTaskAndReply(
779 base::Bind(&StoreFile
, stub_policy_path
, policy_blob
),
780 base::Bind(callback
, true),
783 void StoreDeviceLocalAccountPolicy(
784 const std::string
& account_name
,
785 const std::string
& policy_blob
,
786 const StorePolicyCallback
& callback
) override
{
787 StorePolicyForUser(account_name
, policy_blob
, callback
);
789 void SetFlagsForUser(const std::string
& username
,
790 const std::vector
<std::string
>& flags
) override
{}
792 void GetServerBackedStateKeys(const StateKeysCallback
& callback
) override
{
793 std::vector
<std::string
> state_keys
;
794 for (int i
= 0; i
< 5; ++i
)
795 state_keys
.push_back(crypto::SHA256HashString(base::IntToString(i
)));
797 if (!callback
.is_null())
798 callback
.Run(state_keys
);
802 StubDelegate
* delegate_
; // Weak pointer; may be NULL.
803 base::ObserverList
<Observer
> observers_
;
804 std::string device_policy_
;
805 bool screen_is_locked_
;
807 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl
);
810 SessionManagerClient::SessionManagerClient() {
813 SessionManagerClient::~SessionManagerClient() {
816 SessionManagerClient
* SessionManagerClient::Create(
817 DBusClientImplementationType type
) {
818 if (type
== REAL_DBUS_CLIENT_IMPLEMENTATION
)
819 return new SessionManagerClientImpl();
820 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION
, type
);
821 return new SessionManagerClientStubImpl();
824 } // namespace chromeos