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

Side by Side Diff: remoting/host/it2me/it2me_native_messaging_host_main.cc

Issue 2179353004: Update Windows It2Me to allow remote users to interact with elevated windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@it2me_uiaccess
Patch Set: Fixing an Android build issue 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 2013 The Chromium Authors. All rights reserved. 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 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 "remoting/host/it2me/it2me_native_messaging_host_main.h" 5 #include "remoting/host/it2me/it2me_native_messaging_host_main.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/at_exit.h" 9 #include "base/at_exit.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 19 matching lines...) Expand all
30 30
31 #include "base/linux_util.h" 31 #include "base/linux_util.h"
32 #endif // defined(OS_LINUX) 32 #endif // defined(OS_LINUX)
33 33
34 #if defined(OS_MACOSX) 34 #if defined(OS_MACOSX)
35 #include "base/mac/scoped_nsautorelease_pool.h" 35 #include "base/mac/scoped_nsautorelease_pool.h"
36 #endif // defined(OS_MACOSX) 36 #endif // defined(OS_MACOSX)
37 37
38 #if defined(OS_WIN) 38 #if defined(OS_WIN)
39 #include <commctrl.h> 39 #include <commctrl.h>
40
41 #include "remoting/host/switches.h"
42 #include "remoting/host/win/elevation_helpers.h"
40 #endif // defined(OS_WIN) 43 #endif // defined(OS_WIN)
41 44
42 namespace remoting { 45 namespace remoting {
43 46
44 // Creates a It2MeNativeMessagingHost instance, attaches it to stdin/stdout and 47 // Creates a It2MeNativeMessagingHost instance, attaches it to stdin/stdout and
45 // runs the message loop until It2MeNativeMessagingHost signals shutdown. 48 // runs the message loop until It2MeNativeMessagingHost signals shutdown.
46 int StartIt2MeNativeMessagingHost() { 49 int StartIt2MeNativeMessagingHost() {
47 #if defined(OS_MACOSX) 50 #if defined(OS_MACOSX)
48 // Needed so we don't leak objects when threads are created. 51 // Needed so we don't leak objects when threads are created.
49 base::mac::ScopedNSAutoreleasePool pool; 52 base::mac::ScopedNSAutoreleasePool pool;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 86
84 // Need to prime the host OS version value for linux to prevent IO on the 87 // Need to prime the host OS version value for linux to prevent IO on the
85 // network thread. base::GetLinuxDistro() caches the result. 88 // network thread. base::GetLinuxDistro() caches the result.
86 base::GetLinuxDistro(); 89 base::GetLinuxDistro();
87 #endif // OS_LINUX 90 #endif // OS_LINUX
88 91
89 // Enable support for SSL server sockets, which must be done while still 92 // Enable support for SSL server sockets, which must be done while still
90 // single-threaded. 93 // single-threaded.
91 net::EnableSSLServerSockets(); 94 net::EnableSSLServerSockets();
92 95
96 base::File read_file;
97 base::File write_file;
98 bool needs_elevation = false;
99
93 #if defined(OS_WIN) 100 #if defined(OS_WIN)
94 // GetStdHandle() returns pseudo-handles for stdin and stdout even if
95 // the hosting executable specifies "Windows" subsystem. However the returned
96 // handles are invalid in that case unless standard input and output are
97 // redirected to a pipe or file.
98 base::File read_file(GetStdHandle(STD_INPUT_HANDLE));
99 base::File write_file(GetStdHandle(STD_OUTPUT_HANDLE));
100 101
101 // After the native messaging channel starts the native messaging reader 102 const base::CommandLine* command_line =
102 // will keep doing blocking read operations on the input named pipe. 103 base::CommandLine::ForCurrentProcess();
103 // If any other thread tries to perform any operation on STDIN, it will also 104
104 // block because the input named pipe is synchronous (non-overlapped). 105 if (command_line->HasSwitch(kElevateSwitchName)) {
105 // It is pretty common for a DLL to query the device info (GetFileType) of 106 #if defined(OFFICIAL_BUILD)
106 // the STD* handles at startup. So any LoadLibrary request can potentially 107 // Unofficial builds won't have 'UiAccess' since it requires signing.
107 // be blocked. To prevent that from happening we close STDIN and STDOUT 108 CHECK(CurrentProcessHasUiAccess());
Sergey Ulanov 2016/09/02 23:21:14 Do we actually need to crash the process in this c
joedow 2016/09/06 22:51:59 I chose to use a CHECK here as this functionality
108 // handles as soon as we retrieve the corresponding file handles. 109 #endif // defined(OFFICIAL_BUILD)
109 SetStdHandle(STD_INPUT_HANDLE, nullptr); 110
110 SetStdHandle(STD_OUTPUT_HANDLE, nullptr); 111 // The UiAccess binary should always have the "input" and "output" switches
112 // specified, they represent the name of the named pipes that should be used
113 // in place of stdin and stdout.
114 DCHECK(command_line->HasSwitch(kInputSwitchName));
115 DCHECK(command_line->HasSwitch(kOutputSwitchName));
116
117 // presubmit: allow wstring
118 std::wstring input_pipe_name =
119 command_line->GetSwitchValueNative(kInputSwitchName);
120 // presubmit: allow wstring
121 std::wstring output_pipe_name =
122 command_line->GetSwitchValueNative(kOutputSwitchName);
123
124 // A NULL SECURITY_ATTRIBUTES signifies that the handle can't be inherited.
125 read_file =
126 base::File(CreateFile(input_pipe_name.c_str(), GENERIC_READ, 0, nullptr,
127 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
128 if (!read_file.IsValid()) {
129 PLOG(ERROR) << "CreateFile failed on '" << input_pipe_name << "'";
130 return kInitializationFailed;
131 }
132
133 write_file = base::File(CreateFile(output_pipe_name.c_str(), GENERIC_WRITE,
134 0, nullptr, OPEN_EXISTING,
135 FILE_ATTRIBUTE_NORMAL, nullptr));
136 if (!write_file.IsValid()) {
137 PLOG(ERROR) << "CreateFile failed on '" << output_pipe_name << "'";
138 return kInitializationFailed;
139 }
140 } else {
141 needs_elevation = true;
142
143 // GetStdHandle() returns pseudo-handles for stdin and stdout even if
144 // the hosting executable specifies "Windows" subsystem. However the
145 // returned handles are invalid in that case unless standard input and
146 // output are redirected to a pipe or file.
147 read_file = base::File(GetStdHandle(STD_INPUT_HANDLE));
148 write_file = base::File(GetStdHandle(STD_OUTPUT_HANDLE));
149
150 // After the native messaging channel starts the native messaging reader
151 // will keep doing blocking read operations on the input named pipe.
152 // If any other thread tries to perform any operation on STDIN, it will also
153 // block because the input named pipe is synchronous (non-overlapped).
154 // It is pretty common for a DLL to query the device info (GetFileType) of
155 // the STD* handles at startup. So any LoadLibrary request can potentially
156 // be blocked. To prevent that from happening we close STDIN and STDOUT
157 // handles as soon as we retrieve the corresponding file handles.
158 SetStdHandle(STD_INPUT_HANDLE, nullptr);
159 SetStdHandle(STD_OUTPUT_HANDLE, nullptr);
160 }
111 #elif defined(OS_POSIX) 161 #elif defined(OS_POSIX)
112 // The files are automatically closed. 162 // The files are automatically closed.
113 base::File read_file(STDIN_FILENO); 163 read_file = base::File(STDIN_FILENO);
114 base::File write_file(STDOUT_FILENO); 164 write_file = base::File(STDOUT_FILENO);
115 #else 165 #else
116 #error Not implemented. 166 #error Not implemented.
117 #endif 167 #endif
118 168
119 base::MessageLoopForUI message_loop; 169 base::MessageLoopForUI message_loop;
120 base::RunLoop run_loop; 170 base::RunLoop run_loop;
121 171
122 std::unique_ptr<It2MeHostFactory> factory(new It2MeHostFactory()); 172 std::unique_ptr<It2MeHostFactory> factory(new It2MeHostFactory());
123 173
124 std::unique_ptr<NativeMessagingPipe> native_messaging_pipe( 174 std::unique_ptr<NativeMessagingPipe> native_messaging_pipe(
125 new NativeMessagingPipe()); 175 new NativeMessagingPipe());
126 176
127 // Set up the native messaging channel. 177 // Set up the native messaging channel.
128 std::unique_ptr<extensions::NativeMessagingChannel> channel( 178 std::unique_ptr<extensions::NativeMessagingChannel> channel(
129 new PipeMessagingChannel(std::move(read_file), std::move(write_file))); 179 new PipeMessagingChannel(std::move(read_file), std::move(write_file)));
130 180
131 std::unique_ptr<ChromotingHostContext> context = 181 std::unique_ptr<ChromotingHostContext> context =
132 ChromotingHostContext::Create(new remoting::AutoThreadTaskRunner( 182 ChromotingHostContext::Create(new remoting::AutoThreadTaskRunner(
133 message_loop.task_runner(), run_loop.QuitClosure())); 183 message_loop.task_runner(), run_loop.QuitClosure()));
134 std::unique_ptr<extensions::NativeMessageHost> host( 184 std::unique_ptr<extensions::NativeMessageHost> host(
135 new It2MeNativeMessagingHost(std::move(context), std::move(factory))); 185 new It2MeNativeMessagingHost(needs_elevation, /*policy_service=*/nullptr,
186 std::move(context), std::move(factory)));
136 187
137 host->Start(native_messaging_pipe.get()); 188 host->Start(native_messaging_pipe.get());
138 189
139 native_messaging_pipe->Start(std::move(host), std::move(channel)); 190 native_messaging_pipe->Start(std::move(host), std::move(channel));
140 191
141 // Run the loop until channel is alive. 192 // Run the loop until channel is alive.
142 run_loop.Run(); 193 run_loop.Run();
143 194
144 return kSuccessExitCode; 195 return kSuccessExitCode;
145 } 196 }
146 197
147 int It2MeNativeMessagingHostMain(int argc, char** argv) { 198 int It2MeNativeMessagingHostMain(int argc, char** argv) {
148 // This object instance is required by Chrome code (such as MessageLoop). 199 // This object instance is required by Chrome code (such as MessageLoop).
149 base::AtExitManager exit_manager; 200 base::AtExitManager exit_manager;
150 201
151 base::CommandLine::Init(argc, argv); 202 base::CommandLine::Init(argc, argv);
152 remoting::InitHostLogging(); 203 remoting::InitHostLogging();
153 204
154 return StartIt2MeNativeMessagingHost(); 205 return StartIt2MeNativeMessagingHost();
155 } 206 }
156 207
157 } // namespace remoting 208 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698