blob: da3ad9cbd884e73565865c8fe5582569c22613ca [file] [edit]
#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