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
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/corp_host_status_logger.h"
#include <memory>
#include "base/functional/bind.h"
#include "base/logging.h"
#include "remoting/base/corp_auth_util.h"
#include "remoting/base/corp_logging_service_client.h"
#include "remoting/base/http_status.h"
#include "remoting/base/internal_headers.h"
#include "remoting/base/logging.h"
#include "remoting/base/oauth_token_getter_proxy.h"
#include "remoting/base/session_policies.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/credentials_type.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/session_authz_authenticator.h"
#include "remoting/protocol/session_authz_reauthorizer.h"
#include "remoting/protocol/session_manager.h"
namespace remoting {
// static
std::unique_ptr<CorpHostStatusLogger>
CorpHostStatusLogger::CreateForRemoteAccess(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::unique_ptr<net::ClientCertStore> client_cert_store,
const LocalSessionPoliciesProvider* local_session_policies_provider,
const std::string& service_account_email,
const std::string& refresh_token) {
return std::make_unique<CorpHostStatusLogger>(
std::make_unique<CorpLoggingServiceClient>(
url_loader_factory, std::move(client_cert_store),
CreateCorpTokenGetter(url_loader_factory, service_account_email,
refresh_token),
internal::GetRemoteAccessLoggingPath()),
local_session_policies_provider);
}
// static
std::unique_ptr<CorpHostStatusLogger>
CorpHostStatusLogger::CreateForRemoteSupport(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::unique_ptr<net::ClientCertStore> client_cert_store,
const LocalSessionPoliciesProvider* local_session_policies_provider,
base::WeakPtr<OAuthTokenGetter> oauth_token_getter) {
return std::make_unique<CorpHostStatusLogger>(
std::make_unique<CorpLoggingServiceClient>(
url_loader_factory, std::move(client_cert_store),
std::make_unique<OAuthTokenGetterProxy>(oauth_token_getter),
internal::GetRemoteSupportLoggingPath()),
local_session_policies_provider);
}
CorpHostStatusLogger::CorpHostStatusLogger(
std::unique_ptr<LoggingServiceClient> service_client,
const LocalSessionPoliciesProvider* local_session_policies_provider)
: service_client_(std::move(service_client)),
local_session_policies_provider_(local_session_policies_provider) {}
CorpHostStatusLogger::~CorpHostStatusLogger() = default;
void CorpHostStatusLogger::StartObserving(
protocol::SessionManager& session_manager) {
observer_subscription_ = session_manager.AddSessionObserver(this);
}
void CorpHostStatusLogger::OnSessionStateChange(
const protocol::Session& session,
protocol::Session::State state) {
if (state != protocol::Session::State::CLOSED &&
state != protocol::Session::State::FAILED) {
return;
}
if (session.authenticator().credentials_type() !=
protocol::CredentialsType::CORP_SESSION_AUTHZ) {
VLOG(1) << "Current session is not authenticated with SessionAuthz. "
<< "Disconnect event not logged.";
return;
}
const auto& authenticator =
static_cast<const protocol::SessionAuthzAuthenticator&>(
session.authenticator().implementing_authenticator());
const std::string& session_id = authenticator.session_id();
if (session_id.empty()) {
LOG(WARNING) << "SessionAuthz ID is not known. Disconnect event not "
<< "logged.";
return;
}
internal::ReportSessionDisconnectedRequestStruct request;
request.session_authz_id = session_id;
request.session_authz_reauth_token =
authenticator.reauthorizer()
? authenticator.reauthorizer()->session_reauth_token()
: "";
request.host_token = authenticator.host_token();
request.error_code = session.error();
// The effective session policies are technically held by ClientSession, but
// it's difficult to plumb it through multiple layers of abstraction, so we
// just figure out the effective session policies ourselves here.
// If the authenticator state is not `ACCEPTED`, then we don't know whether
// the effective policies come from SessionAuthz or the local store, so we
// keep it unset.
if (session.authenticator().state() == protocol::Authenticator::ACCEPTED) {
const SessionPolicies* session_policies_from_authenticator =
session.authenticator().GetSessionPolicies();
request.effective_session_policies =
session_policies_from_authenticator
? *session_policies_from_authenticator
: local_session_policies_provider_->get_local_policies();
};
service_client_->ReportSessionDisconnected(
request, base::BindOnce([](const HttpStatus& status) {
if (status.ok()) {
HOST_LOG << "Disconnect event logged.";
} else {
LOG(ERROR) << "Failed to log disconnect event: "
<< status.error_message() << '('
<< static_cast<int>(status.error_code()) << ')';
}
}));
}
} // namespace remoting
|