| // 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 <cstdint> | |
| #include <memory> | |
| #include <string> | |
| #include <unordered_map> | |
| #include <utility> | |
| #include <variant> | |
| #include <vector> | |
| #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/check.h" | |
| #include "base/files/file_path.h" | |
| #include "base/memory/ptr_util.h" | |
| #include "base/memory/scoped_refptr.h" | |
| #include "base/memory/weak_ptr.h" | |
| #include "base/timer/timer.h" | |
| #include "cryptohome/proto_bindings/auth_factor.pb.h" | |
| #include "cryptohome/proto_bindings/UserDataAuth.pb.h" | |
| #include "missive/proto/record_constants.pb.h" | |
| #include "secagentd/batch_sender.h" | |
| #include "secagentd/bpf/bpf_types.h" | |
| #include "secagentd/bpf_skeleton_wrappers.h" | |
| #include "secagentd/common.h" | |
| #include "secagentd/device_user.h" | |
| #include "secagentd/message_sender.h" | |
| #include "secagentd/metrics_sender.h" | |
| #include "secagentd/policies_features_broker.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" | |
| #include "user_data_auth/dbus-proxies.h" | |
| namespace secagentd { | |
| using AuthFactorType = cros_xdr::reporting::Authentication_AuthenticationType; | |
| // If the auth factor is not yet filled wait to see | |
| // if dbus signal is late. | |
| static constexpr base::TimeDelta kWaitForAuthFactorS = base::Seconds(1); | |
| static constexpr uint64_t kMaxDelayForLockscreenAttemptsS = 3; | |
| namespace testing { | |
| class AgentPluginTestFixture; | |
| class ProcessPluginTestFixture; | |
| class NetworkPluginTestFixture; | |
| class AuthenticationPluginTestFixture; | |
| } // namespace testing | |
| class PluginInterface { | |
| public: | |
| // Activate the plugin, must be idempotent. | |
| virtual absl::Status Activate() = 0; | |
| // Deactivate the plugin, must be idempotent. | |
| virtual absl::Status Deactivate() = 0; | |
| // Is the plugin currently activated? | |
| virtual bool IsActive() const = 0; | |
| virtual std::string GetName() const = 0; | |
| // Flushes the batch sender if it exists. | |
| virtual void Flush() = 0; | |
| virtual ~PluginInterface() = default; | |
| }; | |
| template <typename HashT, | |
| typename XdrT, | |
| typename XdrAtomicVariantT, | |
| Types::BpfSkeleton SkelType, | |
| reporting::Destination destination> | |
| struct PluginConfig { | |
| using HashType = HashT; | |
| using XdrType = XdrT; | |
| using XdrAtomicType = XdrAtomicVariantT; | |
| static constexpr Types::BpfSkeleton skeleton_type{SkelType}; | |
| static constexpr reporting::Destination reporting_destination{destination}; | |
| }; | |
| class BpfSkeletonHelperInterface { | |
| public: | |
| virtual absl::Status LoadAndAttach(struct BpfCallbacks callbacks) = 0; | |
| virtual absl::Status DetachAndUnload() = 0; | |
| virtual bool IsAttached() const = 0; | |
| virtual ~BpfSkeletonHelperInterface() = default; | |
| }; | |
| template <Types::BpfSkeleton BpfSkeletonType> | |
| class BpfSkeletonHelper : public BpfSkeletonHelperInterface { | |
| public: | |
| BpfSkeletonHelper( | |
| scoped_refptr<BpfSkeletonFactoryInterface> bpf_skeleton_factory, | |
| uint32_t batch_interval_s) | |
| : batch_interval_s_(batch_interval_s), weak_ptr_factory_(this) { | |
| CHECK(bpf_skeleton_factory); | |
| factory_ = std::move(bpf_skeleton_factory); | |
| } | |
| void BpfSkeletonConsumeEvent() const { skeleton_wrapper_->ConsumeEvent(); } | |
| absl::Status LoadAndAttach(struct BpfCallbacks callbacks) override { | |
| if (skeleton_wrapper_) { | |
| return absl::OkStatus(); | |
| } | |
| // If ring_buffer_read_ready_callback is set by the plugin, then don't | |
| // override. If not set, use this default callback | |
| if (!callbacks.ring_buffer_read_ready_callback) { | |
| callbacks.ring_buffer_read_ready_callback = | |
| base::BindRepeating(&BpfSkeletonHelper::BpfSkeletonConsumeEvent, | |
| weak_ptr_factory_.GetWeakPtr()); | |
| } | |
| skeleton_wrapper_ = factory_->Create(BpfSkeletonType, std::move(callbacks), | |
| batch_interval_s_); | |
| if (skeleton_wrapper_ == nullptr) { | |
| return absl::InternalError( | |
| absl::StrFormat("%s BPF program loading error.", BpfSkeletonType)); | |
| } | |
| return absl::OkStatus(); | |
| } | |
| absl::Status DetachAndUnload() override { | |
| // Unset the skeleton_wrapper_ unloads and cleans up the BPFs. | |
| skeleton_wrapper_ = nullptr; | |
| return absl::OkStatus(); | |
| } | |
| bool IsAttached() const override { return skeleton_wrapper_ != nullptr; } | |
| private: | |
| // friend testing::BpfSkeletonHelperTestFixture; | |
| uint32_t batch_interval_s_; | |
| base::WeakPtrFactory<BpfSkeletonHelper> weak_ptr_factory_; | |
| scoped_refptr<BpfSkeletonFactoryInterface> factory_; | |
| std::unique_ptr<BpfSkeletonInterface> skeleton_wrapper_; | |
| }; | |
| class NetworkPlugin : public PluginInterface { | |
| public: | |
| NetworkPlugin( | |
| scoped_refptr<BpfSkeletonFactoryInterface> bpf_skeleton_factory, | |
| scoped_refptr<MessageSenderInterface> message_sender, | |
| scoped_refptr<ProcessCacheInterface> process_cache, | |
| scoped_refptr<PoliciesFeaturesBrokerInterface> policies_features_broker, | |
| scoped_refptr<DeviceUserInterface> device_user, | |
| uint32_t batch_interval_s); | |
| // Load, verify and attach the process BPF applications. | |
| absl::Status Activate() override; | |
| absl::Status Deactivate() override; | |
| bool IsActive() const override; | |
| std::string GetName() const override; | |
| void Flush() override { | |
| if (batch_sender_) { | |
| batch_sender_->Flush(); | |
| } | |
| } | |
| // Handles an individual incoming Process BPF event. | |
| void HandleRingBufferEvent(const bpf::cros_event& bpf_event); | |
| /* Given a set of addresses (in network byte order) | |
| * ,a set of ports and a protocol ID compute the | |
| * community flow ID hash. | |
| */ | |
| static std::string ComputeCommunityHashv1( | |
| const absl::Span<const uint8_t>& saddr_in, | |
| const absl::Span<const uint8_t>& daddr_in, | |
| uint16_t sport, | |
| uint16_t dport, | |
| uint8_t proto, | |
| uint16_t seed = 0); | |
| private: | |
| friend testing::NetworkPluginTestFixture; | |
| using BatchSenderType = | |
| BatchSenderInterface<std::string, | |
| cros_xdr::reporting::XdrNetworkEvent, | |
| cros_xdr::reporting::NetworkEventAtomicVariant>; | |
| // Inject the given (mock) BatchSender object for unit testing. | |
| void SetBatchSenderForTesting(std::unique_ptr<BatchSenderType> given) { | |
| batch_sender_ = std::move(given); | |
| } | |
| // Pushes the given process event into the next outgoing batch. | |
| void EnqueueBatchedEvent( | |
| std::unique_ptr<cros_xdr::reporting::NetworkEventAtomicVariant> | |
| atomic_event); | |
| void OnDeviceUserRetrieved( | |
| std::unique_ptr<cros_xdr::reporting::NetworkEventAtomicVariant> | |
| atomic_event, | |
| const std::string& device_user); | |
| template <typename ProtoT> | |
| void FillProcessTree(ProtoT proto, | |
| const bpf::cros_process_start& process_start, | |
| bool has_full_process_start) const; | |
| std::unique_ptr<cros_xdr::reporting::NetworkSocketListenEvent> | |
| MakeListenEvent( | |
| const secagentd::bpf::cros_network_socket_listen& listen_event) const; | |
| std::unique_ptr<cros_xdr::reporting::NetworkFlowEvent> MakeFlowEvent( | |
| const secagentd::bpf::cros_synthetic_network_flow& flow_event) const; | |
| std::unique_ptr< | |
| base::LRUCache<bpf::cros_flow_map_key, bpf::cros_flow_map_value>> | |
| prev_tx_rx_totals_; // declaring this as a value member strangely seems | |
| // to make it const. | |
| base::WeakPtrFactory<NetworkPlugin> weak_ptr_factory_; | |
| scoped_refptr<ProcessCacheInterface> process_cache_; | |
| scoped_refptr<PoliciesFeaturesBrokerInterface> policies_features_broker_; | |
| scoped_refptr<DeviceUserInterface> device_user_; | |
| std::unique_ptr<BatchSenderType> batch_sender_; | |
| std::unique_ptr<BpfSkeletonHelperInterface> bpf_skeleton_helper_; | |
| }; | |
| class ProcessPlugin : public PluginInterface { | |
| public: | |
| ProcessPlugin( | |
| scoped_refptr<BpfSkeletonFactoryInterface> bpf_skeleton_factory, | |
| scoped_refptr<MessageSenderInterface> message_sender, | |
| scoped_refptr<ProcessCacheInterface> process_cache, | |
| scoped_refptr<PoliciesFeaturesBrokerInterface> policies_features_broker, | |
| scoped_refptr<DeviceUserInterface> device_user, | |
| uint32_t batch_interval_s); | |
| // Load, verify and attach the process BPF applications. | |
| absl::Status Activate() override; | |
| absl::Status Deactivate() override; | |
| bool IsActive() const override; | |
| std::string GetName() const override; | |
| void Flush() override { | |
| if (batch_sender_) { | |
| batch_sender_->Flush(); | |
| } | |
| } | |
| // Handles an individual incoming Process BPF event. | |
| void HandleRingBufferEvent(const bpf::cros_event& bpf_event); | |
| // Requests immediate event consumption from BPF. | |
| void HandleBpfRingBufferReadReady() const; | |
| private: | |
| friend class testing::ProcessPluginTestFixture; | |
| using BatchSenderType = | |
| BatchSenderInterface<std::string, | |
| cros_xdr::reporting::XdrProcessEvent, | |
| cros_xdr::reporting::ProcessEventAtomicVariant>; | |
| // Pushes the given process event into the next outgoing batch. | |
| void EnqueueBatchedEvent( | |
| std::unique_ptr<cros_xdr::reporting::ProcessEventAtomicVariant> | |
| atomic_event); | |
| // Converts the BPF process start event into a XDR process exec | |
| // protobuf. | |
| std::unique_ptr<cros_xdr::reporting::ProcessExecEvent> MakeExecEvent( | |
| const secagentd::bpf::cros_process_start& process_start); | |
| std::unique_ptr<cros_xdr::reporting::ProcessTerminateEvent> | |
| // Converts the BPF process exit event into a XDR process terminate | |
| // protobuf. | |
| MakeTerminateEvent(const secagentd::bpf::cros_process_exit& process_exit); | |
| // Callback function that is ran when the device user is ready. | |
| void OnDeviceUserRetrieved( | |
| std::unique_ptr<cros_xdr::reporting::ProcessEventAtomicVariant> | |
| atomic_event, | |
| const std::string& device_user); | |
| // Inject the given (mock) BatchSender object for unit testing. | |
| void SetBatchSenderForTesting(std::unique_ptr<BatchSenderType> given) { | |
| batch_sender_ = std::move(given); | |
| } | |
| base::WeakPtrFactory<ProcessPlugin> weak_ptr_factory_; | |
| scoped_refptr<ProcessCacheInterface> process_cache_; | |
| scoped_refptr<PoliciesFeaturesBrokerInterface> policies_features_broker_; | |
| scoped_refptr<DeviceUserInterface> device_user_; | |
| std::unique_ptr<BatchSenderType> batch_sender_; | |
| std::unique_ptr<BpfSkeletonHelperInterface> bpf_skeleton_helper_; | |
| }; | |
| class AuthenticationPlugin : public PluginInterface { | |
| public: | |
| AuthenticationPlugin( | |
| scoped_refptr<MessageSenderInterface> message_sender, | |
| scoped_refptr<PoliciesFeaturesBrokerInterface> policies_features_broker, | |
| scoped_refptr<DeviceUserInterface> device_user, | |
| uint32_t batch_interval_s); | |
| // Starts reporting user authentication events. | |
| absl::Status Activate() override; | |
| absl::Status Deactivate() override; | |
| bool IsActive() const override; | |
| std::string GetName() const override; | |
| void Flush() override { | |
| if (batch_sender_) { | |
| batch_sender_->Flush(); | |
| } | |
| } | |
| private: | |
| friend class testing::AuthenticationPluginTestFixture; | |
| using BatchSenderType = | |
| BatchSenderInterface<std::monostate, | |
| cros_xdr::reporting::XdrUserEvent, | |
| cros_xdr::reporting::UserEventAtomicVariant>; | |
| // Creates and sends a screen Lock event. | |
| void OnScreenLock(); | |
| // Creates and sends a screen Unlock event. | |
| void OnScreenUnlock(); | |
| // Logs error if registration fails. | |
| void OnRegistrationResult(const std::string& interface, | |
| const std::string& signal, | |
| bool success); | |
| // Creates and sends a login/out event based on the state. | |
| void OnSessionStateChange(const std::string& state); | |
| // Used to fill the auth factor for login and unlock. | |
| // Also fills in the device user. | |
| void OnAuthenticateAuthFactorCompleted( | |
| const user_data_auth::AuthenticateAuthFactorCompleted& result); | |
| // Fills the proto's auth factor if auth_factor_ is known. | |
| // Returns if auth factor was filled. | |
| bool FillAuthFactor(cros_xdr::reporting::Authentication* proto); | |
| // If there is an entry event but auth factor is not filled, wait and | |
| // then check again for auth factor. If still not found send message anyway. | |
| void DelayedCheckForAuthSignal( | |
| std::unique_ptr<cros_xdr::reporting::UserEventAtomicVariant> xdr_proto, | |
| cros_xdr::reporting::Authentication* authentication); | |
| // Callback function that is ran when the device user is ready. | |
| void OnDeviceUserRetrieved( | |
| std::unique_ptr<cros_xdr::reporting::UserEventAtomicVariant> atomic_event, | |
| const std::string& device_user); | |
| // When the first session start happens in the case of a secagentd restart | |
| // check if a user is already signed in and if so send a login event. | |
| void OnFirstSessionStart(const std::string& device_user); | |
| // Inject the given (mock) BatchSender object for unit testing. | |
| void SetBatchSenderForTesting(std::unique_ptr<BatchSenderType> given) { | |
| batch_sender_ = std::move(given); | |
| } | |
| base::WeakPtrFactory<AuthenticationPlugin> weak_ptr_factory_; | |
| scoped_refptr<PoliciesFeaturesBrokerInterface> policies_features_broker_; | |
| scoped_refptr<DeviceUserInterface> device_user_; | |
| std::unique_ptr<BatchSenderType> batch_sender_; | |
| std::unique_ptr<org::chromium::UserDataAuthInterfaceProxyInterface> | |
| cryptohome_proxy_; | |
| AuthFactorType auth_factor_type_ = | |
| AuthFactorType::Authentication_AuthenticationType_AUTH_TYPE_UNKNOWN; | |
| const std::unordered_map<user_data_auth::AuthFactorType, AuthFactorType> | |
| auth_factor_map_ = { | |
| {user_data_auth::AUTH_FACTOR_TYPE_UNSPECIFIED, | |
| AuthFactorType::Authentication_AuthenticationType_AUTH_TYPE_UNKNOWN}, | |
| {user_data_auth::AUTH_FACTOR_TYPE_PASSWORD, | |
| AuthFactorType::Authentication_AuthenticationType_AUTH_PASSWORD}, | |
| {user_data_auth::AUTH_FACTOR_TYPE_PIN, | |
| AuthFactorType::Authentication_AuthenticationType_AUTH_PIN}, | |
| {user_data_auth::AUTH_FACTOR_TYPE_CRYPTOHOME_RECOVERY, | |
| AuthFactorType:: | |
| Authentication_AuthenticationType_AUTH_ONLINE_RECOVERY}, | |
| {user_data_auth::AUTH_FACTOR_TYPE_KIOSK, | |
| AuthFactorType::Authentication_AuthenticationType_AUTH_KIOSK}, | |
| {user_data_auth::AUTH_FACTOR_TYPE_SMART_CARD, | |
| AuthFactorType::Authentication_AuthenticationType_AUTH_SMART_CARD}, | |
| {user_data_auth::AUTH_FACTOR_TYPE_LEGACY_FINGERPRINT, | |
| AuthFactorType::Authentication_AuthenticationType_AUTH_FINGERPRINT}, | |
| {user_data_auth::AUTH_FACTOR_TYPE_FINGERPRINT, | |
| AuthFactorType::Authentication_AuthenticationType_AUTH_FINGERPRINT}, | |
| }; | |
| std::string signed_in_user_ = device_user::kEmpty; | |
| int64_t latest_successful_login_timestamp_{-1}; | |
| uint64_t latest_pin_failure_{0}; | |
| bool is_active_{false}; | |
| bool last_auth_was_password_{false}; | |
| }; | |
| class AgentPlugin : public PluginInterface { | |
| static constexpr char kBootDataFilepath[] = "sys/kernel/boot_params/data"; | |
| public: | |
| AgentPlugin(scoped_refptr<MessageSenderInterface> message_sender, | |
| scoped_refptr<DeviceUserInterface> device_user, | |
| 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; | |
| absl::Status Deactivate() override; | |
| std::string GetName() const override; | |
| bool IsActive() const override { return is_active_; } | |
| void Flush() override {} | |
| private: | |
| friend class testing::AgentPluginTestFixture; | |
| // Allow calling the private test-only constructor without befriending | |
| // unique_ptr. | |
| template <typename... Args> | |
| static std::unique_ptr<AgentPlugin> CreateForTesting(Args&&... args) { | |
| return base::WrapUnique(new AgentPlugin(std::forward<Args>(args)...)); | |
| } | |
| // Accepts root_path for testing. | |
| AgentPlugin(scoped_refptr<MessageSenderInterface> message_sender, | |
| scoped_refptr<DeviceUserInterface> device_user, | |
| std::unique_ptr<org::chromium::AttestationProxyInterface> | |
| attestation_proxy, | |
| std::unique_ptr<org::chromium::TpmManagerProxyInterface> | |
| tpm_manager_proxy, | |
| base::OnceCallback<void()> cb, | |
| const base::FilePath& root_path, | |
| uint32_t heartbeat_timer); | |
| // 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(); | |
| // Callback that is used when the attestation service is ready that calls | |
| // GetCrosSecureBootInformation and sends metrics. | |
| void AttestationCb(bool available); | |
| // Delayed function that will be called when attestation is ready. Fills the | |
| // boot information in the agent proto if Cros Secure boot is used. | |
| metrics::CrosBootmode GetCrosSecureBootInformation(bool available); | |
| // Callback that is used when the tpm service is ready that calls | |
| // GetTpmInformation and sends metrics. | |
| void TpmCb(bool available); | |
| // Delayed function that will be called when tpm_manager is ready. Fills the | |
| // tpm information in the agent proto. | |
| metrics::Tpm GetTpmInformation(bool available); | |
| // Fills the boot information in the agent proto if Uefi Secure boot is used. | |
| // Note: Only for flex machines. | |
| metrics::UefiBootmode GetUefiSecureBootInformation( | |
| const base::FilePath& boot_params_filepath); | |
| // Sends an agent event dependant on whether it is start or heartbeat event. | |
| // Uses the StartEventStatusCallback() to handle the status of the message. | |
| void SendAgentEvent(bool is_agent_start); | |
| // 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); | |
| inline void SendStartEvent() { SendAgentEvent(true); } | |
| inline void SendHeartbeatEvent() { SendAgentEvent(false); } | |
| // Callback function that is ran when the device user is ready. | |
| void OnDeviceUserRetrieved( | |
| std::unique_ptr<cros_xdr::reporting::AgentEventAtomicVariant> | |
| atomic_event, | |
| const std::string& device_user); | |
| base::RepeatingTimer agent_heartbeat_timer_; | |
| cros_xdr::reporting::TcbAttributes tcb_attributes_; | |
| base::WeakPtrFactory<AgentPlugin> weak_ptr_factory_; | |
| scoped_refptr<MessageSenderInterface> message_sender_; | |
| scoped_refptr<DeviceUserInterface> device_user_; | |
| std::unique_ptr<org::chromium::AttestationProxyInterface> attestation_proxy_; | |
| std::unique_ptr<org::chromium::TpmManagerProxyInterface> tpm_manager_proxy_; | |
| base::OnceCallback<void()> daemon_cb_; | |
| const base::FilePath root_path_; | |
| base::Lock tcb_attributes_lock_; | |
| base::TimeDelta heartbeat_timer_ = base::Minutes(5); | |
| bool is_active_{false}; | |
| }; | |
| class PluginFactoryInterface { | |
| public: | |
| virtual std::unique_ptr<PluginInterface> Create( | |
| Types::Plugin type, | |
| scoped_refptr<MessageSenderInterface> message_sender, | |
| scoped_refptr<ProcessCacheInterface> process_cache, | |
| scoped_refptr<PoliciesFeaturesBrokerInterface> policies_features_broker, | |
| scoped_refptr<DeviceUserInterface> device_user, | |
| uint32_t batch_interval_s) = 0; | |
| virtual std::unique_ptr<PluginInterface> CreateAgentPlugin( | |
| scoped_refptr<MessageSenderInterface> message_sender, | |
| scoped_refptr<DeviceUserInterface> device_user, | |
| 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; | |
| }; | |
| // Support absl format for PluginType. | |
| absl::FormatConvertResult<absl::FormatConversionCharSet::kString> | |
| AbslFormatConvert(const Types::Plugin& type, | |
| const absl::FormatConversionSpec& conversion_spec, | |
| absl::FormatSink* output_sink); | |
| // Support streaming for PluginType. | |
| std::ostream& operator<<(std::ostream& out, const Types::Plugin& 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( | |
| Types::Plugin type, | |
| scoped_refptr<MessageSenderInterface> message_sender, | |
| scoped_refptr<ProcessCacheInterface> process_cache, | |
| scoped_refptr<PoliciesFeaturesBrokerInterface> policies_features_broker, | |
| scoped_refptr<DeviceUserInterface> device_user, | |
| uint32_t batch_interval_s) override; | |
| std::unique_ptr<PluginInterface> CreateAgentPlugin( | |
| scoped_refptr<MessageSenderInterface> message_sender, | |
| scoped_refptr<DeviceUserInterface> device_user, | |
| 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_ |