certificate: Replace lambda with inline function
For API endpoints, it is suggested to break out the entire handlers
into a function, and not rely on a lambda at all. This brings more
readability as it reduces indents.
Tested:
Code compiles, and Redfish Service Validator passed.
Change-Id: I5132149c00b6f553931dae562b83bc7aee678105
Signed-off-by: Jiaqing Zhao <jiaqing.zhao@intel.com>
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index ed42b89..796df8d 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -190,14 +190,8 @@
requestRoutesMessageRegistry(app);
requestRoutesCertificateService(app);
- requestRoutesCertificateActionGenerateCSR(app);
- requestRoutesCertificateActionsReplaceCertificate(app);
requestRoutesHTTPSCertificate(app);
- requestRoutesHTTPSCertificateCollection(app);
- requestRoutesCertificateLocations(app);
- requestRoutesLDAPCertificateCollection(app);
requestRoutesLDAPCertificate(app);
- requestRoutesTrustStoreCertificateCollection(app);
requestRoutesTrustStoreCertificate(app);
requestRoutesSystemPCIeFunctionCollection(app);
diff --git a/redfish-core/lib/certificate_service.hpp b/redfish-core/lib/certificate_service.hpp
index d3aedd0..8701f59 100644
--- a/redfish-core/lib/certificate_service.hpp
+++ b/redfish-core/lib/certificate_service.hpp
@@ -47,50 +47,6 @@
// "redfish standard registries". Need to modify after DMTF
// publish Privilege details for certificate service
-inline void requestRoutesCertificateService(App& app)
-{
- BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/")
- .privileges(redfish::privileges::getCertificateService)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- asyncResp->res.jsonValue["@odata.type"] =
- "#CertificateService.v1_0_0.CertificateService";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/CertificateService";
- asyncResp->res.jsonValue["Id"] = "CertificateService";
- asyncResp->res.jsonValue["Name"] = "Certificate Service";
- asyncResp->res.jsonValue["Description"] =
- "Actions available to manage certificates";
- // /redfish/v1/CertificateService/CertificateLocations is something
- // only ConfigureManager can access then only display when the user
- // has permissions ConfigureManager
- Privileges effectiveUserPrivileges =
- redfish::getUserPrivileges(req.userRole);
- if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
- effectiveUserPrivileges))
- {
- asyncResp->res.jsonValue["CertificateLocations"]["@odata.id"] =
- "/redfish/v1/CertificateService/CertificateLocations";
- }
- nlohmann::json& actions = asyncResp->res.jsonValue["Actions"];
- nlohmann::json& replace =
- actions["#CertificateService.ReplaceCertificate"];
- replace["target"] =
- "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate";
- nlohmann::json::array_t allowed;
- allowed.push_back("PEM");
- replace["CertificateType@Redfish.AllowableValues"] = std::move(allowed);
- actions["#CertificateService.GenerateCSR"]["target"] =
- "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR";
- });
-} // requestRoutesCertificateService
-
inline std::string getCertificateFromReqBody(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const crow::Request& req)
@@ -180,293 +136,6 @@
std::filesystem::path certDirectory;
};
-static std::unique_ptr<sdbusplus::bus::match_t> csrMatcher;
-/**
- * @brief Read data from CSR D-bus object and set to response
- *
- * @param[in] asyncResp Shared pointer to the response message
- * @param[in] certURI Link to certifiate collection URI
- * @param[in] service D-Bus service name
- * @param[in] certObjPath certificate D-Bus object path
- * @param[in] csrObjPath CSR D-Bus object path
- * @return None
- */
-static void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& certURI, const std::string& service,
- const std::string& certObjPath,
- const std::string& csrObjPath)
-{
- BMCWEB_LOG_DEBUG << "getCSR CertObjectPath" << certObjPath
- << " CSRObjectPath=" << csrObjPath
- << " service=" << service;
- crow::connections::systemBus->async_method_call(
- [asyncResp, certURI](const boost::system::error_code ec,
- const std::string& csr) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
- messages::internalError(asyncResp->res);
- return;
- }
- if (csr.empty())
- {
- BMCWEB_LOG_ERROR << "CSR read is empty";
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["CSRString"] = csr;
- asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
- certURI;
- },
- service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
-}
-
-/**
- * Action to Generate CSR
- */
-inline void requestRoutesCertificateActionGenerateCSR(App& app)
-{
- BMCWEB_ROUTE(
- app,
- "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR/")
- .privileges(redfish::privileges::postCertificateService)
- .methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- static const int rsaKeyBitLength = 2048;
-
- // Required parameters
- std::string city;
- std::string commonName;
- std::string country;
- std::string organization;
- std::string organizationalUnit;
- std::string state;
- nlohmann::json certificateCollection;
-
- // Optional parameters
- std::optional<std::vector<std::string>> optAlternativeNames =
- std::vector<std::string>();
- std::optional<std::string> optContactPerson = "";
- std::optional<std::string> optChallengePassword = "";
- std::optional<std::string> optEmail = "";
- std::optional<std::string> optGivenName = "";
- std::optional<std::string> optInitials = "";
- std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
- std::optional<std::string> optKeyCurveId = "secp384r1";
- std::optional<std::string> optKeyPairAlgorithm = "EC";
- std::optional<std::vector<std::string>> optKeyUsage =
- std::vector<std::string>();
- std::optional<std::string> optSurname = "";
- std::optional<std::string> optUnstructuredName = "";
- if (!json_util::readJsonAction(
- req, asyncResp->res, "City", city, "CommonName", commonName,
- "ContactPerson", optContactPerson, "Country", country,
- "Organization", organization, "OrganizationalUnit",
- organizationalUnit, "State", state, "CertificateCollection",
- certificateCollection, "AlternativeNames", optAlternativeNames,
- "ChallengePassword", optChallengePassword, "Email", optEmail,
- "GivenName", optGivenName, "Initials", optInitials,
- "KeyBitLength", optKeyBitLength, "KeyCurveId", optKeyCurveId,
- "KeyPairAlgorithm", optKeyPairAlgorithm, "KeyUsage",
- optKeyUsage, "Surname", optSurname, "UnstructuredName",
- optUnstructuredName))
- {
- return;
- }
-
- // bmcweb has no way to store or decode a private key challenge
- // password, which will likely cause bmcweb to crash on startup
- // if this is not set on a post so not allowing the user to set
- // value
- if (!optChallengePassword->empty())
- {
- messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
- "ChallengePassword");
- return;
- }
-
- std::string certURI;
- if (!redfish::json_util::readJson(certificateCollection, asyncResp->res,
- "@odata.id", certURI))
- {
- return;
- }
-
- std::string objectPath;
- std::string service;
- if (certURI.starts_with(
- "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
- {
- objectPath = certs::httpsObjectPath;
- service = certs::httpsServiceName;
- }
- else if (certURI.starts_with(
- "/redfish/v1/AccountService/LDAP/Certificates"))
- {
- objectPath = certs::ldapObjectPath;
- service = certs::ldapServiceName;
- }
- else
- {
- messages::actionParameterNotSupported(
- asyncResp->res, "CertificateCollection", "GenerateCSR");
- return;
- }
-
- // supporting only EC and RSA algorithm
- if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
- {
- messages::actionParameterNotSupported(
- asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
- return;
- }
-
- // supporting only 2048 key bit length for RSA algorithm due to
- // time consumed in generating private key
- if (*optKeyPairAlgorithm == "RSA" &&
- *optKeyBitLength != rsaKeyBitLength)
- {
- messages::propertyValueNotInList(asyncResp->res,
- std::to_string(*optKeyBitLength),
- "KeyBitLength");
- return;
- }
-
- // validate KeyUsage supporting only 1 type based on URL
- if (certURI.starts_with(
- "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
- {
- if (optKeyUsage->empty())
- {
- optKeyUsage->push_back("ServerAuthentication");
- }
- else if (optKeyUsage->size() == 1)
- {
- if ((*optKeyUsage)[0] != "ServerAuthentication")
- {
- messages::propertyValueNotInList(
- asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
- return;
- }
- }
- else
- {
- messages::actionParameterNotSupported(
- asyncResp->res, "KeyUsage", "GenerateCSR");
- return;
- }
- }
- else if (certURI.starts_with(
- "/redfish/v1/AccountService/LDAP/Certificates"))
- {
- if (optKeyUsage->empty())
- {
- optKeyUsage->push_back("ClientAuthentication");
- }
- else if (optKeyUsage->size() == 1)
- {
- if ((*optKeyUsage)[0] != "ClientAuthentication")
- {
- messages::propertyValueNotInList(
- asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
- return;
- }
- }
- else
- {
- messages::actionParameterNotSupported(
- asyncResp->res, "KeyUsage", "GenerateCSR");
- return;
- }
- }
-
- // Only allow one CSR matcher at a time so setting retry
- // time-out and timer expiry to 10 seconds for now.
- static const int timeOut = 10;
- if (csrMatcher)
- {
- messages::serviceTemporarilyUnavailable(asyncResp->res,
- std::to_string(timeOut));
- return;
- }
-
- // Make this static so it survives outside this method
- static boost::asio::steady_timer timeout(*req.ioService);
- timeout.expires_after(std::chrono::seconds(timeOut));
- timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
- csrMatcher = nullptr;
- if (ec)
- {
- // operation_aborted is expected if timer is canceled
- // before completion.
- if (ec != boost::asio::error::operation_aborted)
- {
- BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
- }
- return;
- }
- BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
- messages::internalError(asyncResp->res);
- });
-
- // create a matcher to wait on CSR object
- BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
- std::string match("type='signal',"
- "interface='org.freedesktop.DBus.ObjectManager',"
- "path='" +
- objectPath +
- "',"
- "member='InterfacesAdded'");
- csrMatcher = std::make_unique<sdbusplus::bus::match_t>(
- *crow::connections::systemBus, match,
- [asyncResp, service, objectPath, certURI](sdbusplus::message_t& m) {
- timeout.cancel();
- if (m.is_method_error())
- {
- BMCWEB_LOG_ERROR << "Dbus method error!!!";
- messages::internalError(asyncResp->res);
- return;
- }
-
- dbus::utility::DBusInteracesMap interfacesProperties;
-
- sdbusplus::message::object_path csrObjectPath;
- m.read(csrObjectPath, interfacesProperties);
- BMCWEB_LOG_DEBUG << "CSR object added" << csrObjectPath.str;
- for (const auto& interface : interfacesProperties)
- {
- if (interface.first == "xyz.openbmc_project.Certs.CSR")
- {
- getCSR(asyncResp, certURI, service, objectPath,
- csrObjectPath.str);
- break;
- }
- }
- });
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec,
- const std::string&) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "DBUS response error: " << ec.message();
- messages::internalError(asyncResp->res);
- return;
- }
- },
- service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
- "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
- commonName, *optContactPerson, country, *optEmail, *optGivenName,
- *optInitials, *optKeyBitLength, *optKeyCurveId,
- *optKeyPairAlgorithm, *optKeyUsage, organization,
- organizationalUnit, state, *optSurname, *optUnstructuredName);
- });
-} // requestRoutesCertificateActionGenerateCSR
-
/**
* @brief Parse and update Certificate Issue/Subject property
*
@@ -707,512 +376,827 @@
});
}
-/**
- * Action to replace an existing certificate
- */
-inline void requestRoutesCertificateActionsReplaceCertificate(App& app)
+inline void handleCertificateServiceGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#CertificateService.v1_0_0.CertificateService";
+ asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/CertificateService";
+ asyncResp->res.jsonValue["Id"] = "CertificateService";
+ asyncResp->res.jsonValue["Name"] = "Certificate Service";
+ asyncResp->res.jsonValue["Description"] =
+ "Actions available to manage certificates";
+ // /redfish/v1/CertificateService/CertificateLocations is something
+ // only ConfigureManager can access then only display when the user
+ // has permissions ConfigureManager
+ Privileges effectiveUserPrivileges =
+ redfish::getUserPrivileges(req.userRole);
+ if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
+ effectiveUserPrivileges))
+ {
+ asyncResp->res.jsonValue["CertificateLocations"]["@odata.id"] =
+ "/redfish/v1/CertificateService/CertificateLocations";
+ }
+ nlohmann::json& actions = asyncResp->res.jsonValue["Actions"];
+ nlohmann::json& replace = actions["#CertificateService.ReplaceCertificate"];
+ replace["target"] =
+ "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate";
+ nlohmann::json::array_t allowed;
+ allowed.push_back("PEM");
+ replace["CertificateType@Redfish.AllowableValues"] = std::move(allowed);
+ actions["#CertificateService.GenerateCSR"]["target"] =
+ "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR";
+}
+
+inline void handleCertificateLocationsGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/CertificateService/CertificateLocations";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#CertificateLocations.v1_0_0.CertificateLocations";
+ asyncResp->res.jsonValue["Name"] = "Certificate Locations";
+ asyncResp->res.jsonValue["Id"] = "CertificateLocations";
+ asyncResp->res.jsonValue["Description"] =
+ "Defines a resource that an administrator can use in order to "
+ "locate all certificates installed on a given service";
+
+ getCertificateList(asyncResp, certs::baseObjectPath,
+ "/Links/Certificates"_json_pointer,
+ "/Links/Certificates@odata.count"_json_pointer);
+}
+
+inline void handleReplaceCertificateAction(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ std::string certificate;
+ nlohmann::json certificateUri;
+ std::optional<std::string> certificateType = "PEM";
+
+ if (!json_util::readJsonAction(req, asyncResp->res, "CertificateString",
+ certificate, "CertificateUri",
+ certificateUri, "CertificateType",
+ certificateType))
+ {
+ BMCWEB_LOG_ERROR << "Required parameters are missing";
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (!certificateType)
+ {
+ // should never happen, but it never hurts to be paranoid.
+ return;
+ }
+ if (certificateType != "PEM")
+ {
+ messages::actionParameterNotSupported(asyncResp->res, "CertificateType",
+ "ReplaceCertificate");
+ return;
+ }
+
+ std::string certURI;
+ if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
+ "@odata.id", certURI))
+ {
+ messages::actionParameterMissing(asyncResp->res, "ReplaceCertificate",
+ "CertificateUri");
+ return;
+ }
+ BMCWEB_LOG_INFO << "Certificate URI to replace: " << certURI;
+
+ boost::urls::result<boost::urls::url_view> parsedUrl =
+ boost::urls::parse_relative_ref(certURI);
+ if (!parsedUrl)
+ {
+ messages::actionParameterValueFormatError(
+ asyncResp->res, certURI, "CertificateUri", "ReplaceCertificate");
+ return;
+ }
+
+ std::string id;
+ sdbusplus::message::object_path objectPath;
+ std::string name;
+ std::string service;
+ if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1", "Managers",
+ "bmc", "NetworkProtocol", "HTTPS",
+ "Certificates", std::ref(id)))
+ {
+ objectPath =
+ sdbusplus::message::object_path(certs::httpsObjectPath) / id;
+ name = "HTTPS certificate";
+ service = certs::httpsServiceName;
+ }
+ else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
+ "AccountService", "LDAP",
+ "Certificates", std::ref(id)))
+ {
+ objectPath =
+ sdbusplus::message::object_path(certs::ldapObjectPath) / id;
+ name = "LDAP certificate";
+ service = certs::ldapServiceName;
+ }
+ else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
+ "Managers", "bmc", "Truststore",
+ "Certificates", std::ref(id)))
+ {
+ objectPath =
+ sdbusplus::message::object_path(certs::authorityObjectPath) / id;
+ name = "TrustStore certificate";
+ service = certs::authorityServiceName;
+ }
+ else
+ {
+ messages::actionParameterNotSupported(asyncResp->res, "CertificateUri",
+ "ReplaceCertificate");
+ return;
+ }
+
+ std::shared_ptr<CertificateFile> certFile =
+ std::make_shared<CertificateFile>(certificate);
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, certFile, objectPath, service, url{*parsedUrl}, id,
+ name](const boost::system::error_code ec) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+ if (ec.value() ==
+ boost::system::linux_error::bad_request_descriptor)
+ {
+ messages::resourceNotFound(asyncResp->res, "Certificate", id);
+ return;
+ }
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ getCertificateProperties(asyncResp, objectPath, service, id, url, name);
+ BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
+ << certFile->getCertFilePath();
+ },
+ service, objectPath, certs::certReplaceIntf, "Replace",
+ certFile->getCertFilePath());
+}
+
+static std::unique_ptr<sdbusplus::bus::match_t> csrMatcher;
+/**
+ * @brief Read data from CSR D-bus object and set to response
+ *
+ * @param[in] asyncResp Shared pointer to the response message
+ * @param[in] certURI Link to certifiate collection URI
+ * @param[in] service D-Bus service name
+ * @param[in] certObjPath certificate D-Bus object path
+ * @param[in] csrObjPath CSR D-Bus object path
+ * @return None
+ */
+static void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& certURI, const std::string& service,
+ const std::string& certObjPath,
+ const std::string& csrObjPath)
+{
+ BMCWEB_LOG_DEBUG << "getCSR CertObjectPath" << certObjPath
+ << " CSRObjectPath=" << csrObjPath
+ << " service=" << service;
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, certURI](const boost::system::error_code ec,
+ const std::string& csr) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (csr.empty())
+ {
+ BMCWEB_LOG_ERROR << "CSR read is empty";
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["CSRString"] = csr;
+ asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
+ certURI;
+ },
+ service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
+}
+
+inline void
+ handleGenerateCSRAction(App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ static const int rsaKeyBitLength = 2048;
+
+ // Required parameters
+ std::string city;
+ std::string commonName;
+ std::string country;
+ std::string organization;
+ std::string organizationalUnit;
+ std::string state;
+ nlohmann::json certificateCollection;
+
+ // Optional parameters
+ std::optional<std::vector<std::string>> optAlternativeNames =
+ std::vector<std::string>();
+ std::optional<std::string> optContactPerson = "";
+ std::optional<std::string> optChallengePassword = "";
+ std::optional<std::string> optEmail = "";
+ std::optional<std::string> optGivenName = "";
+ std::optional<std::string> optInitials = "";
+ std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
+ std::optional<std::string> optKeyCurveId = "secp384r1";
+ std::optional<std::string> optKeyPairAlgorithm = "EC";
+ std::optional<std::vector<std::string>> optKeyUsage =
+ std::vector<std::string>();
+ std::optional<std::string> optSurname = "";
+ std::optional<std::string> optUnstructuredName = "";
+ if (!json_util::readJsonAction(
+ req, asyncResp->res, "City", city, "CommonName", commonName,
+ "ContactPerson", optContactPerson, "Country", country,
+ "Organization", organization, "OrganizationalUnit",
+ organizationalUnit, "State", state, "CertificateCollection",
+ certificateCollection, "AlternativeNames", optAlternativeNames,
+ "ChallengePassword", optChallengePassword, "Email", optEmail,
+ "GivenName", optGivenName, "Initials", optInitials, "KeyBitLength",
+ optKeyBitLength, "KeyCurveId", optKeyCurveId, "KeyPairAlgorithm",
+ optKeyPairAlgorithm, "KeyUsage", optKeyUsage, "Surname", optSurname,
+ "UnstructuredName", optUnstructuredName))
+ {
+ return;
+ }
+
+ // bmcweb has no way to store or decode a private key challenge
+ // password, which will likely cause bmcweb to crash on startup
+ // if this is not set on a post so not allowing the user to set
+ // value
+ if (!optChallengePassword->empty())
+ {
+ messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
+ "ChallengePassword");
+ return;
+ }
+
+ std::string certURI;
+ if (!redfish::json_util::readJson(certificateCollection, asyncResp->res,
+ "@odata.id", certURI))
+ {
+ return;
+ }
+
+ std::string objectPath;
+ std::string service;
+ if (certURI.starts_with(
+ "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
+ {
+ objectPath = certs::httpsObjectPath;
+ service = certs::httpsServiceName;
+ }
+ else if (certURI.starts_with(
+ "/redfish/v1/AccountService/LDAP/Certificates"))
+ {
+ objectPath = certs::ldapObjectPath;
+ service = certs::ldapServiceName;
+ }
+ else
+ {
+ messages::actionParameterNotSupported(
+ asyncResp->res, "CertificateCollection", "GenerateCSR");
+ return;
+ }
+
+ // supporting only EC and RSA algorithm
+ if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
+ {
+ messages::actionParameterNotSupported(
+ asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
+ return;
+ }
+
+ // supporting only 2048 key bit length for RSA algorithm due to
+ // time consumed in generating private key
+ if (*optKeyPairAlgorithm == "RSA" && *optKeyBitLength != rsaKeyBitLength)
+ {
+ messages::propertyValueNotInList(
+ asyncResp->res, std::to_string(*optKeyBitLength), "KeyBitLength");
+ return;
+ }
+
+ // validate KeyUsage supporting only 1 type based on URL
+ if (certURI.starts_with(
+ "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
+ {
+ if (optKeyUsage->empty())
+ {
+ optKeyUsage->push_back("ServerAuthentication");
+ }
+ else if (optKeyUsage->size() == 1)
+ {
+ if ((*optKeyUsage)[0] != "ServerAuthentication")
+ {
+ messages::propertyValueNotInList(asyncResp->res,
+ (*optKeyUsage)[0], "KeyUsage");
+ return;
+ }
+ }
+ else
+ {
+ messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
+ "GenerateCSR");
+ return;
+ }
+ }
+ else if (certURI.starts_with(
+ "/redfish/v1/AccountService/LDAP/Certificates"))
+ {
+ if (optKeyUsage->empty())
+ {
+ optKeyUsage->push_back("ClientAuthentication");
+ }
+ else if (optKeyUsage->size() == 1)
+ {
+ if ((*optKeyUsage)[0] != "ClientAuthentication")
+ {
+ messages::propertyValueNotInList(asyncResp->res,
+ (*optKeyUsage)[0], "KeyUsage");
+ return;
+ }
+ }
+ else
+ {
+ messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
+ "GenerateCSR");
+ return;
+ }
+ }
+
+ // Only allow one CSR matcher at a time so setting retry
+ // time-out and timer expiry to 10 seconds for now.
+ static const int timeOut = 10;
+ if (csrMatcher)
+ {
+ messages::serviceTemporarilyUnavailable(asyncResp->res,
+ std::to_string(timeOut));
+ return;
+ }
+
+ // Make this static so it survives outside this method
+ static boost::asio::steady_timer timeout(*req.ioService);
+ timeout.expires_after(std::chrono::seconds(timeOut));
+ timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
+ csrMatcher = nullptr;
+ if (ec)
+ {
+ // operation_aborted is expected if timer is canceled
+ // before completion.
+ if (ec != boost::asio::error::operation_aborted)
+ {
+ BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
+ }
+ return;
+ }
+ BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
+ messages::internalError(asyncResp->res);
+ });
+
+ // create a matcher to wait on CSR object
+ BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
+ std::string match("type='signal',"
+ "interface='org.freedesktop.DBus.ObjectManager',"
+ "path='" +
+ objectPath +
+ "',"
+ "member='InterfacesAdded'");
+ csrMatcher = std::make_unique<sdbusplus::bus::match_t>(
+ *crow::connections::systemBus, match,
+ [asyncResp, service, objectPath, certURI](sdbusplus::message_t& m) {
+ timeout.cancel();
+ if (m.is_method_error())
+ {
+ BMCWEB_LOG_ERROR << "Dbus method error!!!";
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ dbus::utility::DBusInteracesMap interfacesProperties;
+
+ sdbusplus::message::object_path csrObjectPath;
+ m.read(csrObjectPath, interfacesProperties);
+ BMCWEB_LOG_DEBUG << "CSR object added" << csrObjectPath.str;
+ for (const auto& interface : interfacesProperties)
+ {
+ if (interface.first == "xyz.openbmc_project.Certs.CSR")
+ {
+ getCSR(asyncResp, certURI, service, objectPath,
+ csrObjectPath.str);
+ break;
+ }
+ }
+ });
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec, const std::string&) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "DBUS response error: " << ec.message();
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ },
+ service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
+ "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
+ commonName, *optContactPerson, country, *optEmail, *optGivenName,
+ *optInitials, *optKeyBitLength, *optKeyCurveId, *optKeyPairAlgorithm,
+ *optKeyUsage, organization, organizationalUnit, state, *optSurname,
+ *optUnstructuredName);
+}
+
+inline void requestRoutesCertificateService(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/")
+ .privileges(redfish::privileges::getCertificateService)
+ .methods(boost::beast::http::verb::get)(
+ std::bind_front(handleCertificateServiceGet, std::ref(app)));
+
+ BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
+ .privileges(redfish::privileges::getCertificateLocations)
+ .methods(boost::beast::http::verb::get)(
+ std::bind_front(handleCertificateLocationsGet, std::ref(app)));
+
BMCWEB_ROUTE(
app,
"/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/")
.privileges(redfish::privileges::postCertificateService)
.methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- std::string certificate;
- nlohmann::json certificateUri;
- std::optional<std::string> certificateType = "PEM";
+ std::bind_front(handleReplaceCertificateAction, std::ref(app)));
- if (!json_util::readJsonAction(req, asyncResp->res, "CertificateString",
- certificate, "CertificateUri",
- certificateUri, "CertificateType",
- certificateType))
+ BMCWEB_ROUTE(
+ app,
+ "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR/")
+ .privileges(redfish::privileges::postCertificateService)
+ .methods(boost::beast::http::verb::post)(
+ std::bind_front(handleGenerateCSRAction, std::ref(app)));
+} // requestRoutesCertificateService
+
+inline void handleHTTPSCertificateCollectionGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#CertificateCollection.CertificateCollection";
+ asyncResp->res.jsonValue["Name"] = "HTTPS Certificates Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "A Collection of HTTPS certificate instances";
+
+ getCertificateList(asyncResp, certs::httpsObjectPath,
+ "/Members"_json_pointer,
+ "/Members@odata.count"_json_pointer);
+}
+
+inline void handleHTTPSCertificateCollectionPost(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";
+
+ asyncResp->res.jsonValue["Name"] = "HTTPS Certificate";
+ asyncResp->res.jsonValue["Description"] = "HTTPS Certificate";
+
+ std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
+
+ if (certFileBody.empty())
+ {
+ BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
+ messages::unrecognizedRequestBody(asyncResp->res);
+ return;
+ }
+
+ std::shared_ptr<CertificateFile> certFile =
+ std::make_shared<CertificateFile>(certFileBody);
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, certFile](const boost::system::error_code ec,
+ const std::string& objectPath) {
+ if (ec)
{
- BMCWEB_LOG_ERROR << "Required parameters are missing";
+ BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
messages::internalError(asyncResp->res);
return;
}
- if (!certificateType)
- {
- // should never happen, but it never hurts to be paranoid.
- return;
- }
- if (certificateType != "PEM")
- {
- messages::actionParameterNotSupported(
- asyncResp->res, "CertificateType", "ReplaceCertificate");
- return;
- }
+ sdbusplus::message::object_path path(objectPath);
+ std::string certId = path.filename();
+ const boost::urls::url certURL = crow::utility::urlFromPieces(
+ "redfish", "v1", "Managers", "bmc", "NetworkProtocol", "HTTPS",
+ "Certificates", certId);
+ getCertificateProperties(asyncResp, objectPath, certs::httpsServiceName,
+ certId, certURL, "HTTPS Certificate");
+ BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
+ << certFile->getCertFilePath();
+ },
+ certs::httpsServiceName, certs::httpsObjectPath, certs::certInstallIntf,
+ "Install", certFile->getCertFilePath());
+}
- std::string certURI;
- if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
- "@odata.id", certURI))
- {
- messages::actionParameterMissing(
- asyncResp->res, "ReplaceCertificate", "CertificateUri");
- return;
- }
- BMCWEB_LOG_INFO << "Certificate URI to replace: " << certURI;
+inline void handleHTTPSCertificateGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- boost::urls::result<boost::urls::url_view> parsedUrl =
- boost::urls::parse_relative_ref(certURI);
- if (!parsedUrl)
- {
- messages::actionParameterValueFormatError(asyncResp->res, certURI,
- "CertificateUri",
- "ReplaceCertificate");
- return;
- }
-
- std::string id;
- sdbusplus::message::object_path objectPath;
- std::string name;
- std::string service;
- if (crow::utility::readUrlSegments(
- *parsedUrl, "redfish", "v1", "Managers", "bmc",
- "NetworkProtocol", "HTTPS", "Certificates", std::ref(id)))
- {
- objectPath =
- sdbusplus::message::object_path(certs::httpsObjectPath) / id;
- name = "HTTPS certificate";
- service = certs::httpsServiceName;
- }
- else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
- "AccountService", "LDAP",
- "Certificates", std::ref(id)))
- {
- objectPath =
- sdbusplus::message::object_path(certs::ldapObjectPath) / id;
- name = "LDAP certificate";
- service = certs::ldapServiceName;
- }
- else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
- "Managers", "bmc", "Truststore",
- "Certificates", std::ref(id)))
- {
- objectPath =
- sdbusplus::message::object_path(certs::authorityObjectPath) /
- id;
- name = "TrustStore certificate";
- service = certs::authorityServiceName;
- }
- else
- {
- messages::actionParameterNotSupported(
- asyncResp->res, "CertificateUri", "ReplaceCertificate");
- return;
- }
-
- std::shared_ptr<CertificateFile> certFile =
- std::make_shared<CertificateFile>(certificate);
- crow::connections::systemBus->async_method_call(
- [asyncResp, certFile, objectPath, service, url{*parsedUrl}, id,
- name](const boost::system::error_code ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
- if (ec.value() ==
- boost::system::linux_error::bad_request_descriptor)
- {
- messages::resourceNotFound(asyncResp->res, "Certificate",
- id);
- return;
- }
- messages::internalError(asyncResp->res);
- return;
- }
- getCertificateProperties(asyncResp, objectPath, service, id, url,
- name);
- BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
- << certFile->getCertFilePath();
- },
- service, objectPath, certs::certReplaceIntf, "Replace",
- certFile->getCertFilePath());
- });
-} // requestRoutesCertificateActionsReplaceCertificate
-
-/**
- * Certificate resource describes a certificate used to prove the identity
- * of a component, account or service.
- */
+ BMCWEB_LOG_DEBUG << "HTTPS Certificate ID=" << id;
+ const boost::urls::url certURL = crow::utility::urlFromPieces(
+ "redfish", "v1", "Managers", "bmc", "NetworkProtocol", "HTTPS",
+ "Certificates", id);
+ std::string objPath =
+ sdbusplus::message::object_path(certs::httpsObjectPath) / id;
+ getCertificateProperties(asyncResp, objPath, certs::httpsServiceName, id,
+ certURL, "HTTPS Certificate");
+}
inline void requestRoutesHTTPSCertificate(App& app)
{
+ BMCWEB_ROUTE(app,
+ "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
+ .privileges(redfish::privileges::getCertificateCollection)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleHTTPSCertificateCollectionGet, std::ref(app)));
+
+ BMCWEB_ROUTE(app,
+ "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
+ .privileges(redfish::privileges::postCertificateCollection)
+ .methods(boost::beast::http::verb::post)(std::bind_front(
+ handleHTTPSCertificateCollectionPost, std::ref(app)));
+
BMCWEB_ROUTE(
app,
"/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/<str>/")
.privileges(redfish::privileges::getCertificate)
.methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& id) -> void {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- BMCWEB_LOG_DEBUG << "HTTPS Certificate ID=" << id;
- const boost::urls::url certURL = crow::utility::urlFromPieces(
- "redfish", "v1", "Managers", "bmc", "NetworkProtocol",
- "HTTPS", "Certificates", id);
- std::string objPath =
- sdbusplus::message::object_path(certs::httpsObjectPath) /
- id;
- getCertificateProperties(asyncResp, objPath,
- certs::httpsServiceName, id, certURL,
- "HTTPS Certificate");
- });
+ std::bind_front(handleHTTPSCertificateGet, std::ref(app)));
}
-/**
- * Collection of HTTPS certificates
- */
-inline void requestRoutesHTTPSCertificateCollection(App& app)
+inline void handleLDAPCertificateCollectionGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
- BMCWEB_ROUTE(app,
- "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
- .privileges(redfish::privileges::getCertificateCollection)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates";
- asyncResp->res.jsonValue["@odata.type"] =
- "#CertificateCollection.CertificateCollection";
- asyncResp->res.jsonValue["Name"] = "HTTPS Certificates Collection";
- asyncResp->res.jsonValue["Description"] =
- "A Collection of HTTPS certificate instances";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/AccountService/LDAP/Certificates";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#CertificateCollection.CertificateCollection";
+ asyncResp->res.jsonValue["Name"] = "LDAP Certificates Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "A Collection of LDAP certificate instances";
- getCertificateList(asyncResp, certs::httpsObjectPath,
- "/Members"_json_pointer,
- "/Members@odata.count"_json_pointer);
- });
-
- BMCWEB_ROUTE(app,
- "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
- .privileges(redfish::privileges::postCertificateCollection)
- .methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";
-
- asyncResp->res.jsonValue["Name"] = "HTTPS Certificate";
- asyncResp->res.jsonValue["Description"] = "HTTPS Certificate";
-
- std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
-
- if (certFileBody.empty())
- {
- BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
- messages::unrecognizedRequestBody(asyncResp->res);
- return;
- }
-
- std::shared_ptr<CertificateFile> certFile =
- std::make_shared<CertificateFile>(certFileBody);
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, certFile](const boost::system::error_code ec,
- const std::string& objectPath) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
- messages::internalError(asyncResp->res);
- return;
- }
-
- sdbusplus::message::object_path path(objectPath);
- std::string certId = path.filename();
- const boost::urls::url certURL = crow::utility::urlFromPieces(
- "redfish", "v1", "Managers", "bmc", "NetworkProtocol", "HTTPS",
- "Certificates", certId);
- getCertificateProperties(asyncResp, objectPath,
- certs::httpsServiceName, certId, certURL,
- "HTTPS Certificate");
- BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
- << certFile->getCertFilePath();
- },
- certs::httpsServiceName, certs::httpsObjectPath,
- certs::certInstallIntf, "Install", certFile->getCertFilePath());
- });
-} // requestRoutesHTTPSCertificateCollection
-
-/**
- * The certificate location schema defines a resource that an administrator
- * can use in order to locate all certificates installed on a given service.
- */
-inline void requestRoutesCertificateLocations(App& app)
-{
- BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
- .privileges(redfish::privileges::getCertificateLocations)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/CertificateService/CertificateLocations";
- asyncResp->res.jsonValue["@odata.type"] =
- "#CertificateLocations.v1_0_0.CertificateLocations";
- asyncResp->res.jsonValue["Name"] = "Certificate Locations";
- asyncResp->res.jsonValue["Id"] = "CertificateLocations";
- asyncResp->res.jsonValue["Description"] =
- "Defines a resource that an administrator can use in order to "
- "locate all certificates installed on a given service";
-
- getCertificateList(asyncResp, certs::baseObjectPath,
- "/Links/Certificates"_json_pointer,
- "/Links/Certificates@odata.count"_json_pointer);
- });
+ getCertificateList(asyncResp, certs::ldapObjectPath,
+ "/Members"_json_pointer,
+ "/Members@odata.count"_json_pointer);
}
-// requestRoutesCertificateLocations
-/**
- * Collection of LDAP certificates
- */
-inline void requestRoutesLDAPCertificateCollection(App& app)
+inline void handleLDAPCertificateCollectionPost(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
- BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
- .privileges(redfish::privileges::getCertificateCollection)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
+
+ if (certFileBody.empty())
+ {
+ BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
+ messages::unrecognizedRequestBody(asyncResp->res);
+ return;
+ }
+
+ std::shared_ptr<CertificateFile> certFile =
+ std::make_shared<CertificateFile>(certFileBody);
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, certFile](const boost::system::error_code ec,
+ const std::string& objectPath) {
+ if (ec)
{
+ BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+ messages::internalError(asyncResp->res);
return;
}
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/AccountService/LDAP/Certificates";
- asyncResp->res.jsonValue["@odata.type"] =
- "#CertificateCollection.CertificateCollection";
- asyncResp->res.jsonValue["Name"] = "LDAP Certificates Collection";
- asyncResp->res.jsonValue["Description"] =
- "A Collection of LDAP certificate instances";
+ sdbusplus::message::object_path path(objectPath);
+ std::string certId = path.filename();
+ const boost::urls::url certURL = crow::utility::urlFromPieces(
+ "redfish", "v1", "AccountService", "LDAP", "Certificates", certId);
+ getCertificateProperties(asyncResp, objectPath, certs::ldapServiceName,
+ certId, certURL, "LDAP Certificate");
+ BMCWEB_LOG_DEBUG << "LDAP certificate install file="
+ << certFile->getCertFilePath();
+ },
+ certs::ldapServiceName, certs::ldapObjectPath, certs::certInstallIntf,
+ "Install", certFile->getCertFilePath());
+}
- getCertificateList(asyncResp, certs::ldapObjectPath,
- "/Members"_json_pointer,
- "/Members@odata.count"_json_pointer);
- });
+inline void handleLDAPCertificateGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
- .privileges(redfish::privileges::postCertificateCollection)
- .methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
+ BMCWEB_LOG_DEBUG << "LDAP Certificate ID=" << id;
+ const boost::urls::url certURL = crow::utility::urlFromPieces(
+ "redfish", "v1", "AccountService", "LDAP", "Certificates", id);
+ std::string objPath =
+ sdbusplus::message::object_path(certs::ldapObjectPath) / id;
+ getCertificateProperties(asyncResp, objPath, certs::ldapServiceName, id,
+ certURL, "LDAP Certificate");
+}
- if (certFileBody.empty())
- {
- BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
- messages::unrecognizedRequestBody(asyncResp->res);
- return;
- }
-
- std::shared_ptr<CertificateFile> certFile =
- std::make_shared<CertificateFile>(certFileBody);
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, certFile](const boost::system::error_code ec,
- const std::string& objectPath) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
- messages::internalError(asyncResp->res);
- return;
- }
-
- sdbusplus::message::object_path path(objectPath);
- std::string certId = path.filename();
- const boost::urls::url certURL =
- crow::utility::urlFromPieces("redfish", "v1", "AccountService",
- "LDAP", "Certificates", certId);
- getCertificateProperties(asyncResp, objectPath,
- certs::ldapServiceName, certId, certURL,
- "LDAP Certificate");
- BMCWEB_LOG_DEBUG << "LDAP certificate install file="
- << certFile->getCertFilePath();
- },
- certs::ldapServiceName, certs::ldapObjectPath,
- certs::certInstallIntf, "Install", certFile->getCertFilePath());
- });
-} // requestRoutesLDAPCertificateCollection
-
-/**
- * Certificate resource describes a certificate used to prove the identity
- * of a component, account or service.
- */
inline void requestRoutesLDAPCertificate(App& app)
{
+ BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
+ .privileges(redfish::privileges::getCertificateCollection)
+ .methods(boost::beast::http::verb::get)(
+ std::bind_front(handleLDAPCertificateCollectionGet, std::ref(app)));
+
+ BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
+ .privileges(redfish::privileges::postCertificateCollection)
+ .methods(boost::beast::http::verb::post)(std::bind_front(
+ handleLDAPCertificateCollectionPost, std::ref(app)));
+
BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
.privileges(redfish::privileges::getCertificate)
.methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& id) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ std::bind_front(handleLDAPCertificateGet, std::ref(app)));
+} // requestRoutesLDAPCertificate
+
+inline void handleTrustStoreCertificateCollectionGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Managers/bmc/Truststore/Certificates/";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#CertificateCollection.CertificateCollection";
+ asyncResp->res.jsonValue["Name"] = "TrustStore Certificates Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "A Collection of TrustStore certificate instances";
+
+ getCertificateList(asyncResp, certs::authorityObjectPath,
+ "/Members"_json_pointer,
+ "/Members@odata.count"_json_pointer);
+}
+
+inline void handleTrustStoreCertificateCollectionPost(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
+
+ if (certFileBody.empty())
+ {
+ BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
+ messages::unrecognizedRequestBody(asyncResp->res);
+ return;
+ }
+
+ std::shared_ptr<CertificateFile> certFile =
+ std::make_shared<CertificateFile>(certFileBody);
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, certFile](const boost::system::error_code ec,
+ const std::string& objectPath) {
+ if (ec)
{
+ BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+ messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_DEBUG << "LDAP Certificate ID=" << id;
- const boost::urls::url certURL = crow::utility::urlFromPieces(
- "redfish", "v1", "AccountService", "LDAP", "Certificates", id);
- std::string objPath =
- sdbusplus::message::object_path(certs::ldapObjectPath) / id;
- getCertificateProperties(asyncResp, objPath, certs::ldapServiceName, id,
- certURL, "LDAP Certificate");
- });
-} // requestRoutesLDAPCertificate
-/**
- * Collection of TrustStoreCertificate certificates
- */
-inline void requestRoutesTrustStoreCertificateCollection(App& app)
+ sdbusplus::message::object_path path(objectPath);
+ std::string certId = path.filename();
+ const boost::urls::url certURL =
+ crow::utility::urlFromPieces("redfish", "v1", "Managers", "bmc",
+ "Truststore", "Certificates", certId);
+ getCertificateProperties(asyncResp, objectPath,
+ certs::authorityServiceName, certId, certURL,
+ "TrustStore Certificate");
+ BMCWEB_LOG_DEBUG << "TrustStore certificate install file="
+ << certFile->getCertFilePath();
+ },
+ certs::authorityServiceName, certs::authorityObjectPath,
+ certs::certInstallIntf, "Install", certFile->getCertFilePath());
+}
+
+inline void handleTrustStoreCertificateGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ BMCWEB_LOG_DEBUG << "Truststore Certificate ID=" << id;
+ const boost::urls::url certURL = crow::utility::urlFromPieces(
+ "redfish", "v1", "Managers", "bmc", "Truststore", "Certificates", id);
+ std::string objPath =
+ sdbusplus::message::object_path(certs::authorityObjectPath) / id;
+ getCertificateProperties(asyncResp, objPath, certs::authorityServiceName,
+ id, certURL, "TrustStore Certificate");
+}
+
+inline void handleTrustStoreCertificateDelete(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ BMCWEB_LOG_DEBUG << "Delete TrustStore Certificate ID=" << id;
+ std::string objPath =
+ sdbusplus::message::object_path(certs::authorityObjectPath) / id;
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, id](const boost::system::error_code ec) {
+ if (ec)
+ {
+ messages::resourceNotFound(asyncResp->res, "Certificate", id);
+ return;
+ }
+ BMCWEB_LOG_INFO << "Certificate deleted";
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ },
+ certs::authorityServiceName, objPath, certs::objDeleteIntf, "Delete");
+}
+
+inline void requestRoutesTrustStoreCertificate(App& app)
{
BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
.privileges(redfish::privileges::getCertificate)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Managers/bmc/Truststore/Certificates/";
- asyncResp->res.jsonValue["@odata.type"] =
- "#CertificateCollection.CertificateCollection";
- asyncResp->res.jsonValue["Name"] = "TrustStore Certificates Collection";
- asyncResp->res.jsonValue["Description"] =
- "A Collection of TrustStore certificate instances";
-
- getCertificateList(asyncResp, certs::authorityObjectPath,
- "/Members"_json_pointer,
- "/Members@odata.count"_json_pointer);
- });
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleTrustStoreCertificateCollectionGet, std::ref(app)));
BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
.privileges(redfish::privileges::postCertificateCollection)
- .methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
+ .methods(boost::beast::http::verb::post)(std::bind_front(
+ handleTrustStoreCertificateCollectionPost, std::ref(app)));
- if (certFileBody.empty())
- {
- BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
- messages::unrecognizedRequestBody(asyncResp->res);
- return;
- }
-
- std::shared_ptr<CertificateFile> certFile =
- std::make_shared<CertificateFile>(certFileBody);
- crow::connections::systemBus->async_method_call(
- [asyncResp, certFile](const boost::system::error_code ec,
- const std::string& objectPath) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
- messages::internalError(asyncResp->res);
- return;
- }
-
- sdbusplus::message::object_path path(objectPath);
- std::string certId = path.filename();
- const boost::urls::url certURL = crow::utility::urlFromPieces(
- "redfish", "v1", "Managers", "bmc", "Truststore",
- "Certificates", certId);
- getCertificateProperties(asyncResp, objectPath,
- certs::authorityServiceName, certId,
- certURL, "TrustStore Certificate");
- BMCWEB_LOG_DEBUG << "TrustStore certificate install file="
- << certFile->getCertFilePath();
- },
- certs::authorityServiceName, certs::authorityObjectPath,
- certs::certInstallIntf, "Install", certFile->getCertFilePath());
- });
-} // requestRoutesTrustStoreCertificateCollection
-
-/**
- * Certificate resource describes a certificate used to prove the identity
- * of a component, account or service.
- */
-inline void requestRoutesTrustStoreCertificate(App& app)
-{
BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
.privileges(redfish::privileges::getCertificate)
.methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& id) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- BMCWEB_LOG_DEBUG << "Truststore Certificate ID=" << id;
- const boost::urls::url certURL =
- crow::utility::urlFromPieces("redfish", "v1", "Managers", "bmc",
- "Truststore", "Certificates", id);
- std::string objPath =
- sdbusplus::message::object_path(certs::authorityObjectPath) / id;
- getCertificateProperties(asyncResp, objPath,
- certs::authorityServiceName, id, certURL,
- "TrustStore Certificate");
- });
+ std::bind_front(handleTrustStoreCertificateGet, std::ref(app)));
BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
.privileges(redfish::privileges::deleteCertificate)
.methods(boost::beast::http::verb::delete_)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& id) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- BMCWEB_LOG_DEBUG << "Delete TrustStore Certificate ID=" << id;
- std::string objPath =
- sdbusplus::message::object_path(certs::authorityObjectPath) / id;
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, id](const boost::system::error_code ec) {
- if (ec)
- {
- messages::resourceNotFound(asyncResp->res, "Certificate", id);
- return;
- }
- BMCWEB_LOG_INFO << "Certificate deleted";
- asyncResp->res.result(boost::beast::http::status::no_content);
- },
- certs::authorityServiceName, objPath, certs::objDeleteIntf,
- "Delete");
- });
+ std::bind_front(handleTrustStoreCertificateDelete, std::ref(app)));
} // requestRoutesTrustStoreCertificate
} // namespace redfish