| // Copyright 2023 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef MINIOS_LOG_STORE_MANAGER_H_ |
| #define MINIOS_LOG_STORE_MANAGER_H_ |
| |
| #include <cstdint> |
| #include <memory> |
| #include <optional> |
| #include <utility> |
| |
| #include <base/files/file_path.h> |
| #include <brillo/secure_blob.h> |
| #include <gtest/gtest_prod.h> |
| #include <libcrossystem/crossystem.h> |
| #include <libhwsec-foundation/crypto/secure_blob_util.h> |
| #include <minios/proto_bindings/minios.pb.h> |
| #include <vpd/vpd.h> |
| |
| #include "minios/cgpt_wrapper.h" |
| #include "minios/disk_util.h" |
| #include "minios/log_store_manifest.h" |
| #include "minios/process_manager.h" |
| |
| namespace minios { |
| |
| extern const uint64_t kLogStoreOffset; |
| extern const uint64_t kMaxLogSize; |
| |
| // Interface for a log store manager class. |
| class LogStoreManagerInterface { |
| public: |
| enum class LogDirection { |
| Disk, |
| Stateful, |
| RemovableDevice, |
| }; |
| |
| virtual ~LogStoreManagerInterface() = default; |
| |
| virtual bool Init( |
| std::shared_ptr<DiskUtil> disk_util = std::make_shared<DiskUtil>(), |
| std::shared_ptr<crossystem::Crossystem> cros_system = |
| std::make_shared<crossystem::Crossystem>(), |
| std::shared_ptr<CgptWrapperInterface> cgpt_wrapper = |
| std::make_shared<CgptWrapper>()) = 0; |
| |
| // Save logs to a specified direction. If the direction is not `Disk`, logs |
| // will be written to `path`. |
| virtual bool SaveLogs( |
| LogDirection direction, |
| const std::optional<base::FilePath>& path = std::nullopt) = 0; |
| |
| // Attempt to read, decrypt and extract logs from a specified direction. If |
| // logs are found and successfully unpacked (with the provided key), they will |
| // be placed at `dest_directory`. Returns nullopt on error, or true/false to |
| // indicate whether logs were fetched. |
| virtual std::optional<bool> FetchLogs( |
| LogDirection direction, |
| const base::FilePath& dest_directory, |
| const brillo::SecureBlob& key, |
| const std::optional<base::FilePath>& encrypted_archive_path = |
| std::nullopt) const = 0; |
| |
| // Clear logs on disk. |
| virtual bool ClearLogs() const = 0; |
| }; |
| |
| class LogStoreManager : public LogStoreManagerInterface { |
| public: |
| LogStoreManager() : LogStoreManager(std::nullopt) {} |
| explicit LogStoreManager(std::optional<uint64_t> partition_number) |
| : process_manager_(std::make_shared<ProcessManager>()), |
| partition_number_(partition_number), |
| vpd_(std::make_shared<vpd::Vpd>()) {} |
| |
| LogStoreManager(std::unique_ptr<LogStoreManifestInterface> log_store_manifest, |
| std::shared_ptr<ProcessManagerInterface> process_manager, |
| std::shared_ptr<vpd::Vpd> vpd, |
| const base::FilePath& disk_path, |
| uint64_t kernel_size, |
| uint64_t partition_size) |
| : log_store_manifest_(std::move(log_store_manifest)), |
| process_manager_(process_manager), |
| disk_path_(disk_path), |
| kernel_size_(kernel_size), |
| partition_size_(partition_size), |
| vpd_(vpd) {} |
| |
| ~LogStoreManager() override = default; |
| |
| LogStoreManager(const LogStoreManager&) = delete; |
| LogStoreManager& operator=(const LogStoreManager&) = delete; |
| |
| bool Init(std::shared_ptr<DiskUtil> disk_util = std::make_shared<DiskUtil>(), |
| std::shared_ptr<crossystem::Crossystem> cros_system = |
| std::make_shared<crossystem::Crossystem>(), |
| std::shared_ptr<CgptWrapperInterface> cgpt_wrapper = |
| std::make_shared<CgptWrapper>()) override; |
| |
| bool SaveLogs( |
| LogDirection direction, |
| const std::optional<base::FilePath>& path = std::nullopt) override; |
| |
| std::optional<bool> FetchLogs( |
| LogDirection direction, |
| const base::FilePath& dest_directory, |
| const brillo::SecureBlob& key, |
| const std::optional<base::FilePath>& encrypted_archive_path = |
| std::nullopt) const override; |
| |
| bool ClearLogs() const override; |
| |
| private: |
| FRIEND_TEST(LogStoreManagerEncryptTest, EncryptLogsTest); |
| FRIEND_TEST(LogStoreManagerTest, SaveLogsToPathTest); |
| FRIEND_TEST(LogStoreManagerTest, SaveLogsToDiskTest); |
| FRIEND_TEST(LogStoreManagerInitTest, InitTest); |
| FRIEND_TEST(LogStoreManagerInitTest, InitKernelLogStoreOverlapTest); |
| FRIEND_TEST(LogStoreManagerInitTest, InitSpecifiedPartitionTest); |
| |
| // Helper functions for `SaveLogs`. |
| std::optional<EncryptedLogFile> EncryptLogs( |
| const base::FilePath& archive_path); |
| bool SaveLogsToDisk(const EncryptedLogFile& encrypted_archive); |
| bool SaveLogsToPath(const base::FilePath& path, |
| const EncryptedLogFile& encrypted_archive); |
| // Helper functions for `FetchLogs`. |
| std::optional<bool> ReadLogs( |
| LogDirection direction, |
| const std::optional<base::FilePath>& encrypted_archive_path, |
| EncryptedLogFile& encrypted_archive) const; |
| std::optional<EncryptedLogFile> GetEncryptedArchive( |
| const base::FilePath& path, uint64_t offset = 0) const; |
| bool ExtractLogs(const brillo::SecureBlob& archive, |
| const base::FilePath& dest_directory) const; |
| |
| std::unique_ptr<LogStoreManifestInterface> log_store_manifest_; |
| std::shared_ptr<ProcessManagerInterface> process_manager_; |
| |
| base::FilePath disk_path_; |
| std::optional<uint64_t> kernel_size_; |
| std::optional<uint64_t> partition_size_; |
| // Partition target for saving and fetching logs. |
| std::optional<uint64_t> partition_number_; |
| |
| std::shared_ptr<vpd::Vpd> vpd_; |
| |
| std::optional<brillo::SecureBlob> encrypt_key_; |
| }; |
| |
| } // namespace minios |
| |
| #endif // MINIOS_LOG_STORE_MANAGER_H_ |