Roll src/third_party/WebKit f36d5e0:68b67cd (svn 193299:193303)
[chromium-blink-merge.git] / remoting / host / ipc_util_win.cc
blob22ac15a0ea8472740df023c2e709331857f1e41c
1 // Copyright 2013 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 "remoting/host/ipc_util.h"
7 #include "base/files/file.h"
8 #include "base/logging.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/win/scoped_handle.h"
13 #include "base/win/win_util.h"
14 #include "ipc/ipc_channel.h"
15 #include "ipc/ipc_channel_proxy.h"
16 #include "remoting/host/win/security_descriptor.h"
18 using base::win::ScopedHandle;
20 namespace remoting {
22 // Pipe name prefix used by Chrome IPC channels to convert a channel name into
23 // a pipe name.
24 const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome.";
26 bool CreateConnectedIpcChannel(
27 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
28 IPC::Listener* listener,
29 base::File* client_out,
30 scoped_ptr<IPC::ChannelProxy>* server_out) {
31 // presubmit: allow wstring
32 std::wstring user_sid;
33 if (!base::win::GetUserSidString(&user_sid)) {
34 LOG(ERROR) << "Failed to query the current user SID.";
35 return false;
38 // Create a security descriptor that will be used to protect the named pipe in
39 // between CreateNamedPipe() and CreateFile() calls before it will be passed
40 // to the network process. It gives full access to the account that
41 // the calling code is running under and denies access by anyone else.
42 std::string user_sid_utf8 = base::WideToUTF8(user_sid);
43 std::string security_descriptor =
44 base::StringPrintf("O:%sG:%sD:(A;;GA;;;%s)", user_sid_utf8.c_str(),
45 user_sid_utf8.c_str(), user_sid_utf8.c_str());
47 // Generate a unique name for the channel.
48 std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID();
50 // Create the server end of the channel.
51 ScopedHandle pipe;
52 if (!CreateIpcChannel(channel_name, security_descriptor, &pipe)) {
53 return false;
56 // Wrap the pipe into an IPC channel.
57 scoped_ptr<IPC::ChannelProxy> server =
58 IPC::ChannelProxy::Create(IPC::ChannelHandle(pipe.Get()),
59 IPC::Channel::MODE_SERVER,
60 listener,
61 io_task_runner);
63 // Convert the channel name to the pipe name.
64 std::string pipe_name(kChromePipeNamePrefix);
65 pipe_name.append(channel_name);
67 SECURITY_ATTRIBUTES security_attributes = {0};
68 security_attributes.nLength = sizeof(security_attributes);
69 security_attributes.lpSecurityDescriptor = nullptr;
70 security_attributes.bInheritHandle = TRUE;
72 // Create the client end of the channel. This code should match the code in
73 // IPC::Channel.
74 base::File client(CreateFile(base::UTF8ToUTF16(pipe_name).c_str(),
75 GENERIC_READ | GENERIC_WRITE,
77 &security_attributes,
78 OPEN_EXISTING,
79 SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION |
80 FILE_FLAG_OVERLAPPED,
81 nullptr));
82 if (!client.IsValid()) {
83 PLOG(ERROR) << "Failed to connect to '" << pipe_name << "'";
84 return false;
87 *client_out = client.Pass();
88 *server_out = server.Pass();
89 return true;
92 bool CreateIpcChannel(
93 const std::string& channel_name,
94 const std::string& pipe_security_descriptor,
95 base::win::ScopedHandle* pipe_out) {
96 // Create security descriptor for the channel.
97 ScopedSd sd = ConvertSddlToSd(pipe_security_descriptor);
98 if (!sd) {
99 PLOG(ERROR) << "Failed to create a security descriptor for the Chromoting "
100 "IPC channel";
101 return false;
104 SECURITY_ATTRIBUTES security_attributes = {0};
105 security_attributes.nLength = sizeof(security_attributes);
106 security_attributes.lpSecurityDescriptor = sd.get();
107 security_attributes.bInheritHandle = FALSE;
109 // Convert the channel name to the pipe name.
110 std::string pipe_name(kChromePipeNamePrefix);
111 pipe_name.append(channel_name);
113 // Create the server end of the pipe. This code should match the code in
114 // IPC::Channel with exception of passing a non-default security descriptor.
115 base::win::ScopedHandle pipe;
116 pipe.Set(CreateNamedPipe(
117 base::UTF8ToUTF16(pipe_name).c_str(),
118 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
119 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
121 IPC::Channel::kReadBufferSize,
122 IPC::Channel::kReadBufferSize,
123 5000,
124 &security_attributes));
125 if (!pipe.IsValid()) {
126 PLOG(ERROR)
127 << "Failed to create the server end of the Chromoting IPC channel";
128 return false;
131 *pipe_out = pipe.Pass();
132 return true;
135 } // namespace remoting