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

Side by Side Diff: remoting/host/setup/me2me_native_messaging_host.cc

Issue 2152953002: Refactoring Native Messaging Host process launching code into its own file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing CR feedback. Created 4 years, 4 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/setup/me2me_native_messaging_host.h" 5 #include "remoting/host/setup/me2me_native_messaging_host.h"
6 6
7 #include <cstdint>
8 #include <memory>
7 #include <string> 9 #include <string>
8 #include <utility> 10 #include <utility>
9 11
10 #include "base/bind.h" 12 #include "base/bind.h"
11 #include "base/callback.h" 13 #include "base/callback.h"
12 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
13 #include "base/command_line.h" 15 #include "base/command_line.h"
14 #include "base/logging.h" 16 #include "base/logging.h"
15 #include "base/macros.h" 17 #include "base/macros.h"
16 #include "base/strings/stringize_macros.h" 18 #include "base/strings/stringize_macros.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/threading/thread.h"
20 #include "base/values.h" 19 #include "base/values.h"
21 #include "build/build_config.h" 20 #include "build/build_config.h"
22 #include "google_apis/gaia/gaia_oauth_client.h" 21 #include "google_apis/gaia/gaia_oauth_client.h"
23 #include "google_apis/google_api_keys.h" 22 #include "google_apis/google_api_keys.h"
24 #include "ipc/ipc_channel.h"
25 #include "net/base/network_interfaces.h" 23 #include "net/base/network_interfaces.h"
26 #include "remoting/base/rsa_key_pair.h" 24 #include "remoting/base/rsa_key_pair.h"
27 #include "remoting/host/native_messaging/pipe_messaging_channel.h" 25 #include "remoting/host/native_messaging/pipe_messaging_channel.h"
28 #include "remoting/host/pin_hash.h" 26 #include "remoting/host/pin_hash.h"
29 #include "remoting/host/setup/oauth_client.h" 27 #include "remoting/host/setup/oauth_client.h"
28 #include "remoting/host/switches.h"
30 #include "remoting/protocol/pairing_registry.h" 29 #include "remoting/protocol/pairing_registry.h"
31 30
32 #if defined(OS_WIN) 31 #if defined(OS_WIN)
33 #include <shellapi.h> 32 #include "base/win/scoped_handle.h"
34 #include "base/win/win_util.h" 33 #include "base/win/win_util.h"
35 #include "remoting/host/win/security_descriptor.h" 34 #include "remoting/host/win/launch_native_messaging_host_process.h"
36 #endif // defined(OS_WIN) 35 #endif // defined(OS_WIN)
37 36
38 namespace { 37 namespace {
39 38
40 #if defined(OS_WIN) 39 #if defined(OS_WIN)
41 // Windows will use default buffer size when 0 is passed to CreateNamedPipeW().
42 const DWORD kBufferSize = 0;
43 const int kTimeOutMilliseconds = 2000;
44 const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome_remote_desktop.";
45 const int kElevatedHostTimeoutSeconds = 300; 40 const int kElevatedHostTimeoutSeconds = 300;
46 #endif // defined(OS_WIN) 41 #endif // defined(OS_WIN)
47 42
48 // redirect_uri to use when authenticating service accounts (service account 43 // redirect_uri to use when authenticating service accounts (service account
49 // codes are obtained "out-of-band", i.e., not through an OAuth redirect). 44 // codes are obtained "out-of-band", i.e., not through an OAuth redirect).
50 const char* kServiceAccountRedirectUri = "oob"; 45 const char* kServiceAccountRedirectUri = "oob";
51 46
52 // Features supported in addition to the base protocol. 47 // Features supported in addition to the base protocol.
53 const char* kSupportedFeatures[] = { 48 const char* kSupportedFeatures[] = {
54 "pairingRegistry", 49 "pairingRegistry",
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 return elevated_channel_ != nullptr; 570 return elevated_channel_ != nullptr;
576 } 571 }
577 572
578 void Me2MeNativeMessagingHost::EnsureElevatedHostCreated() { 573 void Me2MeNativeMessagingHost::EnsureElevatedHostCreated() {
579 DCHECK(thread_checker_.CalledOnValidThread()); 574 DCHECK(thread_checker_.CalledOnValidThread());
580 DCHECK(needs_elevation_); 575 DCHECK(needs_elevation_);
581 576
582 if (elevated_channel_) 577 if (elevated_channel_)
583 return; 578 return;
584 579
585 // presubmit: allow wstring 580 base::win::ScopedHandle read_handle;
586 std::wstring user_sid; 581 base::win::ScopedHandle write_handle;
587 if (!base::win::GetUserSidString(&user_sid)) {
588 LOG(ERROR) << "Failed to query the current user SID.";
589 OnError();
590 return;
591 }
592
593 // Create a security descriptor that gives full access to the caller and
594 // BUILTIN_ADMINISTRATORS and denies access by anyone else.
595 // Local admins need access because the privileged host process will run
596 // as a local admin which may not be the same user as the current user.
597 std::string user_sid_ascii = base::UTF16ToASCII(user_sid);
598 std::string security_descriptor =
599 base::StringPrintf("O:%sG:%sD:(A;;GA;;;%s)(A;;GA;;;BA)",
600 user_sid_ascii.c_str(), user_sid_ascii.c_str(),
601 user_sid_ascii.c_str());
602
603 ScopedSd sd = ConvertSddlToSd(security_descriptor);
604 if (!sd) {
605 PLOG(ERROR) << "Failed to create a security descriptor for the"
606 << "Chromoting Me2Me native messaging host.";
607 OnError();
608 return;
609 }
610
611 SECURITY_ATTRIBUTES security_attributes = {0};
612 security_attributes.nLength = sizeof(security_attributes);
613 security_attributes.lpSecurityDescriptor = sd.get();
614 security_attributes.bInheritHandle = FALSE;
615
616 // Generate a unique name for the input channel.
617 std::string input_pipe_name(kChromePipeNamePrefix);
618 input_pipe_name.append(IPC::Channel::GenerateUniqueRandomChannelID());
619
620 base::win::ScopedHandle delegate_write_handle(::CreateNamedPipe(
621 base::ASCIIToUTF16(input_pipe_name).c_str(),
622 PIPE_ACCESS_OUTBOUND,
623 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS,
624 1,
625 kBufferSize,
626 kBufferSize,
627 kTimeOutMilliseconds,
628 &security_attributes));
629
630 if (!delegate_write_handle.IsValid()) {
631 PLOG(ERROR) << "Failed to create named pipe '" << input_pipe_name << "'";
632 OnError();
633 return;
634 }
635
636 // Generate a unique name for the input channel.
637 std::string output_pipe_name(kChromePipeNamePrefix);
638 output_pipe_name.append(IPC::Channel::GenerateUniqueRandomChannelID());
639
640 base::win::ScopedHandle delegate_read_handle(::CreateNamedPipe(
641 base::ASCIIToUTF16(output_pipe_name).c_str(),
642 PIPE_ACCESS_INBOUND,
643 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS,
644 1,
645 kBufferSize,
646 kBufferSize,
647 kTimeOutMilliseconds,
648 &security_attributes));
649
650 if (!delegate_read_handle.IsValid()) {
651 PLOG(ERROR) << "Failed to create named pipe '" << output_pipe_name << "'";
652 OnError();
653 return;
654 }
655
656 const base::CommandLine* current_command_line =
657 base::CommandLine::ForCurrentProcess();
658 const base::CommandLine::SwitchMap& switches =
659 current_command_line->GetSwitches();
660 base::CommandLine::StringVector args = current_command_line->GetArgs();
661
662 // Create the child process command line by copying switches from the current
663 // command line.
664 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
665 command_line.AppendSwitch(kElevatingSwitchName);
666 command_line.AppendSwitchASCII(kInputSwitchName, input_pipe_name);
667 command_line.AppendSwitchASCII(kOutputSwitchName, output_pipe_name);
668
669 DCHECK(!current_command_line->HasSwitch(kElevatingSwitchName));
670 for (base::CommandLine::SwitchMap::const_iterator i = switches.begin();
671 i != switches.end(); ++i) {
672 command_line.AppendSwitchNative(i->first, i->second);
673 }
674 for (base::CommandLine::StringVector::const_iterator i = args.begin();
675 i != args.end(); ++i) {
676 command_line.AppendArgNative(*i);
677 }
678
679 // Get the name of the binary to launch. 582 // Get the name of the binary to launch.
680 base::FilePath binary = current_command_line->GetProgram(); 583 base::FilePath binary = base::CommandLine::ForCurrentProcess()->GetProgram();
681 base::CommandLine::StringType parameters = 584 ProcessLaunchResult result = LaunchNativeMessagingHostProcess(
682 command_line.GetCommandLineString(); 585 binary, parent_window_handle_,
683 586 /*elevate_process=*/true, &read_handle, &write_handle);
684 // Launch the child process requesting elevation. 587 if (result != PROCESS_LAUNCH_RESULT_SUCCESS) {
685 SHELLEXECUTEINFO info; 588 if (result != PROCESS_LAUNCH_RESULT_CANCELLED) {
686 memset(&info, 0, sizeof(info));
687 info.cbSize = sizeof(info);
688 info.hwnd = reinterpret_cast<HWND>(parent_window_handle_);
689 info.lpVerb = L"runas";
690 info.lpFile = binary.value().c_str();
691 info.lpParameters = parameters.c_str();
692 info.nShow = SW_HIDE;
693
694 if (!ShellExecuteEx(&info)) {
695 DWORD error = ::GetLastError();
696 PLOG(ERROR) << "Unable to launch '" << binary.value() << "'";
697 if (error != ERROR_CANCELLED) {
698 OnError(); 589 OnError();
699 } 590 }
700 return; 591 return;
701 } 592 }
702 593
703 if (!::ConnectNamedPipe(delegate_write_handle.Get(), nullptr)) {
704 DWORD error = ::GetLastError();
705 if (error != ERROR_PIPE_CONNECTED) {
706 PLOG(ERROR) << "Unable to connect '" << input_pipe_name << "'";
707 OnError();
708 return;
709 }
710 }
711
712 if (!::ConnectNamedPipe(delegate_read_handle.Get(), nullptr)) {
713 DWORD error = ::GetLastError();
714 if (error != ERROR_PIPE_CONNECTED) {
715 PLOG(ERROR) << "Unable to connect '" << output_pipe_name << "'";
716 OnError();
717 return;
718 }
719 }
720
721 // Set up the native messaging channel to talk to the elevated host. 594 // Set up the native messaging channel to talk to the elevated host.
722 // Note that input for the elevated channel is output for the elevated host. 595 // Note that input for the elevated channel is output for the elevated host.
723 elevated_channel_.reset( 596 elevated_channel_.reset(new PipeMessagingChannel(
724 new PipeMessagingChannel(base::File(delegate_read_handle.Take()), 597 base::File(read_handle.Take()), base::File(write_handle.Take())));
725 base::File(delegate_write_handle.Take())));
726 598
727 elevated_channel_event_handler_.reset( 599 elevated_channel_event_handler_.reset(
728 new Me2MeNativeMessagingHost::ElevatedChannelEventHandler(this)); 600 new Me2MeNativeMessagingHost::ElevatedChannelEventHandler(this));
729 elevated_channel_->Start(elevated_channel_event_handler_.get()); 601 elevated_channel_->Start(elevated_channel_event_handler_.get());
730 602
731 elevated_host_timer_.Start( 603 elevated_host_timer_.Start(
732 FROM_HERE, base::TimeDelta::FromSeconds(kElevatedHostTimeoutSeconds), 604 FROM_HERE, base::TimeDelta::FromSeconds(kElevatedHostTimeoutSeconds),
733 this, &Me2MeNativeMessagingHost::DisconnectElevatedHost); 605 this, &Me2MeNativeMessagingHost::DisconnectElevatedHost);
734 } 606 }
735 607
736 void Me2MeNativeMessagingHost::DisconnectElevatedHost() { 608 void Me2MeNativeMessagingHost::DisconnectElevatedHost() {
737 DCHECK(thread_checker_.CalledOnValidThread()); 609 DCHECK(thread_checker_.CalledOnValidThread());
738 610
739 // This will send an EOF to the elevated host, triggering its shutdown. 611 // This will send an EOF to the elevated host, triggering its shutdown.
740 elevated_channel_.reset(); 612 elevated_channel_.reset();
741 } 613 }
742 614
743 #else // defined(OS_WIN) 615 #else // defined(OS_WIN)
744 616
745 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( 617 bool Me2MeNativeMessagingHost::DelegateToElevatedHost(
746 std::unique_ptr<base::DictionaryValue> message) { 618 std::unique_ptr<base::DictionaryValue> message) {
747 NOTREACHED(); 619 NOTREACHED();
748 return false; 620 return false;
749 } 621 }
750 622
751 #endif // !defined(OS_WIN) 623 #endif // !defined(OS_WIN)
752 624
753 } // namespace remoting 625 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/setup/me2me_native_messaging_host.h ('k') | remoting/host/setup/me2me_native_messaging_host_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698