summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/authentication.hpp15
-rw-r--r--include/file_test_utilities.hpp37
-rw-r--r--include/hostname_monitor.hpp11
-rw-r--r--include/ibm/management_console_rest.hpp5
-rw-r--r--include/openbmc_dbus_rest.hpp8
-rw-r--r--include/ossl_random.hpp20
-rw-r--r--include/sessions.hpp64
-rw-r--r--include/ssl_key_handler.hpp352
-rw-r--r--include/vm_websocket.hpp23
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();
});
}