| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/win/launch_process_with_token.h" | 5 #include "remoting/host/win/launch_process_with_token.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <sddl.h> | 8 #include <sddl.h> |
| 9 #include <winternl.h> | 9 #include <winternl.h> |
| 10 | 10 |
| 11 #include <limits> | 11 #include <limits> |
| 12 | 12 |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 16 #include "base/rand_util.h" | 16 #include "base/rand_util.h" |
| 17 #include "base/scoped_native_library.h" | 17 #include "base/scoped_native_library.h" |
| 18 #include "base/single_thread_task_runner.h" |
| 18 #include "base/stringprintf.h" | 19 #include "base/stringprintf.h" |
| 19 #include "base/utf_string_conversions.h" | 20 #include "base/utf_string_conversions.h" |
| 20 #include "base/win/scoped_handle.h" | 21 #include "base/win/scoped_handle.h" |
| 21 #include "base/win/scoped_process_information.h" | 22 #include "base/win/scoped_process_information.h" |
| 22 #include "base/win/windows_version.h" | 23 #include "base/win/windows_version.h" |
| 23 #include "ipc/ipc_channel.h" | 24 #include "ipc/ipc_channel.h" |
| 25 #include "ipc/ipc_channel_proxy.h" |
| 26 #include "ipc/ipc_channel.h" |
| 24 | 27 |
| 25 using base::win::ScopedHandle; | 28 using base::win::ScopedHandle; |
| 26 | 29 |
| 27 namespace { | 30 namespace { |
| 28 | 31 |
| 29 const char kCreateProcessDefaultPipeNameFormat[] = | 32 const char kCreateProcessDefaultPipeNameFormat[] = |
| 30 "\\\\.\\Pipe\\TerminalServer\\SystemExecSrvr\\%d"; | 33 "\\\\.\\Pipe\\TerminalServer\\SystemExecSrvr\\%d"; |
| 31 | 34 |
| 32 // Undocumented WINSTATIONINFOCLASS value causing | 35 // Undocumented WINSTATIONINFOCLASS value causing |
| 33 // winsta!WinStationQueryInformationW() to return the name of the pipe for | 36 // winsta!WinStationQueryInformationW() to return the name of the pipe for |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 } | 405 } |
| 403 | 406 |
| 404 } // namespace | 407 } // namespace |
| 405 | 408 |
| 406 namespace remoting { | 409 namespace remoting { |
| 407 | 410 |
| 408 // Pipe name prefix used by Chrome IPC channels to convert a channel name into | 411 // Pipe name prefix used by Chrome IPC channels to convert a channel name into |
| 409 // a pipe name. | 412 // a pipe name. |
| 410 const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome."; | 413 const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome."; |
| 411 | 414 |
| 415 bool CreateConnectedIpcChannel( |
| 416 const std::string& channel_name, |
| 417 const std::string& pipe_security_descriptor, |
| 418 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, |
| 419 IPC::Listener* delegate, |
| 420 base::win::ScopedHandle* client_out, |
| 421 scoped_ptr<IPC::ChannelProxy>* server_out) { |
| 422 // Create the server end of the channel. |
| 423 ScopedHandle pipe; |
| 424 if (!CreateIpcChannel(channel_name, pipe_security_descriptor, &pipe)) { |
| 425 return false; |
| 426 } |
| 427 |
| 428 // Wrap the pipe into an IPC channel. |
| 429 scoped_ptr<IPC::ChannelProxy> server(new IPC::ChannelProxy( |
| 430 IPC::ChannelHandle(pipe), |
| 431 IPC::Channel::MODE_SERVER, |
| 432 delegate, |
| 433 io_task_runner)); |
| 434 |
| 435 // Convert the channel name to the pipe name. |
| 436 std::string pipe_name(remoting::kChromePipeNamePrefix); |
| 437 pipe_name.append(channel_name); |
| 438 |
| 439 SECURITY_ATTRIBUTES security_attributes; |
| 440 security_attributes.nLength = sizeof(security_attributes); |
| 441 security_attributes.lpSecurityDescriptor = NULL; |
| 442 security_attributes.bInheritHandle = TRUE; |
| 443 |
| 444 // Create the client end of the channel. This code should match the code in |
| 445 // IPC::Channel. |
| 446 ScopedHandle client; |
| 447 client.Set(CreateFile(UTF8ToUTF16(pipe_name).c_str(), |
| 448 GENERIC_READ | GENERIC_WRITE, |
| 449 0, |
| 450 &security_attributes, |
| 451 OPEN_EXISTING, |
| 452 SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION | |
| 453 FILE_FLAG_OVERLAPPED, |
| 454 NULL)); |
| 455 if (!client.IsValid()) { |
| 456 LOG_GETLASTERROR(ERROR) << "Failed to connect to '" << pipe_name << "'"; |
| 457 return false; |
| 458 } |
| 459 |
| 460 *client_out = client.Pass(); |
| 461 *server_out = server.Pass(); |
| 462 return true; |
| 463 } |
| 464 |
| 412 bool CreateIpcChannel( | 465 bool CreateIpcChannel( |
| 413 const std::string& channel_name, | 466 const std::string& channel_name, |
| 414 const std::string& pipe_security_descriptor, | 467 const std::string& pipe_security_descriptor, |
| 415 base::win::ScopedHandle* pipe_out) { | 468 base::win::ScopedHandle* pipe_out) { |
| 416 // Create security descriptor for the channel. | 469 // Create security descriptor for the channel. |
| 417 SECURITY_ATTRIBUTES security_attributes; | 470 SECURITY_ATTRIBUTES security_attributes; |
| 418 security_attributes.nLength = sizeof(security_attributes); | 471 security_attributes.nLength = sizeof(security_attributes); |
| 419 security_attributes.bInheritHandle = FALSE; | 472 security_attributes.bInheritHandle = FALSE; |
| 420 | 473 |
| 421 ULONG security_descriptor_length = 0; | 474 ULONG security_descriptor_length = 0; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 return false; | 547 return false; |
| 495 } | 548 } |
| 496 | 549 |
| 497 // Revert to the default token. | 550 // Revert to the default token. |
| 498 CHECK(RevertToSelf()); | 551 CHECK(RevertToSelf()); |
| 499 | 552 |
| 500 *token_out = session_token.Pass(); | 553 *token_out = session_token.Pass(); |
| 501 return true; | 554 return true; |
| 502 } | 555 } |
| 503 | 556 |
| 504 // Generates a unique IPC channel name. | |
| 505 std::string GenerateIpcChannelName(void* client) { | |
| 506 // Generate the pipe name. This code is copied from | |
| 507 // src/content/common/child_process_host_impl.cc | |
| 508 return base::StringPrintf("%d.%p.%d", | |
| 509 base::GetCurrentProcId(), client, | |
| 510 base::RandInt(0, std::numeric_limits<int>::max())); | |
| 511 } | |
| 512 | |
| 513 bool LaunchProcessWithToken(const FilePath& binary, | 557 bool LaunchProcessWithToken(const FilePath& binary, |
| 514 const CommandLine::StringType& command_line, | 558 const CommandLine::StringType& command_line, |
| 515 HANDLE user_token, | 559 HANDLE user_token, |
| 516 bool inherit_handles, | 560 bool inherit_handles, |
| 517 DWORD creation_flags, | 561 DWORD creation_flags, |
| 518 ScopedHandle* process_out, | 562 ScopedHandle* process_out, |
| 519 ScopedHandle* thread_out) { | 563 ScopedHandle* thread_out) { |
| 520 FilePath::StringType application_name = binary.value(); | 564 FilePath::StringType application_name = binary.value(); |
| 521 | 565 |
| 522 base::win::ScopedProcessInformation process_info; | 566 base::win::ScopedProcessInformation process_info; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 return false; | 619 return false; |
| 576 } | 620 } |
| 577 | 621 |
| 578 CHECK(process_info.IsValid()); | 622 CHECK(process_info.IsValid()); |
| 579 process_out->Set(process_info.TakeProcessHandle()); | 623 process_out->Set(process_info.TakeProcessHandle()); |
| 580 thread_out->Set(process_info.TakeThreadHandle()); | 624 thread_out->Set(process_info.TakeThreadHandle()); |
| 581 return true; | 625 return true; |
| 582 } | 626 } |
| 583 | 627 |
| 584 } // namespace remoting | 628 } // namespace remoting |
| OLD | NEW |