Просмотр исходного кода

Merge branch 'maint'

* maint:
  ssl/tcl: Try to load the library detected at configure-time
  libtcl.cc: Split long lines
  Expand OPENSSL_SHLIB_VERSION correctly.
  OpenSSL 3.0 works too
  OpenSSL: Prefer 1.1
  Cleanup long lines
  Symbol loading: Add a newline on errors
  Fix LibreSSL 3.5.0+ build

Conflicts:
	src/crypto/dh_util.cc
	src/libcrypto.cc
	src/libssl.cc
	src/libtcl.cc
Bryan Drewery 2 лет назад
Родитель
Сommit
9b7cdb7f4d
12 измененных файлов с 126 добавлено и 43 удалено
  1. 2 0
      build/autotools/includes/acinclude.m4
  2. 2 0
      configure
  3. 2 0
      doc/UPDATES.md
  4. 3 1
      src/buildinfo.h.in
  5. 5 2
      src/common.h
  6. 38 16
      src/compat/openssl.cc
  7. 8 4
      src/crypto/dh_util.cc
  8. 8 4
      src/dhparam.cc
  9. 11 4
      src/libcrypto.cc
  10. 27 5
      src/libssl.cc
  11. 13 3
      src/libtcl.cc
  12. 7 4
      src/openssl.cc

+ 2 - 0
build/autotools/includes/acinclude.m4

@@ -628,6 +628,7 @@ else
   AC_MSG_RESULT([not found])
   AC_MSG_ERROR([OpenSSL is required.], 1)
 fi
+SSL_LIBDIR="${cf_openssl_basedir}/lib"
 unset cf_openssl_basedir
 
 save_CXX="$CXX"
@@ -670,6 +671,7 @@ AC_CHECK_LIB(crypto, AES_encrypt,
 CXX="$save_CXX"
 LIBS="$save_LIBS"
 
+AC_SUBST(SSL_LIBDIR)
 AC_SUBST(SSL_INCLUDES)
 AC_SUBST(SSL_LIBS)
 AC_DEFINE_UNQUOTED(EGG_SSL_EXT, 1, [Defines whether or not SSL is supported])dnl

+ 2 - 0
configure

@@ -637,6 +637,7 @@ TCLINCFN
 TCL_INCLUDES
 TCLLIBFN
 TCLLIB
+SSL_LIBDIR
 SSL_LIBS
 SSL_INCLUDES
 LIBELF_LIB
@@ -6869,6 +6870,7 @@ else
 $as_echo "not found" >&6; }
   as_fn_error 1 "OpenSSL is required." "$LINENO" 5
 fi
+SSL_LIBDIR="${cf_openssl_basedir}/lib"
 unset cf_openssl_basedir
 
 save_CXX="$CXX"

+ 2 - 0
doc/UPDATES.md

@@ -18,6 +18,8 @@
 
 # maint
   * Fix OpenSSL 3 build.
+  * Fix LibreSSL 3.5+ build.
+  * Prefer OpenSSL/TCL found at configure-time.
 
 # 1.4.10
   * Clear FiSH keys when a client quits.

+ 3 - 1
src/buildinfo.h.in

@@ -1,3 +1,5 @@
 #define BUILD_OS "@BUILDOS@"
 #define BUILD_ARCH "@BUILDARCH@"
-
+#define SSL_LIBDIR "@SSL_LIBDIR@"
+#define TCLLIB "@TCLLIB@"
+#define TCLLIBFN "@TCLLIBFN@"

+ 5 - 2
src/common.h

@@ -100,8 +100,11 @@
 #define unlikely(x)  (x)
 #endif
 
-#ifndef STRINGIFY
-#define STRINGIFY(x) #x
+#ifndef __STRING
+#define __STRING(x)     #x              /* stringify without expanding x */
+#endif
+#ifndef __XSTRING
+#define __XSTRING(x)    __STRING(x)     /* expand x, then stringify */
 #endif
 
 #define lengthof(x) (sizeof(x)/sizeof(x[0]))

+ 38 - 16
src/compat/openssl.cc

@@ -1,11 +1,23 @@
+/*
+ * Provide forward compat functions when built from < 1.1 in case the
+ * binary is run against a 1.1+ library. It will first try to find
+ * the symbol it wants, like SSLv23_client_method(), and fallback to
+ * _SSLv23_client_method() for TLS_client_method() if not found.
+ *
+ * Each condition here should match the condition in libssl.cc/libcrypto.cc
+ * for where DLSYM_GLOBAL_FWDCOMPAT() is used.
+ */
 #include <openssl/opensslv.h>
-/* Provide forward compat functions when built from < 1.1. */
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
+
 #include <stdlib.h>
 #include <stdint.h>
 #include "dl.h"
 
 extern "C" {
+/*
+ * src/libssl.cc
+ */
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
 typedef int (*OPENSSL_init_ssl_t)(uint64_t a1, const void *a2);
 static int _OPENSSL_init_ssl(uint64_t a1, const void *a2) {
   if (DLSYM_VAR(OPENSSL_init_ssl) == NULL)
@@ -13,19 +25,6 @@ static int _OPENSSL_init_ssl(uint64_t a1, const void *a2) {
       return 0;
   return DLSYM_VAR(OPENSSL_init_ssl)(a1, a2);
 }
-
-void _ERR_free_strings(void) __attribute__((const));
-void _ERR_free_strings(void) {
-}
-
-void _EVP_cleanup(void) __attribute__((const));
-void _EVP_cleanup(void) {
-}
-
-void _CRYPTO_cleanup_all_ex_data(void) __attribute__((const));
-void _CRYPTO_cleanup_all_ex_data(void) {
-}
-
 int _SSL_library_init(void) {
   return _OPENSSL_init_ssl(0, NULL);
 }
@@ -36,7 +35,10 @@ void _SSL_load_error_strings(void) {
     _OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
                      | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
 }
+#endif
 
+#if !((defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER > 0x20020002L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L))
 typedef void *(*TLS_client_method_t)(void);
 static const void *_TLS_client_method(void) {
   if (DLSYM_VAR(TLS_client_method) == NULL)
@@ -44,10 +46,30 @@ static const void *_TLS_client_method(void) {
       return NULL;
   return DLSYM_VAR(TLS_client_method)();
 }
+#endif
 
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
 const void *_SSLv23_client_method(void) {
   return _TLS_client_method();
 }
+#endif
+
+/*
+ * src/libcrypto.cc
+ */
+#if !((defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L))
+void _ERR_free_strings(void) __attribute__((const));
+void _ERR_free_strings(void) {
+}
+
+void _EVP_cleanup(void) __attribute__((const));
+void _EVP_cleanup(void) {
+}
+
+void _CRYPTO_cleanup_all_ex_data(void) __attribute__((const));
+void _CRYPTO_cleanup_all_ex_data(void) {
+}
+#endif
 
 } /* extern "C" */
-#endif	/* OPENSSL_VERSION_NUMBER < 0x10100000L */

+ 8 - 4
src/crypto/dh_util.cc

@@ -84,7 +84,8 @@ void DH1080_gen(bd::String& privateKey, bd::String& publicKeyB64) {
   const BIGNUM *priv_key, *pub_key;
 
   dh = DH_new();
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (b_prime == NULL || b_generator == NULL ||
       !DH_set0_pqg(dh, BN_dup(b_prime), NULL, BN_dup(b_generator)))
     return;
@@ -99,7 +100,8 @@ void DH1080_gen(bd::String& privateKey, bd::String& publicKeyB64) {
   }
 
   // Get private key
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   DH_get0_key(dh, &pub_key, &priv_key);
 #else
   priv_key = dh->priv_key;
@@ -126,7 +128,8 @@ bool DH1080_comp(const bd::String privateKey, const bd::String theirPublicKeyB64
 
 
   dh = DH_new();
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (b_prime == NULL || b_generator == NULL ||
       !DH_set0_pqg(dh, BN_dup(b_prime), NULL, BN_dup(b_generator)))
     return false;
@@ -137,7 +140,8 @@ bool DH1080_comp(const bd::String privateKey, const bd::String theirPublicKeyB64
 
   // Setup my private key
   b_myPrivkey = BN_bin2bn(reinterpret_cast<const unsigned char*>(privateKey.cbegin()), privateKey.length(), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   DH_set0_key(dh, NULL, b_myPrivkey);
 #else
   dh->priv_key = b_myPrivkey;

+ 8 - 4
src/dhparam.cc

@@ -32,7 +32,8 @@ DH *get_dh2048() {
   if ((dh=DH_new()) == NULL) return(NULL);
   dhp_bn = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
   dhg_bn = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (dhp_bn == NULL || dhg_bn == NULL
       || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
     DH_free(dh);
@@ -82,7 +83,8 @@ DH *get_dh1024() {
   if ((dh=DH_new()) == NULL) return(NULL);
   dhp_bn = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
   dhg_bn = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (dhp_bn == NULL || dhg_bn == NULL
       || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
     DH_free(dh);
@@ -123,7 +125,8 @@ DH *get_dh512() {
   if ((dh=DH_new()) == NULL) return(NULL);
   dhp_bn = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
   dhg_bn = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (dhp_bn == NULL || dhg_bn == NULL
       || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
     DH_free(dh);
@@ -212,7 +215,8 @@ DH *get_dh4096()
         return NULL;
     dhp_bn = BN_bin2bn(dhp_4096, sizeof(dhp_4096), NULL);
     dhg_bn = BN_bin2bn(dhg_4096, sizeof(dhg_4096), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (dhp_bn == NULL || dhg_bn == NULL
       || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
     DH_free(dh);

+ 11 - 4
src/libcrypto.cc

@@ -25,6 +25,7 @@
  */
 
 
+#include "buildinfo.h"
 #include "common.h"
 #include "main.h"
 #include "dl.h"
@@ -37,7 +38,7 @@
 #ifndef OPENSSL_SHLIB_VERSION
 #define OPENSSL_SHLIB_VERSION_STR SHLIB_VERSION_NUMBER
 #else
-#define OPENSSL_SHLIB_VERSION_STR STRINGIFY(OPENSSL_SHLIB_VERSION)
+#define OPENSSL_SHLIB_VERSION_STR __XSTRING(OPENSSL_SHLIB_VERSION)
 #endif
 
 void *libcrypto_handle = NULL;
@@ -84,7 +85,8 @@ static int load_symbols(void *handle) {
   DLSYM_GLOBAL(handle, DH_new);
   DLSYM_GLOBAL(handle, DH_size);
 
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   /* For dh_util.cc */
   DLSYM_GLOBAL(handle, DH_get0_key);
   DLSYM_GLOBAL(handle, DH_set0_key);
@@ -107,7 +109,12 @@ int load_libcrypto() {
 
   sdprintf("Loading libcrypto");
 
-  const auto& libs_list(bd::String("libcrypto.so." OPENSSL_SHLIB_VERSION_STR " "
+  const auto& libs_list(bd::String(
+#if !defined(LIBRESSL_VERSION_NUMBER)
+      SSL_LIBDIR "/libcrypto.so." OPENSSL_SHLIB_VERSION_STR " "
+      "libcrypto.so." OPENSSL_SHLIB_VERSION_STR " "
+#endif
+      SSL_LIBDIR "/libcrypto.so "
       "libcrypto.so "
       "libcrypto.so.12 "
       "libcrypto.so.30 "
@@ -136,7 +143,7 @@ int load_libcrypto() {
   }
 
   if (load_symbols(libcrypto_handle)) {
-    fprintf(stderr, STR("Missing symbols for libcrypto (likely too old)\n"));
+    fprintf(stderr, STR("\nMissing symbols for libcrypto (likely too old)\n"));
     return(1);
   }
 

+ 27 - 5
src/libssl.cc

@@ -25,6 +25,7 @@
  */
 
 
+#include "buildinfo.h"
 #include "common.h"
 #include "main.h"
 #include "dl.h"
@@ -37,7 +38,7 @@
 #ifndef OPENSSL_SHLIB_VERSION
 #define OPENSSL_SHLIB_VERSION_STR SHLIB_VERSION_NUMBER
 #else
-#define OPENSSL_SHLIB_VERSION_STR STRINGIFY(OPENSSL_SHLIB_VERSION)
+#define OPENSSL_SHLIB_VERSION_STR __XSTRING(OPENSSL_SHLIB_VERSION)
 #endif
 
 void *libssl_handle = NULL;
@@ -58,8 +59,15 @@ static int load_symbols(void *handle) {
   DLSYM_GLOBAL(handle, SSL_CTX_ctrl);
   DLSYM_GLOBAL(handle, SSL_CTX_set_cipher_list);
   DLSYM_GLOBAL(handle, SSL_CTX_set_tmp_dh_callback);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
+#if defined(LIBRESSL_VERSION_NUMBER)
+  /* SSL_library_init: always symbol in LibreSSL. */
+  DLSYM_GLOBAL(handle, SSL_library_init);
+  /* SSL_load_error_strings: always symbol in LibreSSL. */
+  DLSYM_GLOBAL(handle, SSL_load_error_strings);
+#elif OPENSSL_VERSION_NUMBER < 0x10100000L
+  /* SSL_library_init: symbol in LibreSSL and 1.0. Macro in 1.1+. */
   DLSYM_GLOBAL_FWDCOMPAT(handle, SSL_library_init);
+  /* SSL_load_error_strings: Symbol in LibreSSL and 1.0. Macro in 1.1+. */
   DLSYM_GLOBAL_FWDCOMPAT(handle, SSL_load_error_strings);
   /* Some forward-compat is handled in src/compat/openssl.cc. */
 #else
@@ -67,9 +75,18 @@ static int load_symbols(void *handle) {
   DLSYM_GLOBAL(handle, OPENSSL_init_ssl);
 #endif
 #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
-  DLSYM_GLOBAL(handle, TLS_client_method);
+  /* Macro in 1.0 and LibreSSL. Symbol in 1.1+. */
   DLSYM_GLOBAL(handle, SSL_CTX_set_options);
+#endif
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER > 0x20020002L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
+  /* Not in 1.0. Symbol in 1.1+ and LibreSSL 2.2+ 0x20020002L. */
+  DLSYM_GLOBAL(handle, TLS_client_method);
+#elif defined(LIBRESSL_VERSION_NUMBER)
+  /* LibreSSL always has a symbol and not a macro to TLS_client_method. */
+  DLSYM_GLOBAL(handle, SSLv23_client_method);
 #else
+  /* Symbol in 1.0 and LibreSSL. Macro in OpenSSL 1.1+. */
   DLSYM_GLOBAL_FWDCOMPAT(handle, SSLv23_client_method);
   /* Some forward-compat is handled in src/compat/openssl.cc. */
 #endif
@@ -85,7 +102,12 @@ int load_libssl() {
 
   sdprintf("Loading libssl");
 
-  const auto& libs_list(bd::String("libssl.so." OPENSSL_SHLIB_VERSION_STR " "
+  const auto& libs_list(bd::String(
+#if !defined(LIBRESSL_VERSION_NUMBER)
+      SSL_LIBDIR "/libssl.so." OPENSSL_SHLIB_VERSION_STR " "
+      "libssl.so." OPENSSL_SHLIB_VERSION_STR " "
+#endif
+      SSL_LIBDIR "/libssl.so "
       "libssl.so "
       "libssl.so.12 "
       "libssl.so.30 "
@@ -114,7 +136,7 @@ int load_libssl() {
   }
 
   if (load_symbols(libssl_handle)) {
-    fprintf(stderr, STR("Missing symbols for libssl (likely too old)\n"));
+    fprintf(stderr, STR("\nMissing symbols for libssl (likely too old)\n"));
     return(1);
   }
 

+ 13 - 3
src/libtcl.cc

@@ -24,7 +24,7 @@
  *
  */
 
-
+#include "buildinfo.h"
 #include "common.h"
 #include "main.h"
 #include "dl.h"
@@ -67,7 +67,17 @@ int load_libtcl() {
   }
 #endif
 
-  const auto& libs_list(bd::String("libtcl.so libtcl83.so libtcl8.3.so libtcl84.so libtcl8.4.so libtcl85.so libtcl8.5.so libtcl86.so libtcl8.6.so").split(' '));
+  const auto& libs_list(bd::String(
+      TCLLIB "/lib" TCLLIBFN " "
+      "libtcl.so "
+      "libtcl83.so "
+      "libtcl8.3.so "
+      "libtcl84.so "
+      "libtcl8.4.so "
+      "libtcl85.so "
+      "libtcl8.5.so "
+      "libtcl86.so "
+      "libtcl8.6.so").split(' '));
 
   for (const auto& lib : libs_list) {
     dlerror(); // Clear Errors
@@ -80,7 +90,7 @@ int load_libtcl() {
   }
 
   if (load_symbols(libtcl_handle)) {
-    fprintf(stderr, STR("Missing symbols for libtcl (likely too old)\n"));
+    fprintf(stderr, STR("\nMissing symbols for libtcl (likely too old)\n"));
     return(1);
   }
 

+ 7 - 4
src/openssl.cc

@@ -78,10 +78,11 @@ int init_openssl() {
   /* good place to init ssl stuff */
   SSL_load_error_strings();
   OpenSSL_add_ssl_algorithms();
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
-  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
-#else
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER > 0x20020002L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   ssl_ctx = SSL_CTX_new(TLS_client_method());
+#else
+  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
 #endif
   if (!ssl_ctx) {
     sdprintf("SSL_CTX_new() failed");
@@ -125,7 +126,9 @@ int uninit_openssl () {
     RAND_write_file(tls_rand_file);
 #endif
 
-#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
+  /* Macro from src/libcrypto.cc */
+#if !((defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L))
   ERR_free_strings();
   EVP_cleanup();
   CRYPTO_cleanup_all_ex_data();