diff --git a/src/org/torproject/android/Orbot.java b/src/org/torproject/android/Orbot.java index 59112dae..d952cc4c 100644 --- a/src/org/torproject/android/Orbot.java +++ b/src/org/torproject/android/Orbot.java @@ -710,7 +710,6 @@ public class Orbot extends Activity implements TorConstants, OnLongClickListener Message msg = Message.obtain(); msg.what = TorServiceConstants.MESSAGE_TRAFFIC_COUNT; - Bundle data = new Bundle(); data.putLong("upload", upload); data.putLong("download", download); @@ -775,12 +774,19 @@ public class Orbot extends Activity implements TorConstants, OnLongClickListener Log.d(TAG,"Total bandwidth error"+e.getMessage()); } - downloadText.setText(formatCount(datacount.Download) + " / " + formatTotal(Long.parseLong(TotalDownload))); - uploadText.setText(formatCount(datacount.Upload) + " / " + formatTotal(Long.parseLong(TotalUpload))); + try + { + downloadText.setText(formatCount(datacount.Download) + " / " + formatTotal(Long.parseLong(TotalDownload))); + uploadText.setText(formatCount(datacount.Upload) + " / " + formatTotal(Long.parseLong(TotalUpload))); + + downloadText.invalidate(); + uploadText.invalidate(); + } + catch (NumberFormatException nfe) + { + //just ignore/swallow + } - downloadText.invalidate(); - uploadText.invalidate(); - break; default: diff --git a/src/org/torproject/android/service/.TorServiceUtils.java.swp b/src/org/torproject/android/service/.TorServiceUtils.java.swp deleted file mode 100644 index b9f0c9e0..00000000 Binary files a/src/org/torproject/android/service/.TorServiceUtils.java.swp and /dev/null differ diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index 23921a98..73c0d717 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -55,7 +55,7 @@ import android.util.Log; public class TorService extends Service implements TorServiceConstants, TorConstants, Runnable, EventHandler { - public static boolean ENABLE_DEBUG_LOG = true; + public static boolean ENABLE_DEBUG_LOG = false; private static int currentStatus = STATUS_OFF; @@ -85,6 +85,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst private File filePrivoxy; private File fileObfsProxy; + private TorTransProxy mTransProxy; + private boolean mTransProxyAll = false; public static void logMessage(String msg) { @@ -611,54 +613,53 @@ public class TorService extends Service implements TorServiceConstants, TorConst boolean hasRoot = prefs.getBoolean(PREF_HAS_ROOT,false); boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false); - TorTransProxy ttProxy = new TorTransProxy(); + if (mTransProxy == null) + mTransProxy = new TorTransProxy(); if (hasRoot && enableTransparentProxy) { - boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false); - boolean transProxyPortFallback = prefs.getBoolean("pref_transparent_port_fallback", false); + mTransProxyAll = prefs.getBoolean("pref_transparent_all", false); boolean transProxyTethering = prefs.getBoolean("pref_transparent_tethering", false); TorService.logMessage ("Transparent Proxying: " + enableTransparentProxy); - String portProxyList = prefs.getString("pref_port_list", ""); + //String portProxyList = prefs.getString("pref_port_list", ""); //TODO: Find a nice place for the next (commented) line //TorTransProxy.setDNSProxying(); int code = 0; // Default state is "okay" - + /* if(transProxyPortFallback) { - showToolbarNotification(getString(R.string.setting_up_port_based_transparent_proxying_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_notify, -1); StringTokenizer st = new StringTokenizer(portProxyList, ","); int status = code; while (st.hasMoreTokens()) { - status = ttProxy.setTransparentProxyingByPort(this, Integer.parseInt(st.nextToken())); + status = mTransProxy.setTransparentProxyingByPort(this, Integer.parseInt(st.nextToken())); if(status != 0) code = status; } } else - { - if(transProxyAll) + {*/ + if(mTransProxyAll) { showToolbarNotification(getString(R.string.setting_up_full_transparent_proxying_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_notify, -1); - code = ttProxy.setTransparentProxyingAll(this); + code = mTransProxy.setTransparentProxyingAll(this); } else { showToolbarNotification(getString(R.string.setting_up_app_based_transparent_proxying_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_notify, -1); - code = ttProxy.setTransparentProxyingByApp(this,AppManager.getApps(this)); + code = mTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this)); } - } + //} TorService.logMessage ("TorTransProxy resp code: " + code); @@ -670,7 +671,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst { showToolbarNotification(getString(R.string.transproxy_enabled_for_tethering_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_notify, -1); - ttProxy.enableTetheringRules(this); + mTransProxy.enableTetheringRules(this); } } @@ -699,14 +700,16 @@ public class TorService extends Service implements TorServiceConstants, TorConst boolean hasRoot = prefs.getBoolean(PREF_HAS_ROOT,false); boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false); - if (hasRoot && enableTransparentProxy) { TorService.logMessage ("Clearing TransProxy rules"); - new TorTransProxy().flushIptables(this); - + if (mTransProxyAll) + mTransProxy.clearTransparentProxyingAll(this); + else + mTransProxy.clearTransparentProxyingByApp(this,AppManager.getApps(this)); + showToolbarNotification(getString(R.string.transproxy_rules_cleared), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_notify, -1); @@ -1185,7 +1188,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst prefPersistNotifications = prefs.getBoolean(TorConstants.PREF_PERSIST_NOTIFICATIONS, true); - new Thread () { @@ -1499,7 +1501,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - ENABLE_DEBUG_LOG = prefs.getBoolean("pref_enable_logging",true); + 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); diff --git a/src/org/torproject/android/service/TorTransProxy.java b/src/org/torproject/android/service/TorTransProxy.java index 5269a495..18eec844 100644 --- a/src/org/torproject/android/service/TorTransProxy.java +++ b/src/org/torproject/android/service/TorTransProxy.java @@ -17,9 +17,8 @@ public class TorTransProxy implements TorServiceConstants { public String getIpTablesPath (Context context) { - - if (ipTablesPath == null) - { + android.os.Debug.waitForDebugger(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); if (prefs.getBoolean(TorConstants.PREF_USE_SYSTEM_IPTABLES, false)) @@ -50,13 +49,12 @@ public class TorTransProxy implements TorServiceConstants { ipTablesPath = new File(context.getDir("bin", 0),"iptables").getAbsolutePath(); } - } return ipTablesPath; } - public int flushIptables(Context context) throws Exception { + public int flushIptablesAll(Context context) throws Exception { String ipTablesPath = getIpTablesPath(context); @@ -220,19 +218,10 @@ public class TorTransProxy implements TorServiceConstants { StringBuilder res = new StringBuilder(); int code = -1; - flushIptables(context); + // flushIptables(context); int torUid = context.getApplicationInfo().uid; - // Allow everything for Tor - script.append(ipTablesPath); - script.append(" -t filter"); - script.append(" -A OUTPUT"); - script.append(" -m owner --uid-owner "); - script.append(torUid); - script.append(" -j ACCEPT"); - script.append(" || exit\n"); - //build up array of shell cmds to execute under one root context for (TorifiedApp tApp:apps) { @@ -244,11 +233,12 @@ public class TorTransProxy implements TorServiceConstants { { TorService.logMessage("enabling transproxy for app: " + tApp.getUsername() + "(" + tApp.getUid() + ")"); - - // Set up port redirection - script.append(ipTablesPath); + + // Set up port redirection + script.append(ipTablesPath); + script.append(" -A OUTPUT"); script.append(" -t nat"); - script.append(" -A OUTPUT -p tcp"); + script.append(" -p tcp"); script.append(" ! -d 127.0.0.1"); //allow access to localhost script.append(" -m owner --uid-owner "); script.append(tApp.getUid()); @@ -259,37 +249,24 @@ public class TorTransProxy implements TorServiceConstants { // Same for DNS script.append(ipTablesPath); + script.append(" -A OUTPUT"); script.append(" -t nat"); - script.append(" -A OUTPUT -p udp"); - script.append(" -m owner --uid-owner "); + script.append(" -p udp -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(TOR_DNS_PORT); script.append(" || exit\n"); - - // Allow loopback - script.append(ipTablesPath); - script.append(" -t filter"); - script.append(" -A OUTPUT"); - script.append(" -m owner --uid-owner "); - script.append(tApp.getUid()); - script.append(" -o lo"); - script.append(" -j ACCEPT"); - script.append(" || exit\n"); - - /* - //Outgoing loopback already allowed (23/7/12) - + int[] ports = {TOR_DNS_PORT,TOR_TRANSPROXY_PORT,PORT_SOCKS,PORT_HTTP}; for (int port : ports) { // Allow packets to localhost (contains all the port-redirected ones) script.append(ipTablesPath); - script.append(" -t filter"); script.append(" -A OUTPUT"); + script.append(" -t filter"); script.append(" -m owner --uid-owner "); script.append(tApp.getUid()); script.append(" -p tcp"); @@ -299,12 +276,34 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -j ACCEPT"); script.append(" || exit\n"); } - */ - + + // Allow loopback + script.append(ipTablesPath); + script.append(" -A OUTPUT"); + script.append(" -t filter"); + script.append(" -m owner --uid-owner "); + script.append(tApp.getUid()); + script.append(" -p tcp"); + script.append(" -o lo"); + script.append(" -j ACCEPT"); + script.append(" || exit\n"); + + // Reject DNS that is not from Tor (order is important - first matched rule counts!) + script.append(ipTablesPath); + script.append(" -A OUTPUT"); + script.append(" -t filter"); + script.append(" -m owner --uid-owner "); + script.append(tApp.getUid()); + script.append(" -p udp"); + script.append(" --dport "); + script.append(STANDARD_DNS_PORT); + script.append(" -j REJECT"); + script.append(" || exit\n"); + // Reject all other outbound TCP packets script.append(ipTablesPath); - script.append(" -t filter"); script.append(" -A OUTPUT"); + script.append(" -t filter"); script.append(" -m owner --uid-owner "); script.append(tApp.getUid()); script.append(" -p tcp"); @@ -317,8 +316,8 @@ public class TorTransProxy implements TorServiceConstants { // Allow everything for Tor script.append(ipTablesPath); - script.append(" -t filter"); script.append(" -A OUTPUT"); + script.append(" -t filter"); script.append(" -m owner --uid-owner "); script.append(torUid); script.append(" -j ACCEPT"); @@ -330,10 +329,108 @@ public class TorTransProxy implements TorServiceConstants { String msg = res.toString(); TorService.logMessage(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg); - return code; } + public int clearTransparentProxyingByApp(Context context, ArrayList apps) throws Exception + { + + boolean runRoot = true; + boolean waitFor = true; + + //redirectDNSResolvConf(); //not working yet + + String ipTablesPath = getIpTablesPath(context); + + StringBuilder script = new StringBuilder(); + + StringBuilder res = new StringBuilder(); + int code = -1; + + int torUid = context.getApplicationInfo().uid; + + //build up array of shell cmds to execute under one root context + for (TorifiedApp tApp:apps) + { + + if (tApp.isTorified() + && (!tApp.getUsername().equals(TorServiceConstants.TOR_APP_USERNAME)) + && (!tApp.getUsername().equals(TorServiceConstants.ORWEB_APP_USERNAME)) + ) //if app is set to true + { + + TorService.logMessage("clear transproxy for app: " + tApp.getUsername() + "(" + tApp.getUid() + ")"); + + // Set up port redirection + script.append(ipTablesPath); + script.append(" -D OUTPUT"); + script.append(" -t nat"); + script.append(" -p tcp"); + script.append(" ! -d 127.0.0.1"); //allow access to localhost + script.append(" -m owner --uid-owner "); + script.append(tApp.getUid()); + script.append(" -m tcp --syn"); + script.append(" -j REDIRECT --to-ports "); + script.append(TOR_TRANSPROXY_PORT); + script.append(" || exit\n"); + + // Same for DNS + script.append(ipTablesPath); + script.append(" -D OUTPUT"); + script.append(" -t nat"); + script.append(" -p udp -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(TOR_DNS_PORT); + script.append(" || exit\n"); + + // Reject DNS that is not from Tor (order is important - first matched rule counts!) + script.append(ipTablesPath); + script.append(" -D OUTPUT"); + script.append(" -t filter"); + script.append(" -m owner --uid-owner "); + script.append(tApp.getUid()); + script.append(" -p udp"); + script.append(" --dport "); + script.append(STANDARD_DNS_PORT); + script.append(" -j REJECT"); + script.append(" || exit\n"); + + // Reject all other outbound TCP packets + script.append(ipTablesPath); + script.append(" -D OUTPUT"); + script.append(" -t filter"); + script.append(" -m owner --uid-owner "); + script.append(tApp.getUid()); + script.append(" -p tcp"); + script.append(" -j REJECT"); + script.append(" || exit\n"); + + } + } + + + // Allow everything for Tor + script.append(ipTablesPath); + script.append(" -D OUTPUT"); + script.append(" -t filter"); + script.append(" -m owner --uid-owner "); + script.append(torUid); + script.append(" -j ACCEPT"); + script.append(" || exit\n"); + + String[] cmdAdd = {script.toString()}; + + code = TorServiceUtils.doShellCommand(cmdAdd, res, runRoot, waitFor); + String msg = res.toString(); + TorService.logMessage(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg); + + return code; + } + /* + // this is a bad idea so removing public int setTransparentProxyingByPort(Context context, int port) throws Exception { @@ -348,7 +445,7 @@ public class TorTransProxy implements TorServiceConstants { StringBuilder res = new StringBuilder(); int code = -1; - flushIptables(context); + //flushIptables(context); //TCP //iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $srcPortNumber -j REDIRECT --to-port $dstPortNumbe @@ -390,7 +487,8 @@ public class TorTransProxy implements TorServiceConstants { return code; } - + */ + public int enableTetheringRules (Context context) throws Exception { @@ -447,12 +545,12 @@ public class TorTransProxy implements TorServiceConstants { StringBuilder res = new StringBuilder(); int code = -1; - flushIptables(context); + //flushIptables(context); int torUid = context.getApplicationInfo().uid; - // Set up port redirection - script.append(ipTablesPath); + // Set up port redirection + script.append(ipTablesPath); script.append(" -t nat"); script.append(" -A OUTPUT -p tcp"); script.append(" ! -d 127.0.0.1"); //allow access to localhost @@ -466,36 +564,14 @@ public class TorTransProxy implements TorServiceConstants { // Same for DNS script.append(ipTablesPath); script.append(" -t nat"); - script.append(" -A OUTPUT -p udp"); - script.appent(" -m owner ! --uid-owner "); + script.append(" -A OUTPUT -p udp -m owner ! --uid-owner "); script.append(torUid); script.append(" -m udp --dport "); script.append(STANDARD_DNS_PORT); script.append(" -j REDIRECT --to-ports "); script.append(TOR_DNS_PORT); script.append(" || exit\n"); - - // Allow loopback - script.append(ipTablesPath); - script.append(" -t filter"); - script.append(" -A OUTPUT"); - script.append(" -o lo"); - script.append(" -j ACCEPT"); - script.append(" || exit\n"); - // Allow everything for Tor - script.append(ipTablesPath); - script.append(" -t filter"); - script.append(" -A OUTPUT"); - script.append(" -m owner --uid-owner "); - script.append(torUid); - script.append(" -j ACCEPT"); - script.append(" || exit\n"); - - - /* - //Outgoing loopback already allowed (23/7/12) - int[] ports = {TOR_DNS_PORT,TOR_TRANSPROXY_PORT,PORT_SOCKS,PORT_HTTP}; for (int port : ports) @@ -513,8 +589,25 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -j ACCEPT"); script.append(" || exit\n"); - } */ + } + // Allow loopback + script.append(ipTablesPath); + script.append(" -t filter"); + script.append(" -A OUTPUT"); + script.append(" -p tcp"); + script.append(" -o lo"); + script.append(" -j ACCEPT"); + script.append(" || exit\n"); + + // Allow everything for Tor + script.append(ipTablesPath); + script.append(" -t filter"); + script.append(" -A OUTPUT"); + script.append(" -m owner --uid-owner "); + script.append(torUid); + script.append(" -j ACCEPT"); + script.append(" || exit\n"); if (TorService.ENABLE_DEBUG_LOG) { @@ -563,6 +656,74 @@ public class TorTransProxy implements TorServiceConstants { String msg = res.toString(); TorService.logMessage(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg); + return code; + } + + public int clearTransparentProxyingAll(Context context) throws Exception + { + boolean runRoot = true; + boolean waitFor = true; + + //redirectDNSResolvConf(); //not working yet + + String ipTablesPath = getIpTablesPath(context); + + StringBuilder script = new StringBuilder(); + + StringBuilder res = new StringBuilder(); + int code = -1; + + + int torUid = context.getApplicationInfo().uid; + + // Set up port redirection + script.append(ipTablesPath); + script.append(" -D OUTPUT -p tcp"); + script.append(" -t nat"); + script.append(" ! -d 127.0.0.1"); //allow access to localhost + script.append(" -m owner ! --uid-owner "); + script.append(torUid); + script.append(" -m tcp --syn"); + script.append(" -j REDIRECT --to-ports "); + script.append(TOR_TRANSPROXY_PORT); + script.append(" || exit\n"); + + // Same for DNS + script.append(ipTablesPath); + script.append(" -D OUTPUT"); + script.append(" -t nat"); + script.append(" -p udp -m owner ! --uid-owner "); + script.append(torUid); + script.append(" -m udp --dport "); + script.append(STANDARD_DNS_PORT); + script.append(" -j REDIRECT --to-ports "); + script.append(TOR_DNS_PORT); + script.append(" || exit\n"); + + // Reject DNS that is not from Tor (order is important - first matched rule counts!) + script.append(ipTablesPath); + script.append(" -D OUTPUT"); + script.append(" -t filter"); + script.append(" -p udp"); + script.append(" --dport "); + script.append(STANDARD_DNS_PORT); + script.append(" -j REJECT"); + script.append(" || exit\n"); + + // Reject all other outbound TCP packets + script.append(ipTablesPath); + script.append(" -D OUTPUT"); + script.append(" -t filter"); + script.append(" -p tcp"); + script.append(" -j REJECT"); + script.append(" || exit\n"); + + String[] cmdAdd = {script.toString()}; + + code = TorServiceUtils.doShellCommand(cmdAdd, res, runRoot, waitFor); + String msg = res.toString(); + TorService.logMessage(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg); + return code; diff --git a/src/org/torproject/android/settings/SettingsPreferences.java b/src/org/torproject/android/settings/SettingsPreferences.java index afac094b..46a2211e 100644 --- a/src/org/torproject/android/settings/SettingsPreferences.java +++ b/src/org/torproject/android/settings/SettingsPreferences.java @@ -203,7 +203,7 @@ public class SettingsPreferences private void clearTransProxyState () { try { - new TorTransProxy().flushIptables(this); + new TorTransProxy().clearTransparentProxyingAll(this); } catch (Exception e) { Log.e(TorConstants.TAG,"error flushing iptables",e); }