blob: bb94631aace9729292cd07ff29db832f18cfb2ad [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SECAGENTD_PLUGINS_H_
#define SECAGENTD_PLUGINS_H_
#include <memory>
#include <string>
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "attestation/proto_bindings/interface.pb.h"
#include "attestation-client/attestation/dbus-proxies.h"
#include "base/memory/scoped_refptr.h"
#include "base/timer/timer.h"
#include "secagentd/bpf_skeleton_wrappers.h"
#include "secagentd/message_sender.h"
#include "secagentd/process_cache.h"
#include "secagentd/proto/security_xdr_events.pb.h"
#include "tpm_manager/proto_bindings/tpm_manager.pb.h"
#include "tpm_manager-client/tpm_manager/dbus-proxies.h"
namespace secagentd {
namespace testing {
class AgentPluginTestFixture;
}
class PluginInterface {
public:
// Activate the plugin.
virtual absl::Status Activate() = 0;
virtual std::string GetName() const = 0;
virtual ~PluginInterface() = default;
};
class ProcessPlugin : public PluginInterface {
public:
ProcessPlugin(scoped_refptr<BpfSkeletonFactoryInterface> bpf_skeleton_factory,
scoped_refptr<MessageSenderInterface> message_sender,
scoped_refptr<ProcessCacheInterface> process_cache);
// Load, verify and attach the process BPF applications.
absl::Status Activate() override;
std::string GetName() const override;
void HandleRingBufferEvent(const bpf::cros_event& bpf_event);
void HandleBpfRingBufferReadReady() const;
private:
std::unique_ptr<cros_xdr::reporting::XdrProcessEvent> MakeExecEvent(
const secagentd::bpf::cros_process_start& process_start);
std::unique_ptr<cros_xdr::reporting::XdrProcessEvent> MakeTerminateEvent(
const secagentd::bpf::cros_process_exit& process_exit);
// This is static because it must be accessible to a C style function.
static struct BpfCallbacks callbacks_;
base::WeakPtrFactory<ProcessPlugin> weak_ptr_factory_;
scoped_refptr<MessageSenderInterface> message_sender_;
scoped_refptr<ProcessCacheInterface> process_cache_;
scoped_refptr<BpfSkeletonFactoryInterface> factory_;
std::unique_ptr<BpfSkeletonInterface> skeleton_wrapper_;
};
class AgentPlugin : public PluginInterface {
public:
explicit AgentPlugin(scoped_refptr<MessageSenderInterface> message_sender,
std::unique_ptr<org::chromium::AttestationProxyInterface>
attestation_proxy,
std::unique_ptr<org::chromium::TpmManagerProxyInterface>
tpm_manager_proxy,
base::OnceCallback<void()> cb,
uint32_t heartbeat_timer);
// Initialize Agent proto and starts agent heartbeat events.
absl::Status Activate() override;
std::string GetName() const override;
private:
friend class testing::AgentPluginTestFixture;
// Starts filling in the tcb fields of the agent proto and initializes async
// timers that wait for tpm_manager and attestation to be ready. When services
// are ready GetCrosSecureBootInformation() and GetTpmInformation()
// will be called to fill remaining fields.
void StartInitializingAgentProto();
// Delayed function that will be called when attestation is ready. Fills the
// boot information in the agent proto if Cros Secure boot is used.
void GetCrosSecureBootInformation(bool available);
// Delayed function that will be called when tpm_manager is ready. Fills the
// tpm information in the agent proto.
void GetTpmInformation(bool available);
// Fills the boot information in the agent proto if Uefi Secure boot is used.
// Note: Only for flex machines.
void GetUefiSecureBootInformation(const base::FilePath& boot_params_filepath);
// Sends the agent start event. Uses the StartEventStatusCallback() to handle
// the status of the message.
void SendAgentStartEvent();
// Sends an agent heartbeat event every 5 minutes.
void SendAgentHeartbeatEvent();
// Checks the message status of the agent start event. If the message is
// successfully sent it calls the daemon callback to run the remaining
// plugins. If the message fails to send it will retry sending the message
// every 3 seconds.
void StartEventStatusCallback(reporting::Status status);
base::RepeatingTimer agent_heartbeat_timer_;
cros_xdr::reporting::TcbAttributes tcb_attributes_;
base::WeakPtrFactory<AgentPlugin> weak_ptr_factory_;
scoped_refptr<MessageSenderInterface> message_sender_;
std::unique_ptr<org::chromium::AttestationProxyInterface> attestation_proxy_;
std::unique_ptr<org::chromium::TpmManagerProxyInterface> tpm_manager_proxy_;
base::OnceCallback<void()> daemon_cb_;
base::Lock tcb_attributes_lock_;
base::TimeDelta heartbeat_timer_ = base::Minutes(5);
};
class PluginFactoryInterface {
public:
enum class PluginType { kAgent, kProcess };
virtual std::unique_ptr<PluginInterface> Create(
PluginType type,
scoped_refptr<MessageSenderInterface> message_sender,
scoped_refptr<ProcessCacheInterface> process_cache) = 0;
virtual std::unique_ptr<PluginInterface> Create(
PluginType type,
scoped_refptr<MessageSenderInterface> message_sender,
std::unique_ptr<org::chromium::AttestationProxyInterface>
attestation_proxy,
std::unique_ptr<org::chromium::TpmManagerProxyInterface>
tpm_manager_proxy,
base::OnceCallback<void()> cb,
uint32_t heartbeat_timer) = 0;
virtual ~PluginFactoryInterface() = default;
};
namespace Types {
using Plugin = PluginFactoryInterface::PluginType;
} // namespace Types
// Support absl format for PluginType.
absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
AbslFormatConvert(const PluginFactoryInterface::PluginType& type,
const absl::FormatConversionSpec& conversion_spec,
absl::FormatSink* output_sink);
// Support streaming for PluginType.
std::ostream& operator<<(std::ostream& out,
const PluginFactoryInterface::PluginType& type);
class PluginFactory : public PluginFactoryInterface {
public:
PluginFactory();
explicit PluginFactory(
scoped_refptr<BpfSkeletonFactoryInterface> bpf_skeleton_factory)
: bpf_skeleton_factory_(bpf_skeleton_factory) {}
std::unique_ptr<PluginInterface> Create(
PluginType type,
scoped_refptr<MessageSenderInterface> message_sender,
scoped_refptr<ProcessCacheInterface> process_cache) override;
std::unique_ptr<PluginInterface> Create(
PluginType type,
scoped_refptr<MessageSenderInterface> message_sender,
std::unique_ptr<org::chromium::AttestationProxyInterface>
attestation_proxy,
std::unique_ptr<org::chromium::TpmManagerProxyInterface>
tpm_manager_proxy,
base::OnceCallback<void()> cb,
uint32_t heartbeat_timer) override;
private:
scoped_refptr<BpfSkeletonFactoryInterface> bpf_skeleton_factory_;
};
} // namespace secagentd
#endif // SECAGENTD_PLUGINS_H_