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
This commit is contained in:
Nathan Freitas 2014-09-14 16:07:18 -04:00
parent ee10ac0f07
commit 08317a94d7
2 changed files with 71 additions and 90 deletions

View File

@ -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)
@ -825,38 +828,20 @@ 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<TorifiedApp> 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<TorifiedApp> 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)
{
Shell shell = Shell.startRootShell();
if (hadEnableTransparentProxy)
disableTransparentProxy();
disableTransparentProxy(shell);
if (mEnableTransparentProxy)
{
disableTransparentProxy();
enableTransparentProxy();
}
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();
}
}

View File

@ -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<TorifiedApp> apps, boolean enableRule) throws Exception
public int setTransparentProxyingByApp(Context context, ArrayList<TorifiedApp> 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,8 +535,6 @@ public class TorTransProxy implements TorServiceConstants {
action = " -D ";
String ip6tablesPath = getIp6TablesPath(context);
Shell shell = Shell.startRootShell();
StringBuilder script;
@ -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(" -F ");
Shell shell = Shell.startRootShell();
executeCommand (shell, script.toString());
script = new StringBuilder();
script.append(ipTablesPath);
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 ";
@ -618,11 +610,10 @@ 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;
}