| // 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. |
| |
| #include <cstdint> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #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 "secagentd/bpf_skeleton_wrappers.h" |
| #include "secagentd/message_sender.h" |
| #include "secagentd/plugins.h" |
| |
| namespace secagentd { |
| |
| absl::FormatConvertResult<absl::FormatConversionCharSet::kString> |
| AbslFormatConvert(const Types::BpfSkeleton& type, |
| const absl::FormatConversionSpec&, |
| absl::FormatSink* output_sink) { |
| static const absl::flat_hash_map<Types::BpfSkeleton, std::string> |
| kTypeToString{{Types::BpfSkeleton::kProcess, "Process"}}; |
| auto i = kTypeToString.find(type); |
| output_sink->Append(i != kTypeToString.end() ? i->second : "Unknown"); |
| return {.value = true}; |
| } |
| |
| std::ostream& operator<<(std::ostream& out, const Types::BpfSkeleton& type) { |
| out << absl::StreamFormat("%s", type); |
| return out; |
| } |
| |
| std::unique_ptr<BpfSkeletonInterface> BpfSkeletonFactory::Create( |
| BpfSkeletonType type, BpfCallbacks cbs) { |
| if (created_skeletons_.contains(type)) { |
| return nullptr; |
| } |
| |
| std::unique_ptr<BpfSkeletonInterface> rv{nullptr}; |
| switch (type) { |
| case BpfSkeletonType::kProcess: |
| rv = di_.process ? std::move(di_.process) |
| : std::make_unique<ProcessBpfSkeleton>(); |
| break; |
| default: |
| LOG(ERROR) << "Failed to create skeleton: unhandled type " << type; |
| return nullptr; |
| } |
| |
| rv->RegisterCallbacks(std::move(cbs)); |
| absl::Status status = rv->LoadAndAttach(); |
| if (!status.ok()) { |
| LOG(ERROR) << "Failed to create skeleton of type " << type << ":" |
| << status.message(); |
| return nullptr; |
| } |
| created_skeletons_.insert(type); |
| return rv; |
| } |
| |
| absl::FormatConvertResult<absl::FormatConversionCharSet::kString> |
| AbslFormatConvert(const Types::Plugin& type, |
| const absl::FormatConversionSpec&, |
| absl::FormatSink* sink) { |
| static const absl::flat_hash_map<Types::Plugin, std::string> kTypeToString{ |
| {Types::Plugin::kProcess, "Process"}, {Types::Plugin::kAgent, "Agent"}}; |
| |
| auto i = kTypeToString.find(type); |
| sink->Append(i != kTypeToString.end() ? i->second : "Unknown"); |
| return {.value = true}; |
| } |
| |
| std::ostream& operator<<(std::ostream& out, const Types::Plugin& type) { |
| out << absl::StreamFormat("%s", type); |
| return out; |
| } |
| |
| PluginFactory::PluginFactory() { |
| bpf_skeleton_factory_ = ::base::MakeRefCounted<BpfSkeletonFactory>(); |
| } |
| |
| std::unique_ptr<PluginInterface> PluginFactory::Create( |
| PluginType type, |
| scoped_refptr<MessageSenderInterface> message_sender, |
| scoped_refptr<ProcessCacheInterface> process_cache) { |
| std::unique_ptr<PluginInterface> rv{nullptr}; |
| switch (type) { |
| case PluginType::kProcess: |
| rv = std::make_unique<ProcessPlugin>(bpf_skeleton_factory_, |
| message_sender, process_cache); |
| break; |
| |
| default: |
| CHECK(false) << "Unsupported plugin type"; |
| } |
| return rv; |
| } |
| |
| std::unique_ptr<PluginInterface> PluginFactory::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 set_heartbeat_period_s_for_testing) { |
| std::unique_ptr<PluginInterface> rv{nullptr}; |
| switch (type) { |
| case PluginType::kAgent: |
| rv = std::make_unique<AgentPlugin>( |
| message_sender, std::move(attestation_proxy), |
| std::move(tpm_manager_proxy), std::move(cb), |
| set_heartbeat_period_s_for_testing); |
| break; |
| |
| default: |
| CHECK(false) << "Unsupported plugin type"; |
| } |
| return rv; |
| } |
| } // namespace secagentd |