From d35abeeda0fbe66878d7ae751a560061ee7c6b9c Mon Sep 17 00:00:00 2001 From: "alexeypa@chromium.org" Date: Fri, 24 May 2013 00:54:31 +0000 Subject: Make CreateConnectedIpcChannel() a cross-platform API. CreateConnectedIpcChannel() is used to create a pre-conected IPC channel, the client end of which can be passed to another process. This CL moves this function and related code to dedicated remoting/host/ipc_util.h. It also eliminates platform-specific implementations of DesktopSessionAgent class, since the channel created was the only platform specific code they were implementing. BUG=225451 Review URL: https://chromiumcodereview.appspot.com/15559004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201947 0039d316-1c4b-4281-b951-d872f2087c98 --- remoting/host/desktop_process.cc | 10 +- remoting/host/desktop_session_agent.cc | 121 ++++++++++--------- remoting/host/desktop_session_agent.h | 40 +------ remoting/host/desktop_session_agent_posix.cc | 107 ----------------- remoting/host/desktop_session_agent_win.cc | 105 ---------------- remoting/host/ipc_util.h | 55 +++++++++ remoting/host/ipc_util_posix.cc | 58 +++++++++ remoting/host/ipc_util_win.cc | 133 +++++++++++++++++++++ remoting/host/win/launch_process_with_token.cc | 102 ---------------- remoting/host/win/launch_process_with_token.h | 34 ------ remoting/host/win/unprivileged_process_delegate.cc | 14 +-- .../host/win/worker_process_launcher_unittest.cc | 1 + remoting/host/win/wts_session_process_delegate.cc | 1 + remoting/remoting.gyp | 7 +- 14 files changed, 322 insertions(+), 466 deletions(-) delete mode 100644 remoting/host/desktop_session_agent_posix.cc delete mode 100644 remoting/host/desktop_session_agent_win.cc create mode 100644 remoting/host/ipc_util.h create mode 100644 remoting/host/ipc_util_posix.cc create mode 100644 remoting/host/ipc_util_win.cc (limited to 'remoting') diff --git a/remoting/host/desktop_process.cc b/remoting/host/desktop_process.cc index c07fa1d..2f524aa 100644 --- a/remoting/host/desktop_process.cc +++ b/remoting/host/desktop_process.cc @@ -122,11 +122,11 @@ bool DesktopProcess::Start( AutoThread::Create("Video capture thread", caller_task_runner_); // Create a desktop agent. - desktop_agent_ = DesktopSessionAgent::Create(audio_task_runner, - caller_task_runner_, - input_task_runner_, - io_task_runner, - video_capture_task_runner); + desktop_agent_ = new DesktopSessionAgent(audio_task_runner, + caller_task_runner_, + input_task_runner_, + io_task_runner, + video_capture_task_runner); // Start the agent and create an IPC channel to talk to it. IPC::PlatformFileForTransit desktop_pipe; diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc index 025f6e9..490ef90 100644 --- a/remoting/host/desktop_session_agent.cc +++ b/remoting/host/desktop_session_agent.cc @@ -16,6 +16,7 @@ #include "remoting/host/chromoting_messages.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/input_injector.h" +#include "remoting/host/ipc_util.h" #include "remoting/host/remote_input_filter.h" #include "remoting/host/screen_controls.h" #include "remoting/host/screen_resolution.h" @@ -106,18 +107,27 @@ class DesktopSessionAgent::SharedBuffer : public webrtc::SharedMemory { DesktopSessionAgent::Delegate::~Delegate() { } -DesktopSessionAgent::~DesktopSessionAgent() { - DCHECK(!audio_capturer_); - DCHECK(!desktop_environment_); - DCHECK(!network_channel_); - DCHECK(!screen_controls_); - DCHECK(!video_capturer_); - - CloseDesktopPipeHandle(); +DesktopSessionAgent::DesktopSessionAgent( + scoped_refptr audio_capture_task_runner, + scoped_refptr caller_task_runner, + scoped_refptr input_task_runner, + scoped_refptr io_task_runner, + scoped_refptr video_capture_task_runner) + : audio_capture_task_runner_(audio_capture_task_runner), + caller_task_runner_(caller_task_runner), + input_task_runner_(input_task_runner), + io_task_runner_(io_task_runner), + video_capture_task_runner_(video_capture_task_runner), + control_factory_(this), + desktop_pipe_(IPC::InvalidPlatformFileForTransit()), + next_shared_buffer_id_(1), + shared_buffers_(0), + started_(false) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); } bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); bool handled = true; if (started_) { @@ -147,7 +157,7 @@ bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) { } void DesktopSessionAgent::OnChannelConnected(int32 peer_pid) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); VLOG(1) << "IPC: desktop <- network (" << peer_pid << ")"; @@ -155,7 +165,7 @@ void DesktopSessionAgent::OnChannelConnected(int32 peer_pid) { } void DesktopSessionAgent::OnChannelError() { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); // Make sure the channel is closed. network_channel_.reset(); @@ -167,7 +177,7 @@ void DesktopSessionAgent::OnChannelError() { } webrtc::SharedMemory* DesktopSessionAgent::CreateSharedMemory(size_t size) { - DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); + DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); scoped_ptr buffer = SharedBuffer::Create(this, size, next_shared_buffer_id_); @@ -197,6 +207,16 @@ webrtc::SharedMemory* DesktopSessionAgent::CreateSharedMemory(size_t size) { return buffer.release(); } +DesktopSessionAgent::~DesktopSessionAgent() { + DCHECK(!audio_capturer_); + DCHECK(!desktop_environment_); + DCHECK(!network_channel_); + DCHECK(!screen_controls_); + DCHECK(!video_capturer_); + + CloseDesktopPipeHandle(); +} + const std::string& DesktopSessionAgent::client_jid() const { return client_jid_; } @@ -206,13 +226,13 @@ void DesktopSessionAgent::DisconnectSession() { } void DesktopSessionAgent::OnLocalMouseMoved(const SkIPoint& new_pos) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); remote_input_filter_->LocalMouseMoved(new_pos); } void DesktopSessionAgent::SetDisableInputs(bool disable_inputs) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); // Do not expect this method to be called because it is only used by It2Me. NOTREACHED(); @@ -222,7 +242,7 @@ void DesktopSessionAgent::OnStartSessionAgent( const std::string& authenticated_jid, const ScreenResolution& resolution, bool virtual_terminal) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); DCHECK(!started_); DCHECK(!audio_capturer_); DCHECK(!desktop_environment_); @@ -266,18 +286,18 @@ void DesktopSessionAgent::OnStartSessionAgent( // Start the audio capturer. if (delegate_->desktop_environment_factory().SupportsAudioCapture()) { audio_capturer_ = desktop_environment_->CreateAudioCapturer(); - audio_capture_task_runner()->PostTask( + audio_capture_task_runner_->PostTask( FROM_HERE, base::Bind(&DesktopSessionAgent::StartAudioCapturer, this)); } // Start the video capturer. video_capturer_ = desktop_environment_->CreateVideoCapturer(); - video_capture_task_runner()->PostTask( + video_capture_task_runner_->PostTask( FROM_HERE, base::Bind(&DesktopSessionAgent::StartVideoCapturer, this)); } void DesktopSessionAgent::OnCaptureCompleted(webrtc::DesktopFrame* frame) { - DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); + DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); last_frame_.reset(frame); @@ -301,7 +321,7 @@ void DesktopSessionAgent::OnCaptureCompleted(webrtc::DesktopFrame* frame) { void DesktopSessionAgent::OnCursorShapeChanged( scoped_ptr cursor_shape) { - DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); + DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); SendToNetwork(new ChromotingDesktopNetworkMsg_CursorShapeChanged( *cursor_shape)); @@ -309,7 +329,7 @@ void DesktopSessionAgent::OnCursorShapeChanged( void DesktopSessionAgent::InjectClipboardEvent( const protocol::ClipboardEvent& event) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); std::string serialized_event; if (!event.SerializeToString(&serialized_event)) { @@ -322,7 +342,7 @@ void DesktopSessionAgent::InjectClipboardEvent( } void DesktopSessionAgent::ProcessAudioPacket(scoped_ptr packet) { - DCHECK(audio_capture_task_runner()->BelongsToCurrentThread()); + DCHECK(audio_capture_task_runner_->BelongsToCurrentThread()); std::string serialized_packet; if (!packet->SerializeToString(&serialized_packet)) { @@ -335,20 +355,22 @@ void DesktopSessionAgent::ProcessAudioPacket(scoped_ptr packet) { bool DesktopSessionAgent::Start(const base::WeakPtr& delegate, IPC::PlatformFileForTransit* desktop_pipe_out) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); DCHECK(delegate_.get() == NULL); delegate_ = delegate; // Create an IPC channel to communicate with the network process. - bool result = CreateChannelForNetworkProcess(&desktop_pipe_, - &network_channel_); + bool result = CreateConnectedIpcChannel(io_task_runner_, + this, + &desktop_pipe_, + &network_channel_); *desktop_pipe_out = desktop_pipe_; return result; } void DesktopSessionAgent::Stop() { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); delegate_.reset(); @@ -373,18 +395,18 @@ void DesktopSessionAgent::Stop() { screen_controls_.reset(); // Stop the audio capturer. - audio_capture_task_runner()->PostTask( + audio_capture_task_runner_->PostTask( FROM_HERE, base::Bind(&DesktopSessionAgent::StopAudioCapturer, this)); // Stop the video capturer. - video_capture_task_runner()->PostTask( + video_capture_task_runner_->PostTask( FROM_HERE, base::Bind(&DesktopSessionAgent::StopVideoCapturer, this)); } } void DesktopSessionAgent::OnCaptureFrame() { - if (!video_capture_task_runner()->BelongsToCurrentThread()) { - video_capture_task_runner()->PostTask( + if (!video_capture_task_runner_->BelongsToCurrentThread()) { + video_capture_task_runner_->PostTask( FROM_HERE, base::Bind(&DesktopSessionAgent::OnCaptureFrame, this)); return; @@ -400,7 +422,7 @@ void DesktopSessionAgent::OnCaptureFrame() { void DesktopSessionAgent::OnInjectClipboardEvent( const std::string& serialized_event) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); protocol::ClipboardEvent event; if (!event.ParseFromString(serialized_event)) { @@ -415,7 +437,7 @@ void DesktopSessionAgent::OnInjectClipboardEvent( void DesktopSessionAgent::OnInjectKeyEvent( const std::string& serialized_event) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); protocol::KeyEvent event; if (!event.ParseFromString(serialized_event)) { @@ -435,7 +457,7 @@ void DesktopSessionAgent::OnInjectKeyEvent( void DesktopSessionAgent::OnInjectMouseEvent( const std::string& serialized_event) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); protocol::MouseEvent event; if (!event.ParseFromString(serialized_event)) { @@ -450,15 +472,15 @@ void DesktopSessionAgent::OnInjectMouseEvent( void DesktopSessionAgent::SetScreenResolution( const ScreenResolution& resolution) { - DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); if (screen_controls_ && resolution.IsEmpty()) screen_controls_->SetScreenResolution(resolution); } void DesktopSessionAgent::SendToNetwork(IPC::Message* message) { - if (!caller_task_runner()->BelongsToCurrentThread()) { - caller_task_runner()->PostTask( + if (!caller_task_runner_->BelongsToCurrentThread()) { + caller_task_runner_->PostTask( FROM_HERE, base::Bind(&DesktopSessionAgent::SendToNetwork, this, message)); return; @@ -472,7 +494,7 @@ void DesktopSessionAgent::SendToNetwork(IPC::Message* message) { } void DesktopSessionAgent::StartAudioCapturer() { - DCHECK(audio_capture_task_runner()->BelongsToCurrentThread()); + DCHECK(audio_capture_task_runner_->BelongsToCurrentThread()); if (audio_capturer_) { audio_capturer_->Start(base::Bind(&DesktopSessionAgent::ProcessAudioPacket, @@ -481,13 +503,13 @@ void DesktopSessionAgent::StartAudioCapturer() { } void DesktopSessionAgent::StopAudioCapturer() { - DCHECK(audio_capture_task_runner()->BelongsToCurrentThread()); + DCHECK(audio_capture_task_runner_->BelongsToCurrentThread()); audio_capturer_.reset(); } void DesktopSessionAgent::StartVideoCapturer() { - DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); + DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); if (video_capturer_) { video_capturer_->SetMouseShapeObserver(this); @@ -496,7 +518,7 @@ void DesktopSessionAgent::StartVideoCapturer() { } void DesktopSessionAgent::StopVideoCapturer() { - DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); + DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); video_capturer_.reset(); last_frame_.reset(); @@ -505,27 +527,8 @@ void DesktopSessionAgent::StopVideoCapturer() { DCHECK_EQ(shared_buffers_, 0); } -DesktopSessionAgent::DesktopSessionAgent( - scoped_refptr audio_capture_task_runner, - scoped_refptr caller_task_runner, - scoped_refptr input_task_runner, - scoped_refptr io_task_runner, - scoped_refptr video_capture_task_runner) - : audio_capture_task_runner_(audio_capture_task_runner), - caller_task_runner_(caller_task_runner), - input_task_runner_(input_task_runner), - io_task_runner_(io_task_runner), - video_capture_task_runner_(video_capture_task_runner), - control_factory_(this), - desktop_pipe_(IPC::InvalidPlatformFileForTransit()), - next_shared_buffer_id_(1), - shared_buffers_(0), - started_(false) { - DCHECK(caller_task_runner_->BelongsToCurrentThread()); -} - void DesktopSessionAgent::OnSharedBufferDeleted(int id) { - DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); + DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); DCHECK(id != 0); shared_buffers_--; diff --git a/remoting/host/desktop_session_agent.h b/remoting/host/desktop_session_agent.h index 91320ab..e121c94 100644 --- a/remoting/host/desktop_session_agent.h +++ b/remoting/host/desktop_session_agent.h @@ -62,7 +62,7 @@ class DesktopSessionAgent virtual void OnNetworkProcessDisconnected() = 0; }; - static scoped_refptr Create( + DesktopSessionAgent( scoped_refptr audio_capture_task_runner, scoped_refptr caller_task_runner, scoped_refptr input_task_runner, @@ -101,12 +101,6 @@ class DesktopSessionAgent protected: friend class base::RefCountedThreadSafe; - DesktopSessionAgent( - scoped_refptr audio_capture_task_runner, - scoped_refptr caller_task_runner, - scoped_refptr input_task_runner, - scoped_refptr io_task_runner, - scoped_refptr video_capture_task_runner); virtual ~DesktopSessionAgent(); // ClientSessionControl interface. @@ -115,12 +109,6 @@ class DesktopSessionAgent virtual void OnLocalMouseMoved(const SkIPoint& position) OVERRIDE; virtual void SetDisableInputs(bool disable_inputs) OVERRIDE; - // Creates a connected IPC channel to be used to access the screen/audio - // recorders and input stubs. - virtual bool CreateChannelForNetworkProcess( - IPC::PlatformFileForTransit* client_out, - scoped_ptr* server_out) = 0; - // Handles StartSessionAgent request from the client. void OnStartSessionAgent(const std::string& authenticated_jid, const ScreenResolution& resolution, @@ -156,32 +144,6 @@ class DesktopSessionAgent // Posted to |video_capture_task_runner_| to stop the video capturer. void StopVideoCapturer(); - // Getters providing access to the task runners for platform-specific derived - // classes. - scoped_refptr audio_capture_task_runner() const { - return audio_capture_task_runner_; - } - - scoped_refptr caller_task_runner() const { - return caller_task_runner_; - } - - scoped_refptr input_task_runner() const { - return input_task_runner_; - } - - scoped_refptr io_task_runner() const { - return io_task_runner_; - } - - scoped_refptr video_capture_task_runner() const { - return video_capture_task_runner_; - } - - const base::WeakPtr& delegate() const { - return delegate_; - } - private: class SharedBuffer; friend class SharedBuffer; diff --git a/remoting/host/desktop_session_agent_posix.cc b/remoting/host/desktop_session_agent_posix.cc deleted file mode 100644 index e48991d..0000000 --- a/remoting/host/desktop_session_agent_posix.cc +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/host/desktop_session_agent.h" - -#include -#include -#include -#include - -#include "base/posix/eintr_wrapper.h" -#include "base/single_thread_task_runner.h" -#include "ipc/ipc_channel.h" -#include "ipc/ipc_channel_proxy.h" -#include "remoting/base/auto_thread_task_runner.h" - -namespace remoting { - -// Provides screen/audio capturing and input injection services for -// the network process. -class DesktopSessionAgentPosix : public DesktopSessionAgent { - public: - DesktopSessionAgentPosix( - scoped_refptr audio_capture_task_runner, - scoped_refptr caller_task_runner, - scoped_refptr input_task_runner, - scoped_refptr io_task_runner, - scoped_refptr video_capture_task_runner); - - protected: - virtual ~DesktopSessionAgentPosix(); - - virtual bool CreateChannelForNetworkProcess( - IPC::PlatformFileForTransit* client_out, - scoped_ptr* server_out) OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(DesktopSessionAgentPosix); -}; - -DesktopSessionAgentPosix::DesktopSessionAgentPosix( - scoped_refptr audio_capture_task_runner, - scoped_refptr caller_task_runner, - scoped_refptr input_task_runner, - scoped_refptr io_task_runner, - scoped_refptr video_capture_task_runner) - : DesktopSessionAgent(audio_capture_task_runner, caller_task_runner, - input_task_runner, io_task_runner, - video_capture_task_runner) { -} - -DesktopSessionAgentPosix::~DesktopSessionAgentPosix() { -} - -bool DesktopSessionAgentPosix::CreateChannelForNetworkProcess( - IPC::PlatformFileForTransit* client_out, - scoped_ptr* server_out) { - // Create a socket pair. - int pipe_fds[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { - PLOG(ERROR) << "socketpair()"; - return false; - } - - // Set both ends to be non-blocking. - if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || - fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { - PLOG(ERROR) << "fcntl(O_NONBLOCK)"; - if (HANDLE_EINTR(close(pipe_fds[0])) < 0) - PLOG(ERROR) << "close()"; - if (HANDLE_EINTR(close(pipe_fds[1])) < 0) - PLOG(ERROR) << "close()"; - return false; - } - - // Generate a unique name for the channel. - std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID(); - std::string socket_name = "DesktopSessionAgent socket"; - - // Wrap the pipe into an IPC channel. - base::FileDescriptor fd(pipe_fds[0], false); - IPC::ChannelHandle handle(socket_name, fd); - server_out->reset(new IPC::ChannelProxy( - IPC::ChannelHandle(socket_name, fd), - IPC::Channel::MODE_SERVER, - this, - io_task_runner())); - - *client_out = base::FileDescriptor(pipe_fds[1], false); - return true; -} - -// static -scoped_refptr DesktopSessionAgent::Create( - scoped_refptr audio_capture_task_runner, - scoped_refptr caller_task_runner, - scoped_refptr input_task_runner, - scoped_refptr io_task_runner, - scoped_refptr video_capture_task_runner) { - return scoped_refptr( - new DesktopSessionAgentPosix(audio_capture_task_runner, - caller_task_runner, input_task_runner, - io_task_runner, video_capture_task_runner)); -} - -} // namespace remoting diff --git a/remoting/host/desktop_session_agent_win.cc b/remoting/host/desktop_session_agent_win.cc deleted file mode 100644 index 4b32d0e..0000000 --- a/remoting/host/desktop_session_agent_win.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/host/desktop_session_agent.h" - -#include "base/logging.h" -#include "base/single_thread_task_runner.h" -#include "base/stringprintf.h" -#include "base/utf_string_conversions.h" -#include "base/win/scoped_handle.h" -#include "base/win/win_util.h" -#include "ipc/ipc_channel.h" -#include "ipc/ipc_channel_proxy.h" -#include "remoting/base/auto_thread_task_runner.h" -#include "remoting/host/win/launch_process_with_token.h" - -using base::win::ScopedHandle; - -namespace remoting { - -// Provides screen/audio capturing and input injection services for -// the network process. -class DesktopSessionAgentWin : public DesktopSessionAgent { - public: - DesktopSessionAgentWin( - scoped_refptr audio_capture_task_runner, - scoped_refptr caller_task_runner, - scoped_refptr input_task_runner, - scoped_refptr io_task_runner, - scoped_refptr video_capture_task_runner); - - protected: - virtual ~DesktopSessionAgentWin(); - - virtual bool CreateChannelForNetworkProcess( - IPC::PlatformFileForTransit* client_out, - scoped_ptr* server_out) OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(DesktopSessionAgentWin); -}; - -DesktopSessionAgentWin::DesktopSessionAgentWin( - scoped_refptr audio_capture_task_runner, - scoped_refptr caller_task_runner, - scoped_refptr input_task_runner, - scoped_refptr io_task_runner, - scoped_refptr video_capture_task_runner) - : DesktopSessionAgent(audio_capture_task_runner, - caller_task_runner, - input_task_runner, - io_task_runner, - video_capture_task_runner) { -} - -DesktopSessionAgentWin::~DesktopSessionAgentWin() { -} - -bool DesktopSessionAgentWin::CreateChannelForNetworkProcess( - IPC::PlatformFileForTransit* client_out, - scoped_ptr* server_out) { - // Generate a unique name for the channel. - std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID(); - - // presubmit: allow wstring - std::wstring user_sid; - if (!base::win::GetUserSidString(&user_sid)) { - LOG(ERROR) << "Failed to query the current user SID."; - return false; - } - - // Create a security descriptor that will be used to protect the named pipe in - // between CreateNamedPipe() and CreateFile() calls before it will be passed - // to the network process. It gives full access to the account that - // the calling code is running under and denies access by anyone else. - std::string security_descriptor = base::StringPrintf( - "O:%1$sG:%1$sD:(A;;GA;;;%1$s)", WideToUTF8(user_sid).c_str()); - - // Create a connected IPC channel. - ScopedHandle client; - scoped_ptr server; - if (!CreateConnectedIpcChannel(channel_name, security_descriptor, - io_task_runner(), this, &client, &server)) { - return false; - } - - *client_out = client.Take(); - *server_out = server.Pass(); - return true; -} - -// static -scoped_refptr DesktopSessionAgent::Create( - scoped_refptr audio_capture_task_runner, - scoped_refptr caller_task_runner, - scoped_refptr input_task_runner, - scoped_refptr io_task_runner, - scoped_refptr video_capture_task_runner) { - return scoped_refptr(new DesktopSessionAgentWin( - audio_capture_task_runner, caller_task_runner, input_task_runner, - io_task_runner, video_capture_task_runner)); -} - -} // namespace remoting diff --git a/remoting/host/ipc_util.h b/remoting/host/ipc_util.h new file mode 100644 index 0000000..78b7271 --- /dev/null +++ b/remoting/host/ipc_util.h @@ -0,0 +1,55 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_HOST_IPC_UTIL_H_ +#define REMOTING_HOST_IPC_UTIL_H_ + +#include + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "ipc/ipc_platform_file.h" + +#if defined(OS_WIN) +#include "base/win/scoped_handle.h" +#endif // defined(OS_WIN) + +namespace base { +class SingleThreadTaskRunner; +} // namespace base + +namespace IPC { +class ChannelProxy; +class Listener; +} // namespace IPC + +namespace remoting { + +// Creates an already connected IPC channel. The server end of the channel +// is wrapped into a channel proxy that will invoke methods of |listener| +// on the caller's thread while using |io_task_runner| to send and receive +// messages in the background. The client end is returned as a pipe handle +// (inheritable on Windows). +bool CreateConnectedIpcChannel( + scoped_refptr io_task_runner, + IPC::Listener* listener, + IPC::PlatformFileForTransit* client_out, + scoped_ptr* server_out); + +#if defined(OS_WIN) + +// Creates the server end of the IPC channel and applies the security +// descriptor |pipe_security_descriptor| to it. +bool CreateIpcChannel( + const std::string& channel_name, + const std::string& pipe_security_descriptor, + base::win::ScopedHandle* pipe_out); + +#endif // defined(OS_WIN) + +} // namespace remoting + +#endif // REMOTING_HOST_IPC_UTIL_H_ diff --git a/remoting/host/ipc_util_posix.cc b/remoting/host/ipc_util_posix.cc new file mode 100644 index 0000000..e747a77 --- /dev/null +++ b/remoting/host/ipc_util_posix.cc @@ -0,0 +1,58 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/host/ipc_util.h" + +#include +#include +#include +#include + +#include "base/logging.h" +#include "base/posix/eintr_wrapper.h" +#include "base/single_thread_task_runner.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" + +namespace remoting { + +bool CreateConnectedIpcChannel( + scoped_refptr io_task_runner, + IPC::Listener* listener, + IPC::PlatformFileForTransit* client_out, + scoped_ptr* server_out) { + // Create a socket pair. + int pipe_fds[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { + PLOG(ERROR) << "socketpair()"; + return false; + } + + // Set both ends to be non-blocking. + if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || + fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { + PLOG(ERROR) << "fcntl(O_NONBLOCK)"; + if (HANDLE_EINTR(close(pipe_fds[0])) < 0) + PLOG(ERROR) << "close()"; + if (HANDLE_EINTR(close(pipe_fds[1])) < 0) + PLOG(ERROR) << "close()"; + return false; + } + + std::string socket_name = "Chromoting socket"; + + // Wrap the pipe into an IPC channel. + base::FileDescriptor fd(pipe_fds[0], false); + IPC::ChannelHandle handle(socket_name, fd); + server_out->reset(new IPC::ChannelProxy( + IPC::ChannelHandle(socket_name, fd), + IPC::Channel::MODE_SERVER, + listener, + io_task_runner)); + + *client_out = base::FileDescriptor(pipe_fds[1], false); + return true; +} + +} // namespace remoting diff --git a/remoting/host/ipc_util_win.cc b/remoting/host/ipc_util_win.cc new file mode 100644 index 0000000..e445225 --- /dev/null +++ b/remoting/host/ipc_util_win.cc @@ -0,0 +1,133 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/host/ipc_util.h" + +#include "base/logging.h" +#include "base/single_thread_task_runner.h" +#include "base/stringprintf.h" +#include "base/utf_string_conversions.h" +#include "base/win/scoped_handle.h" +#include "base/win/win_util.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" +#include "remoting/host/win/security_descriptor.h" + +using base::win::ScopedHandle; + +namespace remoting { + +// Pipe name prefix used by Chrome IPC channels to convert a channel name into +// a pipe name. +const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome."; + +bool CreateConnectedIpcChannel( + scoped_refptr io_task_runner, + IPC::Listener* listener, + IPC::PlatformFileForTransit* client_out, + scoped_ptr* server_out) { + // presubmit: allow wstring + std::wstring user_sid; + if (!base::win::GetUserSidString(&user_sid)) { + LOG(ERROR) << "Failed to query the current user SID."; + return false; + } + + // Create a security descriptor that will be used to protect the named pipe in + // between CreateNamedPipe() and CreateFile() calls before it will be passed + // to the network process. It gives full access to the account that + // the calling code is running under and denies access by anyone else. + std::string security_descriptor = base::StringPrintf( + "O:%1$sG:%1$sD:(A;;GA;;;%1$s)", WideToUTF8(user_sid).c_str()); + + // Generate a unique name for the channel. + std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID(); + + // Create the server end of the channel. + ScopedHandle pipe; + if (!CreateIpcChannel(channel_name, security_descriptor, &pipe)) { + return false; + } + + // Wrap the pipe into an IPC channel. + scoped_ptr server(new IPC::ChannelProxy( + IPC::ChannelHandle(pipe), + IPC::Channel::MODE_SERVER, + listener, + io_task_runner)); + + // Convert the channel name to the pipe name. + std::string pipe_name(kChromePipeNamePrefix); + pipe_name.append(channel_name); + + SECURITY_ATTRIBUTES security_attributes = {0}; + security_attributes.nLength = sizeof(security_attributes); + security_attributes.lpSecurityDescriptor = NULL; + security_attributes.bInheritHandle = TRUE; + + // Create the client end of the channel. This code should match the code in + // IPC::Channel. + ScopedHandle client; + client.Set(CreateFile(UTF8ToUTF16(pipe_name).c_str(), + GENERIC_READ | GENERIC_WRITE, + 0, + &security_attributes, + OPEN_EXISTING, + SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION | + FILE_FLAG_OVERLAPPED, + NULL)); + if (!client.IsValid()) { + LOG_GETLASTERROR(ERROR) << "Failed to connect to '" << pipe_name << "'"; + return false; + } + + *client_out = client.Take(); + *server_out = server.Pass(); + return true; +} + +bool CreateIpcChannel( + const std::string& channel_name, + const std::string& pipe_security_descriptor, + base::win::ScopedHandle* pipe_out) { + // Create security descriptor for the channel. + ScopedSd sd = ConvertSddlToSd(pipe_security_descriptor); + if (!sd) { + LOG_GETLASTERROR(ERROR) << + "Failed to create a security descriptor for the Chromoting IPC channel"; + return false; + } + + SECURITY_ATTRIBUTES security_attributes = {0}; + security_attributes.nLength = sizeof(security_attributes); + security_attributes.lpSecurityDescriptor = sd.get(); + security_attributes.bInheritHandle = FALSE; + + // Convert the channel name to the pipe name. + std::string pipe_name(kChromePipeNamePrefix); + pipe_name.append(channel_name); + + // Create the server end of the pipe. This code should match the code in + // IPC::Channel with exception of passing a non-default security descriptor. + base::win::ScopedHandle pipe; + pipe.Set(CreateNamedPipe( + UTF8ToUTF16(pipe_name).c_str(), + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, + 1, + IPC::Channel::kReadBufferSize, + IPC::Channel::kReadBufferSize, + 5000, + &security_attributes)); + if (!pipe.IsValid()) { + LOG_GETLASTERROR(ERROR) << + "Failed to create the server end of the Chromoting IPC channel"; + return false; + } + + *pipe_out = pipe.Pass(); + return true; +} + +} // namespace remoting diff --git a/remoting/host/win/launch_process_with_token.cc b/remoting/host/win/launch_process_with_token.cc index 72089f5..8f0173c 100644 --- a/remoting/host/win/launch_process_with_token.cc +++ b/remoting/host/win/launch_process_with_token.cc @@ -14,17 +14,12 @@ #include "base/process_util.h" #include "base/rand_util.h" #include "base/scoped_native_library.h" -#include "base/single_thread_task_runner.h" #include "base/string16.h" #include "base/stringprintf.h" #include "base/utf_string_conversions.h" #include "base/win/scoped_handle.h" #include "base/win/scoped_process_information.h" #include "base/win/windows_version.h" -#include "ipc/ipc_channel.h" -#include "ipc/ipc_channel_proxy.h" -#include "ipc/ipc_channel.h" -#include "remoting/host/win/security_descriptor.h" using base::win::ScopedHandle; @@ -410,106 +405,9 @@ bool CreateRemoteSessionProcess( namespace remoting { -// Pipe name prefix used by Chrome IPC channels to convert a channel name into -// a pipe name. -const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome."; - base::LazyInstance::Leaky g_inherit_handles_lock = LAZY_INSTANCE_INITIALIZER; -bool CreateConnectedIpcChannel( - const std::string& channel_name, - const std::string& pipe_security_descriptor, - scoped_refptr io_task_runner, - IPC::Listener* delegate, - base::win::ScopedHandle* client_out, - scoped_ptr* server_out) { - // Create the server end of the channel. - ScopedHandle pipe; - if (!CreateIpcChannel(channel_name, pipe_security_descriptor, &pipe)) { - return false; - } - - // Wrap the pipe into an IPC channel. - scoped_ptr server(new IPC::ChannelProxy( - IPC::ChannelHandle(pipe), - IPC::Channel::MODE_SERVER, - delegate, - io_task_runner)); - - // Convert the channel name to the pipe name. - std::string pipe_name(remoting::kChromePipeNamePrefix); - pipe_name.append(channel_name); - - SECURITY_ATTRIBUTES security_attributes = {0}; - security_attributes.nLength = sizeof(security_attributes); - security_attributes.lpSecurityDescriptor = NULL; - security_attributes.bInheritHandle = TRUE; - - // Create the client end of the channel. This code should match the code in - // IPC::Channel. - ScopedHandle client; - client.Set(CreateFile(UTF8ToUTF16(pipe_name).c_str(), - GENERIC_READ | GENERIC_WRITE, - 0, - &security_attributes, - OPEN_EXISTING, - SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION | - FILE_FLAG_OVERLAPPED, - NULL)); - if (!client.IsValid()) { - LOG_GETLASTERROR(ERROR) << "Failed to connect to '" << pipe_name << "'"; - return false; - } - - *client_out = client.Pass(); - *server_out = server.Pass(); - return true; -} - -bool CreateIpcChannel( - const std::string& channel_name, - const std::string& pipe_security_descriptor, - base::win::ScopedHandle* pipe_out) { - // Create security descriptor for the channel. - ScopedSd sd = ConvertSddlToSd(pipe_security_descriptor); - if (!sd) { - LOG_GETLASTERROR(ERROR) << - "Failed to create a security descriptor for the Chromoting IPC channel"; - return false; - } - - SECURITY_ATTRIBUTES security_attributes = {0}; - security_attributes.nLength = sizeof(security_attributes); - security_attributes.lpSecurityDescriptor = sd.get(); - security_attributes.bInheritHandle = FALSE; - - // Convert the channel name to the pipe name. - std::string pipe_name(kChromePipeNamePrefix); - pipe_name.append(channel_name); - - // Create the server end of the pipe. This code should match the code in - // IPC::Channel with exception of passing a non-default security descriptor. - base::win::ScopedHandle pipe; - pipe.Set(CreateNamedPipe( - UTF8ToUTF16(pipe_name).c_str(), - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, - 1, - IPC::Channel::kReadBufferSize, - IPC::Channel::kReadBufferSize, - 5000, - &security_attributes)); - if (!pipe.IsValid()) { - LOG_GETLASTERROR(ERROR) << - "Failed to create the server end of the Chromoting IPC channel"; - return false; - } - - *pipe_out = pipe.Pass(); - return true; -} - // Creates a copy of the current process token for the given |session_id| so // it can be used to launch a process in that session. bool CreateSessionToken(uint32 session_id, ScopedHandle* token_out) { diff --git a/remoting/host/win/launch_process_with_token.h b/remoting/host/win/launch_process_with_token.h index cd44d71..f33c132 100644 --- a/remoting/host/win/launch_process_with_token.h +++ b/remoting/host/win/launch_process_with_token.h @@ -11,51 +11,17 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/lazy_instance.h" -#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/synchronization/lock.h" #include "base/win/scoped_handle.h" -namespace base { -class SingleThreadTaskRunner; -} // namespace base - -namespace IPC { -class ChannelProxy; -class Listener; -} // namespace IPC - namespace remoting { -// Pipe name prefix used by Chrome IPC channels to convert a channel name into -// a pipe name. -extern const char kChromePipeNamePrefix[]; - // This lock should be taken when creating handles that will be inherited by // a child process. Without it the child process can inherit handles created for // a different child process started at the same time. extern base::LazyInstance::Leaky g_inherit_handles_lock; -// Creates an already connected IPC channel. The server end of the channel -// is wrapped into a channel proxy that will invoke methods of |delegate| -// on the caller's thread while using |io_task_runner| to send and receive -// messages in the background. The client end is returned as an inheritable NT -// handle. |pipe_security_descriptor| is applied to the underlying pipe. -bool CreateConnectedIpcChannel( - const std::string& channel_name, - const std::string& pipe_security_descriptor, - scoped_refptr io_task_runner, - IPC::Listener* delegate, - base::win::ScopedHandle* client_out, - scoped_ptr* server_out); - -// Creates the server end of the IPC channel and applies the security -// descriptor |pipe_security_descriptor| to it. -bool CreateIpcChannel( - const std::string& channel_name, - const std::string& pipe_security_descriptor, - base::win::ScopedHandle* pipe_out); - // Creates a copy of the current process token for the given |session_id| so // it can be used to launch a process in that session. bool CreateSessionToken(uint32 session_id, base::win::ScopedHandle* token_out); diff --git a/remoting/host/win/unprivileged_process_delegate.cc b/remoting/host/win/unprivileged_process_delegate.cc index ce65b0f..a52876e 100644 --- a/remoting/host/win/unprivileged_process_delegate.cc +++ b/remoting/host/win/unprivileged_process_delegate.cc @@ -26,6 +26,7 @@ #include "ipc/ipc_message.h" #include "remoting/base/typed_buffer.h" #include "remoting/host/ipc_constants.h" +#include "remoting/host/ipc_util.h" #include "remoting/host/win/launch_process_with_token.h" #include "remoting/host/win/security_descriptor.h" #include "remoting/host/win/window_station_and_desktop.h" @@ -45,12 +46,6 @@ namespace { // UnprivilegedProcessDelegate replaces the first printf parameter in // the strings below by the logon SID assigned to the worker process. -// Security descriptor used to protect the named pipe in between -// CreateNamedPipe() and CreateFile() calls before it is passed to the network -// process. It gives full access to LocalSystem and denies access by anyone -// else. -const char kDaemonIpcSd[] = "O:SYG:SYD:(A;;GA;;;SY)"; - // Security descriptor of the desktop the worker process attaches to. It gives // SYSTEM and the logon SID full access to the desktop. const char kDesktopSdFormat[] = "O:SYG:SYD:(A;;0xf01ff;;;SY)(A;;0xf01ff;;;%s)"; @@ -235,9 +230,6 @@ void UnprivilegedProcessDelegate::LaunchProcess( scoped_ptr server; - // Generate a unique name for the channel. - std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID(); - // Create a restricted token that will be used to run the worker process. ScopedHandle token; if (!CreateRestrictedToken(&token)) { @@ -283,8 +275,8 @@ void UnprivilegedProcessDelegate::LaunchProcess( // Create a connected IPC channel. ScopedHandle client; - if (!CreateConnectedIpcChannel(channel_name, kDaemonIpcSd, io_task_runner_, - this, &client, &server)) { + if (!CreateConnectedIpcChannel(io_task_runner_, this, client.Receive(), + &server)) { ReportFatalError(); return; } diff --git a/remoting/host/win/worker_process_launcher_unittest.cc b/remoting/host/win/worker_process_launcher_unittest.cc index cf19356..6991996 100644 --- a/remoting/host/win/worker_process_launcher_unittest.cc +++ b/remoting/host/win/worker_process_launcher_unittest.cc @@ -15,6 +15,7 @@ #include "remoting/base/auto_thread_task_runner.h" #include "remoting/host/chromoting_messages.h" #include "remoting/host/host_exit_codes.h" +#include "remoting/host/ipc_util.h" #include "remoting/host/win/launch_process_with_token.h" #include "remoting/host/win/worker_process_launcher.h" #include "remoting/host/worker_process_ipc_delegate.h" diff --git a/remoting/host/win/wts_session_process_delegate.cc b/remoting/host/win/wts_session_process_delegate.cc index 939f786..26e4eea 100644 --- a/remoting/host/win/wts_session_process_delegate.cc +++ b/remoting/host/win/wts_session_process_delegate.cc @@ -23,6 +23,7 @@ #include "ipc/ipc_message.h" #include "remoting/host/host_main.h" #include "remoting/host/ipc_constants.h" +#include "remoting/host/ipc_util.h" #include "remoting/host/win/launch_process_with_token.h" #include "remoting/host/win/worker_process_launcher.h" #include "remoting/host/win/wts_terminal_monitor.h" diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 558f57b..b883868 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -393,6 +393,9 @@ 'host/ipc_input_injector.h', 'host/ipc_screen_controls.cc', 'host/ipc_screen_controls.h', + 'host/ipc_util.h', + 'host/ipc_util_posix.cc', + 'host/ipc_util_win.cc', 'host/ipc_video_frame_capturer.cc', 'host/ipc_video_frame_capturer.h', 'host/it2me_desktop_environment.cc', @@ -1452,8 +1455,6 @@ 'host/desktop_session.h', 'host/desktop_session_agent.cc', 'host/desktop_session_agent.h', - 'host/desktop_session_agent_posix.cc', - 'host/desktop_session_agent_win.cc', 'host/desktop_session_win.cc', 'host/desktop_session_win.h', 'host/host_exit_codes.h', @@ -2616,8 +2617,6 @@ 'host/desktop_session.h', 'host/desktop_session_agent.cc', 'host/desktop_session_agent.h', - 'host/desktop_session_agent_posix.cc', - 'host/desktop_session_agent_win.cc', 'host/heartbeat_sender_unittest.cc', 'host/host_change_notification_listener_unittest.cc', 'host/host_mock_objects.cc', -- cgit v1.1