]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add OpenSSL error handler
authorFred Morcos <fred.morcos@open-xchange.com>
Tue, 22 Nov 2022 11:18:47 +0000 (12:18 +0100)
committerFred Morcos <fred.morcos@open-xchange.com>
Tue, 10 Jan 2023 14:50:35 +0000 (15:50 +0100)
pdns/misc.cc
pdns/misc.hh

index 7e5cb070636ce1d2d5d21ef1cb74d1c47b93effb..3d76f8fd2ef5c46bade09d346825874830dd271b 100644 (file)
@@ -35,6 +35,7 @@
 #include <fstream>
 #include "misc.hh"
 #include <vector>
+#include <string>
 #include <sstream>
 #include <cerrno>
 #include <cstring>
 #  include <sched.h>
 #endif
 
+#if defined(HAVE_LIBCRYPTO)
+#include <openssl/err.h>
+#endif // HAVE_LIBCRYPTO
+
 size_t writen2(int fd, const void *buf, size_t count)
 {
   const char *ptr = reinterpret_cast<const char*>(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);
index 437cb63ea00fcf8f6c4cf813f60d8fd38a3290e9..5be0c7b095355bb3a920ada47f8c72a2e2ecacde 100644 (file)
@@ -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();