blob: b6648599ca0c88e1c3a9aee6fd711b5309c73cc2 [file] [log] [blame]
// 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 "chrome/enterprise_companion/enterprise_companion_service_stub.h"
#include <memory>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/sequence_checker.h"
#include "chrome/enterprise_companion/enterprise_companion_service.h"
#include "chrome/enterprise_companion/enterprise_companion_status.h"
#include "chrome/enterprise_companion/mojom/enterprise_companion.mojom.h"
#include "components/named_mojo_ipc_server/connection_info.h"
#include "components/named_mojo_ipc_server/endpoint_options.h"
#include "components/named_mojo_ipc_server/named_mojo_ipc_server.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
namespace enterprise_companion {
namespace {
class UntrustedCallerStub final : public mojom::EnterpriseCompanion {
public:
UntrustedCallerStub() = default;
// Overrides for mojom::EnterpriseCompanion.
void Shutdown(ShutdownCallback callback) override {
std::move(callback).Run(
EnterpriseCompanionStatus(ApplicationError::kIpcCallerNotAllowed)
.ToMojomStatus());
}
void FetchPolicies(FetchPoliciesCallback callback) override {
std::move(callback).Run(
EnterpriseCompanionStatus(ApplicationError::kIpcCallerNotAllowed)
.ToMojomStatus());
}
};
// Manages the NamedMojoIpcServer and forwards calls to the underlying service.
class Stub final : public mojom::EnterpriseCompanion {
public:
Stub(std::unique_ptr<EnterpriseCompanionService> service,
const named_mojo_ipc_server::EndpointOptions& options,
IpcTrustDecider trust_decider,
base::RepeatingClosure endpoint_created_listener_for_testing)
: service_(std::move(service)),
server_(options,
base::BindRepeating(
[](IpcTrustDecider trust_decider,
mojom::EnterpriseCompanion* stub,
mojom::EnterpriseCompanion* untrusted_stub,
std::unique_ptr<named_mojo_ipc_server::ConnectionInfo>
connection_info) {
return trust_decider.Run(*connection_info)
? stub
: untrusted_stub;
},
trust_decider,
base::Unretained(this),
base::Unretained(untrusted_stub_.get()))) {
server_.set_disconnect_handler(base::BindRepeating(
[] { VLOG(1) << "EnterpriseCompanion client disconnected"; }));
if (endpoint_created_listener_for_testing) {
server_.set_on_server_endpoint_created_callback_for_testing(
endpoint_created_listener_for_testing);
}
server_.StartServer();
}
~Stub() override = default;
// Overrides for mjom::EnterpriseCompanion.
void Shutdown(ShutdownCallback callback) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
service_->Shutdown(
base::BindOnce(std::move(callback),
EnterpriseCompanionStatus::Success().ToMojomStatus()));
}
void FetchPolicies(FetchPoliciesCallback callback) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
service_->FetchPolicies(
base::BindOnce([](const EnterpriseCompanionStatus& status) {
return status.ToMojomStatus();
}).Then(std::move(callback)));
}
private:
SEQUENCE_CHECKER(sequence_checker_);
std::unique_ptr<UntrustedCallerStub> untrusted_stub_ =
std::make_unique<UntrustedCallerStub>();
std::unique_ptr<EnterpriseCompanionService> service_;
named_mojo_ipc_server::NamedMojoIpcServer<mojom::EnterpriseCompanion> server_;
};
} // namespace
named_mojo_ipc_server::EndpointOptions CreateServerEndpointOptions(
const mojo::NamedPlatformChannel::ServerName& server_name) {
return {
.server_name = server_name,
.message_pipe_id =
named_mojo_ipc_server::EndpointOptions::kUseIsolatedConnection,
#if BUILDFLAG(IS_WIN)
// Allow access from local system account only.
.security_descriptor = L"D:(A;;GA;;;SY)",
#endif
};
}
// Creates a stub that receives RPC calls from the client and delegates them to
// an `EnterpriseCompanionService`. The stub creates and manages a
// `NamedMojoIpcServer` to listen for and broker new Mojo connections with
// clients.
std::unique_ptr<mojom::EnterpriseCompanion>
CreateEnterpriseCompanionServiceStub(
std::unique_ptr<EnterpriseCompanionService> service,
const named_mojo_ipc_server::EndpointOptions& options,
IpcTrustDecider trust_decider,
base::RepeatingClosure endpoint_created_listener_for_testing) {
return std::make_unique<Stub>(std::move(service), options, trust_decider,
endpoint_created_listener_for_testing);
}
} // namespace enterprise_companion