From c5959637af053d8b98584dbf0666c6a61e8af0a7 Mon Sep 17 00:00:00 2001 From: Nathan Freitas Date: Mon, 13 Jan 2014 21:48:28 -0500 Subject: [PATCH] solves problem with binaries being stored on external SDcard --- .../android/service/TorService.java | 285 ++++++++++-------- .../android/service/TorServiceConstants.java | 1 + 2 files changed, 161 insertions(+), 125 deletions(-) diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index f27f8355..40976aa1 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -31,7 +31,6 @@ import org.torproject.android.TorConstants; import org.torproject.android.Utils; import org.torproject.android.settings.AppManager; -import android.annotation.SuppressLint; import android.app.Application; import android.app.Notification; import android.app.NotificationManager; @@ -46,13 +45,13 @@ import android.content.SharedPreferences.Editor; import android.graphics.Color; import android.net.ConnectivityManager; import android.os.Build; -import android.os.Handler; import android.os.IBinder; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Builder; import android.util.Log; +import android.widget.Toast; public class TorService extends Service implements TorServiceConstants, TorConstants, Runnable, EventHandler { @@ -103,6 +102,11 @@ public class TorService extends Service implements TorServiceConstants, TorConst private NotificationManager mNotificationManager = null; private Builder mNotifyBuilder; + + private boolean mHasRoot = false; + private boolean mEnableTransparentProxy = false; + private boolean mTransProxyAll = false; + private boolean mTransProxyTethering = false; public void logMessage(String msg) { @@ -126,38 +130,40 @@ public class TorService extends Service implements TorServiceConstants, TorConst private boolean findExistingProc () { - try + if (fileTorLink != null) { - if (fileTorLink == null) - initTorPathLink(); - - int procId = TorServiceUtils.findProcessId(fileTorLink.getAbsolutePath()); - - if (procId != -1) - { - logNotice("Found existing Tor process"); - - sendCallbackLogMessage (getString(R.string.found_existing_tor_process)); - - currentStatus = STATUS_CONNECTING; - - initControlConnection(); - - processSettingsImpl(); - - currentStatus = STATUS_ON; - - return true; - - } - - return false; + try + { + int procId = TorServiceUtils.findProcessId(fileTorLink.getAbsolutePath()); + + if (procId != -1) + { + logNotice("Found existing Tor process"); + + sendCallbackLogMessage (getString(R.string.found_existing_tor_process)); + + currentStatus = STATUS_CONNECTING; + + initControlConnection(); + + processSettingsImpl(); + + currentStatus = STATUS_ON; + + return true; + + } + + return false; + } + catch (Exception e) + { + Log.e(TAG,"error finding proc",e); + return false; + } } - catch (Exception e) - { - Log.e(TAG,"error finding proc",e); + else return false; - } } @@ -252,8 +258,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst try { - initTorPaths(); - sendCallbackLogMessage("Welcome back, Carter!"); } catch (Exception e) @@ -271,15 +275,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst _torInstance = this; - try - { - initTorPaths(); - } - catch (Exception e) - { - Log.e(TAG,"error setting up Tor",e); - throw new RuntimeException("Unable to start Tor",e); - } IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(mNetworkStateReceiver , mNetworkStateFilter); @@ -331,9 +326,11 @@ public class TorService extends Service implements TorServiceConstants, TorConst isRunning = true; } catch (Exception e) - { + { + logException("Unable to start Tor: " + e.getMessage(),e); + sendCallbackStatusMessage(getString(R.string.unable_to_start_tor) + ' ' + e.getMessage()); currentStatus = STATUS_OFF; - this.showToolbarNotification(getString(R.string.status_disabled), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr, -1, false); + this.showToolbarNotification(getString(R.string.unable_to_start_tor) + ": " + e.getMessage(), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr, -1, false); Log.d(TAG,"Unable to start Tor: " + e.getMessage(),e); } } @@ -455,19 +452,74 @@ public class TorService extends Service implements TorServiceConstants, TorConst return null; } - private void initTorPathLink () throws Exception + private void initTorPathLinkAndPerms () throws Exception { - fileTorLink = new File(appBinHome,"tor"); + fileTorLink.getParentFile().mkdirs(); - StringBuilder log = new StringBuilder(); - - String[] cmdDel = { "rm " + fileTorLink.getAbsolutePath() }; - TorServiceUtils.doShellCommand(cmdDel,log, false, false); + if (fileTorOrig.getAbsolutePath().startsWith("/mnt")) + { + logNotice("app installed on external storage - copying binaries to internal"); + + //can't execute binaries off the external storage, so copy them internal + StringBuilder log = new StringBuilder(); + int errCode = -1; + + if (!fileTorLink.exists()||(fileTorOrig.length()!=fileTorLink.length())) + { + String[] cmd = { SHELL_CMD_CP + ' ' + fileTorOrig.getAbsolutePath() + ' ' + fileTorLink.getAbsolutePath() }; + errCode = TorServiceUtils.doShellCommand(cmd,log, false, true); + logNotice("link CP err=" + errCode + " out: " + log.toString()); + } + enableBinExec(fileTorLink); + + log = new StringBuilder(); + File filePrivoxyLink = new File(appBinHome,"privoxy"); + if (!filePrivoxyLink.exists()||(filePrivoxy.length()!=filePrivoxyLink.length())) + { + String[] cmd1 = { SHELL_CMD_CP + ' ' + filePrivoxy.getAbsolutePath() + ' ' + filePrivoxyLink.getAbsolutePath() }; + errCode = TorServiceUtils.doShellCommand(cmd1,log, false, true); + logNotice("link CP err=" + errCode + " out: " + log.toString()); + } + filePrivoxy = filePrivoxyLink; + enableBinExec(filePrivoxy); + + log = new StringBuilder(); + File fileObfsProxyLink = new File(appBinHome,"obfsproxy"); + if (!fileObfsProxyLink.exists()||(fileObfsProxy.length()!=fileObfsProxyLink.length())) + { + String[] cmd2 = { SHELL_CMD_CP + ' ' + fileObfsProxy.getAbsolutePath() + ' ' + fileObfsProxyLink.getAbsolutePath() }; + errCode = TorServiceUtils.doShellCommand(cmd2,log, false, true); + logNotice("link CP err=" + errCode + " out: " + log.toString()); + } + fileObfsProxy = fileObfsProxyLink; + enableBinExec(fileObfsProxy); + + } + else + { + + + if (fileTorLink.exists()) + { + StringBuilder log = new StringBuilder(); + String[] cmdDel = { "rm " + fileTorLink.getAbsolutePath() }; + int errCode = TorServiceUtils.doShellCommand(cmdDel,log, false, true); + logNotice("link RM err=" + errCode + " out: " + log.toString()); + } + + StringBuilder log = new StringBuilder(); + String[] cmd = { SHELL_CMD_LINK + ' ' + fileTorOrig.getAbsolutePath() + ' ' + fileTorLink.getAbsolutePath() }; + int errCode = TorServiceUtils.doShellCommand(cmd,log, false, true); + logNotice("link LN err=" + errCode + " out: " + log.toString()); + + enableBinExec(fileTorOrig); + + enableBinExec(filePrivoxy); + enableBinExec(fileObfsProxy); + + } - String[] cmd = { SHELL_CMD_LINK + ' ' + fileTorOrig.getAbsolutePath() + ' ' + fileTorLink.getAbsolutePath() }; - TorServiceUtils.doShellCommand(cmd,log, false, false); - logNotice("link command output: " + log.toString()); } private void killTorProcess () throws Exception @@ -493,40 +545,49 @@ public class TorService extends Service implements TorServiceConstants, TorConst } int killDelayMs = 300; + int maxTry = 5; + int currTry = 0; - while ((procId = TorServiceUtils.findProcessId(fileTorLink.getAbsolutePath())) != -1) + while ((procId = TorServiceUtils.findProcessId(fileTorLink.getAbsolutePath())) != -1 && currTry++ < maxTry) { + sendCallbackStatusMessage ("Found existing orphan Tor process; Trying to shutdown now (device restart may be needed)..."); - logNotice("Found Tor PID=" + procId + " - killing now..."); + logNotice("Found Tor PID=" + procId + " - attempt to shutdown now..."); String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" }; - TorServiceUtils.doShellCommand(cmd,log, false, false); - try { Thread.sleep(killDelayMs); } - catch (Exception e){} - } - - while ((procId = TorServiceUtils.findProcessId(filePrivoxy.getAbsolutePath())) != -1) - { - - logNotice("Found Privoxy PID=" + procId + " - killing now..."); - String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" }; - - TorServiceUtils.doShellCommand(cmd,log, false, false); + TorServiceUtils.doShellCommand(cmd,log, mHasRoot, false); try { Thread.sleep(killDelayMs); } catch (Exception e){} } - while ((procId = TorServiceUtils.findProcessId(fileObfsProxy.getAbsolutePath())) != -1) + if (procId == -1) { + while ((procId = TorServiceUtils.findProcessId(filePrivoxy.getAbsolutePath())) != -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){} + } - logNotice("Found ObfsProxy PID=" + procId + " - killing now..."); - String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" }; - - TorServiceUtils.doShellCommand(cmd,log, false, false); - try { Thread.sleep(killDelayMs); } - catch (Exception e){} + while ((procId = TorServiceUtils.findProcessId(fileObfsProxy.getAbsolutePath())) != -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){} + } + } + else + { + throw new Exception("*** Unable to kill existing Tor process. Please REBOOT your device. ***"); } - } private void logNotice (String msg) @@ -540,9 +601,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst } } - private void initTorPaths () throws IOException + private void initTorPaths () throws Exception { - appBinHome = getDir("bin",Application.MODE_PRIVATE); appCacheHome = getDir("data",Application.MODE_PRIVATE); appLibsHome = new File(getApplicationInfo().nativeLibraryDir); @@ -588,45 +648,26 @@ public class TorService extends Service implements TorServiceConstants, TorConst } - try - { - setBinaryPerms(); - } - catch (Exception e) - { - logNotice("Error setting binary permissions: " + e.toString()); - } + initTorPathLinkAndPerms(); } - private void setBinaryPerms () throws Exception + private boolean enableBinExec (File fileBin) throws Exception { - logNotice("Is Tor binary exec? " + fileTorOrig.canExecute()); - logNotice("Is Tor binary exec? " + filePrivoxy.canExecute()); - logNotice("Is Tor binary exec? " + fileObfsProxy.canExecute()); + logNotice(fileBin.getName() + ": PRE: Is binary exec? " + fileBin.canExecute()); - StringBuilder log = new StringBuilder (); - logNotice("(re)Setting permission on Tor binary"); - String[] cmd1 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + fileTorOrig.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("(re)Setting permission on Privoxy binary"); - String[] cmd2 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + filePrivoxy.getAbsolutePath()}; - TorServiceUtils.doShellCommand(cmd2, log, false, true); - - logNotice("(re)Setting permission on Obfsproxy binary"); - String[] cmd3 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + fileObfsProxy.getAbsolutePath()}; - TorServiceUtils.doShellCommand(cmd3, log, false, true); - + + logNotice(fileBin.getName() + ": POST: Is binary exec? " + fileBin.canExecute()); + + return fileBin.canExecute(); } - private boolean mHasRoot = false; - private boolean mEnableTransparentProxy = false; - private boolean mTransProxyAll = false; - private boolean mTransProxyTethering = false; private void updateSettings () { @@ -646,6 +687,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst public void initTor () throws Exception { + initTorPaths(); + updateSettings (); currentStatus = STATUS_CONNECTING; @@ -654,27 +697,14 @@ public class TorService extends Service implements TorServiceConstants, TorConst sendCallbackStatusMessage(getString(R.string.status_starting_up)); - initTorPathLink (); - killTorProcess (); - try { - - //setBinaryPerms(); - - runTorShellCmd(); - runPrivoxyShellCmd(); - - if (mHasRoot && mEnableTransparentProxy) - enableTransparentProxy(mTransProxyAll, mTransProxyTethering); - - - } catch (Exception e) { - logException("Unable to start Tor: " + e.getMessage(),e); - sendCallbackStatusMessage(getString(R.string.unable_to_start_tor) + ' ' + e.getMessage()); - - } - + runTorShellCmd(); + runPrivoxyShellCmd(); + + if (mHasRoot && mEnableTransparentProxy) + enableTransparentProxy(mTransProxyAll, mTransProxyTethering); + } /* @@ -758,6 +788,12 @@ public class TorService extends Service implements TorServiceConstants, TorConst private void runTorShellCmd() throws Exception { + if (!fileTorLink.exists()) + throw new RuntimeException("Sorry Tor binary not installed properly: " + fileTorLink.getAbsolutePath()); + + if (!fileTorLink.canExecute()) + throw new RuntimeException("Sorry can't execute Tor: " + fileTorLink.getAbsolutePath()); + SharedPreferences prefs =getSharedPrefs(getApplicationContext()); StringBuilder log = new StringBuilder(); @@ -1248,7 +1284,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst { try { - initTorPaths(); findExistingProc (); } catch (Exception e) diff --git a/src/org/torproject/android/service/TorServiceConstants.java b/src/org/torproject/android/service/TorServiceConstants.java index 469427bd..2d3bfa4c 100644 --- a/src/org/torproject/android/service/TorServiceConstants.java +++ b/src/org/torproject/android/service/TorServiceConstants.java @@ -41,6 +41,7 @@ public interface TorServiceConstants { public final static String SHELL_CMD_PS = "ps"; public final static String SHELL_CMD_PIDOF = "pidof"; public final static String SHELL_CMD_LINK = "ln -s"; + public final static String SHELL_CMD_CP = "cp"; public final static String CHMOD_EXE_VALUE = "700";