| OLD | NEW |
| 1 | 1 |
| 2 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
| 5 // | 5 // |
| 6 // This file implements the Windows service controlling Me2Me host processes | 6 // This file implements the Windows service controlling Me2Me host processes |
| 7 // running within user sessions. | 7 // running within user sessions. |
| 8 | 8 |
| 9 #include "remoting/host/win/unprivileged_process_delegate.h" | 9 #include "remoting/host/win/unprivileged_process_delegate.h" |
| 10 | 10 |
| 11 #include <sddl.h> | 11 #include <sddl.h> |
| 12 | 12 |
| 13 #include <utility> | 13 #include <utility> |
| 14 | 14 |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/files/file.h" | 16 #include "base/files/file.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/rand_util.h" | 18 #include "base/rand_util.h" |
| 19 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
| 20 #include "base/strings/string16.h" | 20 #include "base/strings/string16.h" |
| 21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 22 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 23 #include "base/synchronization/lock.h" | 23 #include "base/synchronization/lock.h" |
| 24 #include "base/win/scoped_handle.h" | 24 #include "base/win/scoped_handle.h" |
| 25 #include "ipc/attachment_broker.h" | 25 #include "ipc/attachment_broker.h" |
| 26 #include "ipc/ipc_channel.h" | 26 #include "ipc/ipc_channel.h" |
| 27 #include "ipc/ipc_channel_proxy.h" | 27 #include "ipc/ipc_channel_proxy.h" |
| 28 #include "ipc/ipc_message.h" | 28 #include "ipc/ipc_message.h" |
| 29 #include "mojo/edk/embedder/embedder.h" | |
| 30 #include "mojo/edk/embedder/platform_channel_pair.h" | |
| 31 #include "remoting/base/typed_buffer.h" | 29 #include "remoting/base/typed_buffer.h" |
| 30 #include "remoting/host/ipc_util.h" |
| 32 #include "remoting/host/switches.h" | 31 #include "remoting/host/switches.h" |
| 33 #include "remoting/host/win/launch_process_with_token.h" | 32 #include "remoting/host/win/launch_process_with_token.h" |
| 34 #include "remoting/host/win/security_descriptor.h" | 33 #include "remoting/host/win/security_descriptor.h" |
| 35 #include "remoting/host/win/window_station_and_desktop.h" | 34 #include "remoting/host/win/window_station_and_desktop.h" |
| 36 #include "sandbox/win/src/restricted_token.h" | 35 #include "sandbox/win/src/restricted_token.h" |
| 37 | 36 |
| 38 using base::win::ScopedHandle; | 37 using base::win::ScopedHandle; |
| 39 | 38 |
| 40 namespace remoting { | 39 namespace remoting { |
| 41 | 40 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 DCHECK(!worker_process_.IsValid()); | 232 DCHECK(!worker_process_.IsValid()); |
| 234 } | 233 } |
| 235 | 234 |
| 236 void UnprivilegedProcessDelegate::LaunchProcess( | 235 void UnprivilegedProcessDelegate::LaunchProcess( |
| 237 WorkerProcessLauncher* event_handler) { | 236 WorkerProcessLauncher* event_handler) { |
| 238 DCHECK(CalledOnValidThread()); | 237 DCHECK(CalledOnValidThread()); |
| 239 DCHECK(!event_handler_); | 238 DCHECK(!event_handler_); |
| 240 | 239 |
| 241 event_handler_ = event_handler; | 240 event_handler_ = event_handler; |
| 242 | 241 |
| 242 std::unique_ptr<IPC::ChannelProxy> server; |
| 243 |
| 243 // Create a restricted token that will be used to run the worker process. | 244 // Create a restricted token that will be used to run the worker process. |
| 244 ScopedHandle token; | 245 ScopedHandle token; |
| 245 if (!CreateRestrictedToken(&token)) { | 246 if (!CreateRestrictedToken(&token)) { |
| 246 PLOG(ERROR) << "Failed to create a restricted LocalService token"; | 247 PLOG(ERROR) << "Failed to create a restricted LocalService token"; |
| 247 ReportFatalError(); | 248 ReportFatalError(); |
| 248 return; | 249 return; |
| 249 } | 250 } |
| 250 | 251 |
| 251 // Determine our logon SID, so we can grant it access to our window station | 252 // Determine our logon SID, so we can grant it access to our window station |
| 252 // and desktop. | 253 // and desktop. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 269 SECURITY_ATTRIBUTES process_attributes; | 270 SECURITY_ATTRIBUTES process_attributes; |
| 270 process_attributes.nLength = sizeof(process_attributes); | 271 process_attributes.nLength = sizeof(process_attributes); |
| 271 process_attributes.lpSecurityDescriptor = process_sd.get(); | 272 process_attributes.lpSecurityDescriptor = process_sd.get(); |
| 272 process_attributes.bInheritHandle = FALSE; | 273 process_attributes.bInheritHandle = FALSE; |
| 273 | 274 |
| 274 SECURITY_ATTRIBUTES thread_attributes; | 275 SECURITY_ATTRIBUTES thread_attributes; |
| 275 thread_attributes.nLength = sizeof(thread_attributes); | 276 thread_attributes.nLength = sizeof(thread_attributes); |
| 276 thread_attributes.lpSecurityDescriptor = thread_sd.get(); | 277 thread_attributes.lpSecurityDescriptor = thread_sd.get(); |
| 277 thread_attributes.bInheritHandle = FALSE; | 278 thread_attributes.bInheritHandle = FALSE; |
| 278 | 279 |
| 279 // Create our own window station and desktop accessible by |logon_sid|. | 280 ScopedHandle worker_process; |
| 280 WindowStationAndDesktop handles; | 281 { |
| 281 if (!CreateWindowStationAndDesktop(std::move(logon_sid), &handles)) { | 282 // Take a lock when any inheritable handles are open to make sure that only |
| 282 PLOG(ERROR) << "Failed to create a window station and desktop"; | 283 // one process inherits them. |
| 283 ReportFatalError(); | 284 base::AutoLock lock(g_inherit_handles_lock.Get()); |
| 284 return; | 285 |
| 286 // Create a connected IPC channel. |
| 287 base::File client; |
| 288 if (!CreateConnectedIpcChannel(io_task_runner_, this, &client, &server)) { |
| 289 ReportFatalError(); |
| 290 return; |
| 291 } |
| 292 |
| 293 // Convert the handle value into a decimal integer. Handle values are 32bit |
| 294 // even on 64bit platforms. |
| 295 std::string pipe_handle = base::StringPrintf( |
| 296 "%d", reinterpret_cast<ULONG_PTR>(client.GetPlatformFile())); |
| 297 |
| 298 // Pass the IPC channel via the command line. |
| 299 base::CommandLine command_line(target_command_->argv()); |
| 300 command_line.AppendSwitchASCII(kDaemonPipeSwitchName, pipe_handle); |
| 301 |
| 302 // Create our own window station and desktop accessible by |logon_sid|. |
| 303 WindowStationAndDesktop handles; |
| 304 if (!CreateWindowStationAndDesktop(std::move(logon_sid), &handles)) { |
| 305 PLOG(ERROR) << "Failed to create a window station and desktop"; |
| 306 ReportFatalError(); |
| 307 return; |
| 308 } |
| 309 |
| 310 // Try to launch the worker process. The launched process inherits |
| 311 // the window station, desktop and pipe handles, created above. |
| 312 ScopedHandle worker_thread; |
| 313 if (!LaunchProcessWithToken( |
| 314 command_line.GetProgram(), command_line.GetCommandLineString(), |
| 315 token.Get(), &process_attributes, &thread_attributes, true, 0, |
| 316 nullptr, &worker_process, &worker_thread)) { |
| 317 ReportFatalError(); |
| 318 return; |
| 319 } |
| 285 } | 320 } |
| 286 | 321 |
| 287 const std::string mojo_child_token = mojo::edk::GenerateRandomToken(); | |
| 288 const std::string mojo_message_pipe_token = mojo::edk::GenerateRandomToken(); | |
| 289 | |
| 290 std::unique_ptr<IPC::ChannelProxy> server = | |
| 291 base::MakeUnique<IPC::ChannelProxy>(this, io_task_runner_); | |
| 292 IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel( | |
| 293 server.get(), io_task_runner_); | |
| 294 server->Init(mojo::edk::CreateParentMessagePipe(mojo_message_pipe_token, | |
| 295 mojo_child_token) | |
| 296 .release(), | |
| 297 IPC::Channel::MODE_SERVER, /*create_pipe_now=*/true); | |
| 298 base::CommandLine command_line(target_command_->argv()); | |
| 299 command_line.AppendSwitchASCII(kMojoPipeToken, mojo_message_pipe_token); | |
| 300 | |
| 301 base::HandlesToInheritVector handles_to_inherit = { | |
| 302 handles.desktop(), handles.window_station(), | |
| 303 }; | |
| 304 mojo::edk::PlatformChannelPair mojo_channel; | |
| 305 mojo_channel.PrepareToPassClientHandleToChildProcess(&command_line, | |
| 306 &handles_to_inherit); | |
| 307 | |
| 308 // Try to launch the worker process. The launched process inherits | |
| 309 // the window station, desktop and pipe handles, created above. | |
| 310 ScopedHandle worker_process; | |
| 311 ScopedHandle worker_thread; | |
| 312 if (!LaunchProcessWithToken( | |
| 313 command_line.GetProgram(), command_line.GetCommandLineString(), | |
| 314 token.Get(), &process_attributes, &thread_attributes, | |
| 315 handles_to_inherit, /* creation_flags= */ 0, | |
| 316 /* thread_attributes= */ nullptr, &worker_process, &worker_thread)) { | |
| 317 mojo::edk::ChildProcessLaunchFailed(mojo_child_token); | |
| 318 ReportFatalError(); | |
| 319 return; | |
| 320 } | |
| 321 mojo::edk::ChildProcessLaunched( | |
| 322 worker_process.Get(), mojo_channel.PassServerHandle(), mojo_child_token); | |
| 323 | |
| 324 channel_ = std::move(server); | 322 channel_ = std::move(server); |
| 325 | 323 |
| 326 ReportProcessLaunched(std::move(worker_process)); | 324 ReportProcessLaunched(std::move(worker_process)); |
| 327 } | 325 } |
| 328 | 326 |
| 329 void UnprivilegedProcessDelegate::Send(IPC::Message* message) { | 327 void UnprivilegedProcessDelegate::Send(IPC::Message* message) { |
| 330 DCHECK(CalledOnValidThread()); | 328 DCHECK(CalledOnValidThread()); |
| 331 | 329 |
| 332 if (channel_) { | 330 if (channel_) { |
| 333 channel_->Send(message); | 331 channel_->Send(message); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 PLOG(ERROR) << "Failed to duplicate a handle"; | 413 PLOG(ERROR) << "Failed to duplicate a handle"; |
| 416 ReportFatalError(); | 414 ReportFatalError(); |
| 417 return; | 415 return; |
| 418 } | 416 } |
| 419 ScopedHandle limited_handle(temp_handle); | 417 ScopedHandle limited_handle(temp_handle); |
| 420 | 418 |
| 421 event_handler_->OnProcessLaunched(std::move(limited_handle)); | 419 event_handler_->OnProcessLaunched(std::move(limited_handle)); |
| 422 } | 420 } |
| 423 | 421 |
| 424 } // namespace remoting | 422 } // namespace remoting |
| OLD | NEW |