[tor-commits] r24645: {projects} Improved transproxy code for background service (projects/android/trunk/Orbot/src/org/torproject/android/service)

Nathan Freitas nathan at freitas.net
Sun Apr 17 06:04:28 UTC 2011


Author: n8fr8
Date: 2011-04-17 06:04:27 +0000 (Sun, 17 Apr 2011)
New Revision: 24645

Modified:
   projects/android/trunk/Orbot/src/org/torproject/android/service/Api.java
   projects/android/trunk/Orbot/src/org/torproject/android/service/ITorService.aidl
   projects/android/trunk/Orbot/src/org/torproject/android/service/TorService.java
   projects/android/trunk/Orbot/src/org/torproject/android/service/TorServiceConstants.java
   projects/android/trunk/Orbot/src/org/torproject/android/service/TorServiceUtils.java
   projects/android/trunk/Orbot/src/org/torproject/android/service/TorTransProxy.java
Log:
Improved transproxy code for background service


Modified: projects/android/trunk/Orbot/src/org/torproject/android/service/Api.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/service/Api.java	2011-04-17 06:03:32 UTC (rev 24644)
+++ projects/android/trunk/Orbot/src/org/torproject/android/service/Api.java	2011-04-17 06:04:27 UTC (rev 24645)
@@ -801,23 +801,29 @@
 		boolean changed = false;
 		try {
 			// Check iptables_g1
-			File file = new File(ctx.getDir("bin",0), "iptables_g1");
+			File file = new File(ctx.getDir("bin",0), "iptables");
+			
 			if ((!file.exists()) && isARMv6()) {
 				copyRawFile(ctx, R.raw.iptables_g1, file, "755");
 				changed = true;
 			}
+			
 			// Check iptables_n1
-			file = new File(ctx.getDir("bin",0), "iptables_n1");
+			file = new File(ctx.getDir("bin",0), "iptables");
 			if ((!file.exists()) && (!isARMv6())) {
 				copyRawFile(ctx, R.raw.iptables_n1, file, "755");
 				changed = true;
 			}
+			
 			// Check busybox
+			/*
 			file = new File(ctx.getDir("bin",0), "busybox_g1");
 			if (!file.exists()) {
 				copyRawFile(ctx, R.raw.busybox_g1, file, "755");
 				changed = true;
 			}
+			*/
+			
 			if (changed) {
 				Toast.makeText(ctx, R.string.status_install_success, Toast.LENGTH_LONG).show();
 			}

Modified: projects/android/trunk/Orbot/src/org/torproject/android/service/ITorService.aidl
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/service/ITorService.aidl	2011-04-17 06:03:32 UTC (rev 24644)
+++ projects/android/trunk/Orbot/src/org/torproject/android/service/ITorService.aidl	2011-04-17 06:04:27 UTC (rev 24645)
@@ -37,6 +37,11 @@
     * Set configuration
     **/
     boolean updateConfiguration (String name, String value, boolean saveToDisk);
+ 
+    /**
+    * Set configuration
+    **/
+    void processSettings();
     
     /**
     * Set configuration

Modified: projects/android/trunk/Orbot/src/org/torproject/android/service/TorService.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/service/TorService.java	2011-04-17 06:03:32 UTC (rev 24644)
+++ projects/android/trunk/Orbot/src/org/torproject/android/service/TorService.java	2011-04-17 06:04:27 UTC (rev 24645)
@@ -4,6 +4,7 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.Socket;
 import java.util.ArrayList;
@@ -18,8 +19,10 @@
 
 import org.torproject.android.AppManager;
 import org.torproject.android.Orbot;
+import org.torproject.android.ProcessSettingsAsyncTask;
 import org.torproject.android.R;
 import org.torproject.android.TorConstants;
+import org.torproject.android.Utils;
 
 import android.app.AlertDialog;
 import android.app.Notification;
@@ -31,6 +34,7 @@
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.preference.PreferenceManager;
@@ -39,6 +43,7 @@
 public class TorService extends Service implements TorServiceConstants, Runnable, EventHandler
 {
 	
+	private static boolean ENABLE_DEBUG_LOG = false;
 	
 	private static int currentStatus = STATUS_READY;
 		
@@ -48,6 +53,7 @@
 	private static TorService _torInstance;
 	
 	private static final int NOTIFY_ID = 1;
+	private static int NOTIFY_ID_ERROR = 2;
 	
 	private static final int MAX_START_TRIES = 3;
 
@@ -69,11 +75,23 @@
     public void onCreate() {
     	super.onCreate();
        
-    	Log.i(TAG, "serviced created");
+    	logMessage("serviced created");
       
     }
     
+    public static void logMessage(String msg)
+    {
+    	if (ENABLE_DEBUG_LOG)
+    		Log.d(TAG,msg);
+    }
     
+    public static void logException(String msg, Exception e)
+    {
+    	if (ENABLE_DEBUG_LOG)
+    		Log.e(TAG,msg,e);
+    }
+    
+    
     private boolean findExistingProc ()
     {
     	 int procId = TorServiceUtils.findProcessId(torBinaryPath);
@@ -96,13 +114,12 @@
 			} catch (RuntimeException e) {
 				Log.d(TAG,"Unable to connect to existing Tor instance,",e);
 				currentStatus = STATUS_OFF;
-				this.stopTor();
 				
 			} catch (Exception e) {
 				Log.d(TAG,"Unable to connect to existing Tor instance,",e);
 				currentStatus = STATUS_OFF;
-				this.stopTor();
 				
+				
 			}
  		}
  		
@@ -144,7 +161,7 @@
     }
 	
    
-	private void showToolbarNotification (String notifyMsg, int icon)
+	private void showToolbarNotification (String notifyMsg, int notifyId, int icon)
 	{
 	
 		
@@ -166,7 +183,7 @@
 		notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
 
 
-		mNotificationManager.notify(NOTIFY_ID, notification);
+		mNotificationManager.notify(notifyId, notification);
 
 
 	}
@@ -196,7 +213,7 @@
 		} catch (Exception e) {
 
 			logNotice("unable to find tor binaries: " + e.getMessage());
-	    	showToolbarNotification(e.getMessage(), R.drawable.tornotificationoff);
+	    	showToolbarNotification(e.getMessage(), NOTIFY_ID_ERROR, R.drawable.tornotificationoff);
 
 			Log.e(TAG, "error checking tor binaries", e);
 		}
@@ -226,13 +243,12 @@
 	     try
 	     {
 		   initTor();
-		   
-		   
+		   isRunning = true;
 	     }
 	     catch (Exception e)
 	     {
 	    	 currentStatus = STATUS_OFF;
-	    	 this.showToolbarNotification(getString(R.string.status_disabled), R.drawable.tornotification);
+	    	 this.showToolbarNotification(getString(R.string.status_disabled), NOTIFY_ID_ERROR, R.drawable.tornotification);
 	    	 Log.d(TAG,"Unable to start Tor: " + e.getMessage(),e);
 	     }
 		}
@@ -243,10 +259,11 @@
     {
     	super.onDestroy();
     	
+    	Log.d(TAG,"onDestroy called");
+    	
     	  // Unregister all callbacks.
         mCallbacks.kill();
       
-    	stopTor();
     }
     
     private void stopTor ()
@@ -259,7 +276,7 @@
 				
     		currentStatus = STATUS_READY;
     
-    		showToolbarNotification (getString(R.string.status_disabled),R.drawable.tornotificationoff);
+    		showToolbarNotification (getString(R.string.status_disabled),NOTIFY_ID,R.drawable.tornotificationoff);
     		sendCallbackStatusMessage(getString(R.string.status_disabled));
 
     		setupTransProxy(false);
@@ -275,7 +292,7 @@
     
  
    
-    
+    /*
     public void reloadConfig ()
     {
     	try
@@ -294,8 +311,212 @@
     	{
     		Log.d(TAG,"Unable to reload configuration",e);
     	}
-    }
+    }*/
     
+    
+    /*
+	private void loadTorSettingsFromPreferences () throws RemoteException
+	{
+		try
+		{
+    		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+    		ENABLE_DEBUG_LOG = prefs.getBoolean("pref_enable_logging",false);
+    		Log.i(TAG,"debug logging:" + ENABLE_DEBUG_LOG);
+    		
+			boolean useBridges = prefs.getBoolean(TorConstants.PREF_BRIDGES_ENABLED, false);
+			
+			//boolean autoUpdateBridges = prefs.getBoolean(PREF_BRIDGES_UPDATED, false);
+	
+	        boolean becomeRelay = prefs.getBoolean(TorConstants.PREF_OR, false);
+	
+	        boolean ReachableAddresses = prefs.getBoolean(TorConstants.PREF_REACHABLE_ADDRESSES,false);
+	
+	        boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
+			
+			boolean enableTransparentProxy = prefs.getBoolean(TorConstants.PREF_TRANSPARENT, false);		
+			mBinder.updateTransProxy();
+			
+			String bridgeList = prefs.getString(TorConstants.PREF_BRIDGES_LIST,"");
+	
+			if (useBridges)
+			{
+				if (bridgeList == null || bridgeList.length() == 0)
+				{
+				
+					showAlert("Bridge Error","In order to use the bridge feature, you must enter at least one bridge IP address." +
+							"Send an email to bridges at torproject.org with the line \"get bridges\" by itself in the body of the mail from a gmail account.");
+					
+				
+					return;
+				}
+				
+				
+				mBinder.updateConfiguration("UseBridges", "1", false);
+					
+				String bridgeDelim = "\n";
+				
+				if (bridgeList.indexOf(",") != -1)
+				{
+					bridgeDelim = ",";
+				}
+				
+				StringTokenizer st = new StringTokenizer(bridgeList,bridgeDelim);
+				while (st.hasMoreTokens())
+				{
+	
+					mBinder.updateConfiguration("bridge", st.nextToken(), false);
+	
+				}
+				
+				mBinder.updateConfiguration("UpdateBridgesFromAuthority", "0", false);
+				
+			}
+			else
+			{
+				mBinder.updateConfiguration("UseBridges", "0", false);
+	
+			}
+	
+	        try
+	        {
+	            if (ReachableAddresses)
+	            {
+	                String ReachableAddressesPorts =
+	                    prefs.getString(TorConstants.PREF_REACHABLE_ADDRESSES_PORTS, "*:80,*:443");
+	                
+	                mBinder.updateConfiguration("ReachableAddresses", ReachableAddressesPorts, false);
+	
+	            }
+	            else
+	            {
+	            	mBinder.updateConfiguration("ReachableAddresses", "", false);
+	            }
+	        }
+	        catch (Exception e)
+	        {
+	           showAlert("Config Error","Your ReachableAddresses settings caused an exception!");
+	        }
+	
+	        try
+	        {
+	            if (becomeRelay && (!useBridges) && (!ReachableAddresses))
+	            {
+	                int ORPort =  Integer.parseInt(prefs.getString(TorConstants.PREF_OR_PORT, "9001"));
+	                String nickname = prefs.getString(TorConstants.PREF_OR_NICKNAME, "Orbot");
+	
+	                mBinder.updateConfiguration("ORPort", ORPort + "", false);
+	                mBinder.updateConfiguration("Nickname", nickname, false);
+	                mBinder.updateConfiguration("ExitPolicy", "reject *:*", false);
+	
+	            }
+	            else
+	            {
+	            	mBinder.updateConfiguration("ORPort", "", false);
+	            	mBinder.updateConfiguration("Nickname", "", false);
+	            	mBinder.updateConfiguration("ExitPolicy", "", false);
+	            }
+	        }
+	        catch (Exception e)
+	        {
+	            showAlert("Uh-oh!","Your relay settings caused an exception!");
+	          
+	            return;
+	        }
+	
+	        if (enableHiddenServices)
+	        {
+	        	mBinder.updateConfiguration("HiddenServiceDir","/data/data/org.torproject.android/", false);
+	        	
+	        	String hsPorts = prefs.getString("pref_hs_ports","");
+	        	
+	        	StringTokenizer st = new StringTokenizer (hsPorts,",");
+	        	String hsPortConfig = null;
+	        	
+	        	while (st.hasMoreTokens())
+	        	{
+	        		hsPortConfig = st.nextToken();
+	        		
+	        		if (hsPortConfig.indexOf(":")==-1) //setup the port to localhost if not specifed
+	        		{
+	        			hsPortConfig = hsPortConfig + " 127.0.0.1:" + hsPortConfig;
+	        		}
+	        		
+	        		mBinder.updateConfiguration("HiddenServicePort",hsPortConfig, false);
+	        	}
+	        	
+	        	//force save now so the hostname file gets generated
+	        	mBinder.saveConfiguration();
+	        	 
+	        	String onionHostname = getHiddenServiceHostname();
+	        	
+	        	if (onionHostname != null)
+	        	{
+	        		
+	        		Editor pEdit = prefs.edit();
+	    			pEdit.putString("pref_hs_hostname",onionHostname);
+	    			pEdit.commit();
+	        		
+	        	}
+	        }
+	        else
+	        {
+	        	mBinder.updateConfiguration("HiddenServiceDir","", false);	       
+	        }
+	        
+	        mBinder.saveConfiguration();
+	        
+		 }
+        catch (Exception e)
+        {
+            showAlert("Uh-oh!","There was an error updating your settings");
+          
+            Log.w(TAG, "processSettings()", e);
+            
+            return;
+        }
+
+	}*/
+
+	private void getHiddenServiceHostname ()
+	{
+
+    	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		
+        boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
+
+        if (enableHiddenServices)
+        {
+	    	File file = new File(appDataHome, "hostname");
+	    	
+	    	if (file.exists())
+	    	{
+		    	try {
+					String onionHostname = Utils.readString(new FileInputStream(file));
+					showToolbarNotification("hidden service on: " + onionHostname, NOTIFY_ID_ERROR, R.drawable.tornotification);
+					Editor pEdit = prefs.edit();
+					pEdit.putString("pref_hs_hostname",onionHostname);
+					pEdit.commit();
+				
+					
+				} catch (FileNotFoundException e) {
+					logException("unable to read onion hostname file",e);
+					showToolbarNotification("unable to read hidden service name", NOTIFY_ID_ERROR, R.drawable.tornotification);
+					return;
+				}
+	    	}
+	    	else
+	    	{
+				showToolbarNotification("unable to read hidden service name", NOTIFY_ID_ERROR, R.drawable.tornotification);
+	
+	    		
+	    	}
+        }
+        
+        return;
+	}
+	
+    
     private void killTorProcess () throws Exception
     {
 		//android.os.Debug.waitForDebugger();
@@ -348,96 +569,15 @@
     {
     	if (msg != null && msg.trim().length() > 0)
     	{
-    		if (LOG_OUTPUT_TO_DEBUG)        	
+    		if (ENABLE_DEBUG_LOG)        	
         		Log.d(TAG, msg);
     	
     		sendCallbackLogMessage(msg);
     	}
     }
     
-    /*
-    private String findAPK ()
-    {
-    	
-    	String apkBase = "/data/app/";
-    	
-    	String APK_EXT = ".apk";
-    	
-    	int MAX_TRIES = 10;
-    	
-    	String buildPath = apkBase + TOR_APP_USERNAME + APK_EXT;
-    	logNotice("Checking APK location: " + buildPath);
-		
-    	File fileApk = new File(buildPath);
-    	
-    	if (fileApk.exists())
-    		return fileApk.getAbsolutePath();
-    	
-    	for (int i = 0; i < MAX_TRIES; i++)
-    	{
-    		buildPath = apkBase + TOR_APP_USERNAME + '-' + i + APK_EXT;
-    		fileApk = new File(buildPath);
-    	
-    		logNotice( "Checking APK location: " + buildPath);
-    		
-    		if (fileApk.exists())
-    			return fileApk.getAbsolutePath();
-    	}
-    	
-    	String apkBaseExt = "/mnt/asec/" + TOR_APP_USERNAME;
-    	String pkgFile = "/pkg.apk";
-    	
-    	buildPath = apkBaseExt + pkgFile;
-    	fileApk = new File(buildPath);
-    	
-    	logNotice( "Checking external storage APK location: " + buildPath);
-		
-		if (fileApk.exists())
-			return fileApk.getAbsolutePath();
-		
-    	for (int i = 0; i < MAX_TRIES; i++)
-    	{
-    		buildPath = apkBaseExt + '-' + i + pkgFile;
-    		fileApk = new File(buildPath);
-    	
-    		logNotice( "Checking external storage APK location: " + buildPath);
-    		
-    		if (fileApk.exists())
-    			return fileApk.getAbsolutePath();
-    	}
-    	
 
-    	apkBase = "/sd-ext/app/";
-    	
-    	APK_EXT = ".apk";
-    	
-    	MAX_TRIES = 10;
-    	
-    	buildPath = apkBase + TOR_APP_USERNAME + APK_EXT;
-    	logNotice("Checking Apps2SD APK location: " + buildPath);
-		
-    	fileApk = new File(buildPath);
-    	
-    	if (fileApk.exists())
-    		return fileApk.getAbsolutePath();
-    	
-    	for (int i = 0; i < MAX_TRIES; i++)
-    	{
-    		buildPath = apkBase + TOR_APP_USERNAME + '-' + i + APK_EXT;
-    		fileApk = new File(buildPath);
-    	
-    		logNotice( "Checking Apps2SD location: " + buildPath);
-    		
-    		if (fileApk.exists())
-    			return fileApk.getAbsolutePath();
-    	}
-    	
-    	
-    	
-    	return null;
-    }*/
     
-    
     private boolean checkTorBinaries () throws Exception
     {
     	//android.os.Debug.waitForDebugger();
@@ -475,7 +615,7 @@
     		{
     			logNotice(getString(R.string.status_install_success));
     	
-    			showToolbarNotification(getString(R.string.status_install_success), R.drawable.tornotification);
+    			showToolbarNotification(getString(R.string.status_install_success), NOTIFY_ID, R.drawable.tornotification);
     		
     		}
     		else
@@ -522,30 +662,100 @@
     		
     		killTorProcess ();
     		
-    		
-    		new Thread()
-    		{
-    			public void run ()
-    			{
-    				try {
-    		    		runTorShellCmd();
-    		    		
-    		    		setupTransProxy(true);
-    		    		
-       		    		runPrivoxyShellCmd();
+    		try {
 
+	    		runTorShellCmd();
+	    		runPrivoxyShellCmd();
+	    		setupTransProxy(true);
 
-    				} catch (Exception e) {
-    			    	Log.d(TAG,"Unable to start Tor: " + e.getMessage(),e);	
-    			    	sendCallbackStatusMessage("Unable to start Tor: " + e.getMessage());
-    			    	stopTor();
-    			    } 
-    			}
-    		}.start();
+			} catch (Exception e) {
+		    	logException("Unable to start Tor: " + e.getMessage(),e);	
+		    	sendCallbackStatusMessage("Unable to start Tor: " + e.getMessage());
+		    	
+		    } 
     		
-    		
     }
     
+    
+    private boolean setupTransProxy (boolean activate) throws Exception
+ 	{
+    	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ 		boolean hasRoot;
+ 		
+ 		if (prefs.contains("has_root"))
+ 		{
+ 			hasRoot = prefs.getBoolean("has_root",false);
+ 		}
+ 		else
+ 		{
+ 			hasRoot = TorServiceUtils.checkRootAccess();
+ 			Editor pEdit = prefs.edit();
+ 			pEdit.putBoolean("has_root",hasRoot);
+ 			pEdit.commit();
+ 		}
+ 		
+ 		if (!hasRoot)
+ 			return false;
+ 		
+    	if (activate)
+    	{
+	 		
+	 		boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false);
+	 		boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false);
+	 		boolean transProxyPortFallback = prefs.getBoolean("pref_transparent_port_fallback", false);
+	 		
+	     	TorService.logMessage ("Transparent Proxying: " + enableTransparentProxy);
+	     	
+	     	String portProxyList = prefs.getString("pref_port_list", "");
+	
+	 		if (enableTransparentProxy)
+	 		{
+				showAlert("Status", "Setting up transparent proxying...");
+
+				//TorTransProxy.setDNSProxying();
+				int code = TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this),transProxyAll);
+			
+				TorService.logMessage ("TorTransProxy resp code: " + code);
+				
+				if (code == 0)
+				{
+					showAlert("Status", "Transparent proxying ENABLED");
+				}
+				else
+				{
+					showAlert("Status", "WARNING: error starting transparent proxying!");
+				}
+				
+				//this is for Androids w/o owner module support as a circumvention only fallback
+				if (transProxyPortFallback)
+				{
+					StringTokenizer st = new StringTokenizer(portProxyList, ",");
+					
+					while (st.hasMoreTokens())
+						TorTransProxy.setTransparentProxyingByPort(this, Integer.parseInt(st.nextToken()));
+					
+				}
+				
+				return true;
+	 				
+	 		}
+	 		else
+	 		{
+	 			TorTransProxy.purgeIptables(this);
+				showAlert("Status", "Transparent proxying DISABLED");
+
+	 		}
+    	}
+    	else
+    	{	 	
+    		TorTransProxy.purgeIptables(this);
+			showAlert("Status", "Transparent proxying DISABLED");
+
+    	}
+    	
+ 		return true;
+ 	}
+    
     private void runTorShellCmd() throws Exception
     {
     	
@@ -598,9 +808,11 @@
 		
 			logNotice("Tor process id=" + procId);
 			
-			showToolbarNotification(getString(R.string.status_starting_up), R.drawable.tornotification);
+			showToolbarNotification(getString(R.string.status_starting_up), NOTIFY_ID, R.drawable.tornotification);
 			
 			initControlConnection ();
+
+	        applyPreferences();
 	    }
     }
     
@@ -644,7 +856,6 @@
     		}
     		
 			sendCallbackLogMessage("Privoxy is running on port: " + PORT_HTTP);
-			Thread.sleep(100);
 			
     		logNotice("Privoxy process id=" + privoxyProcId);
 			
@@ -699,7 +910,6 @@
 	
 				        addEventHandler();
 				        
-				        applyPreferences();
 			        }
 			        
 			        break; //don't need to retry
@@ -811,9 +1021,9 @@
 
 	            Thread thread = new Thread(this);
 	            thread.start();
-
+	           
 			}
-			else
+			else if (profile == PROFILE_OFF)
 			{
 				currentStatus = STATUS_OFF;
 	            sendCallbackStatusMessage ("shutting down...");
@@ -828,29 +1038,37 @@
 
 	public void message(String severity, String msg) {
 		
+		
 		logNotice(  "[Tor Control Port] " + severity + ": " + msg);
           
           if (msg.indexOf(TOR_CONTROL_PORT_MSG_BOOTSTRAP_DONE)!=-1)
           {
         	  currentStatus = STATUS_ON;
-        	  showToolbarNotification (getString(R.string.status_activated),R.drawable.tornotificationon);
-  			  
+        	
+
+   		   	getHiddenServiceHostname ();
+   		   
           }
-         
+          
+          
+    	  showToolbarNotification (getString(R.string.status_activated),NOTIFY_ID,R.drawable.tornotificationon);
+    		 
           sendCallbackStatusMessage (msg);
           
 	}
 
 	private void showAlert(String title, String msg)
 	{
-		 
+		 /*
 		 new AlertDialog.Builder(this)
          .setTitle(title)
          .setMessage(msg)
          .setPositiveButton(android.R.string.ok, null)
          .show();
+         */
+		showToolbarNotification(msg, NOTIFY_ID_ERROR, R.drawable.tornotification);
 	}
-
+	
 	public void newDescriptors(List<String> orList) {
 		
 	}
@@ -858,7 +1076,7 @@
 
 	public void orConnStatus(String status, String orName) {
 		
-		if (LOG_OUTPUT_TO_DEBUG)
+		if (ENABLE_DEBUG_LOG)
 		{
 			StringBuilder sb = new StringBuilder();
 			sb.append("orConnStatus (");
@@ -873,7 +1091,7 @@
 
 	public void streamStatus(String status, String streamID, String target) {
 		
-		if (LOG_OUTPUT_TO_DEBUG)
+		if (ENABLE_DEBUG_LOG)
 		{
 			StringBuilder sb = new StringBuilder();
 			sb.append("StreamStatus (");
@@ -888,7 +1106,7 @@
 
 	public void unrecognized(String type, String msg) {
 		
-		if (LOG_OUTPUT_TO_DEBUG)
+		if (ENABLE_DEBUG_LOG)
 		{
 			StringBuilder sb = new StringBuilder();
 			sb.append("Message (");
@@ -903,20 +1121,23 @@
 
 	public void bandwidthUsed(long read, long written) {
 		
-		StringBuilder sb = new StringBuilder();
-		sb.append("Bandwidth used: ");
-		sb.append(read/1000);
-		sb.append("kb read / ");
-		sb.append(written/1000);
-		sb.append("kb written");
-		
-		logNotice(sb.toString());
+		if (ENABLE_DEBUG_LOG)
+		{
+			StringBuilder sb = new StringBuilder();
+			sb.append("Bandwidth used: ");
+			sb.append(read/1000);
+			sb.append("kb read / ");
+			sb.append(written/1000);
+			sb.append("kb written");
+			
+			logNotice(sb.toString());
+		}
 
 	}
 
 	public void circuitStatus(String status, String circID, String path) {
 		
-		if (LOG_OUTPUT_TO_DEBUG)
+		if (ENABLE_DEBUG_LOG)
 		{
 			StringBuilder sb = new StringBuilder();
 			sb.append("Circuit (");
@@ -947,7 +1168,7 @@
 		catch (Exception e)
 		{
 			logNotice("unable to find tor binaries: " + e.getMessage());
-	    	showToolbarNotification(e.getMessage(), R.drawable.tornotificationoff);
+	    	showToolbarNotification(e.getMessage(), NOTIFY_ID_ERROR, R.drawable.tornotificationoff);
 
 			Log.d(TAG,"Unable to check for Tor binaries",e);
 			return null;
@@ -977,7 +1198,8 @@
      */
     private final ITorService.Stub mBinder = new ITorService.Stub() {
     	
-        public void registerCallback(ITorServiceCallback cb) {
+       
+		public void registerCallback(ITorServiceCallback cb) {
             if (cb != null) mCallbacks.register(cb);
         }
         public void unregisterCallback(ITorServiceCallback cb) {
@@ -993,6 +1215,18 @@
         	
         }
         
+        public void processSettings ()
+        {
+        	
+        	
+        	try {
+				applyPreferences();
+			} catch (RemoteException e) {
+				logException ("error applying prefs",e);
+			}
+        	
+        }
+        
         public boolean updateTransProxy ()
         {
         	
@@ -1044,6 +1278,7 @@
         	
         	return null;
         }
+        
         /**
          * Set configuration
          **/
@@ -1057,7 +1292,7 @@
 	        
         	if (value == null || value.length() == 0)
         	{
-        		
+        		resetBuffer.add(name);
         		/*
         		if (conn != null)
         		{
@@ -1066,10 +1301,7 @@
 					} catch (IOException e) {
 						Log.w(TAG, "Unable to reset conf",e);
 					}
-        		}
-        		*/
-        		
-        		resetBuffer.add(name);
+        		}*/
         	}
         	else
         		configBuffer.add(name + ' ' + value);
@@ -1083,13 +1315,13 @@
         	{
 	        	if (conn != null)
 	        	{
+	        		
 	        		 if (resetBuffer != null && resetBuffer.size() > 0)
 				        {	
 				        	conn.resetConf(resetBuffer);
 				        	resetBuffer = null;
 				        }
 	   	       
-	        		 
 	        		 if (configBuffer != null && configBuffer.size() > 0)
 				        {
 	        			 	
@@ -1117,24 +1349,21 @@
     
     private ArrayList<String> callbackBuffer = new ArrayList<String>();
     private boolean inCallbackStatus = false;
-    private boolean inCallbackLog = false;
+    private boolean inCallback = false;
     
-    private void sendCallbackStatusMessage (String newStatus)
+    private synchronized void sendCallbackStatusMessage (String newStatus)
     {
     	 
     	if (mCallbacks == null)
     		return;
     	
-    	
-    	
         // Broadcast to all clients the new value.
         final int N = mCallbacks.beginBroadcast();
         
-        inCallbackStatus = true;
+        inCallback = true;
         
         if (N > 0)
         {
-        
         	 for (int i=0; i<N; i++) {
 		            try {
 		                mCallbacks.getBroadcastItem(i).statusChanged(newStatus);
@@ -1148,58 +1377,58 @@
         }
         
         mCallbacks.finishBroadcast();
-        inCallbackStatus = false;
+        inCallback = false;
     }
     
-    private void sendCallbackLogMessage (String logMessage)
+    private synchronized void sendCallbackLogMessage (String logMessage)
     {
     	 
     	if (mCallbacks == null)
     		return;
     	
     	callbackBuffer.add(logMessage);
-    	
-    	
-        // Broadcast to all clients the new value.
-        final int N = mCallbacks.beginBroadcast();
-        
-        inCallbackLog = true;
 
+    	if (!inCallback)
+    	{
+
+	        inCallback = true;
+	        // Broadcast to all clients the new value.
+	        final int N = mCallbacks.beginBroadcast();
+	        
+	
+	        if (N > 0)
+	        {
+	        
+	        	Iterator<String> it = callbackBuffer.iterator();
+	        	String status = null;
+	        	
+	        	while (it.hasNext())
+	        	{
+	        		status = it.next();
+	        		
+			        for (int i=0; i<N; i++) {
+			            try {
+			                mCallbacks.getBroadcastItem(i).logMessage(status);
+			                
+			            } catch (RemoteException e) {
+			                // The RemoteCallbackList will take care of removing
+			                // the dead object for us.
+			            }
+			        }
+	        	}
+		        
+		        callbackBuffer.clear();
+	        }
+	        
+	        mCallbacks.finishBroadcast();
+	        inCallback = false;
+    	}
     	
-        if (N > 0)
-        {
-        
-        	Iterator<String> it = callbackBuffer.iterator();
-        	String status = null;
-        	
-        	while (it.hasNext())
-        	{
-        		status = it.next();
-        		
-		        for (int i=0; i<N; i++) {
-		            try {
-		                mCallbacks.getBroadcastItem(i).logMessage(status);
-		                
-		                
-		            } catch (RemoteException e) {
-		                // The RemoteCallbackList will take care of removing
-		                // the dead object for us.
-		            }
-		        }
-        	}
-	        
-	        callbackBuffer.clear();
-        }
-        
-        mCallbacks.finishBroadcast();
-        inCallbackLog = false;
     }
     
-    private void applyPreferences () throws RemoteException
+    private boolean applyPreferences () throws RemoteException
     {
     	
-    	
-    	
     	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
 		
 		boolean useBridges = prefs.getBoolean(TorConstants.PREF_BRIDGES_ENABLED, false);
@@ -1214,11 +1443,19 @@
 
 		boolean enableTransparentProxy = prefs.getBoolean(TorConstants.PREF_TRANSPARENT, false);
 		
+		try
+		{
+			setupTransProxy(currentStatus != STATUS_OFF); 		
+		}
+		catch (Exception e)
+		{
+			logException("unable to setup transproxy",e);
+		}
 		
-		String bridgeList = prefs.getString(TorConstants.PREF_BRIDGES_LIST,"");
-
 		if (useBridges)
 		{
+			String bridgeList = prefs.getString(TorConstants.PREF_BRIDGES_LIST,"");
+
 			if (bridgeList == null || bridgeList.length() == 0)
 			{
 			
@@ -1226,7 +1463,7 @@
 						"Send an email to bridges at torproject.org with the line \"get bridges\" by itself in the body of the mail from a gmail account.");
 				
 			
-				return;
+				return false;
 			}
 			
 			
@@ -1274,6 +1511,8 @@
         catch (Exception e)
         {
            showAlert("Config Error","Your ReachableAddresses settings caused an exception!");
+           
+           return false;
         }
 
         try
@@ -1299,12 +1538,12 @@
         {
             showAlert("Uh-oh!","Your relay settings caused an exception!");
           
-            return;
+            return false;
         }
 
         if (enableHiddenServices)
         {
-        	mBinder.updateConfiguration("HiddenServiceDir","/data/data/org.torproject.android/", false);
+        	mBinder.updateConfiguration("HiddenServiceDir",appDataHome, false);
         	
         	String hsPorts = prefs.getString("pref_hs_ports","");
         	
@@ -1332,77 +1571,10 @@
         }
         
         mBinder.saveConfiguration();
-		
+	
+        return true;
     }
     
     
-    private boolean setupTransProxy (boolean enabled) throws Exception
-	{
-    	
-		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplication());
-		
-		if (prefs.contains("has_root"))
-		{
-			hasRoot = prefs.getBoolean("has_root",false);//TorServiceUtils.checkRootAccess();
-		}
-		else
-		{
-			hasRoot = TorServiceUtils.checkRootAccess();
-			Editor pEdit = prefs.edit();
-			pEdit.putBoolean("has_root",hasRoot);
-			pEdit.commit();
-		}
-		
-		boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false);
-		boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false);
-	
-		boolean transProxyPortFallback = prefs.getBoolean("pref_transparent_port_fallback", false);
-		
-    	logNotice ("Transparent Proxying: " + enableTransparentProxy);
-    	
-    	String portProxyList = prefs.getString("pref_port_list", "");
-
-		if (enabled)
-		{
-		
-
-			if (hasRoot)
-			{
-				if (enableTransparentProxy)
-				{
-				
-				
-					//TorTransProxy.setDNSProxying();
-					int code = TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this),transProxyAll);
-				
-					logNotice ("TorTransProxy resp code: " + code);
-					
-					//this is for Androids w/o owner module support as a circumvention only fallback
-					if (transProxyPortFallback)
-					{
-						StringTokenizer st = new StringTokenizer(portProxyList, ",");
-						
-						while (st.hasMoreTokens())
-							TorTransProxy.setTransparentProxyingByPort(this, Integer.parseInt(st.nextToken()));
-						
-					}
-					
-					return true;
-				
-				
-				}
-				else
-				{
-					TorTransProxy.purgeIptables(this);
-	
-				}
-			}
-		}
-		else if (hasRoot)
-		{
-			TorTransProxy.purgeIptables(this);
-		}
-		
-		return true;
-	}
+   
 }

Modified: projects/android/trunk/Orbot/src/org/torproject/android/service/TorServiceConstants.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/service/TorServiceConstants.java	2011-04-17 06:03:32 UTC (rev 24644)
+++ projects/android/trunk/Orbot/src/org/torproject/android/service/TorServiceConstants.java	2011-04-17 06:04:27 UTC (rev 24645)
@@ -6,8 +6,6 @@
 
 	public final static String TAG = "ORBOT";
 
-	public static boolean LOG_OUTPUT_TO_DEBUG = true;
-
 	public final static String TOR_APP_USERNAME = "org.torproject.android";
 	
 	public final static String ASSETS_BASE = "assets/";
@@ -78,4 +76,9 @@
     
     public final static int PROFILE_OFF = -1;
     public final static int PROFILE_ON = 1;
+
+    public static final int STATUS_MSG = 1;
+    public static final int ENABLE_TOR_MSG = 2;
+    public static final int DISABLE_TOR_MSG = 3;
+    public static final int LOG_MSG = 4;
 }

Modified: projects/android/trunk/Orbot/src/org/torproject/android/service/TorServiceUtils.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/service/TorServiceUtils.java	2011-04-17 06:03:32 UTC (rev 24644)
+++ projects/android/trunk/Orbot/src/org/torproject/android/service/TorServiceUtils.java	2011-04-17 06:04:27 UTC (rev 24645)
@@ -34,22 +34,19 @@
 			
 		} catch (IOException e) {
 			//this means that there is no root to be had (normally) so we won't log anything
+			TorService.logException("Error checking for root access",e);
+			
 		}
 		catch (Exception e) {
-			Log.w(TAG,"Error checking for root access: " + e.getMessage());
+			TorService.logException("Error checking for root access",e);
 			//this means that there is no root to be had (normally)
 		}
 		
-		logNotice("Could not acquire root permissions");
+		TorService.logMessage("Could not acquire root permissions");
 		return false;
 	}
 	
 	
-	private static void logNotice (String msg)
-	{
-		if (LOG_OUTPUT_TO_DEBUG)
-			Log.d(TAG, msg);
-	}
 	
 	public static int findProcessId(String command) 
 	{
@@ -106,7 +103,7 @@
         	}
         	catch (NumberFormatException e)
         	{
-        		logNotice("unable to parse process pid: " + line);
+        		TorService.logException("unable to parse process pid: " + line,e);
         	}
         }
             
@@ -153,7 +150,7 @@
 	
 	public static int doShellCommand(String[] cmds, StringBuilder log, boolean runAsRoot, boolean waitFor) throws Exception
 	{
-		logNotice("executing shell cmds: " + cmds[0] + "; runAsRoot=" + runAsRoot);
+		TorService.logMessage("executing shell cmds: " + cmds[0] + "; runAsRoot=" + runAsRoot);
 		
 		 	
 		Process proc = null;
@@ -201,7 +198,7 @@
 				log.append(exitCode);
 				log.append("\n");
 				
-				logNotice("command process exit value: " + exitCode);
+				TorService.logMessage("command process exit value: " + exitCode);
 			}
         
         

Modified: projects/android/trunk/Orbot/src/org/torproject/android/service/TorTransProxy.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/service/TorTransProxy.java	2011-04-17 06:03:32 UTC (rev 24644)
+++ projects/android/trunk/Orbot/src/org/torproject/android/service/TorTransProxy.java	2011-04-17 06:04:27 UTC (rev 24645)
@@ -11,55 +11,11 @@
 	
 	private final static String TAG = TorServiceConstants.TAG;
 		
-	//private static String BASE_DIR = "/data/data/" + TorServiceConstants.TOR_APP_USERNAME + "/";
 
-	private static void logNotice (String msg)
-	{
-		if (LOG_OUTPUT_TO_DEBUG)
-			Log.d(TAG, msg);
-	}
-
-	/**
-	 * Check if we have root access
-	 * @return boolean true if we have root
-	 */
-	/*
-	public static String getIPTablesVersion() {
 	
-
-		StringBuilder log = new StringBuilder();
-		
-		try {
-			
-			// Run an empty script just to check root access
-			String[] cmd = {"iptables -v"};
-			int code = TorServiceUtils.doShellCommand(cmd, log, true, true);
-			String msg = log.toString();
-			logNotice(cmd[0] + ";errCode=" + code + ";resp=" + msg);
-			
-			
-			String out = log.toString();
-			if (out.indexOf(" v")!=-1)
-			{
-			
-				out = out.substring(out.indexOf(" v")+2);
-				out = out.substring(0,out.indexOf(":"));
-				
-				return out.trim();
-			}
-			
-			
-		} catch (Exception e) {
-			Log.w(TAG,"Error checking iptables version: " + e.getMessage() ,e);
-		}
-		
-		logNotice("Could not acquire check iptables: " + log.toString());
-		return null;
-	}*/
-	
 	public static int purgeIptables(Context context) throws Exception {
 		
-	String ipTablesPath = new File(context.getDir("bin", 0),"iptables_n1").getAbsolutePath();
+	String ipTablesPath = new File(context.getDir("bin", 0),"iptables").getAbsolutePath();
 		
     	final StringBuilder script = new StringBuilder();
     	
@@ -78,7 +34,8 @@
     	String[] cmd = {script.toString()};	    	
 		code = TorServiceUtils.doShellCommand(cmd, res, true, true);		
 		String msg = res.toString();
-		logNotice(cmd[0] + ";errCode=" + code + ";resp=" + msg);
+		
+		TorService.logMessage(cmd[0] + ";errCode=" + code + ";resp=" + msg);
 			
 		
 		return code;
@@ -90,7 +47,7 @@
 
 		//restoreDNSResolvConf(); //not working yet
 		
-		String ipTablesPath = new File(context.getDir("bin", 0),"iptables_n1").getAbsolutePath();
+		String ipTablesPath = new File(context.getDir("bin", 0),"iptables").getAbsolutePath();
 		
     	final StringBuilder script = new StringBuilder();
     	
@@ -171,12 +128,14 @@
 	public static int setTransparentProxyingByApp(Context context, TorifiedApp[] apps, boolean forceAll) throws Exception
 	{
 
+		boolean runRoot = true;
+    	boolean waitFor = true;
+    	
 		//android.os.Debug.waitForDebugger();
 		
 		//redirectDNSResolvConf(); //not working yet
 		
-		//String baseDir = context.getDir("bin", 0).getAbsolutePath() + "/";
-		String ipTablesPath = new File(context.getDir("bin", 0),"iptables_n1").getAbsolutePath();
+		String ipTablesPath = new File(context.getDir("bin", 0),"iptables").getAbsolutePath();
 
 		boolean ipTablesOld = false;
 		
@@ -202,17 +161,8 @@
 					continue;
 				}
 				
-				logNotice("enabling transproxy for app: " + apps[i].getUsername() + "(" + apps[i].getUid() + ")");
+				TorService.logMessage("enabling transproxy for app: " + apps[i].getUsername() + "(" + apps[i].getUid() + ")");
 			 
-				/*
-				 * iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner anonymous -m tcp --syn -j REDIRECT --to-ports 9040 
-iptables -t nat -A OUTPUT -p udp -m owner --uid-owner anonymous -m udp --dport 53 -j REDIRECT --to-ports 53 
-iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
-				 */
-				
-				
-				//iptables -t nat -A output -p tcp -m owner --uid-owner 100 -m tcp --sync -j REDIRECT --to-ports 9040
-				
 				//TCP
 				script.append(ipTablesPath);
 				script.append(" -t nat");
@@ -248,7 +198,6 @@
 				script.append(" || exit\n");
 				
 				
-				//EVERYTHING ELSE - DROP!
 				if (ipTablesOld) //for some reason this doesn't work on iptables 1.3.7
 				{
 					script.append(ipTablesPath);
@@ -288,18 +237,17 @@
 					
 				}
 				
+				
 			}		
-			else
-			{
-			}
 		}
 		
+		String[] cmdAdd = {script.toString()};    	
     	
-    	String[] cmdAdd = {script.toString()};    	
-		code = TorServiceUtils.doShellCommand(cmdAdd, res, true, true);
+		code = TorServiceUtils.doShellCommand(cmdAdd, res, runRoot, waitFor);
 		String msg = res.toString();
-		logNotice(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg);
+		TorService.logMessage(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg);
 		
+		
 		return code;
     }	
 	
@@ -311,7 +259,7 @@
 		//redirectDNSResolvConf(); //not working yet
 		
 		//String baseDir = context.getDir("bin",0).getAbsolutePath() + '/';
-		String ipTablesPath = new File(context.getDir("bin", 0),"iptables_n1").getAbsolutePath();
+		String ipTablesPath = new File(context.getDir("bin", 0),"iptables").getAbsolutePath();
 
 		boolean ipTablesOld = false;
 		
@@ -380,7 +328,7 @@
     	String[] cmdAdd = {script.toString()};    	
 		code = TorServiceUtils.doShellCommand(cmdAdd, res, true, true);
 		String msg = res.toString();
-		logNotice(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg);
+		TorService.logMessage(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg);
 		
 		return code;
     }	



More information about the tor-commits mailing list