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

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: Removing the CHECK assertion and replacing it with LOG(ERROR) instead. 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 if (!CurrentProcessHasUiAccess()) {
108 // handles as soon as we retrieve the corresponding file handles. 109 LOG(ERROR) << "UiAccess permission missing from elevated It2Me process.";
109 SetStdHandle(STD_INPUT_HANDLE, nullptr); 110 }
110 SetStdHandle(STD_OUTPUT_HANDLE, nullptr); 111 #endif // defined(OFFICIAL_BUILD)
112
113 // The UiAccess binary should always have the "input" and "output" switches
114 // specified, they represent the name of the named pipes that should be used
115 // in place of stdin and stdout.
116 DCHECK(command_line->HasSwitch(kInputSwitchName));
117 DCHECK(command_line->HasSwitch(kOutputSwitchName));
118
119 // presubmit: allow wstring
120 std::wstring input_pipe_name =
121 command_line->GetSwitchValueNative(kInputSwitchName);
122 // presubmit: allow wstring
123 std::wstring output_pipe_name =
124 command_line->GetSwitchValueNative(kOutputSwitchName);
125
126 // A NULL SECURITY_ATTRIBUTES signifies that the handle can't be inherited.
127 read_file =
128 base::File(CreateFile(input_pipe_name.c_str(), GENERIC_READ, 0, nullptr,
129 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
130 if (!read_file.IsValid()) {
131 PLOG(ERROR) << "CreateFile failed on '" << input_pipe_name << "'";
132 return kInitializationFailed;
133 }
134
135 write_file = base::File(CreateFile(output_pipe_name.c_str(), GENERIC_WRITE,
136 0, nullptr, OPEN_EXISTING,
137 FILE_ATTRIBUTE_NORMAL, nullptr));
138 if (!write_file.IsValid()) {
139 PLOG(ERROR) << "CreateFile failed on '" << output_pipe_name << "'";
140 return kInitializationFailed;
141 }
142 } else {
143 needs_elevation = true;
144
145 // GetStdHandle() returns pseudo-handles for stdin and stdout even if
146 // the hosting executable specifies "Windows" subsystem. However the
147 // returned handles are invalid in that case unless standard input and
148 // output are redirected to a pipe or file.
149 read_file = base::File(GetStdHandle(STD_INPUT_HANDLE));
150 write_file = base::File(GetStdHandle(STD_OUTPUT_HANDLE));
151
152 // After the native messaging channel starts the native messaging reader
153 // will keep doing blocking read operations on the input named pipe.
154 // If any other thread tries to perform any operation on STDIN, it will also
155 // block because the input named pipe is synchronous (non-overlapped).
156 // It is pretty common for a DLL to query the device info (GetFileType) of
157 // the STD* handles at startup. So any LoadLibrary request can potentially
158 // be blocked. To prevent that from happening we close STDIN and STDOUT
159 // handles as soon as we retrieve the corresponding file handles.
160 SetStdHandle(STD_INPUT_HANDLE, nullptr);
161 SetStdHandle(STD_OUTPUT_HANDLE, nullptr);
162 }
111 #elif defined(OS_POSIX) 163 #elif defined(OS_POSIX)
112 // The files are automatically closed. 164 // The files are automatically closed.
113 base::File read_file(STDIN_FILENO); 165 read_file = base::File(STDIN_FILENO);
114 base::File write_file(STDOUT_FILENO); 166 write_file = base::File(STDOUT_FILENO);
115 #else 167 #else
116 #error Not implemented. 168 #error Not implemented.
117 #endif 169 #endif
118 170
119 base::MessageLoopForUI message_loop; 171 base::MessageLoopForUI message_loop;
120 base::RunLoop run_loop; 172 base::RunLoop run_loop;
121 173
122 std::unique_ptr<It2MeHostFactory> factory(new It2MeHostFactory()); 174 std::unique_ptr<It2MeHostFactory> factory(new It2MeHostFactory());
123 175
124 std::unique_ptr<NativeMessagingPipe> native_messaging_pipe( 176 std::unique_ptr<NativeMessagingPipe> native_messaging_pipe(
125 new NativeMessagingPipe()); 177 new NativeMessagingPipe());
126 178
127 // Set up the native messaging channel. 179 // Set up the native messaging channel.
128 std::unique_ptr<extensions::NativeMessagingChannel> channel( 180 std::unique_ptr<extensions::NativeMessagingChannel> channel(
129 new PipeMessagingChannel(std::move(read_file), std::move(write_file))); 181 new PipeMessagingChannel(std::move(read_file), std::move(write_file)));
130 182
131 std::unique_ptr<ChromotingHostContext> context = 183 std::unique_ptr<ChromotingHostContext> context =
132 ChromotingHostContext::Create(new remoting::AutoThreadTaskRunner( 184 ChromotingHostContext::Create(new remoting::AutoThreadTaskRunner(
133 message_loop.task_runner(), run_loop.QuitClosure())); 185 message_loop.task_runner(), run_loop.QuitClosure()));
134 std::unique_ptr<extensions::NativeMessageHost> host( 186 std::unique_ptr<extensions::NativeMessageHost> host(
135 new It2MeNativeMessagingHost(std::move(context), std::move(factory))); 187 new It2MeNativeMessagingHost(needs_elevation, /*policy_service=*/nullptr,
188 std::move(context), std::move(factory)));
136 189
137 host->Start(native_messaging_pipe.get()); 190 host->Start(native_messaging_pipe.get());
138 191
139 native_messaging_pipe->Start(std::move(host), std::move(channel)); 192 native_messaging_pipe->Start(std::move(host), std::move(channel));
140 193
141 // Run the loop until channel is alive. 194 // Run the loop until channel is alive.
142 run_loop.Run(); 195 run_loop.Run();
143 196
144 return kSuccessExitCode; 197 return kSuccessExitCode;
145 } 198 }
146 199
147 int It2MeNativeMessagingHostMain(int argc, char** argv) { 200 int It2MeNativeMessagingHostMain(int argc, char** argv) {
148 // This object instance is required by Chrome code (such as MessageLoop). 201 // This object instance is required by Chrome code (such as MessageLoop).
149 base::AtExitManager exit_manager; 202 base::AtExitManager exit_manager;
150 203
151 base::CommandLine::Init(argc, argv); 204 base::CommandLine::Init(argc, argv);
152 remoting::InitHostLogging(); 205 remoting::InitHostLogging();
153 206
154 return StartIt2MeNativeMessagingHost(); 207 return StartIt2MeNativeMessagingHost();
155 } 208 }
156 209
157 } // namespace remoting 210 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/it2me/it2me_native_messaging_host.cc ('k') | remoting/host/it2me/it2me_native_messaging_host_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698