// 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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& 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