From e5b70ba4ab02cecf462d84ad7437e7b51ee7f575 Mon Sep 17 00:00:00 2001 From: Nathan Freitas Date: Mon, 7 Apr 2014 11:10:31 -0400 Subject: [PATCH] improve shell command, root and permissions handling --- src/org/torproject/android/service/Root.java | 107 ------------ .../android/service/TorService.java | 125 +++++++------- .../android/service/TorServiceConstants.java | 5 +- .../android/service/TorServiceUtils.java | 3 +- .../android/service/TorTransProxy.java | 162 +++++++++--------- .../android/settings/SettingsPreferences.java | 19 +- .../android/wizard/Permissions.java | 77 +++------ 7 files changed, 169 insertions(+), 329 deletions(-) delete mode 100644 src/org/torproject/android/service/Root.java diff --git a/src/org/torproject/android/service/Root.java b/src/org/torproject/android/service/Root.java deleted file mode 100644 index d41b48c3..00000000 --- a/src/org/torproject/android/service/Root.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.torproject.android.service; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.util.ArrayList; - -import org.torproject.android.service.ExecShell.SHELL_CMD; - -import android.util.Log; - -/** - * @author Kevin Kowalewski - * - */ -public class Root { - - private static String LOG_TAG = Root.class.getName(); - - public boolean isDeviceRooted() { - if (checkRootMethod1()){return true;} - if (checkRootMethod2()){return true;} - if (checkRootMethod3()){return true;} - return false; - } - - public boolean checkRootMethod1(){ - String buildTags = android.os.Build.TAGS; - - if (buildTags != null && buildTags.contains("test-keys")) { - return true; - } - return false; - } - - public boolean checkRootMethod2(){ - try { - File file = new File("/system/app/Superuser.apk"); - if (file.exists()) { - return true; - } - } catch (Exception e) { } - - return false; - } - - public boolean checkRootMethod3() { - if (new ExecShell().executeCommand(SHELL_CMD.check_su_binary) != null){ - return true; - }else{ - return false; - } - } -} - - -/** - * @author Kevin Kowalewski - * - */ -class ExecShell { - - private static String LOG_TAG = ExecShell.class.getName(); - - public static enum SHELL_CMD { - check_su_binary(new String[] {"/system/xbin/which","su"}), - ; - - String[] command; - - SHELL_CMD(String[] command){ - this.command = command; - } - } - - public ArrayList executeCommand(SHELL_CMD shellCmd){ - String line = null; - ArrayList fullResponse = new ArrayList(); - Process localProcess = null; - - try { - localProcess = Runtime.getRuntime().exec(shellCmd.command); - } catch (Exception e) { - return null; - //e.printStackTrace(); - } - - BufferedWriter out = new BufferedWriter(new OutputStreamWriter(localProcess.getOutputStream())); - BufferedReader in = new BufferedReader(new InputStreamReader(localProcess.getInputStream())); - - try { - while ((line = in.readLine()) != null) { - Log.d(LOG_TAG, "--> Line received: " + line); - fullResponse.add(line); - } - } catch (Exception e) { - e.printStackTrace(); - } - - Log.d(LOG_TAG, "--> Full response was: " + fullResponse); - - return fullResponse; - } - -} \ No newline at end of file diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index 55e2a7f1..1cede611 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -25,6 +25,10 @@ import net.freehaven.tor.control.ConfigEntry; import net.freehaven.tor.control.EventHandler; import net.freehaven.tor.control.TorControlConnection; +import org.sufficientlysecure.rootcommands.RootCommands; +import org.sufficientlysecure.rootcommands.Shell; +import org.sufficientlysecure.rootcommands.Toolbox; +import org.sufficientlysecure.rootcommands.command.SimpleCommand; import org.torproject.android.Orbot; import org.torproject.android.R; import org.torproject.android.TorConstants; @@ -135,7 +139,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst { try { - int procId = TorServiceUtils.findProcessId(fileTor.getAbsolutePath()); + int procId = TorServiceUtils.findProcessId(fileTor.getCanonicalPath()); if (procId != -1) { @@ -457,40 +461,36 @@ public class TorService extends Service implements TorServiceConstants, TorConst int maxTry = 5; int currTry = 0; - while ((procId = TorServiceUtils.findProcessId(fileTor.getAbsolutePath())) != -1 && currTry++ < maxTry) + Shell shell = Shell.startShell(); + Toolbox tb = new Toolbox(shell); + + while ((procId = TorServiceUtils.findProcessId(fileTor.getCanonicalPath())) != -1 && currTry++ < maxTry) { + sendCallbackStatusMessage ("Found existing orphan Tor process; Trying to shutdown now (device restart may be needed)..."); logNotice("Found Tor PID=" + procId + " - attempt to shutdown now..."); - String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" }; - TorServiceUtils.doShellCommand(cmd,log, mHasRoot, false); - try { Thread.sleep(killDelayMs); } - catch (Exception e){} + tb.killAll(fileTor.getCanonicalPath()); + } if (procId == -1) { - while ((procId = TorServiceUtils.findProcessId(filePrivoxy.getAbsolutePath())) != -1) + while ((procId = TorServiceUtils.findProcessId(filePrivoxy.getCanonicalPath())) != -1) { logNotice("Found Privoxy PID=" + procId + " - killing now..."); - String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" }; - TorServiceUtils.doShellCommand(cmd,log, mHasRoot, false); - try { Thread.sleep(killDelayMs); } - catch (Exception e){} + tb.killAll(filePrivoxy.getCanonicalPath()); } - while ((procId = TorServiceUtils.findProcessId(fileObfsProxy.getAbsolutePath())) != -1) + while ((procId = TorServiceUtils.findProcessId(fileObfsProxy.getCanonicalPath())) != -1) { logNotice("Found ObfsProxy PID=" + procId + " - killing now..."); - String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" }; - TorServiceUtils.doShellCommand(cmd,log, mHasRoot, false); - try { Thread.sleep(killDelayMs); } - catch (Exception e){} + tb.killAll(fileObfsProxy.getCanonicalPath()); } } else @@ -543,15 +543,18 @@ public class TorService extends Service implements TorServiceConstants, TorConst { logNotice(fileBin.getName() + ": PRE: Is binary exec? " + fileBin.canExecute()); - - StringBuilder log = new StringBuilder (); + + if (!fileBin.canExecute()) + { + logNotice("(re)Setting permission on binary: " + fileBin.getCanonicalPath()); + Shell shell = Shell.startShell(new ArrayList(), appBinHome.getAbsolutePath()); - logNotice("(re)Setting permission on binary: " + fileBin.getAbsolutePath()); - String[] cmd1 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + fileBin.getAbsolutePath()}; - TorServiceUtils.doShellCommand(cmd1, log, false, true); - - logNotice(fileBin.getName() + ": POST: Is binary exec? " + fileBin.canExecute()); - + shell.add(new SimpleCommand("chmod " + CHMOD_EXE_VALUE + ' ' + fileBin.getCanonicalPath())).waitForFinish(); + + File fileTest = new File(fileBin.getCanonicalPath()); + logNotice(fileTest.getName() + ": POST: Is binary exec? " + fileTest.canExecute()); + } + return fileBin.canExecute(); } @@ -600,7 +603,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst * * the idea is that if Tor is off then transproxy is off */ - private boolean enableTransparentProxy (boolean proxyAll, boolean enableTether) throws Exception + protected boolean enableTransparentProxy (boolean proxyAll, boolean enableTether) throws Exception { if (mTransProxy == null) @@ -668,7 +671,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst mTransProxy = new TorTransProxy(this); mTransProxy.clearTransparentProxyingAll(this); - // mTransProxy.clearTransparentProxyingByApp(this,AppManager.getApps(this)); clearNotifications(); @@ -679,53 +681,50 @@ public class TorService extends Service implements TorServiceConstants, TorConst { if (!fileTor.exists()) - throw new RuntimeException("Sorry Tor binary not installed properly: " + fileTor.getAbsolutePath()); + throw new RuntimeException("Sorry Tor binary not installed properly: " + fileTor.getCanonicalPath()); if (!fileTor.canExecute()) - throw new RuntimeException("Sorry can't execute Tor: " + fileTor.getAbsolutePath()); + throw new RuntimeException("Sorry can't execute Tor: " + fileTor.getCanonicalPath()); SharedPreferences prefs =getSharedPrefs(getApplicationContext()); - StringBuilder log = new StringBuilder(); - - String torrcPath = new File(appBinHome, TORRC_ASSET_KEY).getAbsolutePath(); + String torrcPath = new File(appBinHome, TORRC_ASSET_KEY).getCanonicalPath(); boolean transProxyTethering = prefs.getBoolean("pref_transparent_tethering", false); if (transProxyTethering) { - torrcPath = new File(appBinHome, TORRC_TETHER_KEY).getAbsolutePath(); + torrcPath = new File(appBinHome, TORRC_TETHER_KEY).getCanonicalPath(); } - String[] torCmd = { - "export HOME=" + appBinHome.getAbsolutePath(), - fileTor.getAbsolutePath() + " DataDirectory " + appCacheHome.getAbsolutePath() + " -f " + torrcPath + " || exit\n" - }; - - boolean runAsRootFalse = false; - boolean waitForProcess = false; int procId = -1; int attempts = 0; int torRetryWaitTimeMS = 2000; + ArrayList alEnv = new ArrayList(); + alEnv.add("HOME=" + appBinHome.getCanonicalPath()); + + Shell shell = Shell.startShell(alEnv,appBinHome.getCanonicalPath()); + SimpleCommand cmdTor = new SimpleCommand(fileTor.getCanonicalPath() + " DataDirectory " + appCacheHome.getCanonicalPath() + " -f " + torrcPath + "&"); + shell.add(cmdTor); + while (procId == -1 && attempts < MAX_START_TRIES) { - log = new StringBuilder(); sendCallbackStatusMessage(getString(R.string.status_starting_up)); - TorServiceUtils.doShellCommand(torCmd, log, runAsRootFalse, waitForProcess); + shell.add(cmdTor); Thread.sleep(torRetryWaitTimeMS); - procId = TorServiceUtils.findProcessId(fileTor.getAbsolutePath()); + procId = TorServiceUtils.findProcessId(fileTor.getCanonicalPath()); if (procId == -1) { Thread.sleep(torRetryWaitTimeMS); - procId = TorServiceUtils.findProcessId(fileTor.getAbsolutePath()); + procId = TorServiceUtils.findProcessId(fileTor.getCanonicalPath()); attempts++; } else @@ -738,7 +737,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (procId == -1) { - logNotice(log.toString()); + logNotice(cmdTor.getExitCode() + ": " + cmdTor.getOutput()); sendCallbackStatusMessage(getString(R.string.couldn_t_start_tor_process_)); throw new Exception ("Unable to start Tor"); @@ -748,8 +747,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst logNotice("Tor process id=" + procId); - //showToolbarNotification(getString(R.string.status_starting_up), NOTIFY_ID, R.drawable.ic_stat_tor); - initControlConnection (); processSettingsImpl(); @@ -761,32 +758,27 @@ public class TorService extends Service implements TorServiceConstants, TorConst logNotice( "Starting privoxy process"); - int privoxyProcId = TorServiceUtils.findProcessId(filePrivoxy.getAbsolutePath()); + int privoxyProcId = TorServiceUtils.findProcessId(filePrivoxy.getCanonicalPath()); StringBuilder log = null; int attempts = 0; + Shell shell = Shell.startShell(); + if (privoxyProcId == -1) { log = new StringBuilder(); - String privoxyConfigPath = new File(appBinHome, PRIVOXYCONFIG_ASSET_KEY).getAbsolutePath(); + String privoxyConfigPath = new File(appBinHome, PRIVOXYCONFIG_ASSET_KEY).getCanonicalPath(); + SimpleCommand cmdPrivoxy = new SimpleCommand(filePrivoxy.getCanonicalPath() + " " + privoxyConfigPath + " &"); - String[] cmds = - { filePrivoxy.getAbsolutePath() + " " + privoxyConfigPath + " &" }; - - logNotice (cmds[0]); - - boolean runAsRoot = false; - boolean waitFor = false; - - TorServiceUtils.doShellCommand(cmds, log, runAsRoot, waitFor); + shell.add(cmdPrivoxy); //wait one second to make sure it has started up Thread.sleep(1000); - while ((privoxyProcId = TorServiceUtils.findProcessId(filePrivoxy.getAbsolutePath())) == -1 && attempts < MAX_START_TRIES) + while ((privoxyProcId = TorServiceUtils.findProcessId(filePrivoxy.getCanonicalPath())) == -1 && attempts < MAX_START_TRIES) { logNotice("Couldn't find Privoxy process... retrying...\n" + log); Thread.sleep(3000); @@ -1523,9 +1515,12 @@ public class TorService extends Service implements TorServiceConstants, TorConst logNotice("Network connectivity is good. Waking Tor up..."); showToolbarNotification(getString(R.string.status_activated),NOTIFY_ID,R.drawable.ic_stat_tor,-1,prefPersistNotifications); + if (mHasRoot && mEnableTransparentProxy) + enableTransparentProxy(mTransProxyAll, mTransProxyTethering); } - } catch (RemoteException e) { - logException ("error applying mPrefs",e); + + } catch (Exception e) { + logException ("error updating state after network restart",e); } } } @@ -1596,8 +1591,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst } - mBinder.updateConfiguration("GeoIPFile", fileGeoIP.getAbsolutePath(), false); - mBinder.updateConfiguration("GeoIPv6File", fileGeoIP6.getAbsolutePath(), false); + mBinder.updateConfiguration("GeoIPFile", fileGeoIP.getCanonicalPath(), false); + mBinder.updateConfiguration("GeoIPv6File", fileGeoIP6.getCanonicalPath(), false); } catch (Exception e) @@ -1656,7 +1651,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (obfsBridges) { - mBinder.updateConfiguration("ClientTransportPlugin","obfs2 exec " + fileObfsProxy.getAbsolutePath() + " --managed", false); + mBinder.updateConfiguration("ClientTransportPlugin","obfs2 exec " + fileObfsProxy.getCanonicalPath() + " --managed", false); } mBinder.updateConfiguration("UpdateBridgesFromAuthority", "0", false); @@ -1723,7 +1718,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst { logNotice("hidden services are enabled"); - mBinder.updateConfiguration("HiddenServiceDir",appCacheHome.getAbsolutePath(), false); + mBinder.updateConfiguration("HiddenServiceDir",appCacheHome.getCanonicalPath(), false); //mBinder.updateConfiguration("RendPostPeriod", "600 seconds", false); //possible feature to investigate String hsPorts = prefs.getString("pref_hs_ports",""); @@ -1777,7 +1772,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst bw.println("nameserver 8.8.4.4"); bw.close(); - return file.getAbsolutePath(); + return file.getCanonicalPath(); } diff --git a/src/org/torproject/android/service/TorServiceConstants.java b/src/org/torproject/android/service/TorServiceConstants.java index 94f5c49d..bd1c64c2 100644 --- a/src/org/torproject/android/service/TorServiceConstants.java +++ b/src/org/torproject/android/service/TorServiceConstants.java @@ -44,9 +44,8 @@ public interface TorServiceConstants { public final static String SHELL_CMD_CP = "cp"; - public final static String CHMOD_EXE_VALUE = "700"; + public final static String CHMOD_EXE_VALUE = "770"; - public final static int FILE_WRITE_BUFFER_SIZE = 2048; //HTTP Proxy server port @@ -87,7 +86,7 @@ public interface TorServiceConstants { public static final String PREF_BINARY_PRIVOXY_VERSION_INSTALLED = "BINARY_PRIVOXY_VERSION_INTALLED"; //obfsproxy - public static final String OBFSPROXY_ASSET_KEY = "libobfsproxy.so"; + public static final String OBFSPROXY_ASSET_KEY = "obfsproxy"; public static final int MESSAGE_TRAFFIC_COUNT = 5; diff --git a/src/org/torproject/android/service/TorServiceUtils.java b/src/org/torproject/android/service/TorServiceUtils.java index c1f31459..e5cf25e0 100644 --- a/src/org/torproject/android/service/TorServiceUtils.java +++ b/src/org/torproject/android/service/TorServiceUtils.java @@ -118,7 +118,7 @@ public class TorServiceUtils implements TorServiceConstants { } - + /** public static int doShellCommand(String[] cmds, StringBuilder log, boolean runAsRoot, boolean waitFor) throws Exception { @@ -222,4 +222,5 @@ public class TorServiceUtils implements TorServiceConstants { return exitCode; } + **/ } diff --git a/src/org/torproject/android/service/TorTransProxy.java b/src/org/torproject/android/service/TorTransProxy.java index 7280eeb0..0a9ae6f4 100644 --- a/src/org/torproject/android/service/TorTransProxy.java +++ b/src/org/torproject/android/service/TorTransProxy.java @@ -3,12 +3,13 @@ package org.torproject.android.service; import java.io.File; import java.util.ArrayList; +import org.sufficientlysecure.rootcommands.Shell; +import org.sufficientlysecure.rootcommands.command.SimpleCommand; import org.torproject.android.TorConstants; import org.torproject.android.settings.TorifiedApp; import android.content.Context; import android.content.SharedPreferences; -import android.preference.PreferenceManager; import android.util.Log; public class TorTransProxy implements TorServiceConstants { @@ -276,26 +277,20 @@ public class TorTransProxy implements TorServiceConstants { public int setTransparentProxyingByApp(Context context, ArrayList apps) throws Exception { - - boolean runRoot = true; - boolean waitFor = true; - String ipTablesPath = getIpTablesPath(context); - StringBuilder script = new StringBuilder(); + //StringBuilder script = new StringBuilder(); - StringBuilder res = new StringBuilder(); - int code = -1; - - String srcChainName = "OUTPUT"; + String srcChainName = "OUTPUT"; //run the delete commands in a separate process as it might error out - String[] cmdExecClear = {script.toString()}; - code = TorServiceUtils.doShellCommand(cmdExecClear, res, runRoot, waitFor); + //String[] cmdExecClear = {script.toString()}; + //code = TorServiceUtils.doShellCommand(cmdExecClear, res, runRoot, waitFor); //reset script - script = new StringBuilder(); - + + Shell shell = Shell.startRootShell(); + //build up array of shell cmds to execute under one root context for (TorifiedApp tApp:apps) { @@ -305,6 +300,8 @@ public class TorTransProxy implements TorServiceConstants { ) //if app is set to true { + StringBuilder script = new StringBuilder(); + logMessage("enabling transproxy for app: " + tApp.getUsername() + "(" + tApp.getUid() + ")"); // Set up port redirection @@ -318,7 +315,9 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -m tcp --syn"); script.append(" -j REDIRECT --to-ports "); script.append(TOR_TRANSPROXY_PORT); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); // Same for DNS script.append(ipTablesPath); @@ -330,7 +329,9 @@ public class TorTransProxy implements TorServiceConstants { script.append(STANDARD_DNS_PORT); script.append(" -j REDIRECT --to-ports "); script.append(TOR_DNS_PORT); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); int[] ports = {TOR_DNS_PORT,TOR_TRANSPROXY_PORT,PORT_SOCKS,PORT_HTTP}; @@ -347,7 +348,10 @@ public class TorTransProxy implements TorServiceConstants { script.append(" --dport "); script.append(port); script.append(" -j ACCEPT"); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); + } // Allow loopback @@ -359,7 +363,9 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -p tcp"); script.append(" -o lo"); script.append(" -j ACCEPT"); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); // Reject all other outbound TCP packets script.append(ipTablesPath); @@ -370,7 +376,9 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -p tcp"); script.append(" ! -d 127.0.0.1"); //allow access to localhost script.append(" -j REJECT"); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); // Reject all other outbound UDP packets script.append(ipTablesPath); @@ -381,62 +389,52 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -p udp"); script.append(" ! -d 127.0.0.1"); //allow access to localhost script.append(" -j REJECT"); - script.append(" || exit\n"); - + + shell.add(new SimpleCommand(script.toString())); + } } - String[] cmdAdd = {script.toString()}; - - code = TorServiceUtils.doShellCommand(cmdAdd, res, runRoot, waitFor); - String msg = res.toString(); - - logMessage(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg); - - return code; + return 1; } public int enableTetheringRules (Context context) throws Exception { - boolean runRoot = true; - boolean waitFor = true; - String ipTablesPath = getIpTablesPath(context); StringBuilder script = new StringBuilder(); - - StringBuilder res = new StringBuilder(); - int code = -1; String[] hwinterfaces = {"usb0","wl0.1"}; + Shell shell = Shell.startRootShell(); + for (int i = 0; i < hwinterfaces.length; i++) { + + script = new StringBuilder(); script.append(ipTablesPath); script.append(" -t nat -A PREROUTING -i "); script.append(hwinterfaces[i]); script.append(" -p udp --dport 53 -j REDIRECT --to-ports "); script.append(TOR_DNS_PORT); - script.append(" || exit\n"); + shell.add(new SimpleCommand(script.toString())); + + script = new StringBuilder(); script.append(ipTablesPath); script.append(" -t nat -A PREROUTING -i "); script.append(hwinterfaces[i]); script.append(" -p tcp -j REDIRECT --to-ports "); script.append(TOR_TRANSPROXY_PORT); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + } - String[] cmdAdd = {script.toString()}; - - code = TorServiceUtils.doShellCommand(cmdAdd, res, runRoot, waitFor); - String msg = res.toString(); - logMessage(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg); - - return code; + return 0; } private void logMessage (String msg) @@ -450,36 +448,30 @@ public class TorTransProxy implements TorServiceConstants { public int clearTransparentProxyingAll(Context context) throws Exception { - boolean runRoot = true; - boolean waitFor = true; - String ipTablesPath = getIpTablesPath(context); StringBuilder script = new StringBuilder(); - StringBuilder res = new StringBuilder(); - int code = -1; + Shell shell = Shell.startRootShell(); + String chainName = "OUTPUT"; script = new StringBuilder(); - res = new StringBuilder(); script.append(ipTablesPath); script.append(" -t nat"); script.append(" -F ").append(chainName); //delete previous user-defined chain - script.append(" || exit\n"); - code = TorServiceUtils.doShellCommand(script.toString(), res, runRoot, waitFor); - logMessage("Exec resp: cmd> " + script.toString() + "; errCode=" + code + ";resp=" + res.toString()); - + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); - res = new StringBuilder(); + script.append(ipTablesPath); script.append(" -t filter"); script.append(" -F ").append(chainName); //delete previous user-defined chain - script.append(" || exit\n"); - code = TorServiceUtils.doShellCommand(script.toString(), res, runRoot, waitFor); - logMessage("Exec resp: cmd> " + script.toString() + "; errCode=" + code + ";resp=" + res.toString()); - - return code; + + shell.add(new SimpleCommand(script.toString())); + + return 0; } public int setTransparentProxyingAll(Context context) throws Exception @@ -492,15 +484,15 @@ public class TorTransProxy implements TorServiceConstants { String ipTablesPath = getIpTablesPath(context); - StringBuilder script = new StringBuilder(); - StringBuilder res = new StringBuilder(); - int code = -1; + Shell shell = Shell.startRootShell(); int torUid = context.getApplicationInfo().uid; String srcChainName = "OUTPUT"; + StringBuilder script = new StringBuilder(); + // Allow everything for Tor script.append(ipTablesPath); script.append(" -t filter"); @@ -508,7 +500,9 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -m owner --uid-owner "); script.append(torUid); script.append(" -j ACCEPT"); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); // Set up port redirection script.append(ipTablesPath); @@ -521,7 +515,9 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -m tcp --syn"); script.append(" -j REDIRECT --to-ports "); script.append(TOR_TRANSPROXY_PORT); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); // Same for DNS script.append(ipTablesPath); @@ -535,7 +531,10 @@ public class TorTransProxy implements TorServiceConstants { script.append(STANDARD_DNS_PORT); script.append(" -j REDIRECT --to-ports "); script.append(TOR_DNS_PORT); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); + /** int[] ports = {TOR_DNS_PORT,TOR_TRANSPROXY_PORT,PORT_SOCKS,PORT_HTTP}; @@ -564,8 +563,10 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -p tcp"); script.append(" -o lo"); script.append(" -j ACCEPT"); - script.append(" || exit\n"); + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); + if (TorService.ENABLE_DEBUG_LOG) { @@ -579,8 +580,10 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -j LOG"); script.append(" --log-prefix='ORBOT_DNSLEAK_PROTECTION'"); script.append(" --log-uid"); - script.append(" || exit\n"); - + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); + script.append(ipTablesPath); script.append(" -t filter"); script.append(" -A ").append(srcChainName); @@ -588,7 +591,10 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -j LOG"); script.append(" --log-prefix='ORBOT_TCPLEAK_PROTECTION'"); script.append(" --log-uid"); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); + } @@ -601,7 +607,9 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -p tcp"); script.append(" ! -d 127.0.0.1"); //allow access to localhost script.append(" -j REJECT"); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); + script = new StringBuilder(); // Reject all other outbound UDP packets script.append(ipTablesPath); @@ -612,16 +620,10 @@ public class TorTransProxy implements TorServiceConstants { script.append(" -p udp"); script.append(" ! -d 127.0.0.1"); //allow access to localhost script.append(" -j REJECT"); - script.append(" || exit\n"); + + shell.add(new SimpleCommand(script.toString())); - String[] cmdExec = {script.toString()}; - - code = TorServiceUtils.doShellCommand(cmdExec, res, runRoot, waitFor); - String msg = res.toString(); - - logMessage("Exec resp: errCode=" + code + ";resp=" + msg); - - return code; + return 0; } diff --git a/src/org/torproject/android/settings/SettingsPreferences.java b/src/org/torproject/android/settings/SettingsPreferences.java index 6cf1e0c6..84b8c91a 100644 --- a/src/org/torproject/android/settings/SettingsPreferences.java +++ b/src/org/torproject/android/settings/SettingsPreferences.java @@ -5,6 +5,7 @@ package org.torproject.android.settings; import java.util.Locale; +import org.sufficientlysecure.rootcommands.RootCommands; import org.torproject.android.R; import org.torproject.android.service.TorServiceUtils; @@ -121,22 +122,8 @@ public class SettingsPreferences if (prefRequestRoot.isChecked()) { - //boolean canRoot = TorServiceUtils.isRootPossible(); - boolean canRoot; - - try - { - StringBuilder res = new StringBuilder(); - String[] cmd = {"ls /data/data"}; //only root can do this! - int code = TorServiceUtils.doShellCommand(cmd, res, true, true); - canRoot = code > -1; - } - catch (Exception e) - { - //probably not root - canRoot = false; - } - + boolean canRoot = RootCommands.rootAccessGiven(); + getPreferenceScreen().getPreference(TRANSPROXY_GROUP_IDX).setEnabled(canRoot); prefRequestRoot.setChecked(canRoot); diff --git a/src/org/torproject/android/wizard/Permissions.java b/src/org/torproject/android/wizard/Permissions.java index 91e93db5..dd4a2179 100644 --- a/src/org/torproject/android/wizard/Permissions.java +++ b/src/org/torproject/android/wizard/Permissions.java @@ -1,11 +1,9 @@ package org.torproject.android.wizard; +import org.sufficientlysecure.rootcommands.RootCommands; import org.torproject.android.R; import org.torproject.android.TorConstants; -import org.torproject.android.service.Root; import org.torproject.android.service.TorService; -import org.torproject.android.service.TorServiceUtils; -import org.torproject.android.service.TorTransProxy; import android.app.Activity; import android.content.Context; @@ -22,7 +20,6 @@ import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toast; public class Permissions extends Activity implements TorConstants { @@ -41,8 +38,8 @@ public class Permissions extends Activity implements TorConstants { super.onStart(); setContentView(R.layout.layout_wizard_permissions); - stepThree(); - + stepFourRoot(); + } @Override @@ -64,21 +61,6 @@ public class Permissions extends Activity implements TorConstants { } - private void stepThree(){ - - boolean isRootPossible = new Root().isDeviceRooted(); - - if (isRootPossible) - { - stepFourRoot(); - } - else - { - stepFour(); - } - - } - private void stepFourRoot(){ String title = context.getString(R.string.wizard_permissions_title); @@ -112,24 +94,27 @@ public class Permissions extends Activity implements TorConstants { boolean isChecked) { + //this is saying do not use root + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); Editor pEdit = prefs.edit(); - pEdit.putBoolean(PREF_TRANSPARENT, !isChecked); - pEdit.putBoolean(PREF_TRANSPARENT_ALL, !isChecked); - - pEdit.putBoolean(PREF_HAS_ROOT, !isChecked); - + pEdit.putBoolean(PREF_TRANSPARENT, false); + pEdit.putBoolean(PREF_TRANSPARENT_ALL, false); + pEdit.putBoolean(PREF_HAS_ROOT, false); pEdit.commit(); + /* Button next = ((Button)findViewById(R.id.btnWizard2)); if(isChecked) next.setEnabled(true); else next.setEnabled(false); + */ + stepFour(); } @@ -142,46 +127,24 @@ public class Permissions extends Activity implements TorConstants { //Check and Install iptables - TorTransProxy.testOwnerModule(this) SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - boolean hasRoot = prefs.getBoolean("has_root",false); - + boolean hasRoot = RootCommands.rootAccessGiven(); + Editor pEdit = prefs.edit(); + pEdit.putBoolean(PREF_HAS_ROOT,hasRoot); + pEdit.commit(); + if (!hasRoot) { - hasRoot = new Root().isDeviceRooted(); - Editor pEdit = prefs.edit(); - pEdit.putBoolean(PREF_HAS_ROOT,hasRoot); - pEdit.commit(); + stepFour(); } - - if (hasRoot) + else { - try { - /* - TorTransProxy ttProxy = new TorTransProxy(); - - int resp = ttProxy.testOwnerModule(context,ttProxy.getIpTablesPath(context)); - - if (resp != 0) - { - hasRoot = false; - Toast.makeText(context, "ERROR: IPTables OWNER module not available", Toast.LENGTH_LONG).show(); + startActivityForResult(new Intent(getBaseContext(), ConfigureTransProxy.class), 1); - Log.i(TorService.TAG,"ERROR: IPTables OWNER module not available"); - stepFour(); - } - */ - - } catch (Exception e) { - - hasRoot = false; - Log.d(TorService.TAG,"ERROR: IPTables OWNER module not available",e); - stepFour(); - } + } - - startActivityForResult(new Intent(getBaseContext(), ConfigureTransProxy.class), 1); }