From c2289c047bddfdd60010b2ed45f06f7d50a32632 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Tue, 11 Sep 2012 02:05:54 +0200 Subject: [PATCH 1/2] Only disable TLS1.1 for openssl1.0.1 and higher, leaving SSL3 alone. --- indra/llmessage/aicurl.cpp | 50 +++++++++++++++++++-------------- indra/llmessage/aicurlprivate.h | 3 ++ 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index b3c6f640b..32daa7fde 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -42,6 +42,7 @@ #define OPENSSL_THREAD_DEFINES #include // OPENSSL_THREADS #include +#include #include "aicurl.h" #include "llbufferstream.h" @@ -241,13 +242,7 @@ void ssl_init(void) CRYPTO_set_dynlock_create_callback(&ssl_dyn_create_function); CRYPTO_set_dynlock_lock_callback(&ssl_dyn_lock_function); CRYPTO_set_dynlock_destroy_callback(&ssl_dyn_destroy_function); - need_renegotiation_hack = (0x10001000UL <= ssleay && ssleay < 0x10001040); - if (need_renegotiation_hack) - { - llwarns << "This version of libopenssl has a bug that we work around by forcing the TLSv1 protocol. " - "That works on Second Life, but might cause you to fail to login on some OpenSim grids. " - "Upgrade to openssl 1.0.1d or higher to avoid this warning." << llendl; - } + need_renegotiation_hack = (0x10001000UL <= ssleay); llinfos << "Successful initialization of " << SSLeay_version(SSLEAY_VERSION) << " (0x" << std::hex << SSLeay() << ")." << llendl; } @@ -896,7 +891,7 @@ void CurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void* us mSSLCtxCallback = callback; mSSLCtxCallbackUserData = userdata; setopt(CURLOPT_SSL_CTX_FUNCTION, callback ? &CurlEasyRequest::SSLCtxCallback : NULL); - setopt(CURLOPT_SSL_CTX_DATA, userdata ? this : NULL); + setopt(CURLOPT_SSL_CTX_DATA, this); } #define llmaybewarns lllog(LLApp::isExiting() ? LLError::LEVEL_INFO : LLError::LEVEL_WARN, NULL, NULL, false, true) @@ -1119,23 +1114,36 @@ void CurlEasyRequest::applyProxySettings(void) } } +//static +CURLcode CurlEasyRequest::curlCtxCallback(CURL* curl, void* sslctx, void* parm) +{ + SSL_CTX* ctx = (SSL_CTX*)sslctx; + // Turn off TLS v1.1 (which is not supported anyway by Linden Lab) because otherwise we fail to connect. + // Also turn off SSL v2, which is highly broken and strongly discouraged[1]. + // [1] http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html#SECURE_RENEGOTIATION + long options = SSL_OP_NO_SSLv2; + if (need_renegotiation_hack) + { + // This option disables openssl to use TLS version 1.1. + // The Linden Lab servers don't support TLS versions later than 1.0, and libopenssl-1.0.1-beta1 up till and including + // libopenssl-1.0.1c have a bug (or feature?) where (re)negotiation fails (see http://rt.openssl.org/Ticket/Display.html?id=2828), + // causing the connection to fail completely without this hack. + // For a commandline test of the same, observe the difference between: + // openssl s_client -connect login.agni.lindenlab.com:443 -CAfile packaged/app_settings/CA.pem -debug + // which gets no response from the server after sending the initial data, and + // openssl s_client -no_tls1_1 -connect login.agni.lindenlab.com:443 -CAfile packaged/app_settings/CA.pem -debug + // which finishes the negotiation and ends with 'Verify return code: 0 (ok)' + options |= SSL_OP_NO_TLSv1_1; + } + SSL_CTX_set_options(ctx, options); + return CURLE_OK; +} + void CurlEasyRequest::applyDefaultOptions(void) { CertificateAuthority_rat CertificateAuthority_r(gCertificateAuthority); setoptString(CURLOPT_CAINFO, CertificateAuthority_r->file); - if (need_renegotiation_hack) - { - // This option forces openssl to use TLS version 1. - // The Linden Lab servers don't support later TLS versions, and libopenssl-1.0.1-beta1 up till and including - // libopenssl-1.0.1c have a bug where renegotiation fails (see http://rt.openssl.org/Ticket/Display.html?id=2828), - // causing the connection to fail completely without this hack. - // For a commandline test of the same, observe the difference between: - // openssl s_client -connect login.agni.lindenlab.com:443 -CAfile packaged/app_settings/CA.pem -debug - // which gets no response from the server after sending the initial data, and - // openssl s_client -tls1 -connect login.agni.lindenlab.com:443 -CAfile packaged/app_settings/CA.pem -debug - // which finishes the negotiation and ends with 'Verify return code: 0 (ok)' - setopt(CURLOPT_SSLVERSION, (long)CURL_SSLVERSION_TLSv1); - } + setSSLCtxCallback(&curlCtxCallback, NULL); setopt(CURLOPT_NOSIGNAL, 1); // The old code did this for the 'buffered' version, but I think it's nonsense. //setopt(CURLOPT_DNS_CACHE_TIMEOUT, 0); diff --git a/indra/llmessage/aicurlprivate.h b/indra/llmessage/aicurlprivate.h index 4f7e9d6cc..1acf08e14 100644 --- a/indra/llmessage/aicurlprivate.h +++ b/indra/llmessage/aicurlprivate.h @@ -253,6 +253,9 @@ class CurlEasyRequest : public CurlEasyHandle { // Called from applyDefaultOptions. void applyProxySettings(void); + // Used in applyProxySettings. + static CURLcode curlCtxCallback(CURL* curl, void* sslctx, void* parm); + public: // Set default options that we want applied to all curl easy handles. void applyDefaultOptions(void); From d57a3b101b0bbecd523ca22ff3117761e2d9d911 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Tue, 11 Sep 2012 14:54:51 +0200 Subject: [PATCH 2/2] Hide quilt patch directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c56bf2a54..84a272544 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ /LICENSES/ /edited-files.txt qtcreator-build/ +/.pc