EventDestination: Implement VerifyCertificate
VerifyCertificate is a property on the Redfish EventDestination schema.
It specifies that this property is:
``` An indication of whether the service will verify the certificate of
the server referenced by the `Destination` property prior to sending the
event ```
To keep prior behavior, and to ensure behavior that's secure by default,
if the user omits the property, it is assumed to be true. This property
is also persisted and restored.
Tested:
Redfish-Event-Listener succeeds with the following procedure
Start Redfish-Event-Listener
PATCH /redfish/v1/Subscriptions/<subid> VerifyCertificate: false
POST /redfish/v1/EventService/Actions/EventService.SubmitTestEvent
Redfish-Event-Listener then hits an internal error, due to an encoding
compatibility unrelated to this patch, but is documented in the receiver
[1]
POST of a subscription with VerifyCertificate: false set, succeeds.
[1] https://github.com/DMTF/Redfish-Event-Listener/blob/6f3f98beafc89fa9bbf86aa4f8cac6c1987390fb/RedfishEventListener_v1.py#L61
Change-Id: I27e0a3fe87b4dbd0432bfaa22ebf593c3955db11
Signed-off-by: Ravi Teja <raviteja28031990@gmail.com>
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/http/http_client.hpp b/http/http_client.hpp
index 107f943..62e7df6 100644
--- a/http/http_client.hpp
+++ b/http/http_client.hpp
@@ -134,8 +134,8 @@
std::string subId;
std::shared_ptr<ConnectionPolicy> connPolicy;
boost::urls::url host;
+ ensuressl::VerifyCertificate verifyCert;
uint32_t connId;
-
// Data buffers
http::request<bmcweb::HttpBody> req;
using parser_type = http::response_parser<bmcweb::HttpBody>;
@@ -608,7 +608,7 @@
if (ssl)
{
std::optional<boost::asio::ssl::context> sslCtx =
- ensuressl::getSSLClientContext();
+ ensuressl::getSSLClientContext(verifyCert);
if (!sslCtx)
{
@@ -633,10 +633,11 @@
explicit ConnectionInfo(
boost::asio::io_context& iocIn, const std::string& idIn,
const std::shared_ptr<ConnectionPolicy>& connPolicyIn,
- const boost::urls::url_view_base& hostIn, unsigned int connIdIn) :
+ const boost::urls::url_view_base& hostIn,
+ ensuressl::VerifyCertificate verifyCertIn, unsigned int connIdIn) :
subId(idIn),
- connPolicy(connPolicyIn), host(hostIn), connId(connIdIn), ioc(iocIn),
- resolver(iocIn), conn(iocIn), timer(iocIn)
+ connPolicy(connPolicyIn), host(hostIn), verifyCert(verifyCertIn),
+ connId(connIdIn), ioc(iocIn), resolver(iocIn), conn(iocIn), timer(iocIn)
{
initializeConnection(host.scheme() == "https");
}
@@ -651,6 +652,7 @@
boost::urls::url destIP;
std::vector<std::shared_ptr<ConnectionInfo>> connections;
boost::container::devector<PendingRequest> requestQueue;
+ ensuressl::VerifyCertificate verifyCert;
friend class HttpClient;
@@ -820,7 +822,7 @@
unsigned int newId = static_cast<unsigned int>(connections.size());
auto& ret = connections.emplace_back(std::make_shared<ConnectionInfo>(
- ioc, id, connPolicy, destIP, newId));
+ ioc, id, connPolicy, destIP, verifyCert, newId));
BMCWEB_LOG_DEBUG("Added connection {} to pool {}",
connections.size() - 1, id);
@@ -832,9 +834,11 @@
explicit ConnectionPool(
boost::asio::io_context& iocIn, const std::string& idIn,
const std::shared_ptr<ConnectionPolicy>& connPolicyIn,
- const boost::urls::url_view_base& destIPIn) :
+ const boost::urls::url_view_base& destIPIn,
+ ensuressl::VerifyCertificate verifyCertIn) :
ioc(iocIn),
- id(idIn), connPolicy(connPolicyIn), destIP(destIPIn)
+ id(idIn), connPolicy(connPolicyIn), destIP(destIPIn),
+ verifyCert(verifyCertIn)
{
BMCWEB_LOG_DEBUG("Initializing connection pool for {}", id);
@@ -876,28 +880,37 @@
// Send a request to destIP where additional processing of the
// result is not required
void sendData(std::string&& data, const boost::urls::url_view_base& destUri,
+ ensuressl::VerifyCertificate verifyCert,
const boost::beast::http::fields& httpHeader,
const boost::beast::http::verb verb)
{
const std::function<void(Response&)> cb = genericResHandler;
- sendDataWithCallback(std::move(data), destUri, httpHeader, verb, cb);
+ sendDataWithCallback(std::move(data), destUri, verifyCert, httpHeader,
+ verb, cb);
}
// Send request to destIP and use the provided callback to
// handle the response
void sendDataWithCallback(std::string&& data,
const boost::urls::url_view_base& destUrl,
+ ensuressl::VerifyCertificate verifyCert,
const boost::beast::http::fields& httpHeader,
const boost::beast::http::verb verb,
const std::function<void(Response&)>& resHandler)
{
- std::string clientKey = std::format("{}://{}", destUrl.scheme(),
+ std::string_view verify = "ssl_verify";
+ if (verifyCert == ensuressl::VerifyCertificate::NoVerify)
+ {
+ verify = "ssl no verify";
+ }
+ std::string clientKey = std::format("{}{}://{}", verify,
+ destUrl.scheme(),
destUrl.encoded_host_and_port());
auto pool = connectionPools.try_emplace(clientKey);
if (pool.first->second == nullptr)
{
pool.first->second = std::make_shared<ConnectionPool>(
- ioc, clientKey, connPolicy, destUrl);
+ ioc, clientKey, connPolicy, destUrl, verifyCert);
}
// Send the data using either the existing connection pool or the
// newly created connection pool