1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
|
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_HOST_IT2ME_IT2ME_HOST_H_
#define REMOTING_HOST_IT2ME_IT2ME_HOST_H_
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "remoting/base/errors.h"
#include "remoting/base/local_session_policies_provider.h"
#include "remoting/base/session_policies.h"
#include "remoting/host/chromeos/chromeos_enterprise_params.h"
#include "remoting/host/host_status_observer.h"
#include "remoting/host/it2me/it2me_confirmation_dialog.h"
#include "remoting/host/it2me/it2me_confirmation_dialog_proxy.h"
#include "remoting/host/it2me/it2me_constants.h"
#include "remoting/host/it2me/reconnect_params.h"
#include "remoting/host/register_support_host_request.h"
#include "remoting/protocol/errors.h"
#include "remoting/protocol/validating_authenticator.h"
#include "remoting/signaling/signal_strategy.h"
namespace remoting {
class ChromotingHost;
class ChromotingHostContext;
class CorpHostStatusLogger;
class DesktopEnvironmentFactory;
class FtlSignalingConnector;
class HostEventLogger;
class HostEventReporter;
class HostStatusMonitor;
class OAuthTokenGetter;
class RegisterSupportHostRequest;
class RsaKeyPair;
namespace protocol {
struct IceConfig;
} // namespace protocol
// Internal implementation of the plugin's It2Me host function.
class It2MeHost : public base::RefCountedThreadSafe<It2MeHost>,
public HostStatusObserver {
public:
struct DeferredConnectContext {
DeferredConnectContext();
~DeferredConnectContext();
std::unique_ptr<RegisterSupportHostRequest> register_request;
std::unique_ptr<SignalStrategy> signal_strategy;
// `signaling_token_getter_` is used for signaling, which may require a
// non-CRD token scope, while `api_token_getter_` is used for all other
// services, which require a CRD token scope.
// `signaling_token_getter` isn't really used by It2MeHost, since
// `signal_strategy` already takes an `OAuthTokenGetter`. This is mostly for
// testing purposes.
std::unique_ptr<OAuthTokenGetter> signaling_token_getter;
std::unique_ptr<OAuthTokenGetter> api_token_getter;
// Only set when FTL signaling is being used.
std::string ftl_device_id;
// Use corp SessionAuthz auth instead of shared secret auth.
// DEPRECATED: use `is_corp_user` instead.
// TODO: crbug.com/417567187 - remove once corp IT2ME directory API is
// rolled out.
bool use_corp_session_authz = false;
// Indicates whether the user is a corp user and corp flows need to be used
// instead of the external ones.
bool is_corp_user = false;
};
using CreateDeferredConnectContext =
base::OnceCallback<std::unique_ptr<DeferredConnectContext>(
ChromotingHostContext*)>;
using HostEventReporterFactory =
base::RepeatingCallback<std::unique_ptr<HostEventReporter>(
scoped_refptr<HostStatusMonitor>)>;
class Observer {
public:
virtual void OnClientAuthenticated(const std::string& client_username) = 0;
virtual void OnStoreAccessCode(const std::string& access_code,
base::TimeDelta access_code_lifetime) = 0;
virtual void OnNatPoliciesChanged(bool nat_traversal_enabled,
bool relay_connections_allowed) = 0;
virtual void OnStateChanged(It2MeHostState state,
protocol::ErrorCode error_code) = 0;
};
It2MeHost();
It2MeHost(const It2MeHost&) = delete;
It2MeHost& operator=(const It2MeHost&) = delete;
// Session parameters provided by the remote command infrastructure when the
// session is started from the admin console for a managed Chrome OS device.
void set_chrome_os_enterprise_params(ChromeOsEnterpriseParams params);
// Callers should call is_enterprise_session() first to ensure the params are
// present and retrievable.
const ChromeOsEnterpriseParams& chrome_os_enterprise_params() const {
return *chrome_os_enterprise_params_;
}
// Indicates whether this support session was initiated by the admin console
// for a managed Chrome OS device.
bool is_enterprise_session() const {
return chrome_os_enterprise_params_.has_value();
}
// If set, only |authorized_helper| will be allowed to connect to this host.
void set_authorized_helper(const std::string& authorized_helper);
const std::string& authorized_helper() const { return authorized_helper_; }
// If set, the host will use `reconnect_params` instead of registering with
// the Directory service and generating new IDs and such.
void set_reconnect_params(ReconnectParams reconnect_params);
// Creates a new ReconnectParams struct if reconnections are allowed and the
// remote client has connected, otherwise an empty optional is returned.
virtual std::optional<ReconnectParams> CreateReconnectParams() const;
// Creates It2Me host structures and starts the host.
virtual void Connect(
std::unique_ptr<ChromotingHostContext> context,
base::Value::Dict policies,
std::unique_ptr<It2MeConfirmationDialogFactory> dialog_factory,
base::WeakPtr<It2MeHost::Observer> observer,
CreateDeferredConnectContext create_context,
const std::string& username,
const protocol::IceConfig& ice_config);
// Disconnects and shuts down the host.
virtual void Disconnect();
// HostStatusObserver implementation.
void OnClientAccessDenied(const std::string& signaling_id) override;
void OnClientConnected(const std::string& signaling_id) override;
void OnClientDisconnected(const std::string& signaling_id) override;
void SetStateForTesting(It2MeHostState state,
protocol::ErrorCode error_code) {
SetState(state, error_code);
}
// Returns the callback used for validating the connection. Do not run the
// returned callback after this object has been destroyed.
protocol::ValidatingAuthenticator::ValidationCallback
GetValidationCallbackForTesting();
#if BUILDFLAG(IS_CHROMEOS)
void SetHostEventReporterFactoryForTesting(HostEventReporterFactory factory);
#endif
// Called when initial policies are read and when they change.
void OnPolicyUpdate(base::Value::Dict policies);
protected:
friend class base::RefCountedThreadSafe<It2MeHost>;
friend class It2MeNativeMessagingHostTest;
~It2MeHost() override;
ChromotingHostContext* host_context() { return host_context_.get(); }
base::WeakPtr<It2MeHost::Observer> observer() { return observer_; }
private:
friend class MockIt2MeHost;
friend class It2MeHostTest;
// Updates state of the host. Can be called only on the network thread.
void SetState(It2MeHostState state, protocol::ErrorCode error_code);
// Returns true if the host is in a post-starting, non-error state.
bool IsRunning() const;
// Processes the result of the confirmation dialog.
void OnConfirmationResult(
protocol::ValidatingAuthenticator::ResultCallback result_callback,
It2MeConfirmationDialog::Result result);
// Task posted to the network thread from Connect().
void ConnectOnNetworkThread(const std::string& username,
const protocol::IceConfig& ice_config,
CreateDeferredConnectContext create_context);
// Called when the support host registration completes.
void OnReceivedSupportID(const std::string& support_id,
const base::TimeDelta& lifetime,
protocol::ErrorCode error_code);
std::optional<ErrorCode> OnEffectiveSessionPoliciesReceived(
const SessionPolicies& session_policies);
// Reports the NAT policies to the observer. Will always report if no policies
// have been reported, and will not report if the policies have not changed.
void ReportNatPolicies(const SessionPolicies& session_policies);
// Handlers for domain policies.
void UpdateHostDomainListPolicy(std::vector<std::string> host_domain_list);
void UpdateClientDomainListPolicy(
std::vector<std::string> client_domain_list);
void UpdateLocalSessionPolicies(const base::Value::Dict& platform_policies);
void DisconnectOnNetworkThread(
protocol::ErrorCode error_code = protocol::ErrorCode::OK);
// Uses details of the connection and current policies to determine if the
// connection should be accepted or rejected.
void ValidateConnectionDetails(
const std::string& remote_jid,
protocol::ValidatingAuthenticator::ResultCallback result_callback);
// Determines if remote support connections are allowed by policy.
bool RemoteSupportConnectionsAllowed(const base::Value::Dict& policies);
// Indicates whether the session allows a ChromeOS admin to reconnect.
bool SessionSupportsReconnections() const;
// Informs the client that the host is ready for reconnections. Sent over the
// signaling channel.
void SendReconnectSessionMessage() const;
// Caller supplied fields.
std::unique_ptr<ChromotingHostContext> host_context_;
base::WeakPtr<It2MeHost::Observer> observer_;
std::unique_ptr<SignalStrategy> signal_strategy_;
std::unique_ptr<FtlSignalingConnector> ftl_signaling_connector_;
std::unique_ptr<OAuthTokenGetter> api_token_getter_;
It2MeHostState state_ = It2MeHostState::kDisconnected;
std::optional<ReconnectParams> reconnect_params_;
std::string support_id_;
// This is empty if shared secret auth is not supported.
std::string host_secret_;
std::string ftl_device_id_;
scoped_refptr<RsaKeyPair> host_key_pair_;
std::unique_ptr<RegisterSupportHostRequest> register_request_;
std::unique_ptr<DesktopEnvironmentFactory> desktop_environment_factory_;
std::unique_ptr<HostEventLogger> host_event_logger_;
std::unique_ptr<LocalSessionPoliciesProvider>
local_session_policies_provider_;
#if BUILDFLAG(IS_CHROMEOS)
std::unique_ptr<HostEventReporter> host_event_reporter_;
HostEventReporterFactory host_event_reporter_factory_;
#endif // BUILDFLAG(IS_CHROMEOS)
bool use_corp_session_authz_ = false;
// Only set if |use_corp_session_authz_| is true.
std::unique_ptr<CorpHostStatusLogger> corp_host_status_logger_;
std::unique_ptr<ChromotingHost> host_;
int failed_login_attempts_ = 0;
std::unique_ptr<It2MeConfirmationDialogFactory> confirmation_dialog_factory_;
std::unique_ptr<It2MeConfirmationDialogProxy> confirmation_dialog_proxy_;
// Indicates whether the session policies can still change. Once the session
// has connected, any changes to the session policies will disconnect the
// session.
bool session_policies_finalized_ = false;
// Stores the last nat traversal policy and relay connections allowed policy
// values that have been reported to the observer. nullopt indicates that the
// policy has not be reported.
// Note: if these policies are not specified in SessionPolicies, they will be
// `true` rather than nullopt.
std::optional<bool> last_reported_nat_traversal_enabled_ = false;
std::optional<bool> last_reported_relay_connections_allowed_ = false;
// Set when the session was initiated for a managed Chrome OS device by an
// admin using the admin console.
std::optional<ChromeOsEnterpriseParams> chrome_os_enterprise_params_;
// Only the username stored in |authorized_helper_| will be allowed to connect
// to this host instance, if set. Note: setting this value does not override
// any applicable Enterprise policies or other constraints.
std::string authorized_helper_;
// The client and host domain policy setting.
std::vector<std::string> required_client_domain_list_;
std::vector<std::string> required_host_domain_list_;
// Stores the remote support connections allowed policy value.
bool remote_support_connections_allowed_ = true;
// Tracks the JID of the remote user when in a connecting state.
std::string connecting_jid_;
base::WeakPtrFactory<It2MeHost> weak_factory_{this};
};
// Having a factory interface makes it possible for the test to provide a mock
// implementation of the It2MeHost.
class It2MeHostFactory {
public:
It2MeHostFactory();
It2MeHostFactory(const It2MeHostFactory&) = delete;
It2MeHostFactory& operator=(const It2MeHostFactory&) = delete;
virtual ~It2MeHostFactory();
virtual std::unique_ptr<It2MeHostFactory> Clone() const;
virtual scoped_refptr<It2MeHost> CreateIt2MeHost();
};
} // namespace remoting
#endif // REMOTING_HOST_IT2ME_IT2ME_HOST_H_
|