Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / remoting / host / ipc_util_win.cc
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.
4
5 #include "remoting/host/ipc_util.h"
6
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"
17
18 using base::win::ScopedHandle;
19
20 namespace remoting {
21
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.";
25
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;
36   }
37
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 security_descriptor = base::StringPrintf(
43       "O:%1$sG:%1$sD:(A;;GA;;;%1$s)", base::WideToUTF8(user_sid).c_str());
44
45   // Generate a unique name for the channel.
46   std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID();
47
48   // Create the server end of the channel.
49   ScopedHandle pipe;
50   if (!CreateIpcChannel(channel_name, security_descriptor, &pipe)) {
51     return false;
52   }
53
54   // Wrap the pipe into an IPC channel.
55   scoped_ptr<IPC::ChannelProxy> server =
56       IPC::ChannelProxy::Create(IPC::ChannelHandle(pipe.Get()),
57                                 IPC::Channel::MODE_SERVER,
58                                 listener,
59                                 io_task_runner);
60
61   // Convert the channel name to the pipe name.
62   std::string pipe_name(kChromePipeNamePrefix);
63   pipe_name.append(channel_name);
64
65   SECURITY_ATTRIBUTES security_attributes = {0};
66   security_attributes.nLength = sizeof(security_attributes);
67   security_attributes.lpSecurityDescriptor = NULL;
68   security_attributes.bInheritHandle = TRUE;
69
70   // Create the client end of the channel. This code should match the code in
71   // IPC::Channel.
72   base::File client(CreateFile(base::UTF8ToUTF16(pipe_name).c_str(),
73                                GENERIC_READ | GENERIC_WRITE,
74                                0,
75                                &security_attributes,
76                                OPEN_EXISTING,
77                                SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION |
78                                    FILE_FLAG_OVERLAPPED,
79                                NULL));
80   if (!client.IsValid()) {
81     PLOG(ERROR) << "Failed to connect to '" << pipe_name << "'";
82     return false;
83   }
84
85   *client_out = client.Pass();
86   *server_out = server.Pass();
87   return true;
88 }
89
90 bool CreateIpcChannel(
91     const std::string& channel_name,
92     const std::string& pipe_security_descriptor,
93     base::win::ScopedHandle* pipe_out) {
94   // Create security descriptor for the channel.
95   ScopedSd sd = ConvertSddlToSd(pipe_security_descriptor);
96   if (!sd) {
97     PLOG(ERROR) << "Failed to create a security descriptor for the Chromoting "
98                    "IPC channel";
99     return false;
100   }
101
102   SECURITY_ATTRIBUTES security_attributes = {0};
103   security_attributes.nLength = sizeof(security_attributes);
104   security_attributes.lpSecurityDescriptor = sd.get();
105   security_attributes.bInheritHandle = FALSE;
106
107   // Convert the channel name to the pipe name.
108   std::string pipe_name(kChromePipeNamePrefix);
109   pipe_name.append(channel_name);
110
111   // Create the server end of the pipe. This code should match the code in
112   // IPC::Channel with exception of passing a non-default security descriptor.
113   base::win::ScopedHandle pipe;
114   pipe.Set(CreateNamedPipe(
115       base::UTF8ToUTF16(pipe_name).c_str(),
116       PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
117       PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
118       1,
119       IPC::Channel::kReadBufferSize,
120       IPC::Channel::kReadBufferSize,
121       5000,
122       &security_attributes));
123   if (!pipe.IsValid()) {
124     PLOG(ERROR)
125         << "Failed to create the server end of the Chromoting IPC channel";
126     return false;
127   }
128
129   *pipe_out = pipe.Pass();
130   return true;
131 }
132
133 } // namespace remoting