Commit fcb8624b authored by Joe Downing's avatar Joe Downing Committed by Chromium LUCI CQ

Allow website to request an elevated It2Me host

This CL adds a flag which will allow the website to request the
'elevated' It2Me host (with the UiAccess manifest value) is used
instead of the base It2Me host which does not have access to
elevated windows.  The flag is overridden by the Chrome policy so
if a network admin has specified that they do not want to allow
elevated remote support hosts, this new flag is ignored.

Change-Id: Ic84968f432db6ab041a5b4afdc38a2ac7be27a50
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586967
Commit-Queue: Joe Downing <joedow@chromium.org>
Reviewed-by: default avatarJamie Walch <jamiewalch@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837138}
parent a891fb7c
...@@ -98,11 +98,11 @@ void PolicyErrorCallback( ...@@ -98,11 +98,11 @@ void PolicyErrorCallback(
} // namespace } // namespace
It2MeNativeMessagingHost::It2MeNativeMessagingHost( It2MeNativeMessagingHost::It2MeNativeMessagingHost(
bool needs_elevation, bool is_process_elevated,
std::unique_ptr<PolicyWatcher> policy_watcher, std::unique_ptr<PolicyWatcher> policy_watcher,
std::unique_ptr<ChromotingHostContext> context, std::unique_ptr<ChromotingHostContext> context,
std::unique_ptr<It2MeHostFactory> factory) std::unique_ptr<It2MeHostFactory> factory)
: needs_elevation_(needs_elevation), : is_process_elevated_(is_process_elevated),
host_context_(std::move(context)), host_context_(std::move(context)),
factory_(std::move(factory)), factory_(std::move(factory)),
policy_watcher_(std::move(policy_watcher)) { policy_watcher_(std::move(policy_watcher)) {
...@@ -219,7 +219,26 @@ void It2MeNativeMessagingHost::ProcessConnect( ...@@ -219,7 +219,26 @@ void It2MeNativeMessagingHost::ProcessConnect(
return; return;
} }
if (needs_elevation_) { #if defined(OS_WIN)
// Requests that the support host is launched with UiAccess on Windows.
// This value, in conjuction with the platform policy, is used to determine
// if an elevated host should be used.
bool use_elevated_host = false;
message->GetBoolean("useElevatedHost", &use_elevated_host);
if (!is_process_elevated_) {
auto allow_elevation_policy = GetAllowElevatedHostPolicyValue();
// Honor the platform policy value if it is set, otherwise use the value
// provided through the native messaging host.
use_elevated_host_ = allow_elevation_policy.has_value()
? allow_elevation_policy.value()
: use_elevated_host;
}
#else
CHECK(!is_process_elevated_) << "Unexpected value for this platform";
#endif
if (use_elevated_host_) {
// Attempt to pass the current message to the elevated process. This method // Attempt to pass the current message to the elevated process. This method
// will spin up the elevated process if it is not already running. On // will spin up the elevated process if it is not already running. On
// success, the elevated process will process the message and respond. // success, the elevated process will process the message and respond.
...@@ -356,7 +375,7 @@ void It2MeNativeMessagingHost::ProcessDisconnect( ...@@ -356,7 +375,7 @@ void It2MeNativeMessagingHost::ProcessDisconnect(
DCHECK(task_runner()->BelongsToCurrentThread()); DCHECK(task_runner()->BelongsToCurrentThread());
DCHECK(policy_received_); DCHECK(policy_received_);
if (needs_elevation_) { if (use_elevated_host_) {
// Attempt to pass the current message to the elevated process. This method // Attempt to pass the current message to the elevated process. This method
// will spin up the elevated process if it is not already running. On // will spin up the elevated process if it is not already running. On
// success, the elevated process will process the message and respond. // success, the elevated process will process the message and respond.
...@@ -379,7 +398,7 @@ void It2MeNativeMessagingHost::ProcessDisconnect( ...@@ -379,7 +398,7 @@ void It2MeNativeMessagingHost::ProcessDisconnect(
void It2MeNativeMessagingHost::ProcessIncomingIq( void It2MeNativeMessagingHost::ProcessIncomingIq(
std::unique_ptr<base::DictionaryValue> message, std::unique_ptr<base::DictionaryValue> message,
std::unique_ptr<base::DictionaryValue> response) { std::unique_ptr<base::DictionaryValue> response) {
if (needs_elevation_) { if (use_elevated_host_) {
// Attempt to pass the current message to the elevated process. This method // Attempt to pass the current message to the elevated process. This method
// will spin up the elevated process if it is not already running. On // will spin up the elevated process if it is not already running. On
// success, the elevated process will process the message and respond. // success, the elevated process will process the message and respond.
...@@ -529,26 +548,9 @@ std::string It2MeNativeMessagingHost::HostStateToString( ...@@ -529,26 +548,9 @@ std::string It2MeNativeMessagingHost::HostStateToString(
void It2MeNativeMessagingHost::OnPolicyUpdate( void It2MeNativeMessagingHost::OnPolicyUpdate(
std::unique_ptr<base::DictionaryValue> policies) { std::unique_ptr<base::DictionaryValue> policies) {
// Don't dynamically change the elevation status since we don't have a good
// way to communicate changes to the user.
if (!policy_received_) { if (!policy_received_) {
bool allow_elevated_host = false;
if (!policies->GetBoolean(
policy::key::kRemoteAccessHostAllowUiAccessForRemoteAssistance,
&allow_elevated_host)) {
LOG(WARNING) << "Failed to retrieve elevated host policy value.";
}
#if defined(OS_WIN)
LOG(INFO) << "Allow UiAccess for Remote Assistance: "
<< allow_elevated_host;
#endif // defined(OS_WIN)
policy_received_ = true; policy_received_ = true;
// If |allow_elevated_host| is false, then we will fall back to using a host
// running in the current context regardless of the elevation request. This
// may not be ideal, but is still functional.
needs_elevation_ = needs_elevation_ && allow_elevated_host;
if (pending_connect_) { if (pending_connect_) {
std::move(pending_connect_).Run(); std::move(pending_connect_).Run();
} }
...@@ -559,6 +561,27 @@ void It2MeNativeMessagingHost::OnPolicyUpdate( ...@@ -559,6 +561,27 @@ void It2MeNativeMessagingHost::OnPolicyUpdate(
} }
} }
base::Optional<bool>
It2MeNativeMessagingHost::GetAllowElevatedHostPolicyValue() {
DCHECK(policy_received_);
#if defined(OS_WIN)
std::unique_ptr<base::DictionaryValue> platform_policies =
policy_watcher_->GetPlatformPolicies();
if (platform_policies) {
auto* platform_policy_value = platform_policies->FindPath(
policy::key::kRemoteAccessHostAllowUiAccessForRemoteAssistance);
if (platform_policy_value) {
// Use the platform policy value.
bool value = platform_policy_value->GetBool();
LOG(INFO) << "Allow UiAccess for remote support policy value: " << value;
return value;
}
}
#endif // defined(OS_WIN)
return base::nullopt;
}
void It2MeNativeMessagingHost::OnPolicyError() { void It2MeNativeMessagingHost::OnPolicyError() {
LOG(ERROR) << "Malformed policies detected."; LOG(ERROR) << "Malformed policies detected.";
policy_received_ = true; policy_received_ = true;
...@@ -625,7 +648,7 @@ std::string It2MeNativeMessagingHost::ExtractAccessToken( ...@@ -625,7 +648,7 @@ std::string It2MeNativeMessagingHost::ExtractAccessToken(
bool It2MeNativeMessagingHost::DelegateToElevatedHost( bool It2MeNativeMessagingHost::DelegateToElevatedHost(
std::unique_ptr<base::DictionaryValue> message) { std::unique_ptr<base::DictionaryValue> message) {
DCHECK(task_runner()->BelongsToCurrentThread()); DCHECK(task_runner()->BelongsToCurrentThread());
DCHECK(needs_elevation_); DCHECK(use_elevated_host_);
if (!elevated_host_) { if (!elevated_host_) {
base::FilePath binary_path = base::FilePath binary_path =
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "build/chromeos_buildflags.h" #include "build/chromeos_buildflags.h"
#include "extensions/browser/api/messaging/native_message_host.h" #include "extensions/browser/api/messaging/native_message_host.h"
...@@ -46,7 +47,7 @@ class PolicyWatcher; ...@@ -46,7 +47,7 @@ class PolicyWatcher;
class It2MeNativeMessagingHost : public It2MeHost::Observer, class It2MeNativeMessagingHost : public It2MeHost::Observer,
public extensions::NativeMessageHost { public extensions::NativeMessageHost {
public: public:
It2MeNativeMessagingHost(bool needs_elevation, It2MeNativeMessagingHost(bool is_process_elevated,
std::unique_ptr<PolicyWatcher> policy_watcher, std::unique_ptr<PolicyWatcher> policy_watcher,
std::unique_ptr<ChromotingHostContext> host_context, std::unique_ptr<ChromotingHostContext> host_context,
std::unique_ptr<It2MeHostFactory> host_factory); std::unique_ptr<It2MeHostFactory> host_factory);
...@@ -120,8 +121,14 @@ class It2MeNativeMessagingHost : public It2MeHost::Observer, ...@@ -120,8 +121,14 @@ class It2MeNativeMessagingHost : public It2MeHost::Observer,
// Extracts OAuth access token from the message passed from the client. // Extracts OAuth access token from the message passed from the client.
std::string ExtractAccessToken(const base::DictionaryValue* message); std::string ExtractAccessToken(const base::DictionaryValue* message);
// Used to determine whether to create and pass messages to an elevated host. // Returns the value of the 'allow_elevated_host' platform policy or empty.
bool needs_elevation_ = false; base::Optional<bool> GetAllowElevatedHostPolicyValue();
// Indicates whether the current process is already elevated.
bool is_process_elevated_ = false;
// Forward messages to an |elevated_host_|.
bool use_elevated_host_ = false;
#if defined(OS_WIN) #if defined(OS_WIN)
// Controls the lifetime of the elevated native messaging host process. // Controls the lifetime of the elevated native messaging host process.
......
...@@ -134,7 +134,7 @@ int It2MeNativeMessagingHostMain(int argc, char** argv) { ...@@ -134,7 +134,7 @@ int It2MeNativeMessagingHostMain(int argc, char** argv) {
base::File read_file; base::File read_file;
base::File write_file; base::File write_file;
bool needs_elevation = false; bool is_process_elevated_ = false;
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -142,6 +142,7 @@ int It2MeNativeMessagingHostMain(int argc, char** argv) { ...@@ -142,6 +142,7 @@ int It2MeNativeMessagingHostMain(int argc, char** argv) {
base::CommandLine::ForCurrentProcess(); base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(kElevateSwitchName)) { if (command_line->HasSwitch(kElevateSwitchName)) {
is_process_elevated_ = true;
#if defined(OFFICIAL_BUILD) #if defined(OFFICIAL_BUILD)
// Unofficial builds won't have 'UiAccess' since it requires signing. // Unofficial builds won't have 'UiAccess' since it requires signing.
if (!CurrentProcessHasUiAccess()) { if (!CurrentProcessHasUiAccess()) {
...@@ -179,8 +180,6 @@ int It2MeNativeMessagingHostMain(int argc, char** argv) { ...@@ -179,8 +180,6 @@ int It2MeNativeMessagingHostMain(int argc, char** argv) {
return kInitializationFailed; return kInitializationFailed;
} }
} else { } else {
needs_elevation = true;
// GetStdHandle() returns pseudo-handles for stdin and stdout even if // GetStdHandle() returns pseudo-handles for stdin and stdout even if
// the hosting executable specifies "Windows" subsystem. However the // the hosting executable specifies "Windows" subsystem. However the
// returned handles are invalid in that case unless standard input and // returned handles are invalid in that case unless standard input and
...@@ -250,7 +249,8 @@ int It2MeNativeMessagingHostMain(int argc, char** argv) { ...@@ -250,7 +249,8 @@ int It2MeNativeMessagingHostMain(int argc, char** argv) {
std::unique_ptr<PolicyWatcher> policy_watcher = std::unique_ptr<PolicyWatcher> policy_watcher =
PolicyWatcher::CreateWithTaskRunner(context->file_task_runner()); PolicyWatcher::CreateWithTaskRunner(context->file_task_runner());
std::unique_ptr<extensions::NativeMessageHost> host( std::unique_ptr<extensions::NativeMessageHost> host(
new It2MeNativeMessagingHost(needs_elevation, std::move(policy_watcher), new It2MeNativeMessagingHost(is_process_elevated_,
std::move(policy_watcher),
std::move(context), std::move(factory))); std::move(context), std::move(factory)));
host->Start(native_messaging_pipe.get()); host->Start(native_messaging_pipe.get());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment