| Index: remoting/host/win/launch_process_with_token.cc
|
| diff --git a/remoting/host/win/launch_process_with_token.cc b/remoting/host/win/launch_process_with_token.cc
|
| index db2f40a3c56e1f4a008afd437af2b914d28babb5..60a883e670ce6c70214b7915fdb2b1418c4c0d7b 100644
|
| --- a/remoting/host/win/launch_process_with_token.cc
|
| +++ b/remoting/host/win/launch_process_with_token.cc
|
| @@ -5,21 +5,32 @@
|
| #include "remoting/host/win/launch_process_with_token.h"
|
|
|
| #include <windows.h>
|
| +#include <sddl.h>
|
| #include <winternl.h>
|
|
|
| +#include <limits>
|
| +
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#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/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_proxy.h"
|
|
|
| using base::win::ScopedHandle;
|
|
|
| namespace {
|
|
|
| +// Match the pipe name prefix used by Chrome IPC channels so that the client
|
| +// could use Chrome IPC APIs instead of connecting manually.
|
| +const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome.";
|
| +
|
| const char kCreateProcessDefaultPipeNameFormat[] =
|
| "\\\\.\\Pipe\\TerminalServer\\SystemExecSrvr\\%d";
|
|
|
| @@ -399,6 +410,63 @@ bool CreateRemoteSessionProcess(
|
|
|
| namespace remoting {
|
|
|
| +bool CreateIpcChannel(
|
| + const std::string& channel_name,
|
| + const std::string& pipe_security_descriptor,
|
| + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
|
| + IPC::Listener* delegate,
|
| + scoped_ptr<IPC::ChannelProxy>* channel_out) {
|
| + // Create security descriptor for the channel.
|
| + SECURITY_ATTRIBUTES security_attributes;
|
| + security_attributes.nLength = sizeof(security_attributes);
|
| + security_attributes.bInheritHandle = FALSE;
|
| +
|
| + ULONG security_descriptor_length = 0;
|
| + if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
|
| + UTF8ToUTF16(pipe_security_descriptor).c_str(),
|
| + SDDL_REVISION_1,
|
| + reinterpret_cast<PSECURITY_DESCRIPTOR*>(
|
| + &security_attributes.lpSecurityDescriptor),
|
| + &security_descriptor_length)) {
|
| + LOG_GETLASTERROR(ERROR) <<
|
| + "Failed to create a security descriptor for the Chromoting IPC channel";
|
| + return 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";
|
| + LocalFree(security_attributes.lpSecurityDescriptor);
|
| + return false;
|
| + }
|
| +
|
| + LocalFree(security_attributes.lpSecurityDescriptor);
|
| +
|
| + // Wrap the pipe into an IPC channel.
|
| + channel_out->reset(new IPC::ChannelProxy(
|
| + IPC::ChannelHandle(pipe),
|
| + IPC::Channel::MODE_SERVER,
|
| + delegate,
|
| + io_task_runner));
|
| + 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) {
|
| @@ -441,9 +509,19 @@ bool CreateSessionToken(uint32 session_id, ScopedHandle* token_out) {
|
| return true;
|
| }
|
|
|
| +// Generates a unique IPC channel name.
|
| +std::string GenerateIpcChannelName(void* client) {
|
| + // Generate the pipe name. This code is copied from
|
| + // src/content/common/child_process_host_impl.cc
|
| + return base::StringPrintf("%d.%p.%d",
|
| + base::GetCurrentProcId(), client,
|
| + base::RandInt(0, std::numeric_limits<int>::max()));
|
| +}
|
| +
|
| bool LaunchProcessWithToken(const FilePath& binary,
|
| const CommandLine::StringType& command_line,
|
| HANDLE user_token,
|
| + bool inherit_handles,
|
| DWORD creation_flags,
|
| ScopedHandle* process_out,
|
| ScopedHandle* thread_out) {
|
| @@ -463,7 +541,7 @@ bool LaunchProcessWithToken(const FilePath& binary,
|
| const_cast<LPWSTR>(command_line.c_str()),
|
| NULL,
|
| NULL,
|
| - FALSE,
|
| + inherit_handles,
|
| creation_flags,
|
| NULL,
|
| NULL,
|
|
|