adium 5118:9c2f63e75aca: Work around buggy TLS implementations i...
commits at adium.im
commits at adium.im
Tue Oct 16 22:11:59 UTC 2012
details: http://hg.adium.im/adium/rev/9c2f63e75aca
revision: 5118:9c2f63e75aca
branch: adium-1.5.4
author: Evan Kinney <emkinney at gmail.com>
date: Tue Oct 16 15:26:52 2012 -0400
Work around buggy TLS implementations in certain older XMPP servers by disabling TLS 1.1 and above on reconnect.
Subject: adium 5119:5a20bccaab6f: Change the following things for Evan's previous patch:
details: http://hg.adium.im/adium/rev/5a20bccaab6f
revision: 5119:5a20bccaab6f
branch: adium-1.5.4
author: Thijs Alkemade <thijsalkemade at gmail.com>
date: Wed Oct 17 00:11:16 2012 +0200
Change the following things for Evan's previous patch:
- Don't permanently workaround buggy servers, try normally once every run, if that fails, activate the workaround.
- Only automatically reconnect if the handshake failed and we might need the workaround, so we don't spam buggy servers that also happen to be offline.
Fixes #16081
diffs (195 lines):
diff -r 24a33c054027 -r 5a20bccaab6f ChangeLogs/Changes.txt
--- a/ChangeLogs/Changes.txt Tue Oct 16 23:34:24 2012 +0200
+++ b/ChangeLogs/Changes.txt Wed Oct 17 00:11:16 2012 +0200
@@ -8,6 +8,7 @@
* Fixed a problem where accepting a group chat invite on Sametime 8.5.1 would crash Adium. (Jonathan Rice and Jere Krischel) (#16114)
* Fixed a problem where accepting a group chat invite on HipChat's XMPP server would crash Adium. (#16007)
* Fix a problem preventing Adium from executing Applescripts when Gatekeeper is enabled.
+ * Added routines to make Secure Transport (on 10.8 and above) work around buggy TLS implementations in certain older XMPP servers. (#16081)
Version 1.5.3 (8/12/2012)
diff -r 24a33c054027 -r 5a20bccaab6f Plugins/Purple Service/ESPurpleJabberAccount.h
--- a/Plugins/Purple Service/ESPurpleJabberAccount.h Tue Oct 16 23:34:24 2012 +0200
+++ b/Plugins/Purple Service/ESPurpleJabberAccount.h Wed Oct 17 00:11:16 2012 +0200
@@ -30,6 +30,8 @@
#define KEY_JABBER_VERIFY_CERTS @"Jabber:Verify Certificates"
#define KEY_JABBER_FT_PROXIES @"Jabber:File Transfer Proxies"
+#define PURPLE_SSL_CDSA_BUGGY_TLS_WORKAROUND "ssl_cdsa_buggy_tls_workaround"
+
@class AMXMLConsoleController, AMPurpleJabberServiceDiscoveryBrowsing, AMPurpleJabberAdHocServer;
@interface ESPurpleJabberAccount : CBPurpleAccount <AIAccount_Files> {
diff -r 24a33c054027 -r 5a20bccaab6f Plugins/Purple Service/ESPurpleJabberAccount.m
--- a/Plugins/Purple Service/ESPurpleJabberAccount.m Tue Oct 16 23:34:24 2012 +0200
+++ b/Plugins/Purple Service/ESPurpleJabberAccount.m Wed Oct 17 00:11:16 2012 +0200
@@ -127,6 +127,19 @@
return supportedPropertyKeys;
}
+- (PurpleAccount *)purpleAccount
+{
+ if (!account) {
+ /* Lets be optimistic and hope they've fixed their buggy server today.
+ * Do this here, so we only do it once for every run of Adium.
+ */
+ account = [super purpleAccount];
+ purple_account_set_bool(account, PURPLE_SSL_CDSA_BUGGY_TLS_WORKAROUND, false);
+ }
+
+ return account;
+}
+
- (void)configurePurpleAccount
{
[super configurePurpleAccount];
@@ -486,7 +499,13 @@
[self serverReportedInvalidPassword];
shouldAttemptReconnect = AIReconnectImmediately;
}
-
+#ifdef HAVE_CDSA
+ else if (purple_account_get_bool([self purpleAccount],PURPLE_SSL_CDSA_BUGGY_TLS_WORKAROUND,false) &&
+ [*disconnectionError isEqualToString:[NSString stringWithUTF8String:_("SSL Handshake Failed")]]) {
+ AILog(@"%@: Reconnecting immediately to try to work around buggy TLS stacks",self);
+ shouldAttemptReconnect = AIReconnectImmediately;
+ }
+#endif
return shouldAttemptReconnect;
}
diff -r 24a33c054027 -r 5a20bccaab6f Plugins/Purple Service/libpurple_extensions/ssl-cdsa.c
--- a/Plugins/Purple Service/libpurple_extensions/ssl-cdsa.c Tue Oct 16 23:34:24 2012 +0200
+++ b/Plugins/Purple Service/libpurple_extensions/ssl-cdsa.c Wed Oct 17 00:11:16 2012 +0200
@@ -51,6 +51,8 @@
#define PURPLE_SSL_CDSA_DATA(gsc) ((PurpleSslCDSAData *)gsc->private_data)
#define PURPLE_SSL_CONNECTION_IS_VALID(gsc) (g_list_find(connections, (gsc)) != NULL)
+#define PURPLE_SSL_CDSA_BUGGY_TLS_WORKAROUND "ssl_cdsa_buggy_tls_workaround"
+
/*
* query_cert_chain - callback for letting the user review the certificate before accepting it
*
@@ -130,6 +132,7 @@
ssl_cdsa_handshake_cb(gpointer data, gint source, PurpleInputCondition cond)
{
PurpleSslConnection *gsc = (PurpleSslConnection *)data;
+ PurpleAccount *account = gsc->account;
PurpleSslCDSAData *cdsa_data = PURPLE_SSL_CDSA_DATA(gsc);
OSStatus err;
@@ -140,66 +143,22 @@
* here and there.
*/
err = SSLHandshake(cdsa_data->ssl_ctx);
- if (err == errSSLPeerBadRecordMac) {
+ if (err == errSSLPeerBadRecordMac
+ && !purple_account_get_bool(account, PURPLE_SSL_CDSA_BUGGY_TLS_WORKAROUND, false)
+ && !strcmp(purple_account_get_protocol_id(account),"prpl-jabber")) {
/*
- * try explicitly forcing TLS 1.0/SSL 3.0 to (maybe) make buggy servers work
+ * Set a flag so we know to explicitly disable TLS 1.1 and 1.2 on our next (immediate) connection attempt for this account.
+ * Some XMPP servers use buggy TLS stacks that incorrectly report their capabilities, which breaks things with 10.8's new support
+ * for TLS 1.1 and 1.2.
*/
- purple_debug_info("cdsa", "SSLHandshake reported bad MAC, forcing TLS 1.0/SSL 3.0\n");
-
- ssl_cdsa_close(gsc);
- ssl_cdsa_create_context(gsc);
- cdsa_data = PURPLE_SSL_CDSA_DATA(gsc);
-
- OSStatus protoErr;
- protoErr = SSLSetProtocolVersionEnabled(cdsa_data->ssl_ctx, kSSLProtocolAll, false);
- if (protoErr != noErr) {
- fprintf(stderr, "cdsa: failed to disable protocols: error %d\n",(int)protoErr);
- purple_debug_error("cdsa", "failed to disable protocols: error %d\n",(int)protoErr);
- if (gsc->error_cb != NULL)
- gsc->error_cb(gsc, PURPLE_SSL_HANDSHAKE_FAILED,
- gsc->connect_cb_data);
-
- purple_ssl_close(gsc);
- return;
- }
- protoErr = SSLSetProtocolVersionEnabled(cdsa_data->ssl_ctx, kTLSProtocol1, true);
- if (protoErr != noErr) {
- fprintf(stderr, "cdsa: failed to enable TLS 1.0: error %d\n",(int)protoErr);
- purple_debug_error("cdsa", "failed to enable TLS 1.0: error %d\n",(int)protoErr);
- if (gsc->error_cb != NULL)
- gsc->error_cb(gsc, PURPLE_SSL_HANDSHAKE_FAILED,
- gsc->connect_cb_data);
-
- purple_ssl_close(gsc);
- return;
- }
- protoErr = SSLSetProtocolVersionEnabled(cdsa_data->ssl_ctx, kSSLProtocol3, true);
- if (protoErr != noErr) {
- fprintf(stderr, "cdsa: failed to enable SSL 3.0: error %d\n",(int)protoErr);
- purple_debug_error("cdsa", "failed to enable SSL 3.0: error %d\n",(int)protoErr);
- if (gsc->error_cb != NULL)
- gsc->error_cb(gsc, PURPLE_SSL_HANDSHAKE_FAILED,
- gsc->connect_cb_data);
-
- purple_ssl_close(gsc);
- return;
- }
-
- purple_debug_info("cdsa", "retrying SSLHandshake\n");
- err = SSLHandshake(cdsa_data->ssl_ctx);
- if (err != noErr) {
- if(err == errSSLWouldBlock)
- return;
- fprintf(stderr,"cdsa: SSLHandshake failed after forcing protocol versions with error %d\n",(int)err);
- purple_debug_error("cdsa", "SSLHandshake failed after forcing protocol versions with error %d\n",(int)err);
- if (gsc->error_cb != NULL)
- gsc->error_cb(gsc, PURPLE_SSL_HANDSHAKE_FAILED,
- gsc->connect_cb_data);
-
- purple_ssl_close(gsc);
- return;
- }
- purple_debug_info("cdsa", "SSLHandshake succeeded after forcing protocol versions, continuing ssl_connect\n");
+ purple_debug_info("cdsa", "SSLHandshake reported that the server rejected our MAC, which most likely means it lied about the TLS versions it supports.");
+ purple_debug_info("cdsa", "Setting a flag in this account to only use TLS 1.0 and below on the next connection attempt.");
+
+ purple_account_set_bool(account, PURPLE_SSL_CDSA_BUGGY_TLS_WORKAROUND, true);
+ if (gsc->error_cb != NULL)
+ gsc->error_cb(gsc, PURPLE_SSL_HANDSHAKE_FAILED, gsc->connect_cb_data);
+ purple_ssl_close(gsc);
+ return;
} else if (err != noErr) {
if(err == errSSLWouldBlock)
return;
@@ -347,6 +306,7 @@
static void
ssl_cdsa_create_context(gpointer data) {
PurpleSslConnection *gsc = (PurpleSslConnection *)data;
+ PurpleAccount *account = gsc->account;
PurpleSslCDSAData *cdsa_data;
OSStatus err;
@@ -444,6 +404,24 @@
return;
}
+ if (purple_account_get_bool(account, PURPLE_SSL_CDSA_BUGGY_TLS_WORKAROUND, false)) {
+ purple_debug_info("cdsa", "Explicitly disabling TLS 1.1 and above to try and work around buggy TLS stacks\n");
+
+ OSStatus protoErr;
+ protoErr = SSLSetProtocolVersionEnabled(cdsa_data->ssl_ctx, kSSLProtocolAll, false);
+ if (protoErr != noErr) {
+ purple_debug_error("cdsa", "SSLSetProtocolVersionEnabled failed to disable protocols\n");
+ if (gsc->error_cb != NULL)
+ gsc->error_cb(gsc, PURPLE_SSL_HANDSHAKE_FAILED, gsc->connect_cb_data);
+ purple_ssl_close(gsc);
+ return;
+ }
+
+ protoErr = SSLSetProtocolVersionEnabled(cdsa_data->ssl_ctx, kSSLProtocol2, true);
+ protoErr = SSLSetProtocolVersionEnabled(cdsa_data->ssl_ctx, kSSLProtocol3, true);
+ protoErr = SSLSetProtocolVersionEnabled(cdsa_data->ssl_ctx, kTLSProtocol1, true);
+ }
+
if(gsc->host) {
/*
* Set the peer's domain name so CDSA can check the certificate's CN
More information about the commits
mailing list