solves problem with binaries being stored on external SDcard

This commit is contained in:
Nathan Freitas 2014-01-13 21:48:28 -05:00
parent 649ca401e7
commit c5959637af
2 changed files with 161 additions and 125 deletions

View File

@ -31,7 +31,6 @@ import org.torproject.android.TorConstants;
import org.torproject.android.Utils; import org.torproject.android.Utils;
import org.torproject.android.settings.AppManager; import org.torproject.android.settings.AppManager;
import android.annotation.SuppressLint;
import android.app.Application; import android.app.Application;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
@ -46,13 +45,13 @@ import android.content.SharedPreferences.Editor;
import android.graphics.Color; import android.graphics.Color;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.os.Build; import android.os.Build;
import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteCallbackList; import android.os.RemoteCallbackList;
import android.os.RemoteException; import android.os.RemoteException;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder; import android.support.v4.app.NotificationCompat.Builder;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
public class TorService extends Service implements TorServiceConstants, TorConstants, Runnable, EventHandler 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 NotificationManager mNotificationManager = null;
private Builder mNotifyBuilder; private Builder mNotifyBuilder;
private boolean mHasRoot = false;
private boolean mEnableTransparentProxy = false;
private boolean mTransProxyAll = false;
private boolean mTransProxyTethering = false;
public void logMessage(String msg) public void logMessage(String msg)
{ {
@ -126,38 +130,40 @@ public class TorService extends Service implements TorServiceConstants, TorConst
private boolean findExistingProc () private boolean findExistingProc ()
{ {
try if (fileTorLink != null)
{ {
if (fileTorLink == null) try
initTorPathLink(); {
int procId = TorServiceUtils.findProcessId(fileTorLink.getAbsolutePath());
int procId = TorServiceUtils.findProcessId(fileTorLink.getAbsolutePath());
if (procId != -1)
if (procId != -1) {
{ logNotice("Found existing Tor process");
logNotice("Found existing Tor process");
sendCallbackLogMessage (getString(R.string.found_existing_tor_process));
sendCallbackLogMessage (getString(R.string.found_existing_tor_process));
currentStatus = STATUS_CONNECTING;
currentStatus = STATUS_CONNECTING;
initControlConnection();
initControlConnection();
processSettingsImpl();
processSettingsImpl();
currentStatus = STATUS_ON;
currentStatus = STATUS_ON;
return true;
return true;
}
}
return false;
return false; }
catch (Exception e)
{
Log.e(TAG,"error finding proc",e);
return false;
}
} }
catch (Exception e) else
{
Log.e(TAG,"error finding proc",e);
return false; return false;
}
} }
@ -252,8 +258,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst
try try
{ {
initTorPaths();
sendCallbackLogMessage("Welcome back, Carter!"); sendCallbackLogMessage("Welcome back, Carter!");
} }
catch (Exception e) catch (Exception e)
@ -271,15 +275,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst
_torInstance = this; _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); IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mNetworkStateReceiver , mNetworkStateFilter); registerReceiver(mNetworkStateReceiver , mNetworkStateFilter);
@ -331,9 +326,11 @@ public class TorService extends Service implements TorServiceConstants, TorConst
isRunning = true; isRunning = true;
} }
catch (Exception e) catch (Exception e)
{ {
logException("Unable to start Tor: " + e.getMessage(),e);
sendCallbackStatusMessage(getString(R.string.unable_to_start_tor) + ' ' + e.getMessage());
currentStatus = STATUS_OFF; 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); Log.d(TAG,"Unable to start Tor: " + e.getMessage(),e);
} }
} }
@ -455,19 +452,74 @@ public class TorService extends Service implements TorServiceConstants, TorConst
return null; return null;
} }
private void initTorPathLink () throws Exception private void initTorPathLinkAndPerms () throws Exception
{ {
fileTorLink = new File(appBinHome,"tor"); fileTorLink = new File(appBinHome,"tor");
fileTorLink.getParentFile().mkdirs();
StringBuilder log = new StringBuilder(); if (fileTorOrig.getAbsolutePath().startsWith("/mnt"))
{
String[] cmdDel = { "rm " + fileTorLink.getAbsolutePath() }; logNotice("app installed on external storage - copying binaries to internal");
TorServiceUtils.doShellCommand(cmdDel,log, false, false);
//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 private void killTorProcess () throws Exception
@ -493,40 +545,49 @@ public class TorService extends Service implements TorServiceConstants, TorConst
} }
int killDelayMs = 300; 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 + "" }; 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(filePrivoxy.getAbsolutePath())) != -1)
{
logNotice("Found Privoxy PID=" + procId + " - killing now...");
String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" };
TorServiceUtils.doShellCommand(cmd,log, false, false);
try { Thread.sleep(killDelayMs); } try { Thread.sleep(killDelayMs); }
catch (Exception e){} 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..."); while ((procId = TorServiceUtils.findProcessId(fileObfsProxy.getAbsolutePath())) != -1)
String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" }; {
TorServiceUtils.doShellCommand(cmd,log, false, false); logNotice("Found ObfsProxy PID=" + procId + " - killing now...");
try { Thread.sleep(killDelayMs); } String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" };
catch (Exception e){}
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) 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); appBinHome = getDir("bin",Application.MODE_PRIVATE);
appCacheHome = getDir("data",Application.MODE_PRIVATE); appCacheHome = getDir("data",Application.MODE_PRIVATE);
appLibsHome = new File(getApplicationInfo().nativeLibraryDir); appLibsHome = new File(getApplicationInfo().nativeLibraryDir);
@ -588,45 +648,26 @@ public class TorService extends Service implements TorServiceConstants, TorConst
} }
try initTorPathLinkAndPerms();
{
setBinaryPerms();
}
catch (Exception e)
{
logNotice("Error setting binary permissions: " + e.toString());
}
} }
private void setBinaryPerms () throws Exception private boolean enableBinExec (File fileBin) throws Exception
{ {
logNotice("Is Tor binary exec? " + fileTorOrig.canExecute()); logNotice(fileBin.getName() + ": PRE: Is binary exec? " + fileBin.canExecute());
logNotice("Is Tor binary exec? " + filePrivoxy.canExecute());
logNotice("Is Tor binary exec? " + fileObfsProxy.canExecute());
StringBuilder log = new StringBuilder (); StringBuilder log = new StringBuilder ();
logNotice("(re)Setting permission on Tor binary"); logNotice("(re)Setting permission on binary: " + fileBin.getAbsolutePath());
String[] cmd1 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + fileTorOrig.getAbsolutePath()}; String[] cmd1 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + fileBin.getAbsolutePath()};
TorServiceUtils.doShellCommand(cmd1, log, false, true); TorServiceUtils.doShellCommand(cmd1, log, false, true);
logNotice("(re)Setting permission on Privoxy binary"); logNotice(fileBin.getName() + ": POST: Is binary exec? " + fileBin.canExecute());
String[] cmd2 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + filePrivoxy.getAbsolutePath()};
TorServiceUtils.doShellCommand(cmd2, log, false, true); return fileBin.canExecute();
logNotice("(re)Setting permission on Obfsproxy binary");
String[] cmd3 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + fileObfsProxy.getAbsolutePath()};
TorServiceUtils.doShellCommand(cmd3, log, false, true);
} }
private boolean mHasRoot = false;
private boolean mEnableTransparentProxy = false;
private boolean mTransProxyAll = false;
private boolean mTransProxyTethering = false;
private void updateSettings () private void updateSettings ()
{ {
@ -646,6 +687,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst
public void initTor () throws Exception public void initTor () throws Exception
{ {
initTorPaths();
updateSettings (); updateSettings ();
currentStatus = STATUS_CONNECTING; currentStatus = STATUS_CONNECTING;
@ -654,27 +697,14 @@ public class TorService extends Service implements TorServiceConstants, TorConst
sendCallbackStatusMessage(getString(R.string.status_starting_up)); sendCallbackStatusMessage(getString(R.string.status_starting_up));
initTorPathLink ();
killTorProcess (); killTorProcess ();
try { runTorShellCmd();
runPrivoxyShellCmd();
//setBinaryPerms();
if (mHasRoot && mEnableTransparentProxy)
runTorShellCmd(); enableTransparentProxy(mTransProxyAll, mTransProxyTethering);
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());
}
} }
/* /*
@ -758,6 +788,12 @@ public class TorService extends Service implements TorServiceConstants, TorConst
private void runTorShellCmd() throws Exception 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()); SharedPreferences prefs =getSharedPrefs(getApplicationContext());
StringBuilder log = new StringBuilder(); StringBuilder log = new StringBuilder();
@ -1248,7 +1284,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst
{ {
try try
{ {
initTorPaths();
findExistingProc (); findExistingProc ();
} }
catch (Exception e) catch (Exception e)

View File

@ -41,6 +41,7 @@ public interface TorServiceConstants {
public final static String SHELL_CMD_PS = "ps"; public final static String SHELL_CMD_PS = "ps";
public final static String SHELL_CMD_PIDOF = "pidof"; public final static String SHELL_CMD_PIDOF = "pidof";
public final static String SHELL_CMD_LINK = "ln -s"; 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"; public final static String CHMOD_EXE_VALUE = "700";