| #include "tpm_event_log.hpp" |
| |
| #include <phosphor-logging/log.hpp> |
| |
| #include <algorithm> |
| #include <filesystem> |
| #include <fstream> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| using phosphor::logging::log; |
| using level = phosphor::logging::level; |
| |
| namespace ipmi_hoth |
| { |
| |
| bool TpmEventLogBlobHandler::canHandleBlob(const std::string &path) |
| { |
| return path == tpmEventLogBlobId; |
| } |
| |
| std::vector<std::string> TpmEventLogBlobHandler::getBlobIds() |
| { |
| return {std::string(tpmEventLogBlobId)}; |
| } |
| |
| bool TpmEventLogBlobHandler::deleteBlob(const std::string &) |
| { |
| return false; |
| } |
| |
| bool TpmEventLogBlobHandler::stat(const std::string &path, blobs::BlobMeta *meta) |
| { |
| if (path != tpmEventLogBlobId) |
| { |
| return false; |
| } |
| |
| try |
| { |
| meta->size = std::filesystem::file_size(tpmEventLogFilePath); |
| } |
| catch (const std::filesystem::filesystem_error &) |
| { |
| return false; |
| } |
| meta->blobState = blobs::StateFlags::open_read; |
| return true; |
| } |
| |
| bool TpmEventLogBlobHandler::open(uint16_t session, uint16_t flags, |
| const std::string &path) |
| { |
| // For each session opened for this Blob, a file of at most 175 bytes |
| // will be read and stored. |
| if (path != tpmEventLogBlobId) |
| { |
| return false; |
| } |
| |
| // We only support reading. |
| if (!(flags & blobs::OpenFlags::read) || (flags & blobs::OpenFlags::write)) |
| { |
| return false; |
| } |
| |
| std::ifstream ifs(tpmEventLogFilePath, std::ios::binary | std::ios::ate); |
| if (!ifs.is_open()) |
| { |
| return false; |
| } |
| |
| auto size = ifs.tellg(); |
| ifs.seekg(0, std::ios::beg); |
| |
| std::vector<uint8_t> buffer(size); |
| if (size > 0) |
| { |
| if (!ifs.read(reinterpret_cast<char *>(buffer.data()), size)) |
| { |
| return false; |
| } |
| } |
| |
| sessions[session] = {flags, std::move(buffer)}; |
| return true; |
| } |
| |
| std::vector<uint8_t> TpmEventLogBlobHandler::read(uint16_t session, |
| uint32_t offset, |
| uint32_t requestedSize) |
| { |
| auto it = sessions.find(session); |
| if (it == sessions.end()) |
| { |
| return {}; |
| } |
| |
| const auto &buffer = it->second.buffer; |
| if (offset >= buffer.size()) |
| { |
| return {}; |
| } |
| |
| uint32_t actualSize = std::min(requestedSize, |
| static_cast<uint32_t>(buffer.size() - offset)); |
| return std::vector<uint8_t>(buffer.begin() + offset, |
| buffer.begin() + offset + actualSize); |
| } |
| |
| bool TpmEventLogBlobHandler::write(uint16_t, uint32_t, |
| const std::vector<uint8_t> &) |
| { |
| return false; |
| } |
| |
| bool TpmEventLogBlobHandler::writeMeta(uint16_t, uint32_t, |
| const std::vector<uint8_t> &) |
| { |
| return false; |
| } |
| |
| bool TpmEventLogBlobHandler::commit(uint16_t, const std::vector<uint8_t> &) |
| { |
| // We don't support writing, so commit is a no-op that fails. |
| return false; |
| } |
| |
| bool TpmEventLogBlobHandler::close(uint16_t session) |
| { |
| return sessions.erase(session) > 0; |
| } |
| |
| bool TpmEventLogBlobHandler::stat(uint16_t session, blobs::BlobMeta *meta) |
| { |
| auto it = sessions.find(session); |
| if (it == sessions.end()) |
| { |
| return false; |
| } |
| |
| meta->size = it->second.buffer.size(); |
| meta->blobState = blobs::StateFlags::open_read; |
| return true; |
| } |
| |
| bool TpmEventLogBlobHandler::expire(uint16_t session) |
| { |
| return close(session); |
| } |
| |
| } // namespace ipmi_hoth |