=== modified file 'acinclude/lib-checks.m4' --- acinclude/lib-checks.m4 2013-05-15 15:56:40 +0000 +++ acinclude/lib-checks.m4 2013-06-29 11:52:57 +0000 @@ -142,74 +142,131 @@ SSL_CTX *sslContext = SSL_CTX_new(SSLv3_method()); X509 ***pCert = (X509 ***)sslContext->cert; X509 *sslCtxCert = pCert && *pCert ? **pCert : (X509 *)0x1; if (sslCtxCert != NULL) return 1; return 0; ]) ], [ AC_MSG_RESULT([yes]) AC_DEFINE(SQUID_USE_SSLGETCERTIFICATE_HACK, 1) ], [ AC_MSG_RESULT([no]) ], []) SQUID_STATE_ROLLBACK(check_SSL_get_certificate) ]) +dnl Checks whether the SSL_CTX_new and similar functions require +dnl a const 'SSL_METHOD *' argument +AC_DEFUN([SQUID_CHECK_OPENSSL_CONST_SSL_METHOD],[ + AH_TEMPLATE(SQUID_USE_CONST_SSL_METHOD, "Define to 1 if the SSL_CTX_new and similar openSSL API functions require 'const SSL_METHOD *'") + SQUID_STATE_SAVE(check_const_SSL_METHOD) + AC_MSG_CHECKING(whether SSL_CTX_new and similar openSSL API functions require 'const SSL_METHOD *'") + + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [ + #include + #include + ], + [ + const SSL_METHOD *method = NULL; + SSL_CTX *sslContext = SSL_CTX_new(method); + return (sslContext != NULL); + ]) + ], + [ + AC_DEFINE(SQUID_USE_CONST_SSL_METHOD, 1) + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + ], + []) + +SQUID_STATE_ROLLBACK(check_const_SSL_METHOD) +] +) dnl Try to handle TXT_DB related problems: dnl 1) The type of TXT_DB::data member changed in openSSL-1.0.1 version dnl 2) The IMPLEMENT_LHASH_* openSSL macros in openSSL-1.0.1 and later releases is not dnl implemented correctly and causes type conversion errors while compiling squid AC_DEFUN([SQUID_CHECK_OPENSSL_TXTDB],[ AH_TEMPLATE(SQUID_SSLTXTDB_PSTRINGDATA, "Define to 1 if the TXT_DB uses OPENSSL_PSTRING data member") + AH_TEMPLATE(SQUID_STACKOF_PSTRINGDATA_HACK, "Define to 1 to use squid workaround for buggy versions of sk_OPENSSL_PSTRING_value") AH_TEMPLATE(SQUID_USE_SSLLHASH_HACK, "Define to 1 to use squid workaround for openssl IMPLEMENT_LHASH_* type conversion errors") SQUID_STATE_SAVE(check_TXTDB) LIBS="$LIBS $SSLLIB" + squid_cv_check_openssl_pstring="no" AC_MSG_CHECKING(whether the TXT_DB use OPENSSL_PSTRING data member) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM( [ #include ], [ TXT_DB *db = NULL; int i = sk_OPENSSL_PSTRING_num(db->data); return 0; ]) ], [ AC_DEFINE(SQUID_SSLTXTDB_PSTRINGDATA, 1) AC_MSG_RESULT([yes]) + squid_cv_check_openssl_pstring="yes" ], [ AC_MSG_RESULT([no]) ], []) + if test x"$squid_cv_check_openssl_pstring" = "xyes"; then + AC_MSG_CHECKING(whether the squid workaround for buggy versions of sk_OPENSSL_PSTRING_value should used) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [ + #include + ], + [ + TXT_DB *db = NULL; + const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db->data, 0)); + return (current_row != NULL); + ]) + ], + [ + AC_MSG_RESULT([no]) + ], + [ + AC_DEFINE(SQUID_STACKOF_PSTRINGDATA_HACK, 1) + AC_MSG_RESULT([yes]) + ], + []) + fi + AC_MSG_CHECKING(whether the workaround for OpenSSL IMPLEMENT_LHASH_ macros should used) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM( [ #include static unsigned long index_serial_hash(const char **a){} static int index_serial_cmp(const char **a, const char **b){} static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **) static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **) ], [ TXT_DB *db = NULL; TXT_DB_create_index(db, 1, NULL, LHASH_HASH_FN(index_serial_hash), LHASH_COMP_FN(index_serial_cmp)); ]) ], [ AC_MSG_RESULT([no]) ], [ === modified file 'configure.ac' --- configure.ac 2013-06-11 15:16:07 +0000 +++ configure.ac 2013-06-29 11:55:25 +0000 @@ -1260,40 +1260,41 @@ SQUID_DEFINE_BOOL(USE_OPENSSL,${with_openssl}, [Define this to make use of the OpenSSL libraries for MD5 calculation rather than Squid-supplied MD5 implementation or if building with SSL encryption]) if test "x$enable_ssl" = "xyes"; then if test "x$SSLLIB" = "x"; then SSLLIB="-lcrypto" # for MD5 routines fi # This is a workaround for RedHat 9 brain damage.. if test -d /usr/kerberos/include -a "x$SSLLIBDIR" = "x" -a -f /usr/include/openssl/kssl.h; then AC_MSG_NOTICE([OpenSSL depends on Kerberos]) SSLLIBDIR="/usr/kerberos/lib" CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include" fi fi if test "x$SSLLIBDIR" != "x" ; then SSLLIB="-L$SSLLIBDIR $SSLLIB" fi AC_SUBST(SSLLIB) if test "x$with_openssl" = "xyes"; then SQUID_CHECK_OPENSSL_GETCERTIFICATE_WORKS +SQUID_CHECK_OPENSSL_CONST_SSL_METHOD SQUID_CHECK_OPENSSL_TXTDB fi AC_ARG_ENABLE(forw-via-db, AS_HELP_STRING([--enable-forw-via-db],[Enable Forw/Via database]), [ SQUID_YESNO([$enableval],[unrecognized argument to --enable-forw-via-db: $enableval]) ]) SQUID_DEFINE_BOOL(USE_FORW_VIA_DB,${enable_forw_via_db:=no}, [Enable Forw/Via database]) AC_MSG_NOTICE([Forw/Via database enabled: $enable_forw_via_db]) AC_ARG_ENABLE(cache-digests, AS_HELP_STRING([--enable-cache-digests], [Use Cache Digests. See http://wiki.squid-cache.org/SquidFaq/CacheDigests]), [ SQUID_YESNO($enableval, [unrecognized argument to --enable-cache-digests: $enableval]) ]) SQUID_DEFINE_BOOL(USE_CACHE_DIGESTS,${enable_cache_digests:=no}, [Use Cache Digests for locating objects in neighbor caches.]) === modified file 'src/ssl/certificate_db.cc' --- src/ssl/certificate_db.cc 2013-05-15 15:41:43 +0000 +++ src/ssl/certificate_db.cc 2013-06-29 12:34:52 +0000 @@ -150,41 +150,45 @@ } if (value) { row[cell] = static_cast(OPENSSL_malloc(sizeof(char) * (strlen(value) + 1))); memcpy(row[cell], value, sizeof(char) * (strlen(value) + 1)); } else row[cell] = NULL; } char ** Ssl::CertificateDb::Row::getRow() { return row; } void Ssl::CertificateDb::sq_TXT_DB_delete(TXT_DB *db, const char **row) { if (!db) return; #if SQUID_SSLTXTDB_PSTRINGDATA for (int i = 0; i < sk_OPENSSL_PSTRING_num(db->data); ++i) { +#if SQUID_STACKOF_PSTRINGDATA_HACK + const char ** current_row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db->data), i)); +#else const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db->data, i)); +#endif #else for (int i = 0; i < sk_num(db->data); ++i) { const char ** current_row = ((const char **)sk_value(db->data, i)); #endif if (current_row == row) { sq_TXT_DB_delete_row(db, i); return; } } } #define countof(arr) (sizeof(arr)/sizeof(*arr)) void Ssl::CertificateDb::sq_TXT_DB_delete_row(TXT_DB *db, int idx) { char **rrow; #if SQUID_SSLTXTDB_PSTRINGDATA rrow = (char **)sk_OPENSSL_PSTRING_delete(db->data, idx); #else rrow = (char **)sk_delete(db->data, idx); #endif @@ -500,85 +504,97 @@ // Normally defined in defines.h file void Ssl::CertificateDb::deleteRow(const char **row, int rowIndex) { const std::string filename(cert_full + "/" + row[cnlSerial] + ".pem"); sq_TXT_DB_delete_row(db.get(), rowIndex); subSize(filename); int ret = remove(filename.c_str()); if (ret < 0 && errno != ENOENT) throw std::runtime_error("Failed to remove certficate file " + filename + " from db"); } bool Ssl::CertificateDb::deleteInvalidCertificate() { if (!db) return false; bool removed_one = false; #if SQUID_SSLTXTDB_PSTRINGDATA for (int i = 0; i < sk_OPENSSL_PSTRING_num(db.get()->data); ++i) { +#if SQUID_STACKOF_PSTRINGDATA_HACK + const char ** current_row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db.get()->data), i)); +#else const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db.get()->data, i)); +#endif #else for (int i = 0; i < sk_num(db.get()->data); ++i) { const char ** current_row = ((const char **)sk_value(db.get()->data, i)); #endif if (!sslDateIsInTheFuture(current_row[cnlExp_date])) { deleteRow(current_row, i); removed_one = true; break; } } if (!removed_one) return false; return true; } bool Ssl::CertificateDb::deleteOldestCertificate() { if (!db) return false; #if SQUID_SSLTXTDB_PSTRINGDATA if (sk_OPENSSL_PSTRING_num(db.get()->data) == 0) #else if (sk_num(db.get()->data) == 0) #endif return false; #if SQUID_SSLTXTDB_PSTRINGDATA +#if SQUID_STACKOF_PSTRINGDATA_HACK + const char **row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db.get()->data), 0)); +#else const char **row = (const char **)sk_OPENSSL_PSTRING_value(db.get()->data, 0); +#endif #else const char **row = (const char **)sk_value(db.get()->data, 0); #endif deleteRow(row, 0); return true; } bool Ssl::CertificateDb::deleteByHostname(std::string const & host) { if (!db) return false; #if SQUID_SSLTXTDB_PSTRINGDATA for (int i = 0; i < sk_OPENSSL_PSTRING_num(db.get()->data); ++i) { +#if SQUID_STACKOF_PSTRINGDATA_HACK + const char ** current_row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db.get()->data), i)); +#else const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db.get()->data, i)); +#endif #else for (int i = 0; i < sk_num(db.get()->data); ++i) { const char ** current_row = ((const char **)sk_value(db.get()->data, i)); #endif if (host == current_row[cnlName]) { deleteRow(current_row, i); return true; } } return false; } bool Ssl::CertificateDb::IsEnabledDiskStore() const { return enabled_disk_store; } === modified file 'src/ssl/gadgets.h' --- src/ssl/gadgets.h 2012-09-06 13:12:26 +0000 +++ src/ssl/gadgets.h 2013-06-29 12:00:59 +0000 @@ -9,44 +9,44 @@ #include "ssl/crtd_message.h" #if HAVE_OPENSSL_SSL_H #include #endif #if HAVE_OPENSSL_TXT_DB_H #include #endif #if HAVE_STRING #include #endif namespace Ssl { /** \defgroup SslCrtdSslAPI ssl_crtd SSL api. These functions must not depend on Squid runtime code such as debug() because they are used by ssl_crtd. */ -#if OPENSSL_VERSION_NUMBER < 0x00909000L -typedef SSL_METHOD * ContextMethod; -#else +#if SQUID_USE_CONST_SSL_METHOD typedef const SSL_METHOD * ContextMethod; +#else +typedef SSL_METHOD * ContextMethod; #endif /** \ingroup SslCrtdSslAPI * Add SSL locking (a.k.a. reference counting) to TidyPointer */ template class LockingPointer: public TidyPointer { public: typedef TidyPointer Parent; LockingPointer(T *t = NULL): Parent(t) { } void resetAndLock(T *t) { if (t != this->get()) { this->reset(t); if (t) CRYPTO_add(&t->references, 1, lock); === modified file 'src/ssl/support.cc' --- src/ssl/support.cc 2013-06-18 10:23:41 +0000 +++ src/ssl/support.cc 2013-06-29 12:01:52 +0000 @@ -954,46 +954,42 @@ debugs(83, DBG_CRITICAL, "ERROR: SSL private key '" << certfile << "' does not match public key '" << keyfile << "': " << ERR_error_string(ssl_error, NULL)); SSL_CTX_free(sslContext); return NULL; } */ if (!configureSslContext(sslContext, port)) { debugs(83, DBG_CRITICAL, "ERROR: Configuring static SSL context"); SSL_CTX_free(sslContext); return NULL; } return sslContext; } SSL_CTX * sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile) { int ssl_error; -#if OPENSSL_VERSION_NUMBER < 0x00909000L - SSL_METHOD *method; -#else - const SSL_METHOD *method; -#endif - SSL_CTX *sslContext; + Ssl::ContextMethod method; + SSL_CTX * sslContext; long fl = Ssl::parse_flags(flags); ssl_initialize(); if (!keyfile) keyfile = certfile; if (!certfile) certfile = keyfile; switch (version) { case 2: #ifndef OPENSSL_NO_SSL2 debugs(83, 5, "Using SSLv2."); method = SSLv2_client_method(); #else debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy."); return NULL; #endif