]> granicus.if.org Git - postgresql/commitdiff
Fix building with LibreSSL.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 15 Sep 2016 19:29:39 +0000 (22:29 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 15 Sep 2016 19:45:08 +0000 (22:45 +0300)
LibreSSL defines OPENSSL_VERSION_NUMBER to claim that it is version 2.0.0,
but it doesn't have the functions added in OpenSSL 1.1.0. Add autoconf
checks for the individual functions we need, and stop relying on
OPENSSL_VERSION_NUMBER.

Backport to 9.5 and 9.6, like the patch that broke this. In the
back-branches, there are still a few OPENSSL_VERSION_NUMBER checks left,
to check for OpenSSL 0.9.8 or 0.9.7. I left them as they were - LibreSSL
has all those functions, so they work as intended.

Per buildfarm member curculio.

Discussion: <2442.1473957669@sss.pgh.pa.us>

configure
configure.in
contrib/pgcrypto/openssl.c
src/backend/libpq/be-secure-openssl.c
src/include/pg_config.h.in
src/interfaces/libpq/fe-secure-openssl.c

index 778bbf0c394812d67b1a4a3c71908a4684fa30c9..877436903728c3a58e7be9cbe1027bc6648a801a 100755 (executable)
--- a/configure
+++ b/configure
@@ -9711,6 +9711,37 @@ if test "x$ac_cv_func_SSL_get_current_compression" = xyes; then :
 #define HAVE_SSL_GET_CURRENT_COMPRESSION 1
 _ACEOF
 
+fi
+done
+
+  # Functions introduced in OpenSSL 1.1.0. We used to check for
+  # OPENSSL_VERSION_NUMBER, but that didn't work with 1.1.0, because LibreSSL
+  # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it
+  # doesn't have these OpenSSL 1.1.0 functions. So check for individual
+  # functions.
+  for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+  # OpenSSL versions before 1.1.0 required setting callback functions, for
+  # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
+  # function was removed.
+  for ac_func in CRYPTO_lock
+do :
+  ac_fn_c_check_func "$LINENO" "CRYPTO_lock" "ac_cv_func_CRYPTO_lock"
+if test "x$ac_cv_func_CRYPTO_lock" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CRYPTO_LOCK 1
+_ACEOF
+
 fi
 done
 
index 09ba479311d69148f6cfc13e6ce96657ae05c89d..cbd5c0be6c6c28460fec000ef3d7b091d3e479e6 100644 (file)
@@ -1118,6 +1118,16 @@ if test "$with_openssl" = yes ; then
      AC_SEARCH_LIBS(SSL_new, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])])
   fi
   AC_CHECK_FUNCS([SSL_get_current_compression])
+  # Functions introduced in OpenSSL 1.1.0. We used to check for
+  # OPENSSL_VERSION_NUMBER, but that didn't work with 1.1.0, because LibreSSL
+  # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it
+  # doesn't have these OpenSSL 1.1.0 functions. So check for individual
+  # functions.
+  AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL])
+  # OpenSSL versions before 1.1.0 required setting callback functions, for
+  # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
+  # function was removed.
+  AC_CHECK_FUNCS([CRYPTO_lock])
 fi
 
 if test "$with_pam" = yes ; then
index cee2afe3e556670f0aa73eb11df71c24e39b732d..682683c210d4b4f70e0a59d2f32bfb8c0f71db21 100644 (file)
@@ -1062,10 +1062,6 @@ px_find_cipher(const char *name, PX_Cipher **res)
 
 static int     openssl_random_init = 0;
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-#define RAND_OpenSSL RAND_SSLeay
-#endif
-
 /*
  * OpenSSL random should re-feeded occasionally. From /dev/urandom
  * preferably.
@@ -1074,7 +1070,13 @@ static void
 init_openssl_rand(void)
 {
        if (RAND_get_rand_method() == NULL)
+       {
+#ifdef HAVE_RAND_OPENSSL
                RAND_set_rand_method(RAND_OpenSSL());
+#else
+               RAND_set_rand_method(RAND_SSLeay());
+#endif
+       }
        openssl_random_init = 1;
 }
 
index 9ffb5af05e756400bb386902e7ea59efadb46b7c..3a39cb7dc6b64da2e70767d8ae54c1c5b775de86 100644 (file)
@@ -167,7 +167,7 @@ be_tls_init(void)
 
        if (!SSL_context)
        {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#ifdef HAVE_OPENSSL_INIT_SSL
                OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
 #else
 #if OPENSSL_VERSION_NUMBER >= 0x0907000L
@@ -678,7 +678,7 @@ be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
  * to retry; do we need to adopt their logic for that?
  */
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#ifndef HAVE_BIO_GET_DATA
 #define BIO_get_data(bio) (bio->ptr)
 #define BIO_set_data(bio, data) (bio->ptr = data)
 #endif
@@ -732,7 +732,7 @@ my_BIO_s_socket(void)
        if (!my_bio_methods)
        {
                BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#ifdef HAVE_BIO_METH_NEW
                int                     my_bio_index;
 
                my_bio_index = BIO_get_new_index();
index b621ff2af57172779a506aedcb53fd9f8c838872..7dbfa90bf4971f2739448d370a8fdce3f8d766d1 100644 (file)
 /* Define to 1 if you have the `append_history' function. */
 #undef HAVE_APPEND_HISTORY
 
+/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */
+#undef HAVE_ASN1_STRING_GET0_DATA
+
 /* Define to 1 if you want to use atomics if available. */
 #undef HAVE_ATOMICS
 
 /* Define to 1 if you have the <atomic.h> header file. */
 #undef HAVE_ATOMIC_H
 
+/* Define to 1 if you have the `BIO_get_data' function. */
+#undef HAVE_BIO_GET_DATA
+
+/* Define to 1 if you have the `BIO_meth_new' function. */
+#undef HAVE_BIO_METH_NEW
+
 /* Define to 1 if you have the `cbrt' function. */
 #undef HAVE_CBRT
 
 /* Define to 1 if you have the `crypt' function. */
 #undef HAVE_CRYPT
 
+/* Define to 1 if you have the `CRYPTO_lock' function. */
+#undef HAVE_CRYPTO_LOCK
+
 /* Define to 1 if you have the <crypt.h> header file. */
 #undef HAVE_CRYPT_H
 
 /* Define to 1 if you have the <net/if.h> header file. */
 #undef HAVE_NET_IF_H
 
+/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
+#undef HAVE_OPENSSL_INIT_SSL
+
 /* Define to 1 if you have the <ossp/uuid.h> header file. */
 #undef HAVE_OSSP_UUID_H
 
 /* Define to 1 if you have the `random' function. */
 #undef HAVE_RANDOM
 
+/* Define to 1 if you have the `RAND_OpenSSL' function. */
+#undef HAVE_RAND_OPENSSL
+
 /* Define to 1 if you have the <readline.h> header file. */
 #undef HAVE_READLINE_H
 
index 13c2286c3a73b0bd36bc3d1529c4bf6d172306b0..d0b3a120df1a390069495c1e172486d6930d9a66 100644 (file)
@@ -508,10 +508,6 @@ wildcard_certificate_match(const char *pattern, const char *string)
        return 1;
 }
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-#define ASN1_STRING_get0_data ASN1_STRING_data
-#endif
-
 /*
  * Check if a name from a server's certificate matches the peer's hostname.
  *
@@ -546,7 +542,11 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
         * There is no guarantee the string returned from the certificate is
         * NULL-terminated, so make a copy that is.
         */
+#ifdef HAVE_ASN1_STRING_GET0_DATA
        namedata = ASN1_STRING_get0_data(name_entry);
+#else
+       namedata = ASN1_STRING_data(name_entry);
+#endif
        len = ASN1_STRING_length(name_entry);
        name = malloc(len + 1);
        if (name == NULL)
@@ -734,10 +734,13 @@ verify_peer_name_matches_certificate(PGconn *conn)
        return found_match && !got_error;
 }
 
-#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L
+#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
 /*
- *     Callback functions for OpenSSL internal locking. (OpenSSL 1.1.0
- *     does its own locking, and doesn't need these anymore.)
+ *     Callback functions for OpenSSL internal locking.  (OpenSSL 1.1.0
+ *     does its own locking, and doesn't need these anymore.  The
+ *     CRYPTO_lock() function was removed in 1.1.0, when the callbacks
+ *     were made obsolete, so we assume that if CRYPTO_lock() exists,
+ *     the callbacks are still required.)
  */
 
 static unsigned long
@@ -767,7 +770,7 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
                        PGTHREAD_ERROR("failed to unlock mutex");
        }
 }
-#endif   /* ENABLE_THREAD_SAFETY && OPENSSL_VERSION_NUMBER < 0x10100000L */
+#endif   /* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */
 
 /*
  * Initialize SSL system, in particular creating the SSL_context object
@@ -806,7 +809,7 @@ pgtls_init(PGconn *conn)
        if (pthread_mutex_lock(&ssl_config_mutex))
                return -1;
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#ifdef HAVE_CRYPTO_LOCK
        if (pq_init_crypto_lib)
        {
                /*
@@ -847,14 +850,14 @@ pgtls_init(PGconn *conn)
                                CRYPTO_set_locking_callback(pq_lockingcallback);
                }
        }
-#endif   /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+#endif   /* HAVE_CRYPTO_LOCK */
 #endif   /* ENABLE_THREAD_SAFETY */
 
        if (!SSL_context)
        {
                if (pq_init_ssl_lib)
                {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#ifdef HAVE_OPENSSL_INIT_SSL
                        OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
 #else
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
@@ -917,7 +920,7 @@ pgtls_init(PGconn *conn)
 static void
 destroy_ssl_system(void)
 {
-#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L
+#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
        /* Mutex is created in initialize_ssl_system() */
        if (pthread_mutex_lock(&ssl_config_mutex))
                return;
@@ -1632,7 +1635,7 @@ PQsslAttribute(PGconn *conn, const char *attribute_name)
  * to retry; do we need to adopt their logic for that?
  */
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#ifndef HAVE_BIO_GET_DATA
 #define BIO_get_data(bio) (bio->ptr)
 #define BIO_set_data(bio, data) (bio->ptr = data)
 #endif
@@ -1705,7 +1708,7 @@ my_BIO_s_socket(void)
        if (!my_bio_methods)
        {
                BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#ifdef HAVE_BIO_METH_NEW
                int                     my_bio_index;
 
                my_bio_index = BIO_get_new_index();