#include <stddef.h>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/message_loop/message_pump_type.h"
#include "base/metrics/field_trial.h"
#include "base/notreached.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringize_macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_executor.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/policy/policy_constants.h"
#include "components/webrtc/thread_wrapper.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_listener.h"
#include "mojo/core/embedder/scoped_ipc_support.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "net/base/network_change_notifier.h"
#include "net/base/url_util.h"
#include "net/socket/client_socket_factory.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/base/constants.h"
#include "remoting/base/corp_session_authz_service_client_factory.h"
#include "remoting/base/cpu_utils.h"
#include "remoting/base/host_settings.h"
#include "remoting/base/is_google_email.h"
#include "remoting/base/local_session_policies_provider.h"
#include "remoting/base/logging.h"
#include "remoting/base/oauth_token_getter_impl.h"
#include "remoting/base/oauth_token_getter_proxy.h"
#include "remoting/base/rsa_key_pair.h"
#include "remoting/base/service_urls.h"
#include "remoting/base/session_policies.h"
#include "remoting/base/util.h"
#include "remoting/host/base/desktop_environment_options.h"
#include "remoting/host/base/host_exit_codes.h"
#include "remoting/host/base/switches.h"
#include "remoting/host/base/username.h"
#include "remoting/host/branding.h"
#include "remoting/host/chromoting_host.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/config_file_watcher.h"
#include "remoting/host/config_watcher.h"
#include "remoting/host/corp_host_status_logger.h"
#include "remoting/host/crash_process.h"
#include "remoting/host/desktop_environment.h"
#include "remoting/host/desktop_session_connector.h"
#include "remoting/host/ftl_echo_message_listener.h"
#include "remoting/host/ftl_host_change_notification_listener.h"
#include "remoting/host/ftl_signaling_connector.h"
#include "remoting/host/heartbeat_sender.h"
#include "remoting/host/host_config.h"
#include "remoting/host/host_event_logger.h"
#include "remoting/host/host_power_save_blocker.h"
#include "remoting/host/host_status_logger.h"
#include "remoting/host/input_injector.h"
#include "remoting/host/ipc_desktop_environment.h"
#include "remoting/host/ipc_host_event_logger.h"
#include "remoting/host/me2me_desktop_environment.h"
#include "remoting/host/mojom/chromoting_host_services.mojom.h"
#include "remoting/host/mojom/desktop_session.mojom.h"
#include "remoting/host/mojom/remoting_host.mojom.h"
#include "remoting/host/pairing_registry_delegate.h"
#include "remoting/host/pin_hash.h"
#include "remoting/host/policy_watcher.h"
#include "remoting/host/security_key/security_key_auth_handler.h"
#include "remoting/host/security_key/security_key_extension.h"
#include "remoting/host/session_policies_from_dict.h"
#include "remoting/host/shutdown_watchdog.h"
#include "remoting/host/test_echo_extension.h"
#include "remoting/host/usage_stats_consent.h"
#include "remoting/host/zombie_host_detector.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/channel_authenticator.h"
#include "remoting/protocol/chromium_port_allocator_factory.h"
#include "remoting/protocol/host_authentication_config.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/me2me_host_authenticator_factory.h"
#include "remoting/protocol/pairing_registry.h"
#include "remoting/protocol/transport_context.h"
#include "remoting/signaling/ftl_host_device_id_provider.h"
#include "remoting/signaling/ftl_signal_strategy.h"
#include "remoting/signaling/remoting_log_to_server.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/webrtc/rtc_base/event_tracer.h"
#if BUILDFLAG(IS_POSIX)
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include "base/file_descriptor_posix.h"
#include "remoting/host/pam_authorization_factory_posix.h"
#include "remoting/host/posix/signal_handler.h"
#endif
#if BUILDFLAG(IS_APPLE)
#include "remoting/host/audio_capturer_mac.h"
#include "remoting/host/desktop_capturer_checker.h"
#include "remoting/host/mac/permission_utils.h"
#endif
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#if defined(REMOTING_USE_X11)
#include <gtk/gtk.h>
#endif
#if defined(REMOTING_USE_X11)
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/gfx/x/xlib_support.h"
#endif
#endif
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "base/linux_util.h"
#include "remoting/host/audio_capturer_linux.h"
#include "remoting/host/linux/certificate_watcher.h"
#endif
#if BUILDFLAG(IS_LINUX)
#include "remoting/host/host_utmp_logger.h"
#endif
#if BUILDFLAG(IS_WIN)
#include <commctrl.h>
#include "base/win/registry.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "remoting/host/pairing_registry_delegate_win.h"
#include "remoting/host/win/session_desktop_environment.h"
#endif
#if BUILDFLAG(IS_LINUX)
#include "remoting/host/linux/wayland_manager.h"
#include "remoting/host/linux/wayland_utils.h"
#endif
PairingRegistry;
#if BUILDFLAG(IS_APPLE)
__attribute__((used))
__attribute__((section("__CGPreLoginApp,__cgpreloginapp")))
static const char magic_section[] = "";
#endif
namespace {
#if !defined(REMOTING_MULTI_PROCESS)
const char kApplicationName[] = …;
const char kStdinConfigPath[] = …;
#endif
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
const char kAudioPipeSwitchName[] = …;
#endif
#if BUILDFLAG(IS_POSIX)
const char kAuthSocknameSwitchName[] = …;
#endif
const char kSignalParentSwitchName[] = …;
const char kReportOfflineReasonSwitchName[] = …;
const int kShutdownTimeoutSeconds = …;
const int kHostOfflineReasonTimeoutSeconds = …;
const char kHostOfflineReasonPolicyReadError[] = …;
const char kHostOfflineReasonPolicyChangeRequiresRestart[] = …;
const char kHostOfflineReasonZombieStateDetected[] = …;
const char kWebRtcTraceEventFile[] = …;
}
namespace remoting {
class HostProcess : public ConfigWatcher::Delegate,
public FtlHostChangeNotificationListener::Listener,
public HeartbeatSender::Delegate,
public IPC::Listener,
public base::RefCountedThreadSafe<HostProcess>,
public mojom::RemotingHostControl,
public mojom::WorkerProcessControl { … };
HostProcess::HostProcess(std::unique_ptr<ChromotingHostContext> context,
int* exit_code_out,
ShutdownWatchdog* shutdown_watchdog)
: … { … }
HostProcess::~HostProcess() { … }
bool HostProcess::InitWithCommandLine(const base::CommandLine* cmd_line) { … }
void HostProcess::OnConfigUpdated(const std::string& serialized_config) { … }
void HostProcess::OnConfigParsed(base::Value::Dict config) { … }
void HostProcess::OnConfigWatcherError() { … }
void HostProcess::SetState(HostState target_state) { … }
void HostProcess::StartOnNetworkThread() { … }
void HostProcess::ShutdownOnNetworkThread() { … }
#if BUILDFLAG(IS_POSIX)
void HostProcess::SigTermHandler(int signal_number) { … }
#endif
void HostProcess::CreateAuthenticatorFactory() { … }
bool HostProcess::OnMessageReceived(const IPC::Message& message) { … }
void HostProcess::OnChannelError() { … }
void HostProcess::OnAssociatedInterfaceRequest(
const std::string& interface_name,
mojo::ScopedInterfaceEndpointHandle handle) { … }
void HostProcess::StartOnUiThread() { … }
void HostProcess::ShutdownOnUiThread() { … }
void HostProcess::OnHostNotFound() { … }
void HostProcess::OnFirstHeartbeatSuccessful() { … }
void HostProcess::OnUpdateHostOwner(const std::string& host_owner) { … }
void HostProcess::OnUpdateIsCorpUser(bool is_corp_user) { … }
void HostProcess::OnUpdateRequireSessionAuthorization(bool require) { … }
void HostProcess::OnHostDeleted() { … }
#if BUILDFLAG(IS_WIN)
void HostProcess::ApplyHostConfig(base::Value::Dict config) {
DCHECK(context_->ui_task_runner()->BelongsToCurrentThread());
OnConfigParsed(std::move(config));
}
void HostProcess::InitializePairingRegistry(
::mojo::PlatformHandle privileged_handle,
::mojo::PlatformHandle unprivileged_handle) {
DCHECK(context_->ui_task_runner()->BelongsToCurrentThread() ||
context_->network_task_runner()->BelongsToCurrentThread());
if (context_->ui_task_runner()->BelongsToCurrentThread()) {
context_->network_task_runner()->PostTask(
FROM_HERE, base::BindOnce(&HostProcess::InitializePairingRegistry, this,
std::move(privileged_handle),
std::move(unprivileged_handle)));
return;
}
DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
DCHECK(!pairing_registry_) << "Received multiple calls to initialize the "
<< "pairing registry";
std::unique_ptr<PairingRegistryDelegateWin> delegate(
new PairingRegistryDelegateWin());
delegate->SetRootKeys(static_cast<HKEY>(privileged_handle.ReleaseHandle()),
static_cast<HKEY>(unprivileged_handle.ReleaseHandle()));
pairing_registry_ =
new PairingRegistry(context_->file_task_runner(), std::move(delegate));
CreateAuthenticatorFactory();
}
void HostProcess::BindChromotingHostServices(
mojo::PendingReceiver<mojom::ChromotingHostServices> receiver,
int peer_pid) {
if (context_->ui_task_runner()->BelongsToCurrentThread()) {
context_->network_task_runner()->PostTask(
FROM_HERE, base::BindOnce(&HostProcess::BindChromotingHostServices,
this, std::move(receiver), peer_pid));
return;
}
DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
if (!host_) {
LOG(ERROR) << "Binding rejected. Host has not started.";
return;
}
host_->BindChromotingHostServices(std::move(receiver), peer_pid);
}
#endif
bool HostProcess::ApplyConfig(const base::Value::Dict& config) { … }
void HostProcess::OnPolicyUpdate(base::Value::Dict policies) { … }
void HostProcess::OnPolicyError() { … }
void HostProcess::ReportPolicyErrorAndRestartHost() { … }
void HostProcess::ApplyHostDomainListPolicy() { … }
void HostProcess::ApplyAllowRemoteAccessConnections() { … }
bool HostProcess::OnHostDomainListPolicyUpdate(
const base::Value::Dict& policies) { … }
bool HostProcess::OnClientDomainListPolicyUpdate(
const base::Value::Dict& policies) { … }
void HostProcess::ApplyUsernamePolicy() { … }
bool HostProcess::OnUsernamePolicyUpdate(const base::Value::Dict& policies) { … }
bool HostProcess::OnCurtainPolicyUpdate(const base::Value::Dict& policies) { … }
bool HostProcess::OnPairingPolicyUpdate(const base::Value::Dict& policies) { … }
bool HostProcess::OnGnubbyAuthPolicyUpdate(const base::Value::Dict& policies) { … }
bool HostProcess::OnAllowPinAuthenticationUpdate(
const base::Value::Dict& policies) { … }
bool HostProcess::OnEnableUserInterfacePolicyUpdate(
const base::Value::Dict& policies) { … }
bool HostProcess::OnAllowRemoteAccessConnections(
const base::Value::Dict& policies) { … }
void HostProcess::InitializeSignaling() { … }
void HostProcess::StartHostIfReady() { … }
void HostProcess::StartHost() { … }
void HostProcess::OnAuthFailed() { … }
void HostProcess::OnZombieStateDetected() { … }
void HostProcess::RestartHost(const std::string& host_offline_reason) { … }
void HostProcess::ShutdownHost(HostExitCodes exit_code) { … }
void HostProcess::GoOffline(const std::string& host_offline_reason) { … }
void HostProcess::OnHostOfflineReasonAck(bool success) { … }
void HostProcess::CrashProcess(const std::string& function_name,
const std::string& file_name,
int line_number) { … }
int HostProcessMain() { … }
}