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

Add forward-compat for OpenSSL 1.1.

It is not ABI compatible but some clever wrapper functions achieve success.

https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
https://abi-laboratory.pro/tracker/objects_report/openssl/1.0.2o/1.1.0/report.html
https://news.ycombinator.com/item?id=13284648
Bryan Drewery 8 лет назад
Родитель
Сommit
cea948bb94
8 измененных файлов с 85 добавлено и 13 удалено
  1. 1 0
      src/Makefile.in
  2. 49 0
      src/compat/openssl.cc
  3. 1 0
      src/dl.cc
  4. 25 0
      src/dl.h
  5. 1 1
      src/generate_defs.sh
  6. 3 5
      src/libcrypto.cc
  7. 5 5
      src/libssl.cc
  8. 0 2
      src/libtcl.cc

+ 1 - 0
src/Makefile.in

@@ -75,6 +75,7 @@ OBJS = auth.So \
 	compat/snprintf.o \
 	compat/memmem.o \
 	compat/memutil.o \
+	compat/openssl.o \
 	compat/strlcpy.o \
 	compat/strsep.o \
 	crypto/aes_util.o \

+ 49 - 0
src/compat/openssl.cc

@@ -0,0 +1,49 @@
+#include <openssl/opensslv.h>
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#include <stdlib.h>
+#include <stdint.h>
+#include "dl.h"
+
+extern "C" {
+typedef int (*OPENSSL_init_ssl_t)(uint64_t a1, const void *a2);
+int _OPENSSL_init_ssl(uint64_t a1 __unused, const void *a2 __unused) {
+  if (DLSYM_VAR(OPENSSL_init_ssl) == NULL)
+    if (DLSYM_GLOBAL_SIMPLE(RTLD_NEXT, OPENSSL_init_ssl) == NULL)
+      return 0;
+  return DLSYM_VAR(OPENSSL_init_ssl)(a1, a2);
+}
+
+void _ERR_free_strings(void) {
+}
+
+void _EVP_cleanup(void) {
+}
+
+void _CRYPTO_cleanup_all_ex_data(void) {
+}
+
+int _SSL_library_init(void) {
+  return _OPENSSL_init_ssl(0, NULL);
+}
+
+#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS    0x00000002L
+#define OPENSSL_INIT_LOAD_SSL_STRINGS       0x00200000L
+void _SSL_load_error_strings(void) {
+    _OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
+                     | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
+}
+
+typedef void *(*TLS_client_method_t)(void);
+const void *_TLS_client_method(void) {
+  if (DLSYM_VAR(TLS_client_method) == NULL)
+    if (DLSYM_GLOBAL_SIMPLE(RTLD_NEXT, TLS_client_method) == NULL)
+      return NULL;
+  return DLSYM_VAR(TLS_client_method)();
+}
+
+const void *_SSLv23_client_method(void) {
+  return _TLS_client_method();
+}
+
+} /* extern "C" */
+#endif	/* OPENSSL_VERSION_NUMBER < 0x10100000L */

+ 1 - 0
src/dl.cc

@@ -32,5 +32,6 @@
 #include <bdlib/src/Array.h>
 #include <bdlib/src/HashTable.h>
 
+const char *dlsym_error;
 bd::HashTable<bd::String, FunctionPtr> dl_symbol_table;
 /* vim: set sts=2 sw=2 ts=8 et: */

+ 25 - 0
src/dl.h

@@ -7,6 +7,8 @@
 #include <bdlib/src/String.h>
 #include <bdlib/src/HashTable.h>
 
+extern const char *dlsym_error;
+
 #define DLSYM(_handle, x) \
   dlerror(); \
   x##_t x; \
@@ -17,6 +19,23 @@
     return(1); \
   }
 
+#define DLSYM_GLOBAL_FWDCOMPAT(_handle, x) do { \
+  dlerror(); \
+  if ((dl_symbol_table[#x] = (FunctionPtr) ((x##_t) dlsym(_handle, #x))) == \
+    NULL) { \
+    if ((dl_symbol_table[#x] = \
+      (FunctionPtr) ((x##_t) dlsym(RTLD_SELF, "_" #x))) == NULL) { \
+      dlsym_error = dlerror(); \
+      if (dlsym_error) { \
+        fprintf(stderr, "%s", dlsym_error); \
+        return(1); \
+      } \
+    } \
+  } else { \
+    my_symbols << #x; \
+  } \
+} while (0)
+
 #define DLSYM_GLOBAL(_handle, x) do { \
   dlerror(); \
   dl_symbol_table[#x] = (FunctionPtr) ((x##_t) dlsym(_handle, #x)); \
@@ -28,12 +47,18 @@
   my_symbols << #x; \
 } while (0)
 
+#define DLSYM_GLOBAL_SIMPLE(_handle, x) ( \
+  dl_symbol_table[#x] = (FunctionPtr) ((x##_t) dlsym(_handle, #x)), \
+  dl_symbol_table[#x] \
+)
+
 #define DLSYM_VAR(x) ((x##_t)dl_symbol_table[#x])
 
 extern bd::HashTable<bd::String, FunctionPtr> dl_symbol_table;
 
 #ifdef GENERATE_DEFS
 #undef DLSYM_GLOBAL
+#undef DLSYM_GLOBAL_FWDCOMPAT
 #endif
 
 #endif /* !_DL_H_ */

+ 1 - 1
src/generate_defs.sh

@@ -51,7 +51,7 @@ for file in ${files}; do
   mv $TMPFILE.sed $TMPFILE
   cd ..
 
-  for symbol in $($SED -n -e 's/.*DLSYM_GLOBAL(.*, \([^)]*\).*/\1/p' $TMPFILE|sort -u); do
+  for symbol in $($SED -n -e 's/.*DLSYM_GLOBAL[^ (]*(.*, \([^)]*\).*/\1/p' $TMPFILE|sort -u); do
     # Check if the typedef is already defined ...
     typedef=$(grep "^typedef .*(\*${symbol}_t)" ${dirname}/${basename}.h)
     # ... if not, generate it

+ 3 - 5
src/libcrypto.cc

@@ -38,8 +38,6 @@ void *libcrypto_handle = NULL;
 static bd::Array<bd::String> my_symbols;
 
 static int load_symbols(void *handle) {
-  const char *dlsym_error = NULL;
-
   DLSYM_GLOBAL(handle, AES_cbc_encrypt);
   DLSYM_GLOBAL(handle, AES_decrypt);
   DLSYM_GLOBAL(handle, AES_encrypt);
@@ -87,9 +85,9 @@ static int load_symbols(void *handle) {
   DLSYM_GLOBAL(handle, DH_set0_pqg);
   DLSYM_GLOBAL(handle, BN_free);
 #else
-  DLSYM_GLOBAL(handle, ERR_free_strings);
-  DLSYM_GLOBAL(handle, EVP_cleanup);
-  DLSYM_GLOBAL(handle, CRYPTO_cleanup_all_ex_data);
+  DLSYM_GLOBAL_FWDCOMPAT(handle, ERR_free_strings);
+  DLSYM_GLOBAL_FWDCOMPAT(handle, EVP_cleanup);
+  DLSYM_GLOBAL_FWDCOMPAT(handle, CRYPTO_cleanup_all_ex_data);
 #endif
 
   return 0;

+ 5 - 5
src/libssl.cc

@@ -38,8 +38,6 @@ void *libssl_handle = NULL;
 static bd::Array<bd::String> my_symbols;
 
 static int load_symbols(void *handle) {
-  const char *dlsym_error = NULL;
-
   DLSYM_GLOBAL(handle, SSL_get_error);
   DLSYM_GLOBAL(handle, SSL_connect);
   DLSYM_GLOBAL(handle, SSL_CTX_free);
@@ -58,8 +56,9 @@ static int load_symbols(void *handle) {
   /* For SSL_library_init and SSL_load_error_strings. */
   DLSYM_GLOBAL(handle, OPENSSL_init_ssl);
 #else
-  DLSYM_GLOBAL(handle, SSL_library_init);
-  DLSYM_GLOBAL(handle, SSL_load_error_strings);
+  DLSYM_GLOBAL_FWDCOMPAT(handle, SSL_library_init);
+  DLSYM_GLOBAL_FWDCOMPAT(handle, SSL_load_error_strings);
+  /* Some forward-compat is handled in src/compat/openssl.cc. */
 #endif
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
   /* For SSLv23_client_method */
@@ -68,7 +67,8 @@ static int load_symbols(void *handle) {
   DLSYM_GLOBAL(handle, TLS_method);
   DLSYM_GLOBAL(handle, SSL_CTX_set_options);
 #else
-  DLSYM_GLOBAL(handle, SSLv23_client_method);
+  DLSYM_GLOBAL_FWDCOMPAT(handle, SSLv23_client_method);
+  /* Some forward-compat is handled in src/compat/openssl.cc. */
 #endif
 
   return 0;

+ 0 - 2
src/libtcl.cc

@@ -45,8 +45,6 @@ void initialize_binds_tcl();
 
 static int load_symbols(void *handle) {
 #ifdef USE_SCRIPT_TCL
-  const char *dlsym_error = NULL;
-
   DLSYM_GLOBAL(handle, Tcl_Eval);
   DLSYM_GLOBAL(handle, Tcl_GetStringResult);
   DLSYM_GLOBAL(handle, Tcl_DeleteInterp);