parent
021e77fd8e
commit
b5874be71b
|
@ -0,0 +1,118 @@
|
|||
diff --git a/lib/nss.c b/lib/nss.c
|
||||
index addc165..26d751a 100644
|
||||
--- a/lib/nss.c
|
||||
+++ b/lib/nss.c
|
||||
@@ -846,6 +846,36 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
+/* This function is supposed to decide, which error codes should be used
|
||||
+ * to conclude server is TLS intolerant.
|
||||
+ *
|
||||
+ * taken from xulrunner - nsNSSIOLayer.cpp
|
||||
+ */
|
||||
+static PRBool
|
||||
+isTLSIntoleranceError(PRInt32 err)
|
||||
+{
|
||||
+ switch (err) {
|
||||
+ case SSL_ERROR_BAD_MAC_ALERT:
|
||||
+ case SSL_ERROR_BAD_MAC_READ:
|
||||
+ case SSL_ERROR_HANDSHAKE_FAILURE_ALERT:
|
||||
+ case SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT:
|
||||
+ case SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE:
|
||||
+ case SSL_ERROR_ILLEGAL_PARAMETER_ALERT:
|
||||
+ case SSL_ERROR_NO_CYPHER_OVERLAP:
|
||||
+ case SSL_ERROR_BAD_SERVER:
|
||||
+ case SSL_ERROR_BAD_BLOCK_PADDING:
|
||||
+ case SSL_ERROR_UNSUPPORTED_VERSION:
|
||||
+ case SSL_ERROR_PROTOCOL_VERSION_ALERT:
|
||||
+ case SSL_ERROR_RX_MALFORMED_FINISHED:
|
||||
+ case SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE:
|
||||
+ case SSL_ERROR_DECODE_ERROR_ALERT:
|
||||
+ case SSL_ERROR_RX_UNKNOWN_ALERT:
|
||||
+ return PR_TRUE;
|
||||
+ default:
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Global SSL init
|
||||
*
|
||||
@@ -1075,7 +1105,11 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
switch (data->set.ssl.version) {
|
||||
default:
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
- ssl3 = tlsv1 = PR_TRUE;
|
||||
+ ssl3 = PR_TRUE;
|
||||
+ if (data->state.ssl_connect_retry)
|
||||
+ infof(data, "TLS disabled due to previous handshake failure\n");
|
||||
+ else
|
||||
+ tlsv1 = PR_TRUE;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
tlsv1 = PR_TRUE;
|
||||
@@ -1098,6 +1132,9 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
+ /* reset the flag to avoid an infinite loop */
|
||||
+ data->state.ssl_connect_retry = FALSE;
|
||||
+
|
||||
/* enable all ciphers from enable_ciphers_by_default */
|
||||
cipher_to_enable = enable_ciphers_by_default;
|
||||
while (SSL_NULL_WITH_NULL_NULL != *cipher_to_enable) {
|
||||
@@ -1276,10 +1313,21 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
return CURLE_OK;
|
||||
|
||||
error:
|
||||
+ /* reset the flag to avoid an infinite loop */
|
||||
+ data->state.ssl_connect_retry = FALSE;
|
||||
+
|
||||
err = PR_GetError();
|
||||
infof(data, "NSS error %d\n", err);
|
||||
if(model)
|
||||
PR_Close(model);
|
||||
+
|
||||
+ if (ssl3 && tlsv1 && isTLSIntoleranceError(err)) {
|
||||
+ /* schedule reconnect through Curl_retry_request() */
|
||||
+ data->state.ssl_connect_retry = TRUE;
|
||||
+ infof(data, "Error in TLS handshake, trying SSLv3...\n");
|
||||
+ return CURLE_OK;
|
||||
+ }
|
||||
+
|
||||
return curlerr;
|
||||
}
|
||||
|
||||
diff --git a/lib/transfer.c b/lib/transfer.c
|
||||
index 1f69706..c3a1976 100644
|
||||
--- a/lib/transfer.c
|
||||
+++ b/lib/transfer.c
|
||||
@@ -2572,10 +2572,11 @@ CURLcode Curl_retry_request(struct connectdata *conn,
|
||||
if(data->set.upload && !(conn->protocol&PROT_HTTP))
|
||||
return CURLE_OK;
|
||||
|
||||
- if((data->req.bytecount +
|
||||
+ if(/* workaround for broken TLS servers */ data->state.ssl_connect_retry ||
|
||||
+ ((data->req.bytecount +
|
||||
data->req.headerbytecount == 0) &&
|
||||
conn->bits.reuse &&
|
||||
- !data->set.opt_no_body) {
|
||||
+ !data->set.opt_no_body)) {
|
||||
/* We got no data, we attempted to re-use a connection and yet we want a
|
||||
"body". This might happen if the connection was left alive when we were
|
||||
done using it before, but that was closed when we wanted to read from
|
||||
diff --git a/lib/urldata.h b/lib/urldata.h
|
||||
index b9e5c24..b181e3f 100644
|
||||
--- a/lib/urldata.h
|
||||
+++ b/lib/urldata.h
|
||||
@@ -1331,6 +1331,9 @@ struct UrlState {
|
||||
} proto;
|
||||
/* current user of this SessionHandle instance, or NULL */
|
||||
struct connectdata *current_conn;
|
||||
+
|
||||
+ /* if true, force SSL connection retry (workaround for certain servers) */
|
||||
+ bool ssl_connect_retry;
|
||||
};
|
||||
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
|
||||
Name: curl
|
||||
Version: 7.19.7
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
License: MIT
|
||||
Group: Applications/Internet
|
||||
Source: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma
|
||||
Source2: curlbuild.h
|
||||
Patch1: curl-7.19.7-modelfree.patch
|
||||
Patch2: curl-7.19.7-ssl-retry.patch
|
||||
Patch101: curl-7.15.3-multilib.patch
|
||||
Patch102: curl-7.16.0-privlibs.patch
|
||||
Patch103: curl-7.19.4-debug.patch
|
||||
|
@ -69,11 +70,13 @@ use cURL's capabilities internally.
|
|||
|
||||
# upstream patches (already applied)
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
|
||||
# Fedora patches
|
||||
%patch101 -p1
|
||||
%patch102 -p1
|
||||
%patch103 -p1
|
||||
autoconf
|
||||
|
||||
# Convert docs to UTF-8
|
||||
for f in CHANGES README; do
|
||||
|
@ -82,7 +85,6 @@ for f in CHANGES README; do
|
|||
done
|
||||
|
||||
%build
|
||||
autoconf
|
||||
%configure --without-ssl --with-nss --enable-ipv6 \
|
||||
--with-ca-bundle=%{_sysconfdir}/pki/tls/certs/ca-bundle.crt \
|
||||
--with-gssapi=%{_prefix}/kerberos --with-libidn \
|
||||
|
@ -157,6 +159,9 @@ rm -rf $RPM_BUILD_ROOT
|
|||
%{_datadir}/aclocal/libcurl.m4
|
||||
|
||||
%changelog
|
||||
* Thu Nov 26 2009 Kamil Dudka <kdudka@redhat.com> 7.19.7-2
|
||||
- workaround for broken TLS servers (#525496, #527771)
|
||||
|
||||
* Thu Nov 12 2009 Kamil Dudka <kdudka@redhat.com> 7.19.7-1
|
||||
- new upstream release, dropped applied patches
|
||||
- fix crash on doubly closed NSPR descriptor, patch contributed
|
||||
|
|
Loading…
Reference in New Issue