diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/authentication.hpp | 15 | ||||
-rw-r--r-- | include/file_test_utilities.hpp | 37 | ||||
-rw-r--r-- | include/hostname_monitor.hpp | 11 | ||||
-rw-r--r-- | include/ibm/management_console_rest.hpp | 5 | ||||
-rw-r--r-- | include/openbmc_dbus_rest.hpp | 8 | ||||
-rw-r--r-- | include/ossl_random.hpp | 20 | ||||
-rw-r--r-- | include/sessions.hpp | 64 | ||||
-rw-r--r-- | include/ssl_key_handler.hpp | 352 | ||||
-rw-r--r-- | include/vm_websocket.hpp | 23 |
9 files changed, 330 insertions, 205 deletions
diff --git a/include/authentication.hpp b/include/authentication.hpp index 0617cf3729..215e464f76 100644 --- a/include/authentication.hpp +++ b/include/authentication.hpp @@ -216,11 +216,18 @@ inline std::shared_ptr<persistent_data::UserSession> // checks if request can be forwarded without authentication inline bool isOnAllowlist(std::string_view url, boost::beast::http::verb method) { + // Handle the case where the router registers routes as both ending with / + // and not. + if (url.ends_with('/')) + { + url.remove_suffix(1); + } if (boost::beast::http::verb::get == method) { - if (url == "/redfish/v1" || url == "/redfish/v1/" || - url == "/redfish" || url == "/redfish/" || - url == "/redfish/v1/odata" || url == "/redfish/v1/odata/") + if ((url == "/redfish") || // + (url == "/redfish/v1") || // + (url == "/redfish/v1/odata") || // + (url == "/redfish/v1/$metadata")) { return true; } @@ -236,9 +243,7 @@ inline bool isOnAllowlist(std::string_view url, boost::beast::http::verb method) if (boost::beast::http::verb::post == method) { if ((url == "/redfish/v1/SessionService/Sessions") || - (url == "/redfish/v1/SessionService/Sessions/") || (url == "/redfish/v1/SessionService/Sessions/Members") || - (url == "/redfish/v1/SessionService/Sessions/Members/") || (url == "/login")) { return true; diff --git a/include/file_test_utilities.hpp b/include/file_test_utilities.hpp new file mode 100644 index 0000000000..bd11a90d8d --- /dev/null +++ b/include/file_test_utilities.hpp @@ -0,0 +1,37 @@ +#pragma once +#include <filesystem> +#include <string> +#include <string_view> + +#include <gtest/gtest.h> + +struct TemporaryFileHandle +{ + std::filesystem::path path; + std::string stringPath; + + // Creates a temporary file with the contents provided, removes it on + // destruction. + explicit TemporaryFileHandle(std::string_view sampleData) : + path(std::filesystem::temp_directory_path() / + "bmcweb_http_response_test_XXXXXXXXXXX") + { + stringPath = path.string(); + + int fd = mkstemp(stringPath.data()); + EXPECT_GT(fd, 0); + EXPECT_EQ(write(fd, sampleData.data(), sampleData.size()), + sampleData.size()); + close(fd); + } + + TemporaryFileHandle(const TemporaryFileHandle&) = delete; + TemporaryFileHandle(TemporaryFileHandle&&) = delete; + TemporaryFileHandle& operator=(const TemporaryFileHandle&) = delete; + TemporaryFileHandle& operator=(TemporaryFileHandle&&) = delete; + + ~TemporaryFileHandle() + { + std::filesystem::remove(path); + } +}; diff --git a/include/hostname_monitor.hpp b/include/hostname_monitor.hpp index bb6998798a..a3a176ded6 100644 --- a/include/hostname_monitor.hpp +++ b/include/hostname_monitor.hpp @@ -121,8 +121,15 @@ inline int onPropertyUpdate(sd_bus_message* m, void* /* userdata */, "Ready to generate new HTTPs certificate with subject cn: {}", *hostname); - ensuressl::generateSslCertificate("/tmp/hostname_cert.tmp", - *hostname); + std::string certData = ensuressl::generateSslCertificate(*hostname); + if (certData.empty()) + { + BMCWEB_LOG_ERROR("Failed to generate cert"); + return 0; + } + ensuressl::writeCertificateToFile("/tmp/hostname_cert.tmp", + certData); + installCertificate("/tmp/hostname_cert.tmp"); } ASN1_STRING_free(asn1); diff --git a/include/ibm/management_console_rest.hpp b/include/ibm/management_console_rest.hpp index 51437c9ac0..c32412a68e 100644 --- a/include/ibm/management_console_rest.hpp +++ b/include/ibm/management_console_rest.hpp @@ -243,9 +243,8 @@ inline void asyncResp->res.jsonValue["Name"] = "ConfigFiles"; asyncResp->res.jsonValue["Members"] = std::move(pathObjList); - asyncResp->res.jsonValue["Actions"]["#IBMConfigFiles.DeleteAll"] = { - {"target", - "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll"}}; + asyncResp->res.jsonValue["Actions"]["#IBMConfigFiles.DeleteAll"]["target"] = + "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll"; } inline void diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp index 72e1c31c06..a2f68b4639 100644 --- a/include/openbmc_dbus_rest.hpp +++ b/include/openbmc_dbus_rest.hpp @@ -2332,10 +2332,10 @@ inline void const char* type = arg->Attribute("type"); if (name != nullptr && type != nullptr) { - argsArray.push_back({ - {"name", name}, - {"type", type}, - }); + nlohmann::json::object_t params; + params["name"] = name; + params["type"] = type; + argsArray.push_back(std::move(params)); } arg = arg->NextSiblingElement("arg"); } diff --git a/include/ossl_random.hpp b/include/ossl_random.hpp index 4d4bc04a06..0a92e37181 100644 --- a/include/ossl_random.hpp +++ b/include/ossl_random.hpp @@ -2,11 +2,6 @@ #include "logging.hpp" -extern "C" -{ -#include <openssl/rand.h> -} - #include <limits> #include <string> @@ -15,18 +10,7 @@ namespace bmcweb struct OpenSSLGenerator { - uint8_t operator()() - { - uint8_t index = 0; - int rc = RAND_bytes(&index, sizeof(index)); - if (rc != opensslSuccess) - { - BMCWEB_LOG_ERROR("Cannot get random number"); - err = true; - } - - return index; - } + uint8_t operator()(); static constexpr uint8_t max() { @@ -53,4 +37,6 @@ struct OpenSSLGenerator std::string getRandomUUID(); +std::string getRandomIdOfLength(size_t length); + } // namespace bmcweb diff --git a/include/sessions.hpp b/include/sessions.hpp index 50299b8f20..10e29c830f 100644 --- a/include/sessions.hpp +++ b/include/sessions.hpp @@ -11,6 +11,7 @@ #include <csignal> #include <optional> #include <random> +#include <string> namespace persistent_data { @@ -183,50 +184,17 @@ class SessionStore PersistenceType persistence = PersistenceType::TIMEOUT, bool isConfigureSelfOnly = false) { - // TODO(ed) find a secure way to not generate session identifiers if - // persistence is set to SINGLE_REQUEST - static constexpr std::array<char, 62> alphanum = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', - 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', - 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; - - std::string sessionToken; - sessionToken.resize(sessionTokenSize, '0'); - std::uniform_int_distribution<size_t> dist(0, alphanum.size() - 1); - - bmcweb::OpenSSLGenerator gen; - - for (char& sessionChar : sessionToken) - { - sessionChar = alphanum[dist(gen)]; - if (gen.error()) - { - return nullptr; - } - } // Only need csrf tokens for cookie based auth, token doesn't matter - std::string csrfToken; - csrfToken.resize(sessionTokenSize, '0'); - for (char& csrfChar : csrfToken) - { - csrfChar = alphanum[dist(gen)]; - if (gen.error()) - { - return nullptr; - } - } + std::string sessionToken = + bmcweb::getRandomIdOfLength(sessionTokenSize); + std::string csrfToken = bmcweb::getRandomIdOfLength(sessionTokenSize); + std::string uniqueId = bmcweb::getRandomIdOfLength(10); - std::string uniqueId; - uniqueId.resize(10, '0'); - for (char& uidChar : uniqueId) + // + if (sessionToken.empty() || csrfToken.empty() || uniqueId.empty()) { - uidChar = alphanum[dist(gen)]; - if (gen.error()) - { - return nullptr; - } + BMCWEB_LOG_ERROR("Failed to generate session tokens"); + return nullptr; } auto session = std::make_shared<UserSession>( @@ -316,6 +284,20 @@ class SessionStore }); } + void removeSessionsByUsernameExceptSession( + std::string_view username, const std::shared_ptr<UserSession>& session) + { + std::erase_if(authTokens, [username, session](const auto& value) { + if (value.second == nullptr) + { + return false; + } + + return value.second->username == username && + value.second->uniqueId != session->uniqueId; + }); + } + void updateAuthMethodsConfig(const AuthConfigMethods& config) { bool isTLSchanged = (authMethodsConfig.tls != config.tls); diff --git a/include/ssl_key_handler.hpp b/include/ssl_key_handler.hpp index 36477da02c..a8bcfa5b6d 100644 --- a/include/ssl_key_handler.hpp +++ b/include/ssl_key_handler.hpp @@ -5,6 +5,8 @@ #include "logging.hpp" #include "ossl_random.hpp" +#include <boost/beast/core/file_posix.hpp> + extern "C" { #include <nghttp2/nghttp2.h> @@ -20,7 +22,10 @@ extern "C" } #include <boost/asio/ssl/context.hpp> +#include <boost/system/error_code.hpp> +#include <filesystem> +#include <memory> #include <optional> #include <random> #include <string> @@ -101,25 +106,57 @@ inline bool validateCertificate(X509* const cert) return false; } -inline bool verifyOpensslKeyCert(const std::string& filepath) +inline std::string verifyOpensslKeyCert(const std::string& filepath) { bool privateKeyValid = false; - bool certValid = false; BMCWEB_LOG_INFO("Checking certs in file {}", filepath); + boost::beast::file_posix file; + boost::system::error_code ec; + file.open(filepath.c_str(), boost::beast::file_mode::read, ec); + if (ec) + { + return ""; + } + bool certValid = false; + std::string fileContents; + fileContents.resize(static_cast<size_t>(file.size(ec)), '\0'); + file.read(fileContents.data(), fileContents.size(), ec); + if (ec) + { + BMCWEB_LOG_ERROR("Failed to read file"); + return ""; + } - FILE* file = fopen(filepath.c_str(), "r"); - if (file != nullptr) + BIO* bufio = BIO_new_mem_buf(static_cast<void*>(fileContents.data()), + static_cast<int>(fileContents.size())); + EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bufio, nullptr, nullptr, nullptr); + BIO_free(bufio); + if (pkey != nullptr) { - EVP_PKEY* pkey = PEM_read_PrivateKey(file, nullptr, nullptr, nullptr); - if (pkey != nullptr) - { #if (OPENSSL_VERSION_NUMBER < 0x30000000L) - RSA* rsa = EVP_PKEY_get1_RSA(pkey); - if (rsa != nullptr) + RSA* rsa = EVP_PKEY_get1_RSA(pkey); + if (rsa != nullptr) + { + BMCWEB_LOG_INFO("Found an RSA key"); + if (RSA_check_key(rsa) == 1) { - BMCWEB_LOG_INFO("Found an RSA key"); - if (RSA_check_key(rsa) == 1) + privateKeyValid = true; + } + else + { + BMCWEB_LOG_ERROR("Key not valid error number {}", + ERR_get_error()); + } + RSA_free(rsa); + } + else + { + EC_KEY* ec = EVP_PKEY_get1_EC_KEY(pkey); + if (ec != nullptr) + { + BMCWEB_LOG_INFO("Found an EC key"); + if (EC_KEY_check_key(ec) == 1) { privateKeyValid = true; } @@ -128,75 +165,55 @@ inline bool verifyOpensslKeyCert(const std::string& filepath) BMCWEB_LOG_ERROR("Key not valid error number {}", ERR_get_error()); } - RSA_free(rsa); - } - else - { - EC_KEY* ec = EVP_PKEY_get1_EC_KEY(pkey); - if (ec != nullptr) - { - BMCWEB_LOG_INFO("Found an EC key"); - if (EC_KEY_check_key(ec) == 1) - { - privateKeyValid = true; - } - else - { - BMCWEB_LOG_ERROR("Key not valid error number {}", - ERR_get_error()); - } - EC_KEY_free(ec); - } + EC_KEY_free(ec); } + } #else - EVP_PKEY_CTX* pkeyCtx = EVP_PKEY_CTX_new_from_pkey(nullptr, pkey, - nullptr); + EVP_PKEY_CTX* pkeyCtx = EVP_PKEY_CTX_new_from_pkey(nullptr, pkey, + nullptr); - if (pkeyCtx == nullptr) - { - BMCWEB_LOG_ERROR("Unable to allocate pkeyCtx {}", - ERR_get_error()); - } - else if (EVP_PKEY_check(pkeyCtx) == 1) + if (pkeyCtx == nullptr) + { + BMCWEB_LOG_ERROR("Unable to allocate pkeyCtx {}", ERR_get_error()); + } + else if (EVP_PKEY_check(pkeyCtx) == 1) + { + privateKeyValid = true; + } + else + { + BMCWEB_LOG_ERROR("Key not valid error number {}", ERR_get_error()); + } +#endif + + if (privateKeyValid) + { + BIO* bufio2 = + BIO_new_mem_buf(static_cast<void*>(fileContents.data()), + static_cast<int>(fileContents.size())); + X509* x509 = PEM_read_bio_X509(bufio2, nullptr, nullptr, nullptr); + BIO_free(bufio2); + if (x509 == nullptr) { - privateKeyValid = true; + BMCWEB_LOG_ERROR("error getting x509 cert {}", ERR_get_error()); } else { - BMCWEB_LOG_ERROR("Key not valid error number {}", - ERR_get_error()); - } -#endif - - if (privateKeyValid) - { - // If the order is certificate followed by key in input file - // then, certificate read will fail. So, setting the file - // pointer to point beginning of file to avoid certificate and - // key order issue. - fseek(file, 0, SEEK_SET); - - X509* x509 = PEM_read_X509(file, nullptr, nullptr, nullptr); - if (x509 == nullptr) - { - BMCWEB_LOG_ERROR("error getting x509 cert {}", - ERR_get_error()); - } - else - { - certValid = validateCertificate(x509); - X509_free(x509); - } + certValid = validateCertificate(x509); + X509_free(x509); } + } #if (OPENSSL_VERSION_NUMBER > 0x30000000L) - EVP_PKEY_CTX_free(pkeyCtx); + EVP_PKEY_CTX_free(pkeyCtx); #endif - EVP_PKEY_free(pkey); - } - fclose(file); + EVP_PKEY_free(pkey); } - return certValid; + if (!certValid) + { + return ""; + } + return fileContents; } inline X509* loadCert(const std::string& filePath) @@ -249,13 +266,26 @@ inline int addExt(X509* cert, int nid, const char* value) return 0; } -inline void generateSslCertificate(const std::string& filepath, - const std::string& cn) +// Writes a certificate to a path, ignoring errors +inline void writeCertificateToFile(const std::string& filepath, + const std::string& certificate) +{ + boost::system::error_code ec; + boost::beast::file_posix file; + file.open(filepath.c_str(), boost::beast::file_mode::write, ec); + if (!ec) + { + file.write(certificate.data(), certificate.size(), ec); + // ignore result + } +} + +inline std::string generateSslCertificate(const std::string& cn) { - FILE* pFile = nullptr; BMCWEB_LOG_INFO("Generating new keys"); initOpenssl(); + std::string buffer; BMCWEB_LOG_INFO("Generating EC key"); EVP_PKEY* pPrivKey = createEcKey(); if (pPrivKey != nullptr) @@ -316,18 +346,33 @@ inline void generateSslCertificate(const std::string& filepath, // Sign the certificate with our private key X509_sign(x509, pPrivKey, EVP_sha256()); - pFile = fopen(filepath.c_str(), "wt"); + BIO* bufio = BIO_new(BIO_s_mem()); - if (pFile != nullptr) + int pkeyRet = PEM_write_bio_PrivateKey( + bufio, pPrivKey, nullptr, nullptr, 0, nullptr, nullptr); + if (pkeyRet <= 0) { - PEM_write_PrivateKey(pFile, pPrivKey, nullptr, nullptr, 0, - nullptr, nullptr); + BMCWEB_LOG_ERROR( + "Failed to write pkey with code {}. Ignoring.", pkeyRet); + } - PEM_write_X509(pFile, x509); - fclose(pFile); - pFile = nullptr; + char* data = nullptr; + long int dataLen = BIO_get_mem_data(bufio, &data); + buffer += std::string_view(data, static_cast<size_t>(dataLen)); + BIO_free(bufio); + + bufio = BIO_new(BIO_s_mem()); + pkeyRet = PEM_write_bio_X509(bufio, x509); + if (pkeyRet <= 0) + { + BMCWEB_LOG_ERROR( + "Failed to write X509 with code {}. Ignoring.", pkeyRet); } + dataLen = BIO_get_mem_data(bufio, &data); + buffer += std::string_view(data, static_cast<size_t>(dataLen)); + BIO_free(bufio); + BMCWEB_LOG_INFO("Cert size is {}", buffer.size()); X509_free(x509); } @@ -336,6 +381,7 @@ inline void generateSslCertificate(const std::string& filepath, } // cleanup_openssl(); + return buffer; } EVP_PKEY* createEcKey() @@ -415,17 +461,48 @@ void initOpenssl() #endif } -inline void ensureOpensslKeyPresentAndValid(const std::string& filepath) +inline std::string ensureOpensslKeyPresentAndValid(const std::string& filepath) { - bool pemFileValid = false; + std::string cert = verifyOpensslKeyCert(filepath); - pemFileValid = verifyOpensslKeyCert(filepath); - - if (!pemFileValid) + if (cert.empty()) { BMCWEB_LOG_WARNING("Error in verifying signature, regenerating"); - generateSslCertificate(filepath, "testhost"); + cert = generateSslCertificate("testhost"); + if (cert.empty()) + { + BMCWEB_LOG_ERROR("Failed to generate cert"); + } + else + { + writeCertificateToFile(filepath, cert); + } } + return cert; +} + +inline std::string ensureCertificate() +{ + namespace fs = std::filesystem; + // Cleanup older certificate file existing in the system + fs::path oldcertPath = fs::path("/home/root/server.pem"); + std::error_code ec; + fs::remove(oldcertPath, ec); + // Ignore failure to remove; File might not exist. + + fs::path certPath = "/etc/ssl/certs/https/"; + // if path does not exist create the path so that + // self signed certificate can be created in the + // path + fs::path certFile = certPath / "server.pem"; + + if (!fs::exists(certPath, ec)) + { + fs::create_directories(certPath, ec); + } + BMCWEB_LOG_INFO("Building SSL Context file= {}", certFile.string()); + std::string sslPemFile(certFile); + return ensuressl::ensureOpensslKeyPresentAndValid(sslPemFile); } inline int nextProtoCallback(SSL* /*unused*/, const unsigned char** data, @@ -458,41 +535,37 @@ inline int alpnSelectProtoCallback(SSL* /*unused*/, const unsigned char** out, return SSL_TLSEXT_ERR_OK; } -inline std::shared_ptr<boost::asio::ssl::context> - getSslContext(const std::string& sslPemFile) +inline bool getSslContext(boost::asio::ssl::context& mSslContext, + const std::string& sslPemFile) { - std::shared_ptr<boost::asio::ssl::context> mSslContext = - std::make_shared<boost::asio::ssl::context>( - boost::asio::ssl::context::tls_server); - mSslContext->set_options(boost::asio::ssl::context::default_workarounds | - boost::asio::ssl::context::no_sslv2 | - boost::asio::ssl::context::no_sslv3 | - boost::asio::ssl::context::single_dh_use | - boost::asio::ssl::context::no_tlsv1 | - boost::asio::ssl::context::no_tlsv1_1); - - // BIG WARNING: This needs to stay disabled, as there will always be - // unauthenticated endpoints - // mSslContext->set_verify_mode(boost::asio::ssl::verify_peer); - - SSL_CTX_set_options(mSslContext->native_handle(), SSL_OP_NO_RENEGOTIATION); + mSslContext.set_options(boost::asio::ssl::context::default_workarounds | + boost::asio::ssl::context::no_sslv2 | + boost::asio::ssl::context::no_sslv3 | + boost::asio::ssl::context::single_dh_use | + boost::asio::ssl::context::no_tlsv1 | + boost::asio::ssl::context::no_tlsv1_1); BMCWEB_LOG_DEBUG("Using default TrustStore location: {}", trustStorePath); - mSslContext->add_verify_path(trustStorePath); + mSslContext.add_verify_path(trustStorePath); - mSslContext->use_certificate_file(sslPemFile, - boost::asio::ssl::context::pem); - mSslContext->use_private_key_file(sslPemFile, - boost::asio::ssl::context::pem); - - if constexpr (BMCWEB_EXPERIMENTAL_HTTP2) + if (!sslPemFile.empty()) { - SSL_CTX_set_next_protos_advertised_cb(mSslContext->native_handle(), - nextProtoCallback, nullptr); + boost::system::error_code ec; - SSL_CTX_set_alpn_select_cb(mSslContext->native_handle(), - alpnSelectProtoCallback, nullptr); + boost::asio::const_buffer buf(sslPemFile.data(), sslPemFile.size()); + mSslContext.use_certificate(buf, boost::asio::ssl::context::pem, ec); + if (ec) + { + return false; + } + mSslContext.use_private_key(buf, boost::asio::ssl::context::pem, ec); + if (ec) + { + BMCWEB_LOG_CRITICAL("Failed to open ssl pkey"); + return false; + } } + // Set up EC curves to auto (boost asio doesn't have a method for this) // There is a pull request to add this. Once this is included in an asio // drop, use the right way @@ -512,36 +585,63 @@ inline std::shared_ptr<boost::asio::ssl::context> "DHE-RSA-AES256-GCM-SHA384:" "DHE-RSA-CHACHA20-POLY1305"; - if (SSL_CTX_set_cipher_list(mSslContext->native_handle(), + if (SSL_CTX_set_cipher_list(mSslContext.native_handle(), mozillaIntermediate) != 1) { BMCWEB_LOG_ERROR("Error setting cipher list"); + return false; } - return mSslContext; + return true; +} + +inline std::shared_ptr<boost::asio::ssl::context> getSslServerContext() +{ + boost::asio::ssl::context sslCtx(boost::asio::ssl::context::tls_server); + + auto certFile = ensureCertificate(); + if (!getSslContext(sslCtx, certFile)) + { + BMCWEB_LOG_CRITICAL("Couldn't get server context"); + return nullptr; + } + + // BIG WARNING: This needs to stay disabled, as there will always be + // unauthenticated endpoints + // mSslContext->set_verify_mode(boost::asio::ssl::verify_peer); + + SSL_CTX_set_options(sslCtx.native_handle(), SSL_OP_NO_RENEGOTIATION); + + if constexpr (BMCWEB_EXPERIMENTAL_HTTP2) + { + SSL_CTX_set_next_protos_advertised_cb(sslCtx.native_handle(), + nextProtoCallback, nullptr); + + SSL_CTX_set_alpn_select_cb(sslCtx.native_handle(), + alpnSelectProtoCallback, nullptr); + } + + return std::make_shared<boost::asio::ssl::context>(std::move(sslCtx)); } inline std::optional<boost::asio::ssl::context> getSSLClientContext() { + namespace fs = std::filesystem; + boost::asio::ssl::context sslCtx(boost::asio::ssl::context::tls_client); - boost::system::error_code ec; + // NOTE, this path is temporary; In the future it will need to change to + // be set per subscription. Do not rely on this. + fs::path certPath = "/etc/ssl/certs/https/client.pem"; + std::string cert = verifyOpensslKeyCert(certPath); - // Support only TLS v1.2 & v1.3 - sslCtx.set_options(boost::asio::ssl::context::default_workarounds | - boost::asio::ssl::context::no_sslv2 | - boost::asio::ssl::context::no_sslv3 | - boost::asio::ssl::context::single_dh_use | - boost::asio::ssl::context::no_tlsv1 | - boost::asio::ssl::context::no_tlsv1_1, - ec); - if (ec) + if (!getSslContext(sslCtx, cert)) { - BMCWEB_LOG_ERROR("SSL context set_options failed"); return std::nullopt; } // Add a directory containing certificate authority files to be used // for performing verification. + boost::system::error_code ec; sslCtx.set_default_verify_paths(ec); if (ec) { @@ -577,7 +677,7 @@ inline std::optional<boost::asio::ssl::context> getSSLClientContext() return std::nullopt; } - return sslCtx; + return {std::move(sslCtx)}; } } // namespace ensuressl diff --git a/include/vm_websocket.hpp b/include/vm_websocket.hpp index 7e55e4ec8c..284b5d2e1c 100644 --- a/include/vm_websocket.hpp +++ b/include/vm_websocket.hpp @@ -421,6 +421,7 @@ inline void { if (ec) { + BMCWEB_LOG_ERROR("DBus getAllProperties error: {}", ec.message()); conn.close("Internal Error"); return; } @@ -433,6 +434,7 @@ inline void if (!success) { + BMCWEB_LOG_ERROR("Failed to unpack properties"); conn.close("Internal Error"); return; } @@ -462,14 +464,20 @@ inline void onOpen(crow::websocket::Connection& conn) { BMCWEB_LOG_DEBUG("nbd-proxy.onopen({})", logPtr(&conn)); - sdbusplus::message::object_path path( - "/xyz/openbmc_project/VirtualMedia/nbd"); + if (conn.url().segments().size() < 2) + { + BMCWEB_LOG_ERROR("Invalid path - \"{}\"", conn.url().path()); + conn.close("Internal error"); + return; + } - path /= std::to_string(0); + std::string index = conn.url().segments().back(); + std::string path = + std::format("/xyz/openbmc_project/VirtualMedia/Proxy/Slot_{}", index); sdbusplus::asio::getAllProperties( *crow::connections::systemBus, "xyz.openbmc_project.VirtualMedia", path, - "xyz.openbmc_project.VirtualMedia", + "xyz.openbmc_project.VirtualMedia.MountPoint", [&conn, path](const boost::system::error_code& ec, const dbus::utility::DBusPropertiesMap& propertiesList) { afterGetSocket(conn, path, ec, propertiesList); @@ -590,9 +598,10 @@ inline void requestRoutes(App& app) return; } - boost::asio::buffer_copy(handler->inputBuffer->prepare(data.size()), - boost::asio::buffer(data)); - handler->inputBuffer->commit(data.size()); + size_t copied = boost::asio::buffer_copy( + handler->inputBuffer->prepare(data.size()), + boost::asio::buffer(data)); + handler->inputBuffer->commit(copied); handler->doWrite(); }); } |