diff options
Diffstat (limited to 'redfish-core/include')
-rw-r--r-- | redfish-core/include/utils/log_services_utils.hpp | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/redfish-core/include/utils/log_services_utils.hpp b/redfish-core/include/utils/log_services_utils.hpp new file mode 100644 index 0000000000..36bf27eb3c --- /dev/null +++ b/redfish-core/include/utils/log_services_utils.hpp @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright OpenBMC Authors +// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation + +#pragma once + +#include "app.hpp" +#include "async_resp.hpp" +#include "error_messages.hpp" +#include "http_body.hpp" +#include "http_response.hpp" +#include "logging.hpp" + +#include <asm-generic/errno.h> +#include <systemd/sd-bus.h> +#include <unistd.h> + +#include <boost/beast/http/field.hpp> +#include <boost/beast/http/status.hpp> +#include <boost/beast/http/verb.hpp> +#include <boost/system/linux_error.hpp> +#include <boost/url/format.hpp> +#include <boost/url/url.hpp> +#include <sdbusplus/message.hpp> +#include <sdbusplus/message/native_types.hpp> +#include <sdbusplus/unpack_properties.hpp> + +#include <cstdio> +#include <format> +#include <memory> +#include <string> + +namespace redfish +{ +namespace log_services_utils +{ + +inline bool checkSizeLimit(int fd, crow::Response& res) +{ + long long int size = lseek(fd, 0, SEEK_END); + if (size <= 0) + { + BMCWEB_LOG_ERROR("Failed to get size of file, lseek() returned {}", + size); + messages::internalError(res); + return false; + } + + // Arbitrary max size of 20MB to accommodate BMC dumps + constexpr long long int maxFileSize = 20LL * 1024LL * 1024LL; + if (size > maxFileSize) + { + BMCWEB_LOG_ERROR("File size {} exceeds maximum allowed size of {}", + size, maxFileSize); + messages::internalError(res); + return false; + } + off_t rc = lseek(fd, 0, SEEK_SET); + if (rc < 0) + { + BMCWEB_LOG_ERROR("Failed to reset file offset to 0"); + messages::internalError(res); + return false; + } + return true; +} + +inline void downloadEntryCallback( + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& entryID, const std::string& downloadEntryType, + const boost::system::error_code& ec, + const sdbusplus::message::unix_fd& unixfd) +{ + if (ec.value() == EBADR) + { + messages::resourceNotFound(asyncResp->res, "EntryAttachment", entryID); + return; + } + if (ec) + { + BMCWEB_LOG_ERROR("DBUS response error: {}", ec); + messages::internalError(asyncResp->res); + return; + } + + // Make sure we know how to process the retrieved entry attachment + if ((downloadEntryType != "BMC") && (downloadEntryType != "System")) + { + BMCWEB_LOG_ERROR("downloadEntryCallback() invalid entry type: {}", + downloadEntryType); + messages::internalError(asyncResp->res); + } + + int fd = -1; + fd = dup(unixfd); + if (fd < 0) + { + BMCWEB_LOG_ERROR("Failed to open file"); + messages::internalError(asyncResp->res); + return; + } + if (!checkSizeLimit(fd, asyncResp->res)) + { + close(fd); + return; + } + if (downloadEntryType == "System") + { + if (!asyncResp->res.openFd(fd, bmcweb::EncodingType::Base64)) + { + messages::internalError(asyncResp->res); + close(fd); + return; + } + asyncResp->res.addHeader( + boost::beast::http::field::content_transfer_encoding, "Base64"); + return; + } + if (!asyncResp->res.openFd(fd)) + { + messages::internalError(asyncResp->res); + close(fd); + return; + } + asyncResp->res.addHeader(boost::beast::http::field::content_type, + "application/octet-stream"); +} +} // namespace log_services_utils +} // namespace redfish |