Add SSL support for http_client (EventService)
This commit adds the initial SSL support for http_client which can be
used for sending asynchronous Events/MetricReports to subscribed Event
Listener servers over secure channel.
Current implementation of http client only works for http protocol.
With current implementation, http client can be configured to work
with secure http (HTTPS). As part of implementation it adds the SSL
handshake mechanism and enforces the peer ceritificate verification.
The http-client uses the cipher suites which are supported by mozilla
browser and as recommended by OWASP. For better security enforcement
its disables the SSLv2, SSLv3, TLSv1, TLSv1.1 as described in below
OWASP cheetsheet.
It is validated with RootCA certificate(PEM) for now. Adding support
for different certificates can be looked in future as need arises.
[1]: https://cheatsheetseries.owasp.org/cheatsheets/TLS_Cipher_String_Cheat_Sheet.html
Tested:
- Created new subscription with SSL destination(https) and confirmed
that events are seen on EventListener side.
URI: /redfish/v1/EventService/Subscriptions
Method: POST
Body:
{
"Context": "CustomText",
"Destination": "https://<IP>:4000/service/collector/event_logs",
"EventFormatType": "Event",
"DeliveryRetryPolicy": "RetryForever",
"Protocol": "Redfish"
}
- Unit tested the non-SSL connection by disabling the check in code
(Note: EventService blocks all Non-SSL destinations). Verified that
all events are properly shown on EventListener.
URI: /redfish/v1/EventService/Subscriptions
Method: POST
Body:
{
"Context": "CustomText",
"Destination": "http://<IP>:4001/service/collector/event_logs",
"EventFormatType": "Event",
"Protocol": "Redfish"
}
- Combined above two tests and verified both SSL & Non-SSL work fine in
congention.
- Created subscription with different URI paths on same IP, Port and
protocol and verified that events sent as expected.
Change-Id: I13b2fc942c9ce6c55cd7348aae1e088a3f3d7fd9
Signed-off-by: AppaRao Puli <apparao.puli@intel.com>
Signed-off-by: Ed Tanous <edtanous@google.com>
diff --git a/http/http_client.hpp b/http/http_client.hpp
index 491030c..d34fb2e 100644
--- a/http/http_client.hpp
+++ b/http/http_client.hpp
@@ -18,6 +18,8 @@
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/basic_endpoint.hpp>
#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ssl/context.hpp>
+#include <boost/asio/ssl/error.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/beast/core/flat_buffer.hpp>
#include <boost/beast/core/flat_static_buffer.hpp>
@@ -27,12 +29,14 @@
#include <boost/beast/http/read.hpp>
#include <boost/beast/http/string_body.hpp>
#include <boost/beast/http/write.hpp>
+#include <boost/beast/ssl/ssl_stream.hpp>
#include <boost/beast/version.hpp>
#include <boost/container/devector.hpp>
#include <boost/system/error_code.hpp>
#include <http/http_response.hpp>
#include <include/async_resolve.hpp>
#include <logging.hpp>
+#include <ssl_key_handler.hpp>
#include <cstdlib>
#include <functional>
@@ -58,6 +62,8 @@
connectInProgress,
connectFailed,
connected,
+ handshakeInProgress,
+ handshakeFailed,
sendInProgress,
sendFailed,
recvInProgress,
@@ -67,6 +73,7 @@
suspended,
terminated,
abortConnection,
+ sslInitFailed,
retry
};
@@ -137,6 +144,8 @@
std::function<void(bool, uint32_t, Response&)> callback;
crow::async_resolve::Resolver resolver;
boost::beast::tcp_stream conn;
+ std::optional<boost::beast::ssl_stream<boost::beast::tcp_stream&>> sslConn;
+
boost::asio::steady_timer timer;
friend class ConnectionPool;
@@ -180,26 +189,66 @@
conn.expires_after(std::chrono::seconds(30));
conn.async_connect(endpointList,
- [self(shared_from_this())](
- const boost::beast::error_code ec,
- const boost::asio::ip::tcp::endpoint& endpoint) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "Connect " << endpoint.address().to_string()
- << ":" << std::to_string(endpoint.port())
- << ", id: " << std::to_string(self->connId)
- << " failed: " << ec.message();
- self->state = ConnState::connectFailed;
- self->waitAndRetry();
- return;
- }
- BMCWEB_LOG_DEBUG
- << "Connected to: " << endpoint.address().to_string() << ":"
- << std::to_string(endpoint.port())
- << ", id: " << std::to_string(self->connId);
- self->state = ConnState::connected;
- self->sendMessage();
- });
+ std::bind_front(&ConnectionInfo::afterConnect, this,
+ shared_from_this()));
+ }
+
+ void afterConnect(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ boost::beast::error_code ec,
+ const boost::asio::ip::tcp::endpoint& endpoint)
+ {
+
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "Connect " << endpoint.address().to_string()
+ << ":" << std::to_string(endpoint.port())
+ << ", id: " << std::to_string(connId)
+ << " failed: " << ec.message();
+ state = ConnState::connectFailed;
+ waitAndRetry();
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "Connected to: " << endpoint.address().to_string()
+ << ":" << std::to_string(endpoint.port())
+ << ", id: " << std::to_string(connId);
+ if (sslConn)
+ {
+ doSSLHandshake();
+ return;
+ }
+ state = ConnState::connected;
+ sendMessage();
+ }
+
+ void doSSLHandshake()
+ {
+ if (!sslConn)
+ {
+ return;
+ }
+ state = ConnState::handshakeInProgress;
+ sslConn->async_handshake(
+ boost::asio::ssl::stream_base::client,
+ std::bind_front(&ConnectionInfo::afterSslHandshake, this,
+ shared_from_this()));
+ }
+
+ void afterSslHandshake(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ boost::beast::error_code ec)
+ {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "SSL Handshake failed -"
+ << " id: " << std::to_string(connId)
+ << " error: " << ec.message();
+ state = ConnState::handshakeFailed;
+ waitAndRetry();
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "SSL Handshake successful -"
+ << " id: " << std::to_string(connId);
+ state = ConnState::connected;
+ sendMessage();
}
void sendMessage()
@@ -210,23 +259,36 @@
conn.expires_after(std::chrono::seconds(30));
// Send the HTTP request to the remote host
- boost::beast::http::async_write(
- conn, req,
- [self(shared_from_this())](const boost::beast::error_code& ec,
- const std::size_t& bytesTransferred) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "sendMessage() failed: " << ec.message();
- self->state = ConnState::sendFailed;
- self->waitAndRetry();
- return;
- }
- BMCWEB_LOG_DEBUG << "sendMessage() bytes transferred: "
- << bytesTransferred;
- boost::ignore_unused(bytesTransferred);
+ if (sslConn)
+ {
+ boost::beast::http::async_write(
+ *sslConn, req,
+ std::bind_front(&ConnectionInfo::afterWrite, this,
+ shared_from_this()));
+ }
+ else
+ {
+ boost::beast::http::async_write(
+ conn, req,
+ std::bind_front(&ConnectionInfo::afterWrite, this,
+ shared_from_this()));
+ }
+ }
- self->recvMessage();
- });
+ void afterWrite(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ const boost::beast::error_code& ec, size_t bytesTransferred)
+ {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "sendMessage() failed: " << ec.message();
+ state = ConnState::sendFailed;
+ waitAndRetry();
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "sendMessage() bytes transferred: "
+ << bytesTransferred;
+
+ recvMessage();
}
void recvMessage()
@@ -237,59 +299,73 @@
parser->body_limit(httpReadBodyLimit);
// Receive the HTTP response
- boost::beast::http::async_read(
- conn, buffer, *parser,
- [self(shared_from_this())](const boost::beast::error_code& ec,
- const std::size_t& bytesTransferred) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "recvMessage() failed: " << ec.message();
- self->state = ConnState::recvFailed;
- self->waitAndRetry();
- return;
- }
- BMCWEB_LOG_DEBUG << "recvMessage() bytes transferred: "
- << bytesTransferred;
- BMCWEB_LOG_DEBUG << "recvMessage() data: "
- << self->parser->get().body();
+ if (sslConn)
+ {
+ boost::beast::http::async_read(
+ *sslConn, buffer, *parser,
+ std::bind_front(&ConnectionInfo::afterRead, this,
+ shared_from_this()));
+ }
+ else
+ {
+ boost::beast::http::async_read(
+ conn, buffer, *parser,
+ std::bind_front(&ConnectionInfo::afterRead, this,
+ shared_from_this()));
+ }
+ }
- unsigned int respCode = self->parser->get().result_int();
- BMCWEB_LOG_DEBUG << "recvMessage() Header Response Code: "
+ void afterRead(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ const boost::beast::error_code& ec,
+ const std::size_t& bytesTransferred)
+ {
+ if (ec && ec != boost::asio::ssl::error::stream_truncated)
+ {
+ BMCWEB_LOG_ERROR << "recvMessage() failed: " << ec.message();
+ state = ConnState::recvFailed;
+ waitAndRetry();
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "recvMessage() bytes transferred: "
+ << bytesTransferred;
+ BMCWEB_LOG_DEBUG << "recvMessage() data: " << parser->get().body();
+
+ unsigned int respCode = parser->get().result_int();
+ BMCWEB_LOG_DEBUG << "recvMessage() Header Response Code: " << respCode;
+
+ // Make sure the received response code is valid as defined by
+ // the associated retry policy
+ if (retryPolicy.invalidResp(respCode))
+ {
+ // The listener failed to receive the Sent-Event
+ BMCWEB_LOG_ERROR << "recvMessage() Listener Failed to "
+ "receive Sent-Event. Header Response Code: "
<< respCode;
+ state = ConnState::recvFailed;
+ waitAndRetry();
+ return;
+ }
- // Make sure the received response code is valid as defined by
- // the associated retry policy
- if (self->retryPolicy.invalidResp(respCode))
- {
- // The listener failed to receive the Sent-Event
- BMCWEB_LOG_ERROR << "recvMessage() Listener Failed to "
- "receive Sent-Event. Header Response Code: "
- << respCode;
- self->state = ConnState::recvFailed;
- self->waitAndRetry();
- return;
- }
+ // Send is successful
+ // Reset the counter just in case this was after retrying
+ retryCount = 0;
- // Send is successful
- // Reset the counter just in case this was after retrying
- self->retryCount = 0;
+ // Keep the connection alive if server supports it
+ // Else close the connection
+ BMCWEB_LOG_DEBUG << "recvMessage() keepalive : "
+ << parser->keep_alive();
- // Keep the connection alive if server supports it
- // Else close the connection
- BMCWEB_LOG_DEBUG << "recvMessage() keepalive : "
- << self->parser->keep_alive();
-
- // Copy the response into a Response object so that it can be
- // processed by the callback function.
- self->res.clear();
- self->res.stringResponse = self->parser->release();
- self->callback(self->parser->keep_alive(), self->connId, self->res);
- });
+ // Copy the response into a Response object so that it can be
+ // processed by the callback function.
+ res.clear();
+ res.stringResponse = parser->release();
+ callback(parser->keep_alive(), connId, res);
}
void waitAndRetry()
{
- if (retryCount >= retryPolicy.maxRetryAttempts)
+ if ((retryCount >= retryPolicy.maxRetryAttempts) ||
+ (state == ConnState::sslInitFailed))
{
BMCWEB_LOG_ERROR << "Maximum number of retries reached.";
BMCWEB_LOG_DEBUG << "Retry policy: "
@@ -348,11 +424,11 @@
self->runningTimer = false;
// Let's close the connection and restart from resolve.
- self->doCloseAndRetry();
+ self->doClose(true);
});
}
- void doClose()
+ void shutdownConn(bool retry)
{
boost::beast::error_code ec;
conn.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
@@ -372,21 +448,43 @@
<< " closed gracefully";
}
- state = ConnState::closed;
+ if ((state != ConnState::suspended) && (state != ConnState::terminated))
+ {
+ if (retry)
+ {
+ // Now let's try to resend the data
+ state = ConnState::retry;
+ this->doResolve();
+ }
+ else
+ {
+ state = ConnState::closed;
+ }
+ }
}
- void doCloseAndRetry()
+ void doClose(bool retry = false)
{
- boost::beast::error_code ec;
- conn.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
- conn.close();
+ if (!sslConn)
+ {
+ shutdownConn(retry);
+ return;
+ }
- // not_connected happens sometimes so don't bother reporting it.
- if (ec && ec != boost::beast::errc::not_connected)
+ sslConn->async_shutdown(
+ std::bind_front(&ConnectionInfo::afterSslShutdown, this,
+ shared_from_this(), retry));
+ }
+
+ void afterSslShutdown(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ bool retry, const boost::system::error_code& ec)
+ {
+
+ if (ec)
{
BMCWEB_LOG_ERROR << host << ":" << std::to_string(port)
<< ", id: " << std::to_string(connId)
- << "shutdown failed: " << ec.message();
+ << " shutdown failed: " << ec.message();
}
else
{
@@ -394,29 +492,82 @@
<< ", id: " << std::to_string(connId)
<< " closed gracefully";
}
+ shutdownConn(retry);
+ }
- // Now let's try to resend the data
- state = ConnState::retry;
- doResolve();
+ void setCipherSuiteTLSext()
+ {
+ if (!sslConn)
+ {
+ return;
+ }
+ // NOTE: The SSL_set_tlsext_host_name is defined in tlsv1.h header
+ // file but its having old style casting (name is cast to void*).
+ // Since bmcweb compiler treats all old-style-cast as error, its
+ // causing the build failure. So replaced the same macro inline and
+ // did corrected the code by doing static_cast to viod*. This has to
+ // be fixed in openssl library in long run. Set SNI Hostname (many
+ // hosts need this to handshake successfully)
+ if (SSL_ctrl(sslConn->native_handle(), SSL_CTRL_SET_TLSEXT_HOSTNAME,
+ TLSEXT_NAMETYPE_host_name,
+ static_cast<void*>(&host.front())) == 0)
+
+ {
+ boost::beast::error_code ec{static_cast<int>(::ERR_get_error()),
+ boost::asio::error::get_ssl_category()};
+
+ BMCWEB_LOG_ERROR << "SSL_set_tlsext_host_name " << host << ":"
+ << port << ", id: " << std::to_string(connId)
+ << " failed: " << ec.message();
+ // Set state as sslInit failed so that we close the connection
+ // and take appropriate action as per retry configuration.
+ state = ConnState::sslInitFailed;
+ waitAndRetry();
+ return;
+ }
}
public:
- explicit ConnectionInfo(boost::asio::io_context& ioc,
- const std::string& idIn, const std::string& destIP,
- const uint16_t destPort,
- const unsigned int connIdIn) :
+ explicit ConnectionInfo(boost::asio::io_context& iocIn,
+ const std::string& idIn,
+ const std::string& destIPIn, uint16_t destPortIn,
+ bool useSSL, unsigned int connIdIn) :
subId(idIn),
- host(destIP), port(destPort), connId(connIdIn), conn(ioc), timer(ioc)
- {}
+ host(destIPIn), port(destPortIn), connId(connIdIn), conn(iocIn),
+ timer(iocIn)
+ {
+ if (useSSL)
+ {
+ std::optional<boost::asio::ssl::context> sslCtx =
+ ensuressl::getSSLClientContext();
+
+ if (!sslCtx)
+ {
+ BMCWEB_LOG_ERROR << "prepareSSLContext failed - " << host << ":"
+ << port << ", id: " << std::to_string(connId);
+ // Don't retry if failure occurs while preparing SSL context
+ // such as certificate is invalid or set cipher failure or set
+ // host name failure etc... Setting conn state to sslInitFailed
+ // and connection state will be transitioned to next state
+ // depending on retry policy set by subscription.
+ state = ConnState::sslInitFailed;
+ waitAndRetry();
+ return;
+ }
+ sslConn.emplace(conn, *sslCtx);
+ setCipherSuiteTLSext();
+ }
+ }
};
class ConnectionPool : public std::enable_shared_from_this<ConnectionPool>
{
private:
boost::asio::io_context& ioc;
- const std::string id;
- const std::string destIP;
- const uint16_t destPort;
+ std::string id;
+ std::string destIP;
+ uint16_t destPort;
+ bool useSSL;
std::vector<std::shared_ptr<ConnectionInfo>> connections;
boost::container::devector<PendingRequest> requestQueue;
@@ -600,8 +751,8 @@
{
unsigned int newId = static_cast<unsigned int>(connections.size());
- auto& ret = connections.emplace_back(
- std::make_shared<ConnectionInfo>(ioc, id, destIP, destPort, newId));
+ auto& ret = connections.emplace_back(std::make_shared<ConnectionInfo>(
+ ioc, id, destIP, destPort, useSSL, newId));
BMCWEB_LOG_DEBUG << "Added connection "
<< std::to_string(connections.size() - 1)
@@ -614,10 +765,10 @@
public:
explicit ConnectionPool(boost::asio::io_context& iocIn,
const std::string& idIn,
- const std::string& destIPIn,
- const uint16_t destPortIn) :
+ const std::string& destIPIn, uint16_t destPortIn,
+ bool useSSLIn) :
ioc(iocIn),
- id(idIn), destIP(destIPIn), destPort(destPortIn)
+ id(idIn), destIP(destIPIn), destPort(destPortIn), useSSL(useSSLIn)
{
BMCWEB_LOG_DEBUG << "Initializing connection pool for " << destIP << ":"
<< std::to_string(destPort);
@@ -661,37 +812,39 @@
// Send a request to destIP:destPort where additional processing of the
// result is not required
void sendData(std::string& data, const std::string& id,
- const std::string& destIP, const uint16_t destPort,
- const std::string& destUri,
+ const std::string& destIP, uint16_t destPort,
+ const std::string& destUri, bool useSSL,
const boost::beast::http::fields& httpHeader,
const boost::beast::http::verb verb,
const std::string& retryPolicyName)
{
- const std::function<void(const Response&)> cb = genericResHandler;
- sendDataWithCallback(data, id, destIP, destPort, destUri, httpHeader,
- verb, retryPolicyName, cb);
+ const std::function<void(Response&)> cb = genericResHandler;
+ sendDataWithCallback(data, id, destIP, destPort, destUri, useSSL,
+ httpHeader, verb, retryPolicyName, cb);
}
// Send request to destIP:destPort and use the provided callback to
// handle the response
void sendDataWithCallback(std::string& data, const std::string& id,
- const std::string& destIP,
- const uint16_t destPort,
- const std::string& destUri,
+ const std::string& destIP, uint16_t destPort,
+ const std::string& destUri, bool useSSL,
const boost::beast::http::fields& httpHeader,
const boost::beast::http::verb verb,
const std::string& retryPolicyName,
const std::function<void(Response&)>& resHandler)
{
- std::string clientKey = destIP + ":" + std::to_string(destPort);
+ std::string clientKey = useSSL ? "https" : "http";
+ clientKey += destIP;
+ clientKey += ":";
+ clientKey += std::to_string(destPort);
// Use nullptr to avoid creating a ConnectionPool each time
- auto result = connectionPools.try_emplace(clientKey, nullptr);
- if (result.second)
+ std::shared_ptr<ConnectionPool>& conn = connectionPools[clientKey];
+ if (conn == nullptr)
{
// Now actually create the ConnectionPool shared_ptr since it does
// not already exist
- result.first->second =
- std::make_shared<ConnectionPool>(ioc, id, destIP, destPort);
+ conn = std::make_shared<ConnectionPool>(ioc, id, destIP, destPort,
+ useSSL);
BMCWEB_LOG_DEBUG << "Created connection pool for " << clientKey;
}
else
@@ -710,8 +863,8 @@
// Send the data using either the existing connection pool or the newly
// created connection pool
- result.first->second->sendData(data, destUri, httpHeader, verb,
- policy.first->second, resHandler);
+ conn->sendData(data, destUri, httpHeader, verb, policy.first->second,
+ resHandler);
}
void setRetryConfig(
diff --git a/include/ssl_key_handler.hpp b/include/ssl_key_handler.hpp
index 431dd84..c6ceb83 100644
--- a/include/ssl_key_handler.hpp
+++ b/include/ssl_key_handler.hpp
@@ -474,4 +474,65 @@
}
return mSslContext;
}
+
+inline std::optional<boost::asio::ssl::context> getSSLClientContext()
+{
+ boost::asio::ssl::context sslCtx(boost::asio::ssl::context::tls_client);
+
+ boost::system::error_code ec;
+
+ // 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)
+ {
+ BMCWEB_LOG_ERROR << "SSL context set_options failed";
+ return std::nullopt;
+ }
+
+ // Add a directory containing certificate authority files to be used
+ // for performing verification.
+ sslCtx.set_default_verify_paths(ec);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "SSL context set_default_verify failed";
+ return std::nullopt;
+ }
+
+ // Verify the remote server's certificate
+ sslCtx.set_verify_mode(boost::asio::ssl::verify_peer, ec);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "SSL context set_verify_mode failed";
+ return std::nullopt;
+ }
+
+ // All cipher suites are set as per OWASP datasheet.
+ // https://cheatsheetseries.owasp.org/cheatsheets/TLS_Cipher_String_Cheat_Sheet.html
+ constexpr const char* sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES128-GCM-SHA256:"
+ "ECDHE-ECDSA-AES256-GCM-SHA384:"
+ "ECDHE-RSA-AES256-GCM-SHA384:"
+ "ECDHE-ECDSA-CHACHA20-POLY1305:"
+ "ECDHE-RSA-CHACHA20-POLY1305:"
+ "DHE-RSA-AES128-GCM-SHA256:"
+ "DHE-RSA-AES256-GCM-SHA384"
+ "TLS_AES_128_GCM_SHA256:"
+ "TLS_AES_256_GCM_SHA384:"
+ "TLS_CHACHA20_POLY1305_SHA256";
+
+ if (SSL_CTX_set_cipher_list(sslCtx.native_handle(), sslCiphers) != 1)
+ {
+ BMCWEB_LOG_ERROR << "SSL_CTX_set_cipher_list failed";
+ return std::nullopt;
+ }
+
+ return sslCtx;
+}
+
} // namespace ensuressl
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 3add4f1..dadeb22 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -396,9 +396,10 @@
return false;
}
+ bool useSSL = (uriProto == "https");
// A connection pool will be created if one does not already exist
crow::HttpClient::getInstance().sendData(
- msg, id, host, port, path, httpHeaders,
+ msg, id, host, port, path, useSSL, httpHeaders,
boost::beast::http::verb::post, retryPolicyName);
eventSeqNum++;
diff --git a/redfish-core/include/redfish_aggregator.hpp b/redfish-core/include/redfish_aggregator.hpp
index 24b42d9..622bb5b 100644
--- a/redfish-core/include/redfish_aggregator.hpp
+++ b/redfish-core/include/redfish_aggregator.hpp
@@ -490,8 +490,8 @@
std::string data = thisReq.req.body();
crow::HttpClient::getInstance().sendDataWithCallback(
data, id, std::string(sat->second.host()),
- sat->second.port_number(), targetURI, thisReq.fields,
- thisReq.method(), retryPolicyName, cb);
+ sat->second.port_number(), targetURI, false /*useSSL*/,
+ thisReq.fields, thisReq.method(), retryPolicyName, cb);
}
// Forward a request for a collection URI to each known satellite BMC
@@ -509,8 +509,8 @@
std::string data = thisReq.req.body();
crow::HttpClient::getInstance().sendDataWithCallback(
data, id, std::string(sat.second.host()),
- sat.second.port_number(), targetURI, thisReq.fields,
- thisReq.method(), retryPolicyName, cb);
+ sat.second.port_number(), targetURI, false /*useSSL*/,
+ thisReq.fields, thisReq.method(), retryPolicyName, cb);
}
}