blob: 33c5db95f1bfceea8b16a7476cd732a6f103bf68 [file] [log] [blame]
Yuwei Huang18b38bc2021-11-02 23:31:041// Copyright 2021 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/host/chromoting_host_services_client.h"
6
7#include "base/bind.h"
Yuwei Huang2796bb62021-12-01 19:45:398#include "base/environment.h"
9#include "base/notreached.h"
Yuwei Huang18b38bc2021-11-02 23:31:0410#include "base/sequence_checker.h"
Yuwei Huang2796bb62021-12-01 19:45:3911#include "build/build_config.h"
Yuwei Huang18b38bc2021-11-02 23:31:0412#include "mojo/public/cpp/bindings/pending_remote.h"
13#include "mojo/public/cpp/system/isolated_connection.h"
14#include "remoting/host/ipc_constants.h"
15#include "remoting/host/mojom/chromoting_host_services.mojom.h"
16
Xiaohan Wang453b38672022-01-13 20:02:4417#if BUILDFLAG(IS_WIN)
Yuwei Huang2796bb62021-12-01 19:45:3918#include <windows.h>
19
20#include "remoting/host/win/acl_util.h"
21#endif
22
Yuwei Huang18b38bc2021-11-02 23:31:0423namespace remoting {
24
Yuwei Huang2796bb62021-12-01 19:45:3925namespace {
26
Xiaohan Wang453b38672022-01-13 20:02:4427#if BUILDFLAG(IS_LINUX)
Yuwei Huang2796bb62021-12-01 19:45:3928constexpr char kChromeRemoteDesktopSessionEnvVar[] =
29 "CHROME_REMOTE_DESKTOP_SESSION";
30#endif
31
32bool g_initialized = false;
33
34} // namespace
35
Yuwei Huang18b38bc2021-11-02 23:31:0436ChromotingHostServicesClient::ChromotingHostServicesClient()
Yuwei Huang2796bb62021-12-01 19:45:3937 : environment_(base::Environment::Create()),
38 server_name_(GetChromotingHostServicesServerName()) {
39 DCHECK(g_initialized)
40 << "ChromotingHostServicesClient::Initialize() has not been called.";
41}
Yuwei Huang18b38bc2021-11-02 23:31:0442
43ChromotingHostServicesClient::~ChromotingHostServicesClient() {
44 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
45}
46
Yuwei Huang2796bb62021-12-01 19:45:3947// static
48bool ChromotingHostServicesClient::Initialize() {
49 DCHECK(!g_initialized);
Xiaohan Wang453b38672022-01-13 20:02:4450#if BUILDFLAG(IS_WIN)
Yuwei Huang2796bb62021-12-01 19:45:3951 // The ChromotingHostServices server runs under the LocalService account,
52 // which normally isn't allowed to query process info like session ID of a
53 // process running under a different account, so we add an ACL to allow it.
54 g_initialized = AddProcessAccessRightForWellKnownSid(
55 WinLocalServiceSid, PROCESS_QUERY_LIMITED_INFORMATION);
56#else
57 // Other platforms don't need initialization.
58 g_initialized = true;
59#endif
60 return g_initialized;
61}
62
63mojom::ChromotingSessionServices*
64ChromotingHostServicesClient::GetSessionServices() const {
Yuwei Huang18b38bc2021-11-02 23:31:0465 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
66
Yuwei Huang2796bb62021-12-01 19:45:3967 if (!const_cast<ChromotingHostServicesClient*>(this)
68 ->EnsureSessionServicesBinding()) {
Yuwei Huang18b38bc2021-11-02 23:31:0469 return nullptr;
70 }
Yuwei Huang2796bb62021-12-01 19:45:3971 return session_services_remote_.get();
Yuwei Huang18b38bc2021-11-02 23:31:0472}
73
74bool ChromotingHostServicesClient::EnsureConnection() {
75 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
76
77 if (remote_.is_bound()) {
78 return true;
79 }
80
81 auto endpoint = mojo::NamedPlatformChannel::ConnectToServer(server_name_);
82 if (!endpoint.is_valid()) {
83 LOG(WARNING) << "Cannot connect to IPC through server name " << server_name_
84 << ". Endpoint is invalid.";
85 return false;
86 }
87 connection_ = std::make_unique<mojo::IsolatedConnection>();
88 mojo::PendingRemote<mojom::ChromotingHostServices> pending_remote(
89 connection_->Connect(std::move(endpoint)), /* version= */ 0);
90 if (!pending_remote.is_valid()) {
91 LOG(WARNING) << "Invalid message pipe.";
92 connection_.reset();
93 return false;
94 }
95 remote_.Bind(std::move(pending_remote));
96 remote_.set_disconnect_handler(base::BindOnce(
97 &ChromotingHostServicesClient::OnDisconnected, base::Unretained(this)));
98 return true;
99}
100
Yuwei Huang2796bb62021-12-01 19:45:39101bool ChromotingHostServicesClient::EnsureSessionServicesBinding() {
102 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
103
104 if (session_services_remote_.is_bound()) {
105 return true;
106 }
Xiaohan Wang453b38672022-01-13 20:02:44107#if BUILDFLAG(IS_LINUX)
Yuwei Huang2796bb62021-12-01 19:45:39108 if (!environment_->HasVar(kChromeRemoteDesktopSessionEnvVar)) {
109 LOG(WARNING) << "Current desktop environment is not remotable.";
110 return false;
111 }
112#endif
113 if (!EnsureConnection()) {
114 return false;
115 }
116 remote_->BindSessionServices(
117 session_services_remote_.BindNewPipeAndPassReceiver());
118 session_services_remote_.reset_on_disconnect();
119 return true;
120}
121
Yuwei Huang18b38bc2021-11-02 23:31:04122void ChromotingHostServicesClient::OnDisconnected() {
123 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
124
125 remote_.reset();
126 connection_.reset();
127}
128
129} // namespace remoting