Integrate MemorizingTrustManager with Beem.
authorDa Risk <da_risk@beem-project.com>
Mon, 22 Aug 2011 23:02:11 +0200
changeset 899 a3141a0d06c5
parent 898 ff346f5bc36f
child 900 56e0eadf8e87
Integrate MemorizingTrustManager with Beem. close #253
src/com/beem/project/beem/BeemService.java
src/com/beem/project/beem/ui/LoginAnim.java
--- a/src/com/beem/project/beem/BeemService.java	Mon Aug 22 22:42:58 2011 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Mon Aug 22 23:02:11 2011 +0200
@@ -78,6 +78,9 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import java.security.GeneralSecurityException;
+import javax.net.ssl.SSLContext;
+
 import com.beem.project.beem.service.XmppConnectionAdapter;
 import com.beem.project.beem.service.XmppFacade;
 import com.beem.project.beem.service.aidl.IXmppFacade;
@@ -88,6 +91,8 @@
 import com.beem.project.beem.smack.avatar.AvatarProvider;
 import com.beem.project.beem.smack.caps.CapsProvider;
 
+import de.duenndns.ssl.MemorizingTrustManager;
+
 /**
  * This class is for the Beem service.
  * It must contains every global informations needed to maintain the background service.
@@ -162,6 +167,7 @@
 	// maybe not the universal path, but it works on most devices (Samsung Galaxy, Google Nexus One)
 	mConnectionConfiguration.setTruststoreType("BKS");
 	mConnectionConfiguration.setTruststorePath("/system/etc/security/cacerts.bks");
+	installMemorizingTrustManager(mConnectionConfiguration);
     }
 
     /**
@@ -212,8 +218,8 @@
 	    if (!"".equals(tmpPort))
 		mPort = Integer.parseInt(tmpPort);
 	}
-	if (mSettings.getBoolean(BeemApplication.FULL_JID_LOGIN_KEY, false) ||
-	    "gmail.com".equals(mService) || "googlemail.com".equals(mService))  {
+	if (mSettings.getBoolean(BeemApplication.FULL_JID_LOGIN_KEY, false)
+		|| "gmail.com".equals(mService) || "googlemail.com".equals(mService))  {
 	    mLogin = tmpJid;
 	}
 
@@ -267,7 +273,8 @@
 	if (mSettings.getBoolean(BeemApplication.NOTIFICATION_VIBRATE_KEY, true))
 	    notif.defaults |= Notification.DEFAULT_VIBRATE;
 	notif.defaults |= Notification.DEFAULT_LIGHTS;
-	String ringtoneStr = mSettings.getString(BeemApplication.NOTIFICATION_SOUND_KEY, Settings.System.DEFAULT_NOTIFICATION_URI.toString());
+	String ringtoneStr = mSettings.getString(BeemApplication.NOTIFICATION_SOUND_KEY,
+		Settings.System.DEFAULT_NOTIFICATION_URI.toString());
 	notif.sound = Uri.parse(ringtoneStr);
 	mNotificationManager.notify(id, notif);
     }
@@ -322,6 +329,22 @@
     }
 
     /**
+     * Install the MemorizingTrustManager in the ConnectionConfiguration of Smack.
+     *
+     * @param config the configuration to modify
+     */
+    private void installMemorizingTrustManager(ConnectionConfiguration config) {
+	try {
+	    SSLContext sc = SSLContext.getInstance("TLS");
+	    sc.init(null, MemorizingTrustManager.getInstanceList(this),
+		    new java.security.SecureRandom());
+	    config.setCustomSSLContext(sc);
+	} catch (GeneralSecurityException e) {
+	    Log.w(TAG, "Unable to use MemorizingTrustManager", e);
+	}
+    }
+
+    /**
      * A sort of patch from this thread: http://www.igniterealtime.org/community/thread/31118. Avoid ClassCastException
      * by bypassing the classloading shit of Smack.
      * @param pm The ProviderManager.
--- a/src/com/beem/project/beem/ui/LoginAnim.java	Mon Aug 22 22:42:58 2011 +0200
+++ b/src/com/beem/project/beem/ui/LoginAnim.java	Mon Aug 22 23:02:11 2011 +0200
@@ -44,8 +44,12 @@
 package com.beem.project.beem.ui;
 
 import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -64,6 +68,8 @@
 import com.beem.project.beem.service.LoginAsyncTask;
 import com.beem.project.beem.service.aidl.IXmppFacade;
 
+import de.duenndns.ssl.MemorizingTrustManager;
+
 /**
  * This class is an activity which display an animation during the connection with the server.
  * @author Da Risk <darisk972@gmail.com>
@@ -72,6 +78,7 @@
 
     private static final String TAG = "LoginAnim";
     private static final Intent SERVICE_INTENT = new Intent();
+    private static final int RECEIVER_PRIORITY = 50;
     static {
 	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
     }
@@ -83,6 +90,7 @@
     private Button mCancelBt;
     private TextView mLoginState;
     private boolean mBinded;
+    private BroadcastReceiver mSslReceiver;
 
     /**
      * Constructor.
@@ -102,6 +110,18 @@
 	mRotateAnim = AnimationUtils.loadAnimation(this, R.anim.rotate_and_scale);
 	mCancelBt = (Button) findViewById(R.id.loginanim_cancel_button);
 	mCancelBt.setOnClickListener(new ClickListener());
+	mSslReceiver = new BroadcastReceiver() {
+	    public void onReceive(Context ctx, Intent i) {
+		try {
+		    Log.i(TAG, "Interception the SSL notification");
+		    PendingIntent pi = i.getParcelableExtra(MemorizingTrustManager.INTERCEPT_DECISION_INTENT_LAUNCH);
+		    pi.send();
+		    abortBroadcast();
+		} catch (PendingIntent.CanceledException e) {
+		    Log.e(TAG, "Error while displaying the SSL dialog", e);
+		}
+	    }
+	};
     }
 
     /* (non-Javadoc)
@@ -115,6 +135,11 @@
 	    mTask = new LoginTask();
 	if (!mBinded)
 	    mBinded = bindService(LoginAnim.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
+	IntentFilter filter = new IntentFilter(MemorizingTrustManager.INTERCEPT_DECISION_INTENT
+		+ "/" + getPackageName());
+	filter.setPriority(RECEIVER_PRIORITY);
+	registerReceiver(mSslReceiver, filter);
+
     }
 
     /* (non-Javadoc)
@@ -127,6 +152,7 @@
 	    unbindService(mServConn);
 	    mXmppFacade = null;
 	}
+	unregisterReceiver(mSslReceiver);
     }
 
     /* (non-Javadoc)