blob: 188deff5641f4614e69f3a9525bc634feffdcceb [file] [log] [blame]
Alan Kuoa8220702020-11-26 11:15:29 +08001#pragma once
2#ifdef BMCWEB_ENABLE_SSL
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08003#include "dbus_singleton.hpp"
4#include "dbus_utility.hpp"
5#include "include/dbus_utility.hpp"
6#include "logging.hpp"
7#include "ssl_key_handler.hpp"
8
Alan Kuoa8220702020-11-26 11:15:29 +08009#include <sdbusplus/bus/match.hpp>
10#include <sdbusplus/message/types.hpp>
Alan Kuoa8220702020-11-26 11:15:29 +080011
12namespace crow
13{
14namespace hostname_monitor
15{
Ed Tanouscf9e4172022-12-21 09:30:16 -080016// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
Patrick Williams59d494e2022-07-22 19:26:55 -050017static std::unique_ptr<sdbusplus::bus::match_t> hostnameSignalMonitor;
Alan Kuoa8220702020-11-26 11:15:29 +080018
19inline void installCertificate(const std::filesystem::path& certPath)
20{
21 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -080022 [certPath](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -070023 if (ec)
24 {
Ed Tanous62598e32023-07-17 17:06:25 -070025 BMCWEB_LOG_ERROR("Replace Certificate Fail..");
Ed Tanous002d39b2022-05-31 08:59:27 -070026 return;
27 }
Alan Kuoa8220702020-11-26 11:15:29 +080028
Ed Tanous62598e32023-07-17 17:06:25 -070029 BMCWEB_LOG_INFO("Replace HTTPs Certificate Success, "
30 "remove temporary certificate file..");
Ed Tanous4c521c32024-04-07 13:47:06 -070031 std::error_code ec2;
32 std::filesystem::remove(certPath.c_str(), ec2);
33 if (ec2)
34 {
35 BMCWEB_LOG_ERROR("Failed to remove certificate");
36 }
Patrick Williams5a39f772023-10-20 11:20:21 -050037 },
Alan Kuoa8220702020-11-26 11:15:29 +080038 "xyz.openbmc_project.Certs.Manager.Server.Https",
39 "/xyz/openbmc_project/certs/server/https/1",
40 "xyz.openbmc_project.Certs.Replace", "Replace", certPath.string());
41}
42
43inline int onPropertyUpdate(sd_bus_message* m, void* /* userdata */,
Ed Tanous81ce6092020-12-17 16:54:55 +000044 sd_bus_error* retError)
Alan Kuoa8220702020-11-26 11:15:29 +080045{
Ed Tanouse662eae2022-01-25 10:39:19 -080046 if (retError == nullptr || (sd_bus_error_is_set(retError) != 0))
Alan Kuoa8220702020-11-26 11:15:29 +080047 {
Ed Tanous62598e32023-07-17 17:06:25 -070048 BMCWEB_LOG_ERROR("Got sdbus error on match");
Alan Kuoa8220702020-11-26 11:15:29 +080049 return 0;
50 }
51
Patrick Williams59d494e2022-07-22 19:26:55 -050052 sdbusplus::message_t message(m);
Alan Kuoa8220702020-11-26 11:15:29 +080053 std::string iface;
Ed Tanousb9d36b42022-02-26 21:42:46 -080054 dbus::utility::DBusPropertiesMap changedProperties;
Alan Kuoa8220702020-11-26 11:15:29 +080055
56 message.read(iface, changedProperties);
Ed Tanousb9d36b42022-02-26 21:42:46 -080057 const std::string* hostname = nullptr;
58 for (const auto& propertyPair : changedProperties)
Alan Kuoa8220702020-11-26 11:15:29 +080059 {
Ed Tanousb9d36b42022-02-26 21:42:46 -080060 if (propertyPair.first == "HostName")
61 {
62 hostname = std::get_if<std::string>(&propertyPair.second);
63 }
Alan Kuoa8220702020-11-26 11:15:29 +080064 }
Alan Kuoa8220702020-11-26 11:15:29 +080065 if (hostname == nullptr)
66 {
Alan Kuoa8220702020-11-26 11:15:29 +080067 return 0;
68 }
69
Ed Tanous62598e32023-07-17 17:06:25 -070070 BMCWEB_LOG_DEBUG("Read hostname from signal: {}", *hostname);
Alan Kuoa8220702020-11-26 11:15:29 +080071 const std::string certFile = "/etc/ssl/certs/https/server.pem";
72
73 X509* cert = ensuressl::loadCert(certFile);
74 if (cert == nullptr)
75 {
Ed Tanous62598e32023-07-17 17:06:25 -070076 BMCWEB_LOG_ERROR("Failed to read cert");
Alan Kuoa8220702020-11-26 11:15:29 +080077 return 0;
78 }
79
80 const int maxKeySize = 256;
81 std::array<char, maxKeySize> cnBuffer{};
82
Patrick Williams89492a12023-05-10 07:51:34 -050083 int cnLength = X509_NAME_get_text_by_NID(X509_get_subject_name(cert),
84 NID_commonName, cnBuffer.data(),
85 cnBuffer.size());
Alan Kuoa8220702020-11-26 11:15:29 +080086 if (cnLength == -1)
87 {
Ed Tanous62598e32023-07-17 17:06:25 -070088 BMCWEB_LOG_ERROR("Failed to read NID_commonName");
Alan Kuoa8220702020-11-26 11:15:29 +080089 X509_free(cert);
90 return 0;
91 }
92 std::string_view cnValue(std::begin(cnBuffer),
93 static_cast<size_t>(cnLength));
94
95 EVP_PKEY* pPubKey = X509_get_pubkey(cert);
96 if (pPubKey == nullptr)
97 {
Ed Tanous62598e32023-07-17 17:06:25 -070098 BMCWEB_LOG_ERROR("Failed to get public key");
Alan Kuoa8220702020-11-26 11:15:29 +080099 X509_free(cert);
100 return 0;
101 }
102 int isSelfSigned = X509_verify(cert, pPubKey);
103 EVP_PKEY_free(pPubKey);
104
Ed Tanous62598e32023-07-17 17:06:25 -0700105 BMCWEB_LOG_DEBUG(
106 "Current HTTPs Certificate Subject CN: {}, New HostName: {}, isSelfSigned: {}",
107 cnValue, *hostname, isSelfSigned);
Alan Kuoa8220702020-11-26 11:15:29 +0800108
109 ASN1_IA5STRING* asn1 = static_cast<ASN1_IA5STRING*>(
110 X509_get_ext_d2i(cert, NID_netscape_comment, nullptr, nullptr));
Ed Tanouse662eae2022-01-25 10:39:19 -0800111 if (asn1 != nullptr)
Alan Kuoa8220702020-11-26 11:15:29 +0800112 {
Ed Tanous46ff87b2022-01-07 09:25:51 -0800113 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Alan Kuoa8220702020-11-26 11:15:29 +0800114 std::string_view comment(reinterpret_cast<const char*>(asn1->data),
115 static_cast<size_t>(asn1->length));
Ed Tanous62598e32023-07-17 17:06:25 -0700116 BMCWEB_LOG_DEBUG("x509Comment: {}", comment);
Alan Kuoa8220702020-11-26 11:15:29 +0800117
118 if (ensuressl::x509Comment == comment && isSelfSigned == 1 &&
119 cnValue != *hostname)
120 {
Ed Tanous62598e32023-07-17 17:06:25 -0700121 BMCWEB_LOG_INFO(
122 "Ready to generate new HTTPs certificate with subject cn: {}",
123 *hostname);
Alan Kuoa8220702020-11-26 11:15:29 +0800124
125 ensuressl::generateSslCertificate("/tmp/hostname_cert.tmp",
126 *hostname);
127 installCertificate("/tmp/hostname_cert.tmp");
128 }
129 ASN1_STRING_free(asn1);
130 }
131 X509_free(cert);
132 return 0;
133}
134
135inline void registerHostnameSignal()
136{
Ed Tanous62598e32023-07-17 17:06:25 -0700137 BMCWEB_LOG_INFO("Register HostName PropertiesChanged Signal");
Alan Kuoa8220702020-11-26 11:15:29 +0800138 std::string propertiesMatchString =
139 ("type='signal',"
140 "interface='org.freedesktop.DBus.Properties',"
141 "path='/xyz/openbmc_project/network/config',"
142 "arg0='xyz.openbmc_project.Network.SystemConfiguration',"
143 "member='PropertiesChanged'");
144
Patrick Williams59d494e2022-07-22 19:26:55 -0500145 hostnameSignalMonitor = std::make_unique<sdbusplus::bus::match_t>(
Alan Kuoa8220702020-11-26 11:15:29 +0800146 *crow::connections::systemBus, propertiesMatchString, onPropertyUpdate,
147 nullptr);
148}
149} // namespace hostname_monitor
150} // namespace crow
151#endif