From: Fred Morcos Date: Tue, 22 Nov 2022 11:18:47 +0000 (+0100) Subject: Add OpenSSL error handler X-Git-Tag: dnsdist-1.8.0-rc1~124^2~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66910c5d0cfceb7175077fda280fa3ba07b12f37;p=thirdparty%2Fpdns.git Add OpenSSL error handler --- diff --git a/pdns/misc.cc b/pdns/misc.cc index 7e5cb07063..3d76f8fd2e 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -35,6 +35,7 @@ #include #include "misc.hh" #include +#include #include #include #include @@ -67,6 +68,10 @@ # include #endif +#if defined(HAVE_LIBCRYPTO) +#include +#endif // HAVE_LIBCRYPTO + size_t writen2(int fd, const void *buf, size_t count) { const char *ptr = reinterpret_cast(buf); @@ -225,6 +230,67 @@ auto pdns::getMessageFromErrno(const int errnum) -> std::string return message; } +#if defined(HAVE_LIBCRYPTO) +auto pdns::OpenSSL::error(const std::string& errorMessage) -> std::runtime_error +{ + unsigned long errorCode = 0; + auto fullErrorMessage{errorMessage}; +#if OPENSSL_VERSION_MAJOR >= 3 + const char* filename = nullptr; + const char* functionName = nullptr; + int lineNumber = 0; + while ((errorCode = ERR_get_error_all(&filename, &lineNumber, &functionName, nullptr, nullptr)) != 0) { + fullErrorMessage += std::string(": ") + std::to_string(errorCode); + + const auto* lib = ERR_lib_error_string(errorCode); + if (lib != nullptr) { + fullErrorMessage += std::string(":") + lib; + } + + const auto* reason = ERR_reason_error_string(errorCode); + if (reason != nullptr) { + fullErrorMessage += std::string("::") + reason; + } + + if (filename != nullptr) { + fullErrorMessage += std::string(" - ") + filename; + } + if (lineNumber != 0) { + fullErrorMessage += std::string(":") + std::to_string(lineNumber); + } + if (functionName != nullptr) { + fullErrorMessage += std::string(" - ") + functionName; + } + } +#else + while ((errorCode = ERR_get_error()) != 0) { + fullErrorMessage += std::string(": ") + std::to_string(errorCode); + + const auto* lib = ERR_lib_error_string(errorCode); + if (lib != nullptr) { + fullErrorMessage += std::string(":") + lib; + } + + const auto* func = ERR_func_error_string(errorCode); + if (func != nullptr) { + fullErrorMessage += std::string(":") + func; + } + + const auto* reason = ERR_reason_error_string(errorCode); + if (reason != nullptr) { + fullErrorMessage += std::string("::") + reason; + } + } +#endif + return std::runtime_error(fullErrorMessage); +} + +auto pdns::OpenSSL::error(const std::string& componentName, const std::string& errorMessage) -> std::runtime_error +{ + return pdns::OpenSSL::error(componentName + ": " + errorMessage); +} +#endif // HAVE_LIBCRYPTO + string nowTime() { time_t now = time(nullptr); diff --git a/pdns/misc.hh b/pdns/misc.hh index 437cb63ea0..5be0c7b095 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -49,6 +49,7 @@ typedef enum { TSIG_MD5, TSIG_SHA1, TSIG_SHA224, TSIG_SHA256, TSIG_SHA384, TSIG_ namespace pdns { +#if defined(HAVE_LIBCRYPTO) /** * \brief Retrieves the errno-based error message in a reentrant way. * @@ -61,6 +62,25 @@ namespace pdns * \return The `std::string` error message. */ auto getMessageFromErrno(int errnum) -> std::string; + +namespace OpenSSL +{ + /** + * \brief Throws a `std::runtime_error` with the current OpenSSL error. + * + * \param[in] errorMessage The message to attach in addition to the OpenSSL error. + */ + [[nodiscard]] auto error(const std::string& errorMessage) -> std::runtime_error; + + /** + * \brief Throws a `std::runtime_error` with a name and the current OpenSSL error. + * + * \param[in] componentName The name of the component to mark the error message with. + * \param[in] errorMessage The message to attach in addition to the OpenSSL error. + */ + [[nodiscard]] auto error(const std::string& componentName, const std::string& errorMessage) -> std::runtime_error; +} +#endif // HAVE_LIBCRYPTO } string nowTime();