From 08317a94d7b3d1b682bfbc7f874a2e7c6611b3f4 Mon Sep 17 00:00:00 2001 From: Nathan Freitas Date: Sun, 14 Sep 2014 16:07:18 -0400 Subject: [PATCH] fixes for transproxy/iptables rules - not all rules were not being cleared in flush - per-app transproxy now still transproxies DNS for full device (not all DNS is done under the app UID) - root shell now created only once and shared across calls --- .../android/service/TorService.java | 69 ++++++-------- .../android/service/TorTransProxy.java | 92 +++++++++---------- 2 files changed, 71 insertions(+), 90 deletions(-) diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index ec56cebb..b5be7b00 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -76,7 +76,6 @@ import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Builder; import android.util.Log; import android.widget.RemoteViews; -import android.widget.Toast; public class TorService extends Service implements TorServiceConstants, TorConstants, EventHandler { @@ -420,7 +419,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst mCurrentStatus = STATUS_OFF; if (mHasRoot && mEnableTransparentProxy) - disableTransparentProxy(); + disableTransparentProxy(Shell.startRootShell()); clearNotifications(); @@ -762,8 +761,12 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (mHasRoot && mEnableTransparentProxy) { - disableTransparentProxy(); - enableTransparentProxy(); + Shell shell = Shell.startRootShell(); + + disableTransparentProxy(shell); + enableTransparentProxy(shell); + + shell.close(); } getHiddenServiceHostname (); @@ -802,7 +805,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst * * the idea is that if Tor is off then transproxy is off */ - private boolean enableTransparentProxy () throws Exception + private boolean enableTransparentProxy (Shell shell) throws Exception { if (mTransProxy == null) @@ -824,39 +827,21 @@ public class TorService extends Service implements TorServiceConstants, TorConst mTransProxy.setTransProxyPort(Integer.parseInt(transProxy)); mTransProxy.setDNSPort(Integer.parseInt(dnsPort)); - - - //TODO: Find a nice place for the next (commented) line - //TorTransProxy.setDNSProxying(); int code = 0; // Default state is "okay" - - debug ("Transparent Proxying: clearing existing rules..."); - - //clear rules first - // mTransProxy.clearTransparentProxyingAll(this); if(mTransProxyAll) { - // showToolbarNotification(getString(R.string.setting_up_full_transparent_proxying_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor); - //clear existing rules - //code = mTransProxy.setTransparentProxyingAll(this, false); - - code = mTransProxy.setTransparentProxyingAll(this, true); + code = mTransProxy.setTransparentProxyingAll(this, true, shell); } else { - //showToolbarNotification(getString(R.string.setting_up_app_based_transparent_proxying_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor); ArrayList apps = AppManager.getApps(this, TorServiceUtils.getSharedPrefs(getApplicationContext())); - - //clear exiting rules - //code = mTransProxy.setTransparentProxyingByApp(this,apps, false); - code = mTransProxy.setTransparentProxyingByApp(this,apps, true); + code = mTransProxy.setTransparentProxyingByApp(this,apps, true, shell); } - - + debug ("TorTransProxy resp code: " + code); if (code == 0) @@ -866,7 +851,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst { showToolbarNotification(getString(R.string.transproxy_enabled_for_tethering_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor); - mTransProxy.enableTetheringRules(this); + mTransProxy.enableTetheringRules(this, Shell.startRootShell()); } else @@ -890,7 +875,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst * * the idea is that if Tor is off then transproxy is off */ - private boolean disableTransparentProxy () throws Exception + private boolean disableTransparentProxy (Shell shell) throws Exception { debug ("Transparent Proxying: disabling..."); @@ -898,9 +883,9 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (mTransProxy == null) mTransProxy = new TorTransProxy(this, fileXtables); - mTransProxy.setTransparentProxyingAll(this, false); + mTransProxy.setTransparentProxyingAll(this, false, shell); ArrayList apps = AppManager.getApps(this, TorServiceUtils.getSharedPrefs(getApplicationContext())); - mTransProxy.setTransparentProxyingByApp(this, apps, false); + mTransProxy.setTransparentProxyingByApp(this, apps, false, shell); return true; } @@ -1735,14 +1720,15 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (mHasRoot) { - if (hadEnableTransparentProxy) - disableTransparentProxy(); + Shell shell = Shell.startRootShell(); - if (mEnableTransparentProxy) - { - disableTransparentProxy(); - enableTransparentProxy(); - } + if (hadEnableTransparentProxy) + disableTransparentProxy(shell); + + if (mEnableTransparentProxy) + enableTransparentProxy(shell); + + shell.close(); } @@ -2056,8 +2042,13 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (mHasRoot && mEnableTransparentProxy && mTransProxyNetworkRefresh) { - disableTransparentProxy(); - enableTransparentProxy(); + + Shell shell = Shell.startRootShell(); + + disableTransparentProxy(shell); + enableTransparentProxy(shell); + + shell.close(); } } diff --git a/src/org/torproject/android/service/TorTransProxy.java b/src/org/torproject/android/service/TorTransProxy.java index b1e21331..78b6ebd4 100644 --- a/src/org/torproject/android/service/TorTransProxy.java +++ b/src/org/torproject/android/service/TorTransProxy.java @@ -21,7 +21,7 @@ public class TorTransProxy implements TorServiceConstants { private TorService mTorService = null; private File mFileXtables = null; - private final static String ALLOW_LOCAL = " ! -o lo ! -d 127.0.0.1 ! -s 127.0.0.1 "; + private final static String ALLOW_LOCAL = " ! -d 127.0.0.1"; private int mTransProxyPort = TorServiceConstants.TOR_TRANSPROXY_PORT_DEFAULT; private int mDNSPort = TorServiceConstants.TOR_DNS_PORT_DEFAULT; @@ -335,7 +335,7 @@ public class TorTransProxy implements TorServiceConstants { return code; }*/ - public int setTransparentProxyingByApp(Context context, ArrayList apps, boolean enableRule) throws Exception + public int setTransparentProxyingByApp(Context context, ArrayList apps, boolean enableRule, Shell shell) throws Exception { String ipTablesPath = getIpTablesPath(context); @@ -353,30 +353,45 @@ public class TorTransProxy implements TorServiceConstants { //reset script - Shell shell = Shell.startRootShell(); int lastExit = -1; StringBuilder script; - + + // Same for DNS + script = new StringBuilder(); + script.append(ipTablesPath); + script.append(" -t nat"); + script.append(action).append(srcChainName); + script.append(" -p udp"); + //script.append(" -m owner --uid-owner "); + //script.append(tApp.getUid()); + //script.append(" -m udp --dport "); + script.append(" --dport "); + script.append(STANDARD_DNS_PORT); + script.append(" -j REDIRECT --to-ports "); + script.append(mDNSPort); + executeCommand (shell, script.toString()); + // Allow everything for Tor //build up array of shell cmds to execute under one root context for (TorifiedApp tApp:apps) { - if (tApp.isTorified() + if (((!enableRule) || tApp.isTorified()) && (!tApp.getUsername().equals(TorServiceConstants.TOR_APP_USERNAME)) ) //if app is set to true { - logMessage("enabling transproxy for app: " + tApp.getUsername() + " (" + tApp.getUid() + ")"); + logMessage("transproxy for app: " + tApp.getUsername() + " (" + tApp.getUid() + "): enable=" + enableRule); - dropAllIPv6Traffic(context, tApp.getUid(),enableRule); + dropAllIPv6Traffic(context, tApp.getUid(),enableRule, shell); script = new StringBuilder(); // Allow loopback + /** script.append(ipTablesPath); script.append(" -t filter"); script.append(action).append(srcChainName); @@ -387,6 +402,7 @@ public class TorTransProxy implements TorServiceConstants { executeCommand (shell, script.toString()); script = new StringBuilder(); + **/ // Set up port redirection script.append(ipTablesPath); @@ -401,21 +417,8 @@ public class TorTransProxy implements TorServiceConstants { script.append(mTransProxyPort); executeCommand (shell, script.toString()); - script = new StringBuilder(); - // Same for DNS - script.append(ipTablesPath); - script.append(" -t nat"); - script.append(action).append(srcChainName); - script.append(" -p udp"); - script.append(" -m owner --uid-owner "); - script.append(tApp.getUid()); - script.append(" -m udp --dport "); - script.append(STANDARD_DNS_PORT); - script.append(" -j REDIRECT --to-ports "); - script.append(mDNSPort); - - executeCommand (shell, script.toString()); + script = new StringBuilder(); // Reject all other outbound packets @@ -433,14 +436,12 @@ public class TorTransProxy implements TorServiceConstants { } } - shell.close(); - return lastExit; } private int executeCommand (Shell shell, String cmdString) throws IOException, TimeoutException { - SimpleCommand cmd = new SimpleCommand(cmdString + "|| exit"); + SimpleCommand cmd = new SimpleCommand(cmdString); shell.add(cmd); int exitCode = cmd.getExitCode(); String output = cmd.getOutput(); @@ -451,7 +452,7 @@ public class TorTransProxy implements TorServiceConstants { } - public int enableTetheringRules (Context context) throws Exception + public int enableTetheringRules (Context context, Shell shell) throws Exception { String ipTablesPath = getIpTablesPath(context); @@ -460,7 +461,6 @@ public class TorTransProxy implements TorServiceConstants { String[] hwinterfaces = {"usb0","wl0.1"}; - Shell shell = Shell.startRootShell(); int lastExit = -1; @@ -492,8 +492,6 @@ public class TorTransProxy implements TorServiceConstants { } - shell.close(); - return lastExit; } @@ -505,12 +503,10 @@ public class TorTransProxy implements TorServiceConstants { - public int fixTransproxyLeak (Context context) throws Exception + public int fixTransproxyLeak (Context context, Shell shell) throws Exception { String ipTablesPath = getIpTablesPath(context); - Shell shell = Shell.startRootShell(); - StringBuilder script = new StringBuilder(); script.append(ipTablesPath); script.append(" -I OUTPUT ! -o lo ! -d 127.0.0.1 ! -s 127.0.0.1 -p tcp -m tcp --tcp-flags ACK,FIN ACK,FIN -j DROP"); @@ -525,13 +521,11 @@ public class TorTransProxy implements TorServiceConstants { int lastExit = executeCommand (shell, script.toString()); script = new StringBuilder(); - shell.close(); - return lastExit; } - public int dropAllIPv6Traffic (Context context, int appUid, boolean enableDrop) throws Exception + public int dropAllIPv6Traffic (Context context, int appUid, boolean enableDrop, Shell shell) throws Exception { String action = " -A "; @@ -541,9 +535,7 @@ public class TorTransProxy implements TorServiceConstants { action = " -D "; String ip6tablesPath = getIp6TablesPath(context); - Shell shell = Shell.startRootShell(); - StringBuilder script; script = new StringBuilder(); @@ -561,8 +553,6 @@ public class TorTransProxy implements TorServiceConstants { int lastExit = executeCommand (shell, script.toString()); - shell.close(); - return lastExit; } @@ -589,27 +579,29 @@ public class TorTransProxy implements TorServiceConstants { public int flushTransproxyRules (Context context) throws Exception { int exit = -1; + String ipTablesPath = getIpTablesPath(context); - + Shell shell = Shell.startRootShell(); + StringBuilder script = new StringBuilder(); script.append(ipTablesPath); - script.append(" -t nat"); + script.append(" -t nat "); script.append(" -F "); - Shell shell = Shell.startRootShell(); - executeCommand (shell, script.toString()); + executeCommand (shell, script.toString()); script = new StringBuilder(); script.append(ipTablesPath); - script.append(" -t filter"); + script.append(" -t filter "); script.append(" -F "); + executeCommand (shell, script.toString()); - dropAllIPv6Traffic(context,-1,false); + dropAllIPv6Traffic(context,-1,false, shell); return exit; } - public int setTransparentProxyingAll(Context context, boolean enable) throws Exception + public int setTransparentProxyingAll(Context context, boolean enable, Shell shell) throws Exception { String action = " -A "; @@ -617,12 +609,11 @@ public class TorTransProxy implements TorServiceConstants { if (!enable) action = " -D "; - - dropAllIPv6Traffic(context,-1,enable); + + dropAllIPv6Traffic(context,-1,enable, shell); String ipTablesPath = getIpTablesPath(context); - Shell shell = Shell.startRootShell(); int torUid = context.getApplicationInfo().uid; @@ -674,7 +665,8 @@ public class TorTransProxy implements TorServiceConstants { script.append(ALLOW_LOCAL); //allow access to localhost script.append(" -m owner ! --uid-owner "); script.append(torUid); - script.append(" -m udp --dport "); + //script.append(" -m udp --dport "); + script.append(" --dport "); script.append(STANDARD_DNS_PORT); script.append(" -j REDIRECT --to-ports "); script.append(mDNSPort); @@ -773,8 +765,6 @@ public class TorTransProxy implements TorServiceConstants { // fixTransproxyLeak (context); - shell.close(); - return lastExit; }