Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Side by Side Diff: chromeos/dbus/session_manager_client.cc

Issue 2310823003: chromeos: Remove dbus::FileDescriptor from SessionManagerClient (Closed)
Patch Set: Add a comment Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chromeos/dbus/session_manager_client.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromeos/dbus/session_manager_client.h" 5 #include "chromeos/dbus/session_manager_client.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <sys/socket.h>
10 9
11 #include <memory> 10 #include <memory>
12 11
13 #include "base/bind.h" 12 #include "base/bind.h"
14 #include "base/callback.h" 13 #include "base/callback.h"
15 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
16 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
17 #include "base/location.h" 16 #include "base/location.h"
18 #include "base/macros.h" 17 #include "base/macros.h"
19 #include "base/path_service.h" 18 #include "base/path_service.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 // Helper to write a file in a background thread. 60 // Helper to write a file in a background thread.
62 void StoreFile(const base::FilePath& path, const std::string& data) { 61 void StoreFile(const base::FilePath& path, const std::string& data) {
63 const int size = static_cast<int>(data.size()); 62 const int size = static_cast<int>(data.size());
64 if (path.empty() || 63 if (path.empty() ||
65 !base::CreateDirectory(path.DirName()) || 64 !base::CreateDirectory(path.DirName()) ||
66 base::WriteFile(path, data.data(), size) != size) { 65 base::WriteFile(path, data.data(), size) != size) {
67 LOG(WARNING) << "Failed to write to " << path.value(); 66 LOG(WARNING) << "Failed to write to " << path.value();
68 } 67 }
69 } 68 }
70 69
71 // Creates a pair of file descriptors that form a conduit for trustworthy
72 // transfer of credentials between Chrome and the session_manager
73 void CreateValidCredConduit(dbus::FileDescriptor* local_auth_fd,
74 dbus::FileDescriptor* remote_auth_fd) {
75 int sockets[2] = {-1, -1};
76 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
77 PLOG(ERROR) << "Failed to create a unix domain socketpair";
78 return;
79 }
80
81 local_auth_fd->PutValue(sockets[0]);
82 local_auth_fd->CheckValidity();
83
84 remote_auth_fd->PutValue(sockets[1]);
85 remote_auth_fd->CheckValidity();
86 }
87
88 } // namespace 70 } // namespace
89 71
90 // The SessionManagerClient implementation used in production. 72 // The SessionManagerClient implementation used in production.
91 class SessionManagerClientImpl : public SessionManagerClient { 73 class SessionManagerClientImpl : public SessionManagerClient {
92 public: 74 public:
93 SessionManagerClientImpl() 75 SessionManagerClientImpl()
94 : session_manager_proxy_(NULL), 76 : session_manager_proxy_(NULL),
95 screen_is_locked_(false), 77 screen_is_locked_(false),
96 weak_ptr_factory_(this) {} 78 weak_ptr_factory_(this) {}
97 79
(...skipping 17 matching lines...) Expand all
115 } 97 }
116 98
117 bool IsScreenLocked() const override { return screen_is_locked_; } 99 bool IsScreenLocked() const override { return screen_is_locked_; }
118 100
119 void EmitLoginPromptVisible() override { 101 void EmitLoginPromptVisible() override {
120 SimpleMethodCallToSessionManager( 102 SimpleMethodCallToSessionManager(
121 login_manager::kSessionManagerEmitLoginPromptVisible); 103 login_manager::kSessionManagerEmitLoginPromptVisible);
122 FOR_EACH_OBSERVER(Observer, observers_, EmitLoginPromptVisibleCalled()); 104 FOR_EACH_OBSERVER(Observer, observers_, EmitLoginPromptVisibleCalled());
123 } 105 }
124 106
125 void RestartJob(const std::vector<std::string>& argv) override { 107 void RestartJob(int socket_fd,
126 dbus::ScopedFileDescriptor local_auth_fd(new dbus::FileDescriptor); 108 const std::vector<std::string>& argv,
127 dbus::ScopedFileDescriptor remote_auth_fd(new dbus::FileDescriptor); 109 const VoidDBusMethodCallback& callback) override {
128 110 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
129 // session_manager's RestartJob call requires the caller to open a socket 111 login_manager::kSessionManagerRestartJob);
130 // pair and pass one end over dbus while holding the local end open for the 112 dbus::MessageWriter writer(&method_call);
131 // duration of the call. session_manager uses this to determine whether the 113 writer.AppendFileDescriptor(socket_fd);
132 // PID the restart request originates from belongs to the browser itself. 114 writer.AppendArrayOfStrings(argv);
133 // 115 session_manager_proxy_->CallMethod(
134 // Here, we call CreateValidCredConduit() to create the socket pair, 116 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
135 // and then pass both ends along to CallRestartJobWithValidFd(), which 117 base::Bind(&SessionManagerClientImpl::OnRestartJob,
136 // takes care of them from there. 118 weak_ptr_factory_.GetWeakPtr(), callback));
137 // NB: PostTaskAndReply ensures that the second callback (which owns the
138 // ScopedFileDescriptor objects) outlives the first, so passing the
139 // bare pointers to CreateValidCredConduit is safe...
140 // -- BUT --
141 // you have to grab pointers to the contents of {local,remote}_auth_fd
142 // _before_ they're acted on by base::Passed() below. Passing ownership
143 // of the ScopedFileDescriptor objects to the callback actually nulls
144 // out the storage inside the local instances. Since there are
145 // no guarantees about the order of evaluation of arguments in a
146 // function call, merely having them appear earlier among the args
147 // to PostTaskAndReply() is not enough. Relying on this crashed on
148 // some platforms.
149 base::Closure create_credentials_conduit_closure = base::Bind(
150 &CreateValidCredConduit, local_auth_fd.get(), remote_auth_fd.get());
151
152 base::WorkerPool::PostTaskAndReply(
153 FROM_HERE, create_credentials_conduit_closure,
154 base::Bind(&SessionManagerClientImpl::CallRestartJobWithValidFd,
155 weak_ptr_factory_.GetWeakPtr(), base::Passed(&local_auth_fd),
156 base::Passed(&remote_auth_fd), argv),
157 false);
158 } 119 }
159 120
160 void StartSession(const cryptohome::Identification& cryptohome_id) override { 121 void StartSession(const cryptohome::Identification& cryptohome_id) override {
161 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 122 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
162 login_manager::kSessionManagerStartSession); 123 login_manager::kSessionManagerStartSession);
163 dbus::MessageWriter writer(&method_call); 124 dbus::MessageWriter writer(&method_call);
164 writer.AppendString(cryptohome_id.id()); 125 writer.AppendString(cryptohome_id.id());
165 writer.AppendString(""); // Unique ID is deprecated 126 writer.AppendString(""); // Unique ID is deprecated
166 session_manager_proxy_->CallMethod( 127 session_manager_proxy_->CallMethod(
167 &method_call, 128 &method_call,
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 session_manager_proxy_->CallMethod( 459 session_manager_proxy_->CallMethod(
499 &method_call, 460 &method_call,
500 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 461 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
501 base::Bind( 462 base::Bind(
502 &SessionManagerClientImpl::OnStorePolicy, 463 &SessionManagerClientImpl::OnStorePolicy,
503 weak_ptr_factory_.GetWeakPtr(), 464 weak_ptr_factory_.GetWeakPtr(),
504 method_name, 465 method_name,
505 callback)); 466 callback));
506 } 467 }
507 468
508 // Calls RestartJob to tell the session manager to restart the browser using
509 // the contents of |argv| as the command line, authorizing the call using
510 // credentials acquired via |remote_auth_fd|. Ownership of |local_auth_fd| is
511 // held for the duration of the dbus call.
512 void CallRestartJobWithValidFd(dbus::ScopedFileDescriptor local_auth_fd,
513 dbus::ScopedFileDescriptor remote_auth_fd,
514 const std::vector<std::string>& argv) {
515 VLOG(1) << "CallRestartJobWithValidFd";
516 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
517 login_manager::kSessionManagerRestartJob);
518 dbus::MessageWriter writer(&method_call);
519 writer.AppendFileDescriptor(*remote_auth_fd);
520 writer.AppendArrayOfStrings(argv);
521
522 // Ownership of local_auth_fd is passed to the callback that is to be
523 // called on completion of this method call. This keeps the browser end
524 // of the socket-pair alive for the duration of the RPC.
525 session_manager_proxy_->CallMethod(
526 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
527 base::Bind(&SessionManagerClientImpl::OnRestartJob,
528 weak_ptr_factory_.GetWeakPtr(),
529 base::Passed(&local_auth_fd)));
530 }
531
532 // Called when kSessionManagerRestartJob method is complete. 469 // Called when kSessionManagerRestartJob method is complete.
533 // Now that the call is complete, local_auth_fd can be closed and discarded, 470 void OnRestartJob(const VoidDBusMethodCallback& callback,
534 // which will happen automatically when it goes out of scope.
535 void OnRestartJob(dbus::ScopedFileDescriptor local_auth_fd,
536 dbus::Response* response) { 471 dbus::Response* response) {
537 VLOG(1) << "OnRestartJob";
538 LOG_IF(ERROR, !response) 472 LOG_IF(ERROR, !response)
539 << "Failed to call " 473 << "Failed to call "
540 << login_manager::kSessionManagerRestartJob; 474 << login_manager::kSessionManagerRestartJob;
475 callback.Run(response ? DBUS_METHOD_CALL_SUCCESS
476 : DBUS_METHOD_CALL_FAILURE);
541 } 477 }
542 478
543 // Called when kSessionManagerStartSession method is complete. 479 // Called when kSessionManagerStartSession method is complete.
544 void OnStartSession(dbus::Response* response) { 480 void OnStartSession(dbus::Response* response) {
545 LOG_IF(ERROR, !response) 481 LOG_IF(ERROR, !response)
546 << "Failed to call " 482 << "Failed to call "
547 << login_manager::kSessionManagerStartSession; 483 << login_manager::kSessionManagerStartSession;
548 } 484 }
549 485
550 // Called when kSessionManagerStopSession method is complete. 486 // Called when kSessionManagerStopSession method is complete.
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 observers_.AddObserver(observer); 745 observers_.AddObserver(observer);
810 } 746 }
811 void RemoveObserver(Observer* observer) override { 747 void RemoveObserver(Observer* observer) override {
812 observers_.RemoveObserver(observer); 748 observers_.RemoveObserver(observer);
813 } 749 }
814 bool HasObserver(const Observer* observer) const override { 750 bool HasObserver(const Observer* observer) const override {
815 return observers_.HasObserver(observer); 751 return observers_.HasObserver(observer);
816 } 752 }
817 bool IsScreenLocked() const override { return screen_is_locked_; } 753 bool IsScreenLocked() const override { return screen_is_locked_; }
818 void EmitLoginPromptVisible() override {} 754 void EmitLoginPromptVisible() override {}
819 void RestartJob(const std::vector<std::string>& argv) override {} 755 void RestartJob(int socket_fd,
756 const std::vector<std::string>& argv,
757 const VoidDBusMethodCallback& callback) override {}
820 void StartSession(const cryptohome::Identification& cryptohome_id) override {} 758 void StartSession(const cryptohome::Identification& cryptohome_id) override {}
821 void StopSession() override {} 759 void StopSession() override {}
822 void NotifySupervisedUserCreationStarted() override {} 760 void NotifySupervisedUserCreationStarted() override {}
823 void NotifySupervisedUserCreationFinished() override {} 761 void NotifySupervisedUserCreationFinished() override {}
824 void StartDeviceWipe() override {} 762 void StartDeviceWipe() override {}
825 void RequestLockScreen() override { 763 void RequestLockScreen() override {
826 if (delegate_) 764 if (delegate_)
827 delegate_->LockScreenForStub(); 765 delegate_->LockScreenForStub();
828 } 766 }
829 void NotifyLockScreenShown() override { 767 void NotifyLockScreenShown() override {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 929
992 SessionManagerClient* SessionManagerClient::Create( 930 SessionManagerClient* SessionManagerClient::Create(
993 DBusClientImplementationType type) { 931 DBusClientImplementationType type) {
994 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 932 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
995 return new SessionManagerClientImpl(); 933 return new SessionManagerClientImpl();
996 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); 934 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
997 return new SessionManagerClientStubImpl(); 935 return new SessionManagerClientStubImpl();
998 } 936 }
999 937
1000 } // namespace chromeos 938 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/dbus/session_manager_client.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698