| // 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; |
| |
| // 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(); |
| } |
| // Indicates whether this support session was initiated by Class tools |
| // for a managed Chrome OS device. |
| bool is_class_management_session() const { |
| return chrome_os_enterprise_params_.has_value() && |
| chrome_os_enterprise_params_->request_origin == |
| remoting::ChromeOsEnterpriseRequestOrigin::kClassManagement; |
| } |
| |
| // 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_ |