Add "Enable legacy SSL" preference

Sam Whited created

Change summary

res/values/strings.xml                              |  6 +
res/xml/preferences.xml                             |  7 ++
src/eu/siacs/conversations/xmpp/XmppConnection.java | 44 +++++++++++---
3 files changed, 43 insertions(+), 14 deletions(-)

Detailed changes

res/values/strings.xml πŸ”—

@@ -249,8 +249,10 @@
     <string name="pref_force_encryption">Force end-to-end encryption</string>
     <string name="pref_force_encryption_summary">Always send messages encrypted (except for conferences)</string>
     <string name="pref_dont_save_encrypted">Don’t save encrypted messages</string>
-    <string name="pref_dont_save_encrypted_summary">Warning: This could lead to message loss</string>
-    <string name="pref_expert_options">Expert options</string>
+		<string name="pref_dont_save_encrypted_summary">Warning: This could lead to message loss</string>
+		<string name="pref_enable_legacy_ssl">Enable legacy SSL</string>
+		<string name="pref_enable_legacy_ssl_summary">Enables SSLv3 support for legacy servers. Warning: SSLv3 is considered insecure.</string>
+		<string name="pref_expert_options">Expert options</string>
     <string name="pref_expert_options_summary">Please be very careful with those</string>
     <string name="pref_use_larger_font">Increase font size</string>
     <string name="pref_use_larger_font_summary">Use larger font sizes across the entire app</string>

res/xml/preferences.xml πŸ”—

@@ -88,6 +88,11 @@
                     android:key="dont_save_encrypted"
                     android:summary="@string/pref_dont_save_encrypted_summary"
                     android:title="@string/pref_dont_save_encrypted" />
+                <CheckBoxPreference
+                    android:defaultValue="true"
+                    android:key="enable_legacy_ssl"
+                    android:summary="@string/pref_enable_legacy_ssl_summary"
+                    android:title="@string/pref_enable_legacy_ssl" />
             </PreferenceCategory>
             <PreferenceCategory android:title="@string/pref_expert_options_other" >
                 <CheckBoxPreference
@@ -105,4 +110,4 @@
             android:title="@string/pref_never_send_crash" />
     </PreferenceCategory>
 
-</PreferenceScreen>
+</PreferenceScreen>

src/eu/siacs/conversations/xmpp/XmppConnection.java πŸ”—

@@ -13,6 +13,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map.Entry;
 
@@ -27,15 +28,19 @@ import org.xmlpull.v1.XmlPullParserException;
 
 import de.duenndns.ssl.MemorizingTrustManager;
 
+import android.content.Context;
+import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.os.SystemClock;
+import android.preference.PreferenceManager;
 import android.util.Log;
 import android.util.SparseArray;
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.ui.StartConversationActivity;
 import eu.siacs.conversations.utils.CryptoHelper;
 import eu.siacs.conversations.utils.DNSHelper;
 import eu.siacs.conversations.utils.zlib.ZLibOutputStream;
@@ -105,6 +110,7 @@ public class XmppConnection implements Runnable {
 	private OnBindListener bindListener = null;
 	private OnMessageAcknowledged acknowledgedListener = null;
 	private MemorizingTrustManager mMemorizingTrustManager;
+    private final Context applicationContext;
 
 	public XmppConnection(Account account, XmppConnectionService service) {
 		this.mRandom = service.getRNG();
@@ -113,6 +119,7 @@ public class XmppConnection implements Runnable {
 		this.wakeLock = service.getPowerManager().newWakeLock(
 				PowerManager.PARTIAL_WAKE_LOCK, account.getJid());
 		tagWriter = new TagWriter();
+        applicationContext = service.getApplicationContext();
 	}
 
 	protected void changeStatus(int nextStatus) {
@@ -363,13 +370,13 @@ public class XmppConnection implements Runnable {
 		iq.addChild("ping", "urn:xmpp:ping");
 		this.sendIqPacket(iq, new OnIqPacketReceived() {
 
-			@Override
-			public void onIqPacketReceived(Account account, IqPacket packet) {
-				Log.d(Config.LOGTAG, account.getJid()
-						+ ": online with resource " + account.getResource());
-				changeStatus(Account.STATUS_ONLINE);
-			}
-		});
+            @Override
+            public void onIqPacketReceived(Account account, IqPacket packet) {
+                Log.d(Config.LOGTAG, account.getJid()
+                        + ": online with resource " + account.getResource());
+                changeStatus(Account.STATUS_ONLINE);
+            }
+        });
 	}
 
 	private Element processPacket(Tag currentTag, int packetType)
@@ -505,6 +512,14 @@ public class XmppConnection implements Runnable {
 		tagWriter.writeTag(startTLS);
 	}
 
+	private SharedPreferences getPreferences() {
+		return PreferenceManager.getDefaultSharedPreferences(applicationContext);
+	}
+
+	private boolean enableLegacySSL() {
+		return getPreferences().getBoolean("enable_legacy_ssl", true);
+	}
+
 	private void switchOverToTls(Tag currentTag) throws XmlPullParserException,
 			IOException {
 		tagReader.readTag();
@@ -524,10 +539,17 @@ public class XmppConnection implements Runnable {
 			// Support all protocols except legacy SSL.
 			// The min SDK version prevents us having to worry about SSLv2. In future, this may be
 			// true of SSLv3 as well.
-			final List<String> supportedProtocols = new LinkedList<String>(Arrays.asList(
-						sslSocket.getSupportedProtocols()));
-			supportedProtocols.remove("SSLv3");
-			sslSocket.setEnabledProtocols(supportedProtocols.toArray(new String[supportedProtocols.size()]));
+			final String[] supportProtocols;
+			if (enableLegacySSL()) {
+				supportProtocols = sslSocket.getSupportedProtocols();
+			} else {
+				final List<String> supportedProtocols = new LinkedList<String>(Arrays.asList(
+							sslSocket.getSupportedProtocols()));
+				supportedProtocols.remove("SSLv3");
+				supportProtocols = new String[supportedProtocols.size()];
+				supportedProtocols.toArray(supportProtocols);
+			}
+			sslSocket.setEnabledProtocols(supportProtocols);
 
 			if (verifier != null
 					&& !verifier.verify(account.getServer(),