added "check" yes/no dialog prompt; debuged iptables/transprox settings on Android 1.6 and 2.2
svn:r22901
This commit is contained in:
		
							parent
							
								
									22caae8989
								
							
						
					
					
						commit
						c288383db1
					
				| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
      package="org.torproject.android"
 | 
			
		||||
      android:versionName="0.2.2.14-orbot-alpha-1.0.2" android:versionCode="8">
 | 
			
		||||
      package="org.torproject.android" android:versionName="0.2.2.14-orbot-alpha-1.0.2" android:versionCode="8">
 | 
			
		||||
       
 | 
			
		||||
       <uses-permission android:name="android.permission.INTERNET" />
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 | 
			
		||||
    <application android:icon="@drawable/icon" android:label="@string/app_name">
 | 
			
		||||
      
 | 
			
		||||
        <activity android:name=".Orbot"
 | 
			
		||||
                  android:theme="@android:style/Theme.NoTitleBar"
 | 
			
		||||
| 
						 | 
				
			
			@ -19,13 +19,22 @@
 | 
			
		|||
            <category android:name="android.intent.category.DEFAULT" />
 | 
			
		||||
            <category android:name="android.intent.category.BROWSABLE" />
 | 
			
		||||
        </intent-filter>
 | 
			
		||||
        
 | 
			
		||||
         <intent-filter>
 | 
			
		||||
                <category android:name="android.intent.category.DEFAULT" />
 | 
			
		||||
            	<action android:name="org.torproject.android.REQUEST_HS_PORT" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
             <intent-filter>
 | 
			
		||||
                <category android:name="android.intent.category.DEFAULT" />
 | 
			
		||||
            	<action android:name="org.torproject.android.START_TOR" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </activity>
 | 
			
		||||
      
 | 
			
		||||
        <activity android:name=".SettingsPreferences"  android:label="@string/app_name"/>
 | 
			
		||||
        <activity android:name=".AppManager"  android:label="@string/app_name"/>
 | 
			
		||||
        <activity android:name=".WizardActivity"  android:label="@string/app_name"/>
 | 
			
		||||
      
 | 
			
		||||
    	<service android:name=".service.TorService" android:process=":remote"  android:debuggable="false">
 | 
			
		||||
    	<service android:name=".service.TorService" android:process=":remote">
 | 
			
		||||
	            <intent-filter>
 | 
			
		||||
	                <action android:name="org.torproject.android.service.ITorService" />
 | 
			
		||||
	              	<action android:name="org.torproject.android.service.TOR_SERVICE" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										
											BIN
										
									
								
								assets/iptables
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/iptables
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -1,9 +1,8 @@
 | 
			
		|||
SocksPort 9050
 | 
			
		||||
SocksListenAddress 127.0.0.1
 | 
			
		||||
SafeSocks 1
 | 
			
		||||
DNSPort 5400
 | 
			
		||||
Log notice stdout
 | 
			
		||||
Log debug syslog
 | 
			
		||||
##Log debug syslog
 | 
			
		||||
DataDirectory /data/data/org.torproject.android/data
 | 
			
		||||
ControlPort 9051
 | 
			
		||||
CookieAuthentication 1
 | 
			
		||||
| 
						 | 
				
			
			@ -12,3 +11,4 @@ RelayBandwidthBurst 20 KBytes
 | 
			
		|||
UseBridges 0
 | 
			
		||||
AutomapHostsOnResolve 1
 | 
			
		||||
TransPort 9040
 | 
			
		||||
DNSPort 5400
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,5 +10,5 @@
 | 
			
		|||
# Indicates whether an apk should be generated for each density.
 | 
			
		||||
split.density=false
 | 
			
		||||
# Project target.
 | 
			
		||||
target=Google Inc.:Google APIs:3
 | 
			
		||||
target=android-3
 | 
			
		||||
apk-configurations=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="pref_hs_group">Hidden Services</string>
 | 
			
		||||
    <string name="app_name">Orbot</string>
 | 
			
		||||
    <string name="app_version">1.0.2</string>
 | 
			
		||||
    <string name="internal_web_url">http://orbot/</string>
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +73,9 @@ and all DNS requests. This includes the built-in Browser, Gmail, YouTube and Map
 | 
			
		|||
<string name="btn_back">Back</string>
 | 
			
		||||
<string name="btn_finish">Finish</string>
 | 
			
		||||
 | 
			
		||||
<string name="btn_okay">Okay</string>
 | 
			
		||||
<string name="btn_cancel">Cancel</string>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 <!-- Welcome Wizard strings (DJH) -->
 | 
			
		||||
    <string name="wizard_welcome_msg">Orbot brings Tor to Android. Tor is free software and an open network that helps you defend against a form of network surveillance that threatens personal freedom and privacy, confidential business activities and relationships, and state security known as traffic analysis.\n\n*WARNING:* Simply installing Orbot will _not_ magically anonymize your mobile traffic! This wizard will help you get started.</string>
 | 
			
		||||
| 
						 | 
				
			
			@ -115,4 +119,5 @@ and all DNS requests. This includes the built-in Browser, Gmail, YouTube and Map
 | 
			
		|||
 | 
			
		||||
	<string name="connect_first_time"> You\'ve successfully connected to the Tor network - but this does NOT mean your device is secure. You can use the \'Check\' option from the menu to test your browser. \n\nVisit us at https://guardianproject.info/apps/orbot or send an email to help@guardianproject.info to learn more.</string>
 | 
			
		||||
 | 
			
		||||
	<string name="tor_check">This will open your default web browser to https://check.torproject.org in order to see if Orbot is probably configured and you are connected to Tor.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,16 +27,6 @@ android:enabled="true"/>
 | 
			
		|||
 | 
			
		||||
</PreferenceCategory>
 | 
			
		||||
 | 
			
		||||
<!-- 
 | 
			
		||||
<PreferenceCategory android:title="Web Proxy">
 | 
			
		||||
<Preference
 | 
			
		||||
android:defaultValue="" 
 | 
			
		||||
android:key="pref_web_proxy"
 | 
			
		||||
android:title="Open Proxy Panel"
 | 
			
		||||
android:summary="Set HTTP Settings (Android 2.x Experimental)"
 | 
			
		||||
android:enabled="true"/>
 | 
			
		||||
</PreferenceCategory>
 | 
			
		||||
 -->
 | 
			
		||||
 
 | 
			
		||||
<PreferenceCategory android:title="Bridges">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -100,4 +90,9 @@ android:dialogTitle="Enter ports"
 | 
			
		|||
/>
 | 
			
		||||
</PreferenceCategory>
 | 
			
		||||
 | 
			
		||||
<PreferenceCategory android:title="@string/pref_hs_group"><CheckBoxPreference android:title="Enable Hidden Services" android:summary="run servers accessible via the Tor network" android:key="pref_hs_enable"></CheckBoxPreference>
 | 
			
		||||
<EditTextPreference android:summary="enter localhost ports for hidden services" android:title="Hidden Service Ports" android:enabled="false" android:key="pref_hs_ports"></EditTextPreference>
 | 
			
		||||
 | 
			
		||||
<EditTextPreference android:key="pref_hs_hostname" android:summary="the addressable name for your hidden service (generated automatically)" android:title=".Onion Hostname"></EditTextPreference>
 | 
			
		||||
</PreferenceCategory>
 | 
			
		||||
</PreferenceScreen>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,10 +3,15 @@
 | 
			
		|||
 | 
			
		||||
package org.torproject.android;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.util.StringTokenizer;
 | 
			
		||||
 | 
			
		||||
import org.torproject.android.service.ITorService;
 | 
			
		||||
import org.torproject.android.service.ITorServiceCallback;
 | 
			
		||||
import org.torproject.android.service.TorServiceConstants;
 | 
			
		||||
import org.torproject.android.service.TorTransProxy;
 | 
			
		||||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
| 
						 | 
				
			
			@ -62,6 +67,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
	/* Tor Service interaction */
 | 
			
		||||
		/* The primary interface we will be calling on the service. */
 | 
			
		||||
    ITorService mService = null;
 | 
			
		||||
	private boolean autoStartOnBind = false;
 | 
			
		||||
	
 | 
			
		||||
    Orbot mOrbot = null;
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -147,15 +153,11 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
		}
 | 
			
		||||
		else if (item.getItemId() == 4)
 | 
			
		||||
		{
 | 
			
		||||
			this.showSettings();
 | 
			
		||||
			showSettings();
 | 
			
		||||
		}
 | 
			
		||||
		else if (item.getItemId() == 6)
 | 
			
		||||
		{
 | 
			
		||||
			this.showMessageLog();
 | 
			
		||||
		}
 | 
			
		||||
		else if (item.getItemId() == 2)
 | 
			
		||||
		{
 | 
			
		||||
			openBrowser(URL_TOR_CHECK);
 | 
			
		||||
			showMessageLog();
 | 
			
		||||
		}
 | 
			
		||||
		else if (item.getItemId() == 3)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -163,8 +165,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
		}
 | 
			
		||||
		else if (item.getItemId() == 7)
 | 
			
		||||
		{
 | 
			
		||||
			//launch check.torproject.org
 | 
			
		||||
			openBrowser(URL_TOR_CHECK);
 | 
			
		||||
			doTorCheck();
 | 
			
		||||
		}
 | 
			
		||||
		else if (item.getItemId() == 8)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -180,15 +181,17 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
	private void doExit ()
 | 
			
		||||
	{
 | 
			
		||||
		try {
 | 
			
		||||
		
 | 
			
		||||
			stopTor();
 | 
			
		||||
			
 | 
			
		||||
			NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
 | 
			
		||||
			mNotificationManager.cancelAll();
 | 
			
		||||
			
 | 
			
		||||
			unbindService();
 | 
			
		||||
			
 | 
			
		||||
            stopService(new Intent(ITorService.class.getName()));
 | 
			
		||||
			
 | 
			
		||||
		
 | 
			
		||||
        	NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
 | 
			
		||||
			mNotificationManager.cancelAll();
 | 
			
		||||
		
 | 
			
		||||
			
 | 
			
		||||
		} catch (RemoteException e) {
 | 
			
		||||
			Log.w(TAG, e);
 | 
			
		||||
| 
						 | 
				
			
			@ -247,6 +250,69 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
	  logBuffer.append(logText);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void doTorCheck ()
 | 
			
		||||
	{
 | 
			
		||||
		
 | 
			
		||||
		DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
 | 
			
		||||
		    @Override
 | 
			
		||||
		    public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
		        switch (which){
 | 
			
		||||
		        case DialogInterface.BUTTON_POSITIVE:
 | 
			
		||||
		            
 | 
			
		||||
		    		openBrowser(URL_TOR_CHECK);
 | 
			
		||||
 | 
			
		||||
					
 | 
			
		||||
		        	
 | 
			
		||||
		            break;
 | 
			
		||||
 | 
			
		||||
		        case DialogInterface.BUTTON_NEGATIVE:
 | 
			
		||||
		        
 | 
			
		||||
		        	//do nothing
 | 
			
		||||
		            break;
 | 
			
		||||
		        }
 | 
			
		||||
		    }
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
 | 
			
		||||
		builder.setMessage(R.string.tor_check).setPositiveButton(R.string.btn_okay, dialogClickListener)
 | 
			
		||||
		    .setNegativeButton(R.string.btn_cancel, dialogClickListener).show();
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void enableHiddenServicePort (int hsPort)
 | 
			
		||||
	{
 | 
			
		||||
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mOrbot);
 | 
			
		||||
		Editor pEdit = prefs.edit();
 | 
			
		||||
		
 | 
			
		||||
		String hsPortString = prefs.getString("pref_hs_ports", "");
 | 
			
		||||
		
 | 
			
		||||
		if (hsPortString.length() > 0 && hsPortString.indexOf(hsPort+"")==-1)
 | 
			
		||||
			hsPortString += ',' + hsPort;
 | 
			
		||||
		else
 | 
			
		||||
			hsPortString = hsPort + "";
 | 
			
		||||
		
 | 
			
		||||
		pEdit.putString("pref_hs_ports", hsPortString);
 | 
			
		||||
		pEdit.putBoolean("pref_hs_enable", true);
 | 
			
		||||
		
 | 
			
		||||
		pEdit.commit();
 | 
			
		||||
		
 | 
			
		||||
		try {
 | 
			
		||||
			processSettings();
 | 
			
		||||
		
 | 
			
		||||
			String onionHostname = getHiddenServiceHostname();
 | 
			
		||||
	
 | 
			
		||||
			Intent nResult = new Intent();
 | 
			
		||||
			nResult.putExtra("hs_host", onionHostname);
 | 
			
		||||
			setResult(RESULT_OK, nResult);
 | 
			
		||||
			
 | 
			
		||||
		} catch (RemoteException e) {
 | 
			
		||||
			// TODO Auto-generated catch block
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* (non-Javadoc)
 | 
			
		||||
	 * @see android.app.Activity#onResume()
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -254,33 +320,80 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
		super.onResume();
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
 | 
			
		||||
		mNotificationManager.cancelAll();
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mOrbot);
 | 
			
		||||
 | 
			
		||||
		boolean showWizard = prefs.getBoolean("show_wizard",true);
 | 
			
		||||
		String action = getIntent().getAction();
 | 
			
		||||
		
 | 
			
		||||
		if (showWizard)
 | 
			
		||||
		if (action != null)
 | 
			
		||||
		{
 | 
			
		||||
		
 | 
			
		||||
			Editor pEdit = prefs.edit();
 | 
			
		||||
			if (action.equals("org.torproject.android.REQUEST_HS_PORT"))
 | 
			
		||||
			{
 | 
			
		||||
				
 | 
			
		||||
				DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
 | 
			
		||||
				    @Override
 | 
			
		||||
				    public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
				        switch (which){
 | 
			
		||||
				        case DialogInterface.BUTTON_POSITIVE:
 | 
			
		||||
				            
 | 
			
		||||
				        	int hsPort = getIntent().getIntExtra("hs_port", -1);
 | 
			
		||||
							
 | 
			
		||||
				        	enableHiddenServicePort (hsPort);
 | 
			
		||||
				        	
 | 
			
		||||
							finish();
 | 
			
		||||
							
 | 
			
		||||
				        	
 | 
			
		||||
				            break;
 | 
			
		||||
 | 
			
		||||
				        case DialogInterface.BUTTON_NEGATIVE:
 | 
			
		||||
				            //No button clicked
 | 
			
		||||
				        	finish();
 | 
			
		||||
				            break;
 | 
			
		||||
				        }
 | 
			
		||||
				    }
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
	        	int hsPort = getIntent().getIntExtra("hs_port", -1);
 | 
			
		||||
 | 
			
		||||
				String requestMsg = "An app wants to open a server port (" + hsPort + ") to the Tor network. This is safe if you trust the app.";
 | 
			
		||||
				AlertDialog.Builder builder = new AlertDialog.Builder(this);
 | 
			
		||||
				builder.setMessage(requestMsg).setPositiveButton("Allow", dialogClickListener)
 | 
			
		||||
				    .setNegativeButton("Deny", dialogClickListener).show();
 | 
			
		||||
				
 | 
			
		||||
			
 | 
			
		||||
			pEdit.putBoolean("show_wizard",false);
 | 
			
		||||
			}
 | 
			
		||||
			else if (action.equals("org.torproject.android.START_TOR"))
 | 
			
		||||
			{
 | 
			
		||||
				autoStartOnBind = true;
 | 
			
		||||
				
 | 
			
		||||
				if (mService == null)
 | 
			
		||||
					bindService();
 | 
			
		||||
				
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			pEdit.commit();
 | 
			
		||||
			
 | 
			
		||||
			showHelp();
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
		
 | 
			
		||||
			NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
 | 
			
		||||
			mNotificationManager.cancelAll();
 | 
			
		||||
			
 | 
			
		||||
			
 | 
			
		||||
			SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mOrbot);
 | 
			
		||||
	
 | 
			
		||||
			boolean showWizard = prefs.getBoolean("show_wizard",true);
 | 
			
		||||
			
 | 
			
		||||
			if (showWizard)
 | 
			
		||||
			{
 | 
			
		||||
			
 | 
			
		||||
				Editor pEdit = prefs.edit();
 | 
			
		||||
				
 | 
			
		||||
				pEdit.putBoolean("show_wizard",false);
 | 
			
		||||
				
 | 
			
		||||
				pEdit.commit();
 | 
			
		||||
				
 | 
			
		||||
				showHelp();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* (non-Javadoc)
 | 
			
		||||
| 
						 | 
				
			
			@ -293,8 +406,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
		startService(new Intent(INTENT_TOR_SERVICE));
 | 
			
		||||
		bindService ();
 | 
			
		||||
		
 | 
			
		||||
		//updateStatus ("");
 | 
			
		||||
		
 | 
			
		||||
		updateStatus ("");
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -414,8 +526,12 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
	
 | 
			
		||||
	        boolean ReachableAddresses = prefs.getBoolean(PREF_REACHABLE_ADDRESSES,false);
 | 
			
		||||
	
 | 
			
		||||
	        boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
 | 
			
		||||
			
 | 
			
		||||
			
 | 
			
		||||
			boolean enableTransparentProxy = prefs.getBoolean(PREF_TRANSPARENT, false);
 | 
			
		||||
			
 | 
			
		||||
		
 | 
			
		||||
			mService.updateTransProxy();
 | 
			
		||||
			
 | 
			
		||||
			String bridgeList = prefs.getString(PREF_BRIDGES_LIST,"");
 | 
			
		||||
| 
						 | 
				
			
			@ -469,6 +585,10 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
	    			mService.updateConfiguration("ReachableAddresses", ReachableAddressesPorts, false);
 | 
			
		||||
	
 | 
			
		||||
	            }
 | 
			
		||||
	            else
 | 
			
		||||
	            {
 | 
			
		||||
	            	mService.updateConfiguration("ReachableAddresses", "", false);
 | 
			
		||||
	            }
 | 
			
		||||
	        }
 | 
			
		||||
	        catch (Exception e)
 | 
			
		||||
	        {
 | 
			
		||||
| 
						 | 
				
			
			@ -487,6 +607,12 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
	    			mService.updateConfiguration("ExitPolicy", "reject *:*", false);
 | 
			
		||||
	
 | 
			
		||||
	            }
 | 
			
		||||
	            else
 | 
			
		||||
	            {
 | 
			
		||||
	            	mService.updateConfiguration("ORPort", "", false);
 | 
			
		||||
	    			mService.updateConfiguration("Nickname", "", false);
 | 
			
		||||
	    			mService.updateConfiguration("ExitPolicy", "", false);
 | 
			
		||||
	            }
 | 
			
		||||
	        }
 | 
			
		||||
	        catch (Exception e)
 | 
			
		||||
	        {
 | 
			
		||||
| 
						 | 
				
			
			@ -495,8 +621,48 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
	            return;
 | 
			
		||||
	        }
 | 
			
		||||
	
 | 
			
		||||
	        if (mService != null)
 | 
			
		||||
	        	mService.saveConfiguration();
 | 
			
		||||
	        if (enableHiddenServices)
 | 
			
		||||
	        {
 | 
			
		||||
	        	mService.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;
 | 
			
		||||
	        		}
 | 
			
		||||
	        		
 | 
			
		||||
	        		mService.updateConfiguration("HiddenServicePort",hsPortConfig, false);
 | 
			
		||||
	        	}
 | 
			
		||||
	        	
 | 
			
		||||
	        	//force save now so the hostname file gets generated
 | 
			
		||||
	        	 mService.saveConfiguration();
 | 
			
		||||
	        	 
 | 
			
		||||
	        	String onionHostname = getHiddenServiceHostname();
 | 
			
		||||
	        	
 | 
			
		||||
	        	if (onionHostname != null)
 | 
			
		||||
	        	{
 | 
			
		||||
	        		
 | 
			
		||||
	        		Editor pEdit = prefs.edit();
 | 
			
		||||
	    			pEdit.putString("pref_hs_hostname",onionHostname);
 | 
			
		||||
	    			pEdit.commit();
 | 
			
		||||
	        		
 | 
			
		||||
	        	}
 | 
			
		||||
	        }
 | 
			
		||||
	        else
 | 
			
		||||
	        {
 | 
			
		||||
	        	mService.updateConfiguration("HiddenServiceDir","", false);
 | 
			
		||||
	        	
 | 
			
		||||
	        }
 | 
			
		||||
	        
 | 
			
		||||
	        mService.saveConfiguration();
 | 
			
		||||
		 }
 | 
			
		||||
        catch (Exception e)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -509,6 +675,20 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private String getHiddenServiceHostname ()
 | 
			
		||||
	{
 | 
			
		||||
    	String appHome = "/data/data/" + TorServiceConstants.TOR_APP_USERNAME + "/";
 | 
			
		||||
 | 
			
		||||
    	File file = new File(appHome, "hostname");
 | 
			
		||||
    	try {
 | 
			
		||||
			String onionHostname = Utils.readString(new FileInputStream(file));
 | 
			
		||||
			return onionHostname.trim();
 | 
			
		||||
		} catch (FileNotFoundException e) {
 | 
			
		||||
			Log.i(TAG, "unable to read onion hostname file",e);
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	private void showAlert(String title, String msg)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -561,7 +741,21 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
		    			
 | 
			
		||||
		    		}
 | 
			
		||||
		    		
 | 
			
		||||
			        boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
 | 
			
		||||
 | 
			
		||||
			        if (enableHiddenServices)
 | 
			
		||||
			        {
 | 
			
		||||
			    		String onionHostname = getHiddenServiceHostname();
 | 
			
		||||
			    		
 | 
			
		||||
			    		if (onionHostname != null)
 | 
			
		||||
			    		{
 | 
			
		||||
			    			Editor pEdit = prefs.edit();
 | 
			
		||||
			    			pEdit.putString("pref_hs_hostname",onionHostname);
 | 
			
		||||
			    			pEdit.commit();
 | 
			
		||||
			    			
 | 
			
		||||
			    		}
 | 
			
		||||
		    		
 | 
			
		||||
			        }
 | 
			
		||||
	    		
 | 
			
		||||
		    
 | 
			
		||||
		    	}
 | 
			
		||||
| 
						 | 
				
			
			@ -651,14 +845,18 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
			else if (mService.getStatus() == STATUS_READY)
 | 
			
		||||
			{
 | 
			
		||||
				
 | 
			
		||||
				startTor();
 | 
			
		||||
				
 | 
			
		||||
				if (event.getAction() == MotionEvent.ACTION_UP)
 | 
			
		||||
				{
 | 
			
		||||
					startTor();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				
 | 
			
		||||
				stopTor();
 | 
			
		||||
				
 | 
			
		||||
				if (event.getAction() == MotionEvent.ACTION_DOWN)
 | 
			
		||||
				{
 | 
			
		||||
					stopTor();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -799,18 +997,29 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
            mService = ITorService.Stub.asInterface(service);
 | 
			
		||||
       
 | 
			
		||||
            updateStatus ("");
 | 
			
		||||
            
 | 
			
		||||
       
 | 
			
		||||
            // We want to monitor the service for as long as we are
 | 
			
		||||
            // connected to it.
 | 
			
		||||
            try {
 | 
			
		||||
                mService.registerCallback(mCallback);
 | 
			
		||||
           
 | 
			
		||||
 | 
			
		||||
	            if (autoStartOnBind)
 | 
			
		||||
	            {
 | 
			
		||||
	            	autoStartOnBind = false;
 | 
			
		||||
	            	
 | 
			
		||||
	            	startTor();
 | 
			
		||||
	            	
 | 
			
		||||
	            }
 | 
			
		||||
            
 | 
			
		||||
            } catch (RemoteException e) {
 | 
			
		||||
                // In this case the service has crashed before we could even
 | 
			
		||||
                // do anything with it; we can count on soon being
 | 
			
		||||
                // disconnected (and then reconnected if it can be restarted)
 | 
			
		||||
                // so there is no need to do anything here.
 | 
			
		||||
            	Log.i(TAG,"error registering callback to service",e);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
       
 | 
			
		||||
          
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -844,8 +1053,6 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
 | 
			
		|||
                try {
 | 
			
		||||
                    mService.unregisterCallback(mCallback);
 | 
			
		||||
                    
 | 
			
		||||
                
 | 
			
		||||
                    
 | 
			
		||||
                } catch (RemoteException e) {
 | 
			
		||||
                    // There is nothing special we need to do if the service
 | 
			
		||||
                    // has crashed.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
 | 
			
		||||
package org.torproject.android;
 | 
			
		||||
 | 
			
		||||
import org.torproject.android.service.TorServiceUtils;
 | 
			
		||||
import org.torproject.android.service.TorTransProxy;
 | 
			
		||||
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
| 
						 | 
				
			
			@ -21,8 +20,7 @@ public class SettingsPreferences
 | 
			
		|||
	private CheckBoxPreference prefCBTransProxy = null;
 | 
			
		||||
	private CheckBoxPreference prefcBTransProxyAll = null;
 | 
			
		||||
	private Preference prefTransProxyApps = null;
 | 
			
		||||
	private Preference prefWebProxy = null;
 | 
			
		||||
	
 | 
			
		||||
	private CheckBoxPreference prefHiddenServices = null;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	private boolean hasRoot = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +35,6 @@ public class SettingsPreferences
 | 
			
		|||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void onResume() {
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -63,10 +60,13 @@ public class SettingsPreferences
 | 
			
		|||
			
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		//disabled for now 28/07 nf
 | 
			
		||||
		//prefWebProxy = ((PreferenceCategory)this.getPreferenceScreen().getPreference(1)).getPreference(0);
 | 
			
		||||
		//prefWebProxy.setOnPreferenceClickListener(this);
 | 
			
		||||
	}
 | 
			
		||||
		prefHiddenServices = ((CheckBoxPreference)((PreferenceCategory)this.getPreferenceScreen().getPreference(4)).getPreference(0));
 | 
			
		||||
		prefHiddenServices.setOnPreferenceClickListener(this);
 | 
			
		||||
		((PreferenceCategory)this.getPreferenceScreen().getPreference(4)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
 | 
			
		||||
		((PreferenceCategory)this.getPreferenceScreen().getPreference(4)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
 | 
			
		||||
				
 | 
			
		||||
		
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -89,18 +89,13 @@ public class SettingsPreferences
 | 
			
		|||
		{
 | 
			
		||||
			startActivity(new Intent(this, AppManager.class));
 | 
			
		||||
		}
 | 
			
		||||
		/*
 | 
			
		||||
		else if (preference == prefWebProxy)
 | 
			
		||||
		else if (preference == prefHiddenServices)
 | 
			
		||||
		{
 | 
			
		||||
			 Intent intent = new Intent();
 | 
			
		||||
			 intent.setClassName(this,"com.android.settings.ProxySelector");
 | 
			
		||||
			 intent.putExtra("title", "Set host=127.0.0.1 and port=8118");
 | 
			
		||||
			 intent.putExtra("button-label", "Save");
 | 
			
		||||
			 
 | 
			
		||||
			 startActivity(intent);
 | 
			
		||||
			 
 | 
			
		||||
			 
 | 
			
		||||
		}*/
 | 
			
		||||
			
 | 
			
		||||
			((PreferenceCategory)this.getPreferenceScreen().getPreference(4)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
 | 
			
		||||
			((PreferenceCategory)this.getPreferenceScreen().getPreference(4)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			prefcBTransProxyAll.setEnabled(prefCBTransProxy.isChecked());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,11 +37,8 @@ public class TorBinaryInstaller implements TorServiceConstants {
 | 
			
		|||
		
 | 
			
		||||
		boolean privoxyBinaryExists = new File(installPath + PRIVOXY_ASSET_KEY).exists();
 | 
			
		||||
		Log.i(TAG,"Privoxy binary exists=" + privoxyBinaryExists);
 | 
			
		||||
		
 | 
			
		||||
		boolean iptablesBinaryExists = new File(installPath + IPTABLES_ASSET_KEY).exists();
 | 
			
		||||
		Log.i(TAG,"IPTables binary exists=" + iptablesBinaryExists);
 | 
			
		||||
		
 | 
			
		||||
		if (!(torBinaryExists && privoxyBinaryExists && iptablesBinaryExists) || force)
 | 
			
		||||
	
 | 
			
		||||
		if (!(torBinaryExists && privoxyBinaryExists) || force)
 | 
			
		||||
			installFromZip ();
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -72,9 +69,6 @@ public class TorBinaryInstaller implements TorServiceConstants {
 | 
			
		|||
			zipen = zip.getEntry(ASSETS_BASE + PRIVOXYCONFIG_ASSET_KEY);
 | 
			
		||||
			streamToFile(zip.getInputStream(zipen),installPath + PRIVOXYCONFIG_ASSET_KEY);
 | 
			
		||||
			
 | 
			
		||||
			zipen = zip.getEntry(ASSETS_BASE + IPTABLES_ASSET_KEY);
 | 
			
		||||
			streamToFile(zip.getInputStream(zipen),installPath + IPTABLES_ASSET_KEY);
 | 
			
		||||
			
 | 
			
		||||
			
 | 
			
		||||
			zip.close();
 | 
			
		||||
			
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -401,13 +401,11 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
    	
 | 
			
		||||
    	torBinaryPath = appHome + TOR_BINARY_ASSET_KEY;
 | 
			
		||||
    	privoxyPath = appHome + PRIVOXY_ASSET_KEY;
 | 
			
		||||
    	String iptablesPath = appHome + IPTABLES_ASSET_KEY;
 | 
			
		||||
    	
 | 
			
		||||
		boolean torBinaryExists = new File(torBinaryPath).exists();
 | 
			
		||||
		boolean privoxyBinaryExists = new File(privoxyPath).exists();
 | 
			
		||||
		boolean iptablesBinaryExists = new File(iptablesPath).exists();
 | 
			
		||||
 | 
			
		||||
		if (!(torBinaryExists && privoxyBinaryExists && iptablesBinaryExists))
 | 
			
		||||
		
 | 
			
		||||
		if (!(torBinaryExists && privoxyBinaryExists))
 | 
			
		||||
		{
 | 
			
		||||
			killTorProcess ();
 | 
			
		||||
			
 | 
			
		||||
| 
						 | 
				
			
			@ -417,7 +415,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
			torBinaryExists = new File(torBinaryPath).exists();
 | 
			
		||||
			privoxyBinaryExists = new File(privoxyPath).exists();
 | 
			
		||||
			
 | 
			
		||||
    		if (torBinaryExists && privoxyBinaryExists && iptablesBinaryExists)
 | 
			
		||||
    		if (torBinaryExists && privoxyBinaryExists)
 | 
			
		||||
    		{
 | 
			
		||||
    			logNotice(getString(R.string.status_install_success));
 | 
			
		||||
    	
 | 
			
		||||
| 
						 | 
				
			
			@ -439,9 +437,8 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
		{
 | 
			
		||||
			logNotice("Found Tor binary: " + torBinaryPath);
 | 
			
		||||
 | 
			
		||||
			logNotice("Found privoxy binary: " + privoxyPath);
 | 
			
		||||
			logNotice("Found Privoxy binary: " + privoxyPath);
 | 
			
		||||
 | 
			
		||||
			logNotice("Found iptables binary: " + iptablesPath);
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
| 
						 | 
				
			
			@ -455,9 +452,6 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
		String[] cmd2 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + privoxyPath};
 | 
			
		||||
		TorServiceUtils.doShellCommand(cmd2, log, false, true);
 | 
			
		||||
				
 | 
			
		||||
		logNotice("(re)Setting permission on iptables binary");
 | 
			
		||||
		String[] cmd3 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + iptablesPath};
 | 
			
		||||
		TorServiceUtils.doShellCommand(cmd3, log, false, true);
 | 
			
		||||
		
 | 
			
		||||
		return true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -947,8 +941,17 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
        {
 | 
			
		||||
        	
 | 
			
		||||
        	//turn on
 | 
			
		||||
    		
 | 
			
		||||
        	return setupTransProxy(currentStatus == STATUS_ON); 
 | 
			
		||||
    		try
 | 
			
		||||
    		{
 | 
			
		||||
    			setupTransProxy(currentStatus == STATUS_ON); 
 | 
			
		||||
    			return true;
 | 
			
		||||
    		}
 | 
			
		||||
    		catch (Exception e)
 | 
			
		||||
    		{
 | 
			
		||||
    			Log.i(TAG, "error enabling transproxy",e);
 | 
			
		||||
    			
 | 
			
		||||
    			return false;
 | 
			
		||||
    		}
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public String getConfiguration (String name)
 | 
			
		||||
| 
						 | 
				
			
			@ -993,7 +996,19 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
        	if (configBuffer == null)
 | 
			
		||||
        		configBuffer = new ArrayList<String>();
 | 
			
		||||
	        		
 | 
			
		||||
	        configBuffer.add(name + ' ' + value);
 | 
			
		||||
        	if (value == null || value.length() == 0)
 | 
			
		||||
        	{
 | 
			
		||||
        		if (conn != null)
 | 
			
		||||
        		{
 | 
			
		||||
        			try {
 | 
			
		||||
						conn.resetConf(Arrays.asList(new String[]{name}));
 | 
			
		||||
					} catch (IOException e) {
 | 
			
		||||
						Log.w(TAG, "Unable to reset conf",e);
 | 
			
		||||
					}
 | 
			
		||||
        		}
 | 
			
		||||
        	}
 | 
			
		||||
        	else
 | 
			
		||||
        		configBuffer.add(name + ' ' + value);
 | 
			
		||||
	        
 | 
			
		||||
        	return false;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1007,7 +1022,6 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
	        		 if (configBuffer != null)
 | 
			
		||||
				        {
 | 
			
		||||
				        	conn.setConf(configBuffer);
 | 
			
		||||
				        	//conn.saveConf();
 | 
			
		||||
				        	configBuffer = null;
 | 
			
		||||
				        }
 | 
			
		||||
	   	       
 | 
			
		||||
| 
						 | 
				
			
			@ -1083,6 +1097,8 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
 | 
			
		||||
        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);
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
| 
						 | 
				
			
			@ -1137,6 +1153,10 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
                mBinder.updateConfiguration("ReachableAddresses", ReachableAddressesPorts, false);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mBinder.updateConfiguration("ReachableAddresses", "", false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -1155,6 +1175,12 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
    			mBinder.updateConfiguration("ExitPolicy", "reject *:*", false);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
            	mBinder.updateConfiguration("ORPort", "", false);
 | 
			
		||||
    			mBinder.updateConfiguration("Nickname", "", false);
 | 
			
		||||
    			mBinder.updateConfiguration("ExitPolicy", "", false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -1163,12 +1189,41 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
            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);
 | 
			
		||||
        	}
 | 
			
		||||
        	
 | 
			
		||||
        	
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
        	mBinder.updateConfiguration("HiddenServiceDir","", false);
 | 
			
		||||
        	
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        mBinder.saveConfiguration();
 | 
			
		||||
		
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    private boolean setupTransProxy (boolean enabled)
 | 
			
		||||
    private boolean setupTransProxy (boolean enabled) throws Exception
 | 
			
		||||
	{
 | 
			
		||||
    	
 | 
			
		||||
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplication());
 | 
			
		||||
| 
						 | 
				
			
			@ -1187,27 +1242,19 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
			if (hasRoot && enableTransparentProxy)
 | 
			
		||||
			{
 | 
			
		||||
				
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
					TorTransProxy.setDNSProxying();
 | 
			
		||||
					boolean success = TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this),transProxyAll);
 | 
			
		||||
				
 | 
			
		||||
					logNotice ("TorTransProxy enabled: " + success);
 | 
			
		||||
					//TorTransProxy.setDNSProxying();
 | 
			
		||||
					int code = TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this),transProxyAll);
 | 
			
		||||
				
 | 
			
		||||
					logNotice ("TorTransProxy resp code: " + code);
 | 
			
		||||
					
 | 
			
		||||
					return true;
 | 
			
		||||
					
 | 
			
		||||
				} catch (Exception e) {
 | 
			
		||||
					
 | 
			
		||||
					logNotice("WARNING: Error configuring transparenty proxying: " + e.getMessage());
 | 
			
		||||
					Log.w(TAG, "error refreshing iptables: err=" + e.getMessage(), e);
 | 
			
		||||
					
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				TorTransProxy.purgeIptables();
 | 
			
		||||
				TorTransProxy.purgeIptables(this,AppManager.getApps(this));
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1215,7 +1262,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
 | 
			
		|||
		{
 | 
			
		||||
			if (hasRoot)
 | 
			
		||||
			{
 | 
			
		||||
				TorTransProxy.purgeIptables();
 | 
			
		||||
				TorTransProxy.purgeIptables(this,AppManager.getApps(this));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,9 +26,6 @@ public interface TorServiceConstants {
 | 
			
		|||
	
 | 
			
		||||
	//privoxy.config
 | 
			
		||||
	public final static String PRIVOXYCONFIG_ASSET_KEY = "privoxy.config";
 | 
			
		||||
	
 | 
			
		||||
	//iptables key
 | 
			
		||||
	public final static String IPTABLES_ASSET_KEY = "iptables";	
 | 
			
		||||
		
 | 
			
		||||
	//various console cmds
 | 
			
		||||
	public final static String SHELL_CMD_CHMOD = "chmod";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@ public class TorTransProxy {
 | 
			
		|||
	
 | 
			
		||||
	private final static String IPTABLES_ADD = " -A ";
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	//private final static String CMD_DNS_PROXYING_DELETE = "iptables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to 127.0.0.1:5400 || exit\n";
 | 
			
		||||
	// - just calling a system wide flush of iptables rules
 | 
			
		||||
	//private final static String IPTABLES_DELETE = " -D "; //not deleting manually anymore - just calling a system wide flush of iptables rules
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +52,40 @@ public class TorTransProxy {
 | 
			
		|||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * 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 exitCode = TorServiceUtils.doShellCommand(cmd, log, true, true);
 | 
			
		||||
			
 | 
			
		||||
			String out = log.toString();
 | 
			
		||||
			if (out.indexOf(" v")!=-1)
 | 
			
		||||
			{
 | 
			
		||||
			
 | 
			
		||||
				out = out.substring(out.indexOf(" v")+2);
 | 
			
		||||
				out = out.substring(0,out.indexOf(":"));
 | 
			
		||||
				
 | 
			
		||||
				return out;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			
 | 
			
		||||
		} catch (Exception e) {
 | 
			
		||||
			Log.w(TAG,"Error checking iptables version: " + e.getMessage() ,e);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		Log.w(TAG, "Could not acquire check iptables: " + log.toString());
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static String findBaseDir ()
 | 
			
		||||
	{
 | 
			
		||||
		/*
 | 
			
		||||
| 
						 | 
				
			
			@ -72,10 +107,11 @@ public class TorTransProxy {
 | 
			
		|||
			return BASE_DIR;
 | 
			
		||||
		}*/
 | 
			
		||||
		
 | 
			
		||||
		return "/system/bin/";
 | 
			
		||||
		return "";
 | 
			
		||||
		
 | 
			
		||||
			
 | 
			
		||||
	}
 | 
			
		||||
	/*
 | 
			
		||||
	public static int setDNSProxying () throws Exception
 | 
			
		||||
	{
 | 
			
		||||
		String baseDir = findBaseDir();
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +127,7 @@ public class TorTransProxy {
 | 
			
		|||
    	return code;
 | 
			
		||||
    	
 | 
			
		||||
    	
 | 
			
		||||
	}
 | 
			
		||||
	}*/
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    public static int setIptablesDropAll() {
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +145,45 @@ public class TorTransProxy {
 | 
			
		|||
    }
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
	public static int purgeIptables(Context context, TorifiedApp[] apps) throws Exception {
 | 
			
		||||
 | 
			
		||||
		String baseDir = findBaseDir();
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
    	final StringBuilder script = new StringBuilder();
 | 
			
		||||
    	
 | 
			
		||||
    	StringBuilder res = new StringBuilder();
 | 
			
		||||
    	int code = -1;
 | 
			
		||||
    	
 | 
			
		||||
			for (int i = 0; i < apps.length; i++)
 | 
			
		||||
			{
 | 
			
		||||
 | 
			
		||||
				//flush nat for every app
 | 
			
		||||
				script.append(baseDir);
 | 
			
		||||
				script.append("iptables -t nat -m owner --uid-owner ");
 | 
			
		||||
				script.append(apps[i].getUid());
 | 
			
		||||
				script.append(" -F || exit\n");
 | 
			
		||||
				script.append("iptables -t filter -m owner --uid-owner ");
 | 
			
		||||
				script.append(apps[i].getUid());
 | 
			
		||||
				script.append(" -F || exit\n");
 | 
			
		||||
					
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
	    	
 | 
			
		||||
	    	String[] cmd = {script.toString()};
 | 
			
		||||
	    	Log.i(TAG, cmd[0]);
 | 
			
		||||
			
 | 
			
		||||
			code = TorServiceUtils.doShellCommand(cmd, res, true, true);
 | 
			
		||||
			
 | 
			
		||||
			String msg = res.toString();
 | 
			
		||||
			Log.i(TAG, msg);
 | 
			
		||||
			
 | 
			
		||||
		
 | 
			
		||||
		return code;
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/*
 | 
			
		||||
	public static boolean purgeIptables() {
 | 
			
		||||
		
 | 
			
		||||
		String baseDir = findBaseDir();
 | 
			
		||||
| 
						 | 
				
			
			@ -129,96 +204,121 @@ public class TorTransProxy {
 | 
			
		|||
			Log.w(TAG,"error purging iptables: " + e);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
    }
 | 
			
		||||
    }*/
 | 
			
		||||
	
 | 
			
		||||
	public static boolean setTransparentProxyingByApp(Context context, TorifiedApp[] apps, boolean forceAll) throws Exception
 | 
			
		||||
	public static int setTransparentProxyingByApp(Context context, TorifiedApp[] apps, boolean forceAll) throws Exception
 | 
			
		||||
	{
 | 
			
		||||
	
 | 
			
		||||
		String baseDir = findBaseDir();
 | 
			
		||||
 | 
			
		||||
		String command = null;
 | 
			
		||||
		String iptablesVersion = getIPTablesVersion();
 | 
			
		||||
		Log.i(TAG, "iptables version: " + iptablesVersion);
 | 
			
		||||
		
 | 
			
		||||
		command = IPTABLES_ADD; //ADD
 | 
			
		||||
		boolean ipTablesOld = false;
 | 
			
		||||
		if (iptablesVersion != null && iptablesVersion.startsWith("1.3")){
 | 
			
		||||
			ipTablesOld = true;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
    	final StringBuilder script = new StringBuilder();
 | 
			
		||||
    	StringBuilder script = new StringBuilder();
 | 
			
		||||
    	
 | 
			
		||||
    	//first we have to flush old settings
 | 
			
		||||
		script.append(baseDir);
 | 
			
		||||
		script.append(CMD_NAT_FLUSH);
 | 
			
		||||
		script.append(" || exit\n");
 | 
			
		||||
		
 | 
			
		||||
		script.append(baseDir);
 | 
			
		||||
		script.append(CMD_FILTER_FLUSH);
 | 
			
		||||
		script.append(" || exit\n");
 | 
			
		||||
		
 | 
			
		||||
    	StringBuilder res = new StringBuilder();
 | 
			
		||||
    	int code = -1;
 | 
			
		||||
    	
 | 
			
		||||
			for (int i = 0; i < apps.length; i++)
 | 
			
		||||
		for (int i = 0; i < apps.length; i++)
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
			//flush nat for every app
 | 
			
		||||
			script.append(baseDir);
 | 
			
		||||
			script.append("iptables -t nat -m owner --uid-owner ");
 | 
			
		||||
			script.append(apps[i].getUid());
 | 
			
		||||
			script.append(" -F || exit\n");
 | 
			
		||||
			script.append("iptables -t filter -m owner --uid-owner ");
 | 
			
		||||
			script.append(apps[i].getUid());
 | 
			
		||||
			script.append(" -F || exit\n");
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
    	String[] cmdFlush = {script.toString()};
 | 
			
		||||
    	Log.i(TAG, cmdFlush[0]);
 | 
			
		||||
		
 | 
			
		||||
		code = TorServiceUtils.doShellCommand(cmdFlush, res, true, true);
 | 
			
		||||
		
 | 
			
		||||
		String msg = res.toString();
 | 
			
		||||
		Log.i(TAG, msg);
 | 
			
		||||
 | 
			
		||||
		script = new StringBuilder();
 | 
			
		||||
		
 | 
			
		||||
		for (int i = 0; i < apps.length; i++)
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
			if (forceAll || apps[i].isTorified())
 | 
			
		||||
			{
 | 
			
		||||
				if (forceAll || apps[i].isTorified())
 | 
			
		||||
				
 | 
			
		||||
				if (apps[i].getUsername().equals(TorServiceConstants.TOR_APP_USERNAME))
 | 
			
		||||
				{
 | 
			
		||||
					Log.i(TAG,"detected Orbot app - will not transproxy");
 | 
			
		||||
					
 | 
			
		||||
					if (apps[i].getUsername().equals(TorServiceConstants.TOR_APP_USERNAME))
 | 
			
		||||
					{
 | 
			
		||||
						Log.i(TAG,"detected Orbot app - will not transproxy");
 | 
			
		||||
						
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					
 | 
			
		||||
					Log.i(TAG,"enabling transproxy for app: " + apps[i].getUsername() + "(" + apps[i].getUid() + ")");
 | 
			
		||||
				 
 | 
			
		||||
					
 | 
			
		||||
					
 | 
			
		||||
					//TCP
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				Log.i(TAG,"enabling transproxy for app: " + apps[i].getUsername() + "(" + apps[i].getUid() + ")");
 | 
			
		||||
			 
 | 
			
		||||
				
 | 
			
		||||
				//TCP
 | 
			
		||||
				script.append(baseDir);
 | 
			
		||||
				script.append("iptables -t nat");
 | 
			
		||||
				script.append(" -A OUTPUT -p tcp --syn");
 | 
			
		||||
				script.append(" -m owner --uid-owner ");
 | 
			
		||||
				script.append(apps[i].getUid());
 | 
			
		||||
				script.append(" -m tcp ");
 | 
			
		||||
				
 | 
			
		||||
				if (ipTablesOld)
 | 
			
		||||
					script.append(" -j DNAT --to 127.0.0.1:9040");
 | 
			
		||||
				else
 | 
			
		||||
					script.append(" -j REDIRECT --to-ports 9040");
 | 
			
		||||
				
 | 
			
		||||
				script.append(" || exit\n");
 | 
			
		||||
				
 | 
			
		||||
				//DNS
 | 
			
		||||
				script.append(baseDir);
 | 
			
		||||
				script.append("iptables -t nat");
 | 
			
		||||
				script.append(" -A OUTPUT -p udp -m owner --uid-owner ");
 | 
			
		||||
				script.append(apps[i].getUid());
 | 
			
		||||
				script.append(" -m udp --dport 53");
 | 
			
		||||
				
 | 
			
		||||
				if (ipTablesOld)
 | 
			
		||||
					script.append(" -j DNAT --to 127.0.0.1:5400");
 | 
			
		||||
				else
 | 
			
		||||
					script.append(" -j REDIRECT --to-ports 5400");
 | 
			
		||||
				
 | 
			
		||||
				script.append(" || exit\n");
 | 
			
		||||
				
 | 
			
		||||
				//EVERYTHING ELSE UDP - DROP!
 | 
			
		||||
				if (!ipTablesOld) //for some reason this doesn't work on iptables 1.3.7
 | 
			
		||||
				{
 | 
			
		||||
					script.append(baseDir);
 | 
			
		||||
					script.append("iptables -t nat");
 | 
			
		||||
					script.append(" -A OUTPUT -p tcp -m owner --uid-owner ");
 | 
			
		||||
					script.append(apps[i].getUid());
 | 
			
		||||
				//	script.append(" -j DNAT --to 127.0.0.1:9040");
 | 
			
		||||
					script.append(" -m tcp --syn -j REDIRECT --to-ports 9040");
 | 
			
		||||
					script.append(" || exit\n");
 | 
			
		||||
					
 | 
			
		||||
					//UDP
 | 
			
		||||
					script.append(baseDir);
 | 
			
		||||
					script.append("iptables -t nat");
 | 
			
		||||
					script.append("iptables");
 | 
			
		||||
					script.append(" -A OUTPUT -p udp -m owner --uid-owner ");
 | 
			
		||||
					script.append(apps[i].getUid());
 | 
			
		||||
					script.append(" --dport 53 -j REDIRECT --to-ports 5400"); //drop all UDP packets as Tor won't handle them
 | 
			
		||||
					script.append(" || exit\n");
 | 
			
		||||
					
 | 
			
		||||
					/*
 | 
			
		||||
					script.append(baseDir);
 | 
			
		||||
					script.append("iptables -t nat");
 | 
			
		||||
					script.append(" -A OUTPUT -m owner --uid-owner ");
 | 
			
		||||
					script.append(apps[i].getUid());
 | 
			
		||||
					script.append(" -j DROP"); //drop all other packets as Tor won't handle them
 | 
			
		||||
					script.append(" || exit\n");
 | 
			
		||||
					*/
 | 
			
		||||
					
 | 
			
		||||
					
 | 
			
		||||
					/*
 | 
			
		||||
					 * iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner anonymous -m tcp -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 filter -A OUTPUT -p tcp -m owner --uid-owner anonymous -m tcp --dport 9040 -j ACCEPT
 | 
			
		||||
iptables -t filter -A OUTPUT -p udp -m owner --uid-owner anonymous -m udp --dport 53 -j ACCEPT
 | 
			
		||||
iptables -t filter -A OUTPUT -m owner --uid-owner anonymous -j DROP
 | 
			
		||||
 | 
			
		||||
					 */
 | 
			
		||||
				}		
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
	    	
 | 
			
		||||
	    	String[] cmd = {script.toString()};
 | 
			
		||||
	    	Log.i(TAG, cmd[0]);
 | 
			
		||||
			
 | 
			
		||||
			code = TorServiceUtils.doShellCommand(cmd, res, true, true);
 | 
			
		||||
			
 | 
			
		||||
			String msg = res.toString();
 | 
			
		||||
			Log.i(TAG, msg);
 | 
			
		||||
				}	
 | 
			
		||||
				
 | 
			
		||||
				
 | 
			
		||||
			}		
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
    	
 | 
			
		||||
    	String[] cmdAdd = {script.toString()};
 | 
			
		||||
    	Log.i(TAG, cmdAdd[0]);
 | 
			
		||||
		
 | 
			
		||||
		code = TorServiceUtils.doShellCommand(cmdAdd, res, true, true);
 | 
			
		||||
		
 | 
			
		||||
		msg = res.toString();
 | 
			
		||||
		Log.i(TAG, msg);
 | 
			
		||||
			
 | 
			
		||||
		
 | 
			
		||||
		return false;
 | 
			
		||||
		return code;
 | 
			
		||||
    }	
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue