put up error notification if Orbot cannot kill a process
There are a couple of different times when Orbot will be unable to kill the running processes. One example is when Orbot is running, then uninstalled, then installed again. closes #5254 https://dev.guardianproject.info/issues/5254
This commit is contained in:
parent
81cf67f955
commit
2f1ad74538
|
@ -222,6 +222,7 @@
|
||||||
<string name="hidden_service_on">hidden service on:</string>
|
<string name="hidden_service_on">hidden service on:</string>
|
||||||
<string name="unable_to_read_hidden_service_name">unable to read hidden service name</string>
|
<string name="unable_to_read_hidden_service_name">unable to read hidden service name</string>
|
||||||
<string name="unable_to_start_tor">Unable to start Tor:</string>
|
<string name="unable_to_start_tor">Unable to start Tor:</string>
|
||||||
|
<string name="unable_to_reset_tor">Reboot your device, unable to reset Tor!</string>
|
||||||
<string name="pref_use_sys_iptables_title">Use Default Iptables</string>
|
<string name="pref_use_sys_iptables_title">Use Default Iptables</string>
|
||||||
<string name="pref_use_sys_iptables_summary">use the built-in iptables binary instead of the one bundled with Orbot</string>
|
<string name="pref_use_sys_iptables_summary">use the built-in iptables binary instead of the one bundled with Orbot</string>
|
||||||
|
|
||||||
|
|
|
@ -429,34 +429,42 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
clearNotifications ();
|
clearNotifications ();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopTor ()
|
private void stopTor ()
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.d(TAG,"Tor is stopping NOW");
|
Log.d(TAG,"Tor is stopping NOW");
|
||||||
|
|
||||||
shutdownTorProcess ();
|
shutdownTorProcess ();
|
||||||
|
|
||||||
//stop the foreground priority and make sure to remove the persistant notification
|
//stop the foreground priority and make sure to remove the persistant notification
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
|
|
||||||
mCurrentStatus = STATUS_OFF;
|
mCurrentStatus = STATUS_OFF;
|
||||||
sendCallbackStatus(mCurrentStatus);
|
sendCallbackStatus(mCurrentStatus);
|
||||||
|
|
||||||
if (mHasRoot && mEnableTransparentProxy)
|
if (mHasRoot && mEnableTransparentProxy)
|
||||||
{
|
{
|
||||||
Shell shellRoot = Shell.startRootShell();
|
Shell shellRoot = Shell.startRootShell();
|
||||||
disableTransparentProxy(shellRoot);
|
disableTransparentProxy(shellRoot);
|
||||||
shellRoot.close();
|
shellRoot.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
clearNotifications();
|
clearNotifications();
|
||||||
|
|
||||||
sendCallbackLogMessage(getString(R.string.status_disabled));
|
sendCallbackLogMessage(getString(R.string.status_disabled));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
catch (CannotKillException e)
|
||||||
|
{
|
||||||
|
Log.d(TAG, "An error occured stopping Tor", e);
|
||||||
|
logNotice("An error occured stopping Tor: " + e.getMessage());
|
||||||
|
sendCallbackLogMessage(getString(R.string.unable_to_reset_tor));
|
||||||
|
showToolbarNotification(getString(R.string.unable_to_reset_tor),
|
||||||
|
ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.d(TAG, "An error occured stopping Tor",e);
|
Log.d(TAG, "An error occured stopping Tor",e);
|
||||||
|
@ -465,44 +473,44 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String getHiddenServiceHostname ()
|
private String getHiddenServiceHostname ()
|
||||||
{
|
{
|
||||||
|
|
||||||
SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
|
SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
|
||||||
|
|
||||||
boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
|
boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
|
||||||
|
|
||||||
StringBuffer result = new StringBuffer();
|
StringBuffer result = new StringBuffer();
|
||||||
|
|
||||||
if (enableHiddenServices)
|
if (enableHiddenServices)
|
||||||
{
|
{
|
||||||
String hsPorts = prefs.getString("pref_hs_ports","");
|
String hsPorts = prefs.getString("pref_hs_ports","");
|
||||||
|
|
||||||
StringTokenizer st = new StringTokenizer (hsPorts,",");
|
StringTokenizer st = new StringTokenizer (hsPorts,",");
|
||||||
String hsPortConfig = null;
|
String hsPortConfig = null;
|
||||||
|
|
||||||
while (st.hasMoreTokens())
|
while (st.hasMoreTokens())
|
||||||
{
|
{
|
||||||
|
|
||||||
int hsPort = Integer.parseInt(st.nextToken().split(" ")[0]);;
|
int hsPort = Integer.parseInt(st.nextToken().split(" ")[0]);;
|
||||||
|
|
||||||
File fileDir = new File(appCacheHome, "hs" + hsPort);
|
File fileDir = new File(appCacheHome, "hs" + hsPort);
|
||||||
File file = new File(fileDir, "hostname");
|
File file = new File(fileDir, "hostname");
|
||||||
|
|
||||||
|
|
||||||
if (file.exists())
|
if (file.exists())
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
String onionHostname = Utils.readString(new FileInputStream(file)).trim();
|
String onionHostname = Utils.readString(new FileInputStream(file)).trim();
|
||||||
|
|
||||||
if (result.length() > 0)
|
if (result.length() > 0)
|
||||||
result.append(",");
|
result.append(",");
|
||||||
|
|
||||||
result.append(onionHostname);
|
result.append(onionHostname);
|
||||||
|
|
||||||
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
logException("unable to read onion hostname file",e);
|
logException("unable to read onion hostname file",e);
|
||||||
showToolbarNotification(getString(R.string.unable_to_read_hidden_service_name), HS_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
|
showToolbarNotification(getString(R.string.unable_to_read_hidden_service_name), HS_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
|
||||||
|
@ -513,28 +521,28 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
{
|
{
|
||||||
showToolbarNotification(getString(R.string.unable_to_read_hidden_service_name), HS_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
|
showToolbarNotification(getString(R.string.unable_to_read_hidden_service_name), HS_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.length() > 0)
|
if (result.length() > 0)
|
||||||
{
|
{
|
||||||
String onionHostname = result.toString();
|
String onionHostname = result.toString();
|
||||||
|
|
||||||
showToolbarNotification(getString(R.string.hidden_service_on) + ' ' + onionHostname, HS_NOTIFY_ID, R.drawable.ic_stat_tor);
|
showToolbarNotification(getString(R.string.hidden_service_on) + ' ' + onionHostname, HS_NOTIFY_ID, R.drawable.ic_stat_tor);
|
||||||
Editor pEdit = prefs.edit();
|
Editor pEdit = prefs.edit();
|
||||||
pEdit.putString("pref_hs_hostname",onionHostname);
|
pEdit.putString("pref_hs_hostname",onionHostname);
|
||||||
pEdit.commit();
|
pEdit.commit();
|
||||||
|
|
||||||
return onionHostname;
|
return onionHostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void shutdownTorProcess () throws Exception
|
private void shutdownTorProcess () throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -542,47 +550,69 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
{
|
{
|
||||||
|
|
||||||
logNotice("Using control port to shutdown Tor");
|
logNotice("Using control port to shutdown Tor");
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logNotice("sending HALT signal to Tor process");
|
logNotice("sending HALT signal to Tor process");
|
||||||
conn.shutdownTor("HALT");
|
conn.shutdownTor("HALT");
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d(TAG,"error shutting down Tor via connection",e);
|
Log.d(TAG,"error shutting down Tor via connection",e);
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = null;
|
conn = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
killProcess(fileTor);
|
killProcess(fileTor);
|
||||||
|
|
||||||
killProcess(filePolipo);
|
killProcess(filePolipo);
|
||||||
killProcess(fileObfsclient);
|
killProcess(fileObfsclient);
|
||||||
killProcess(fileMeekclient);
|
killProcess(fileMeekclient);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void killProcess (File fileProcBin) throws IOException
|
public class CannotKillException extends IllegalStateException {
|
||||||
{
|
private static final long serialVersionUID = -286877277562592501L;
|
||||||
int procId = -1;
|
|
||||||
Shell shell = Shell.startShell();
|
public CannotKillException(File f) {
|
||||||
|
super("Cannot kill " + f.getAbsolutePath());
|
||||||
while ((procId = TorServiceUtils.findProcessId(fileProcBin.getCanonicalPath())) != -1)
|
|
||||||
{
|
|
||||||
|
|
||||||
logNotice("Found " + fileProcBin.getName() + " PID=" + procId + " - killing now...");
|
|
||||||
|
|
||||||
SimpleCommand killCommand = new SimpleCommand("toolbox kill -9 " + procId);
|
|
||||||
shell.add(killCommand);
|
|
||||||
killCommand = new SimpleCommand("kill -9 " + procId);
|
|
||||||
shell.add(killCommand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shell.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void killProcess(File fileProcBin) throws IOException {
|
||||||
|
int procId = -1;
|
||||||
|
int killAttempts = 0;
|
||||||
|
|
||||||
|
while ((procId = TorServiceUtils.findProcessId(fileProcBin.getCanonicalPath())) != -1) {
|
||||||
|
killAttempts++;
|
||||||
|
logNotice("Found " + fileProcBin.getName() + " PID=" + procId + " - killing now...");
|
||||||
|
String pidString = String.valueOf(procId);
|
||||||
|
/*
|
||||||
|
* first try as the normal app user to be safe, then if that fails,
|
||||||
|
* try root since the process might be left over from
|
||||||
|
* uninstall/reinstall with different UID.
|
||||||
|
*/
|
||||||
|
Shell shell;
|
||||||
|
if (mHasRoot && killAttempts > 2) {
|
||||||
|
shell = Shell.startRootShell();
|
||||||
|
Log.i(TAG, "using a root shell");
|
||||||
|
} else {
|
||||||
|
shell = Shell.startShell();
|
||||||
|
}
|
||||||
|
shell.add(new SimpleCommand("busybox killall " + fileProcBin.getName()));
|
||||||
|
shell.add(new SimpleCommand("toolbox kill -9 " + pidString));
|
||||||
|
shell.add(new SimpleCommand("busybox kill -9 " + pidString));
|
||||||
|
shell.add(new SimpleCommand("kill -9 " + pidString));
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
shell.close();
|
||||||
|
if (killAttempts > 4)
|
||||||
|
throw new CannotKillException(fileProcBin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void logNotice (String msg)
|
private void logNotice (String msg)
|
||||||
{
|
{
|
||||||
if (msg != null && msg.trim().length() > 0)
|
if (msg != null && msg.trim().length() > 0)
|
||||||
|
@ -1405,21 +1435,30 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
if (mCurrentStatus == STATUS_OFF)
|
if (mCurrentStatus == STATUS_OFF)
|
||||||
{
|
{
|
||||||
sendCallbackLogMessage (getString(R.string.status_starting_up));
|
sendCallbackLogMessage (getString(R.string.status_starting_up));
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
boolean found = findExistingProc ();
|
boolean found = findExistingProc ();
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
killProcess(fileTor);
|
killProcess(fileTor);
|
||||||
killProcess(filePolipo);
|
killProcess(filePolipo);
|
||||||
|
|
||||||
startTor();
|
startTor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (CannotKillException e)
|
||||||
|
{
|
||||||
|
logException(e.getMessage(), e);
|
||||||
|
mCurrentStatus = STATUS_OFF;
|
||||||
|
sendCallbackStatus(mCurrentStatus);
|
||||||
|
showToolbarNotification(getString(R.string.unable_to_reset_tor),
|
||||||
|
ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
|
||||||
|
stopTor();
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue