diff options
author | Ed Tanous <ed@tanous.net> | 2024-04-13 21:51:10 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2024-05-03 03:48:07 +0300 |
commit | 1aa375b80075c7e1acdc9188440a62bab21b8651 (patch) | |
tree | 661662d0e68d52a8770fd3b0f5c36f472fb8a9d9 /redfish-core/lib | |
parent | 578556628ee1200d8b77d7caca3a27e427847f52 (diff) | |
download | bmcweb-1aa375b80075c7e1acdc9188440a62bab21b8651.tar.xz |
Implement client certificate schemas
The Redfish standard seems to have caught up with some of the OEM
schemas and features we already have, namely MutualTLS and Basic Auth
disablement.
This commit implements most of the GET parameters for which we already
have backends. ClientCertificate is pointed to the same resources as
TrustStore.
Tested: generate_auth_certificates.py succeeds, and shows a certificate
in ClientCertificate collection
Get AccountService, and ClientAuthentication/Certificates returns
expected values.
Redfish service validator passes.
Change-Id: If18e34e9dfa8f38293fceff288596811afd16d4a
Signed-off-by: Ed Tanous <ed@tanous.net>
Diffstat (limited to 'redfish-core/lib')
-rw-r--r-- | redfish-core/lib/account_service.hpp | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp index 972512b145..1d3ef411a8 100644 --- a/redfish-core/lib/account_service.hpp +++ b/redfish-core/lib/account_service.hpp @@ -16,6 +16,7 @@ #pragma once #include "app.hpp" +#include "certificate_service.hpp" #include "dbus_utility.hpp" #include "error_messages.hpp" #include "generated/enums/account_service.hpp" @@ -23,13 +24,17 @@ #include "persistent_data.hpp" #include "query.hpp" #include "registries/privilege_registry.hpp" +#include "utils/collection.hpp" #include "utils/dbus_utils.hpp" #include "utils/json_utils.hpp" +#include <boost/url/format.hpp> +#include <boost/url/url.hpp> #include <sdbusplus/asio/property.hpp> #include <sdbusplus/unpack_properties.hpp> #include <array> +#include <memory> #include <optional> #include <ranges> #include <string> @@ -1174,6 +1179,80 @@ inline void handleAccountServiceHead( } inline void + getClientCertificates(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const nlohmann::json::json_pointer& keyLocation) +{ + boost::urls::url url( + "/redfish/v1/AccountService/MultiFactorAuth/ClientCertificate/Certificates"); + std::array<std::string_view, 1> interfaces = { + "xyz.openbmc_project.Certs.Certificate"}; + std::string path = "/xyz/openbmc_project/certs/authority/truststore"; + + collection_util::getCollectionToKey(asyncResp, url, interfaces, path, + keyLocation); +} + +inline void handleAccountServiceClientCertificatesInstanceHead( + App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& /*id*/) +{ + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + + asyncResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/Certificate/Certificate.json>; rel=describedby"); +} + +inline void handleAccountServiceClientCertificatesInstanceGet( + 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("ClientCertificate Certificate ID={}", id); + const boost::urls::url certURL = boost::urls::format( + "/redfish/v1/AccountService/MultiFactorAuth/ClientCertificate/Certificates/{}", + id); + std::string objPath = + sdbusplus::message::object_path(certs::authorityObjectPath) / id; + getCertificateProperties( + asyncResp, objPath, + "xyz.openbmc_project.Certs.Manager.Authority.Truststore", id, certURL, + "Client Certificate"); +} + +inline void handleAccountServiceClientCertificatesHead( + App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) +{ + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + + asyncResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/CertificateCollection/CertificateCollection.json>; rel=describedby"); +} + +inline void handleAccountServiceClientCertificatesGet( + App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) +{ + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + getClientCertificates(asyncResp, "/Members"_json_pointer); +} + +inline void handleAccountServiceGet(App& app, const crow::Request& req, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { @@ -1214,6 +1293,23 @@ inline void allowed.emplace_back(account_service::BasicAuthState::Disabled); json["HTTPBasicAuth@AllowableValues"] = std::move(allowed); + nlohmann::json::object_t clientCertificate; + clientCertificate["Enabled"] = authMethodsConfig.tls; + clientCertificate["RespondToUnauthenticatedClients"] = true; + clientCertificate["CertificateMappingAttribute"] = + account_service::CertificateMappingAttribute::CommonName; + nlohmann::json::object_t certificates; + certificates["@odata.id"] = + "/redfish/v1/AccountService/MultiFactorAuth/ClientCertificate/Certificates"; + certificates["@odata.type"] = + "#CertificateCollection.CertificateCollection"; + clientCertificate["Certificates"] = std::move(certificates); + json["MultiFactorAuth"]["ClientCertificate"] = std::move(clientCertificate); + + getClientCertificates( + asyncResp, + "/MultiFactorAuth/ClientCertificate/Certificates/Members"_json_pointer); + json["Oem"]["OpenBMC"]["@odata.type"] = "#OpenBMCAccountService.v1_0_0.AccountService"; json["Oem"]["OpenBMC"]["@odata.id"] = @@ -1249,7 +1345,7 @@ inline void return; } - BMCWEB_LOG_DEBUG("Got {}properties for AccountService", + BMCWEB_LOG_DEBUG("Got {} properties for AccountService", propertiesList.size()); const uint8_t* minPasswordLength = nullptr; @@ -2026,6 +2122,34 @@ inline void requestAccountServiceRoutes(App& app) .methods(boost::beast::http::verb::patch)( std::bind_front(handleAccountServicePatch, std::ref(app))); + BMCWEB_ROUTE( + app, + "/redfish/v1/AccountService/MultiFactorAuth/ClientCertificate/Certificates") + .privileges(redfish::privileges::headCertificateCollection) + .methods(boost::beast::http::verb::head)(std::bind_front( + handleAccountServiceClientCertificatesHead, std::ref(app))); + + BMCWEB_ROUTE( + app, + "/redfish/v1/AccountService/MultiFactorAuth/ClientCertificate/Certificates") + .privileges(redfish::privileges::getCertificateCollection) + .methods(boost::beast::http::verb::get)(std::bind_front( + handleAccountServiceClientCertificatesGet, std::ref(app))); + + BMCWEB_ROUTE( + app, + "/redfish/v1/AccountService/MultiFactorAuth/ClientCertificate/Certificates/<str>") + .privileges(redfish::privileges::headCertificate) + .methods(boost::beast::http::verb::head)(std::bind_front( + handleAccountServiceClientCertificatesInstanceHead, std::ref(app))); + + BMCWEB_ROUTE( + app, + "/redfish/v1/AccountService/MultiFactorAuth/ClientCertificate/Certificates/<str>/") + .privileges(redfish::privileges::getCertificate) + .methods(boost::beast::http::verb::get)(std::bind_front( + handleAccountServiceClientCertificatesInstanceGet, std::ref(app))); + BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/") .privileges(redfish::privileges::headManagerAccountCollection) .methods(boost::beast::http::verb::head)( |