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

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

Issue 2310823003: chromeos: Remove dbus::FileDescriptor from SessionManagerClient (Closed)
Patch Set: Fix test 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
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 "base/bind.h" 10 #include "base/bind.h"
12 #include "base/callback.h" 11 #include "base/callback.h"
13 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
14 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
15 #include "base/location.h" 14 #include "base/location.h"
16 #include "base/macros.h" 15 #include "base/macros.h"
17 #include "base/path_service.h" 16 #include "base/path_service.h"
18 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 // Helper to write a file in a background thread. 58 // Helper to write a file in a background thread.
60 void StoreFile(const base::FilePath& path, const std::string& data) { 59 void StoreFile(const base::FilePath& path, const std::string& data) {
61 const int size = static_cast<int>(data.size()); 60 const int size = static_cast<int>(data.size());
62 if (path.empty() || 61 if (path.empty() ||
63 !base::CreateDirectory(path.DirName()) || 62 !base::CreateDirectory(path.DirName()) ||
64 base::WriteFile(path, data.data(), size) != size) { 63 base::WriteFile(path, data.data(), size) != size) {
65 LOG(WARNING) << "Failed to write to " << path.value(); 64 LOG(WARNING) << "Failed to write to " << path.value();
66 } 65 }
67 } 66 }
68 67
69 // Creates a pair of file descriptors that form a conduit for trustworthy
70 // transfer of credentials between Chrome and the session_manager
71 void CreateValidCredConduit(dbus::FileDescriptor* local_auth_fd,
72 dbus::FileDescriptor* remote_auth_fd) {
73 int sockets[2] = {-1, -1};
74 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
75 PLOG(ERROR) << "Failed to create a unix domain socketpair";
76 return;
77 }
78
79 local_auth_fd->PutValue(sockets[0]);
80 local_auth_fd->CheckValidity();
81
82 remote_auth_fd->PutValue(sockets[1]);
83 remote_auth_fd->CheckValidity();
84 }
85
86 } // namespace 68 } // namespace
87 69
88 // The SessionManagerClient implementation used in production. 70 // The SessionManagerClient implementation used in production.
89 class SessionManagerClientImpl : public SessionManagerClient { 71 class SessionManagerClientImpl : public SessionManagerClient {
90 public: 72 public:
91 SessionManagerClientImpl() 73 SessionManagerClientImpl()
92 : session_manager_proxy_(NULL), 74 : session_manager_proxy_(NULL),
93 screen_is_locked_(false), 75 screen_is_locked_(false),
94 weak_ptr_factory_(this) {} 76 weak_ptr_factory_(this) {}
95 77
(...skipping 17 matching lines...) Expand all
113 } 95 }
114 96
115 bool IsScreenLocked() const override { return screen_is_locked_; } 97 bool IsScreenLocked() const override { return screen_is_locked_; }
116 98
117 void EmitLoginPromptVisible() override { 99 void EmitLoginPromptVisible() override {
118 SimpleMethodCallToSessionManager( 100 SimpleMethodCallToSessionManager(
119 login_manager::kSessionManagerEmitLoginPromptVisible); 101 login_manager::kSessionManagerEmitLoginPromptVisible);
120 FOR_EACH_OBSERVER(Observer, observers_, EmitLoginPromptVisibleCalled()); 102 FOR_EACH_OBSERVER(Observer, observers_, EmitLoginPromptVisibleCalled());
121 } 103 }
122 104
123 void RestartJob(const std::vector<std::string>& argv) override { 105 void RestartJob(int socket_fd,
124 dbus::ScopedFileDescriptor local_auth_fd(new dbus::FileDescriptor); 106 const std::vector<std::string>& argv,
125 dbus::ScopedFileDescriptor remote_auth_fd(new dbus::FileDescriptor); 107 const VoidDBusMethodCallback& callback) override {
126 108 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
127 // session_manager's RestartJob call requires the caller to open a socket 109 login_manager::kSessionManagerRestartJob);
128 // pair and pass one end over dbus while holding the local end open for the 110 dbus::MessageWriter writer(&method_call);
129 // duration of the call. session_manager uses this to determine whether the 111 writer.AppendFileDescriptor(socket_fd);
130 // PID the restart request originates from belongs to the browser itself. 112 writer.AppendArrayOfStrings(argv);
131 // 113 session_manager_proxy_->CallMethod(
132 // Here, we call CreateValidCredConduit() to create the socket pair, 114 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
133 // and then pass both ends along to CallRestartJobWithValidFd(), which 115 base::Bind(&SessionManagerClientImpl::OnRestartJob,
134 // takes care of them from there. 116 weak_ptr_factory_.GetWeakPtr(), callback));
135 // NB: PostTaskAndReply ensures that the second callback (which owns the
136 // ScopedFileDescriptor objects) outlives the first, so passing the
137 // bare pointers to CreateValidCredConduit is safe...
138 // -- BUT --
139 // you have to grab pointers to the contents of {local,remote}_auth_fd
140 // _before_ they're acted on by base::Passed() below. Passing ownership
141 // of the ScopedFileDescriptor objects to the callback actually nulls
142 // out the storage inside the local instances. Since there are
143 // no guarantees about the order of evaluation of arguments in a
144 // function call, merely having them appear earlier among the args
145 // to PostTaskAndReply() is not enough. Relying on this crashed on
146 // some platforms.
147 base::Closure create_credentials_conduit_closure = base::Bind(
148 &CreateValidCredConduit, local_auth_fd.get(), remote_auth_fd.get());
149
150 base::WorkerPool::PostTaskAndReply(
151 FROM_HERE, create_credentials_conduit_closure,
stevenjb 2016/09/06 15:59:28 It looks like before we were calling socketpair()
152 base::Bind(&SessionManagerClientImpl::CallRestartJobWithValidFd,
153 weak_ptr_factory_.GetWeakPtr(), base::Passed(&local_auth_fd),
154 base::Passed(&remote_auth_fd), argv),
155 false);
156 } 117 }
157 118
158 void StartSession(const cryptohome::Identification& cryptohome_id) override { 119 void StartSession(const cryptohome::Identification& cryptohome_id) override {
159 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 120 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
160 login_manager::kSessionManagerStartSession); 121 login_manager::kSessionManagerStartSession);
161 dbus::MessageWriter writer(&method_call); 122 dbus::MessageWriter writer(&method_call);
162 writer.AppendString(cryptohome_id.id()); 123 writer.AppendString(cryptohome_id.id());
163 writer.AppendString(""); // Unique ID is deprecated 124 writer.AppendString(""); // Unique ID is deprecated
164 session_manager_proxy_->CallMethod( 125 session_manager_proxy_->CallMethod(
165 &method_call, 126 &method_call,
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 session_manager_proxy_->CallMethod( 445 session_manager_proxy_->CallMethod(
485 &method_call, 446 &method_call,
486 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 447 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
487 base::Bind( 448 base::Bind(
488 &SessionManagerClientImpl::OnStorePolicy, 449 &SessionManagerClientImpl::OnStorePolicy,
489 weak_ptr_factory_.GetWeakPtr(), 450 weak_ptr_factory_.GetWeakPtr(),
490 method_name, 451 method_name,
491 callback)); 452 callback));
492 } 453 }
493 454
494 // Calls RestartJob to tell the session manager to restart the browser using
495 // the contents of |argv| as the command line, authorizing the call using
496 // credentials acquired via |remote_auth_fd|. Ownership of |local_auth_fd| is
497 // held for the duration of the dbus call.
498 void CallRestartJobWithValidFd(dbus::ScopedFileDescriptor local_auth_fd,
499 dbus::ScopedFileDescriptor remote_auth_fd,
500 const std::vector<std::string>& argv) {
501 VLOG(1) << "CallRestartJobWithValidFd";
502 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
503 login_manager::kSessionManagerRestartJob);
504 dbus::MessageWriter writer(&method_call);
505 writer.AppendFileDescriptor(*remote_auth_fd);
506 writer.AppendArrayOfStrings(argv);
507
508 // Ownership of local_auth_fd is passed to the callback that is to be
509 // called on completion of this method call. This keeps the browser end
510 // of the socket-pair alive for the duration of the RPC.
511 session_manager_proxy_->CallMethod(
512 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
513 base::Bind(&SessionManagerClientImpl::OnRestartJob,
514 weak_ptr_factory_.GetWeakPtr(),
515 base::Passed(&local_auth_fd)));
516 }
517
518 // Called when kSessionManagerRestartJob method is complete. 455 // Called when kSessionManagerRestartJob method is complete.
519 // Now that the call is complete, local_auth_fd can be closed and discarded, 456 void OnRestartJob(const VoidDBusMethodCallback& callback,
520 // which will happen automatically when it goes out of scope.
521 void OnRestartJob(dbus::ScopedFileDescriptor local_auth_fd,
522 dbus::Response* response) { 457 dbus::Response* response) {
523 VLOG(1) << "OnRestartJob";
524 LOG_IF(ERROR, !response) 458 LOG_IF(ERROR, !response)
525 << "Failed to call " 459 << "Failed to call "
526 << login_manager::kSessionManagerRestartJob; 460 << login_manager::kSessionManagerRestartJob;
461 callback.Run(response ? DBUS_METHOD_CALL_SUCCESS
462 : DBUS_METHOD_CALL_FAILURE);
527 } 463 }
528 464
529 // Called when kSessionManagerStartSession method is complete. 465 // Called when kSessionManagerStartSession method is complete.
530 void OnStartSession(dbus::Response* response) { 466 void OnStartSession(dbus::Response* response) {
531 LOG_IF(ERROR, !response) 467 LOG_IF(ERROR, !response)
532 << "Failed to call " 468 << "Failed to call "
533 << login_manager::kSessionManagerStartSession; 469 << login_manager::kSessionManagerStartSession;
534 } 470 }
535 471
536 // Called when kSessionManagerStopSession method is complete. 472 // Called when kSessionManagerStopSession method is complete.
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 observers_.AddObserver(observer); 731 observers_.AddObserver(observer);
796 } 732 }
797 void RemoveObserver(Observer* observer) override { 733 void RemoveObserver(Observer* observer) override {
798 observers_.RemoveObserver(observer); 734 observers_.RemoveObserver(observer);
799 } 735 }
800 bool HasObserver(const Observer* observer) const override { 736 bool HasObserver(const Observer* observer) const override {
801 return observers_.HasObserver(observer); 737 return observers_.HasObserver(observer);
802 } 738 }
803 bool IsScreenLocked() const override { return screen_is_locked_; } 739 bool IsScreenLocked() const override { return screen_is_locked_; }
804 void EmitLoginPromptVisible() override {} 740 void EmitLoginPromptVisible() override {}
805 void RestartJob(const std::vector<std::string>& argv) override {} 741 void RestartJob(int socket_fd,
742 const std::vector<std::string>& argv,
743 const VoidDBusMethodCallback& callback) override {}
806 void StartSession(const cryptohome::Identification& cryptohome_id) override {} 744 void StartSession(const cryptohome::Identification& cryptohome_id) override {}
807 void StopSession() override {} 745 void StopSession() override {}
808 void NotifySupervisedUserCreationStarted() override {} 746 void NotifySupervisedUserCreationStarted() override {}
809 void NotifySupervisedUserCreationFinished() override {} 747 void NotifySupervisedUserCreationFinished() override {}
810 void StartDeviceWipe() override {} 748 void StartDeviceWipe() override {}
811 void RequestLockScreen() override { 749 void RequestLockScreen() override {
812 if (delegate_) 750 if (delegate_)
813 delegate_->LockScreenForStub(); 751 delegate_->LockScreenForStub();
814 } 752 }
815 void NotifyLockScreenShown() override { 753 void NotifyLockScreenShown() override {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 911
974 SessionManagerClient* SessionManagerClient::Create( 912 SessionManagerClient* SessionManagerClient::Create(
975 DBusClientImplementationType type) { 913 DBusClientImplementationType type) {
976 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 914 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
977 return new SessionManagerClientImpl(); 915 return new SessionManagerClientImpl();
978 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); 916 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
979 return new SessionManagerClientStubImpl(); 917 return new SessionManagerClientStubImpl();
980 } 918 }
981 919
982 } // namespace chromeos 920 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698