
commit d38e9e1a819f39fcef9b7ff7ca217f006cd722f9 Author: n8fr8 <nathan@guardianproject.info> Date: Tue Jan 28 14:30:29 2020 -0500 improve killing of orphaned tor process --- .../torproject/android/service/OrbotService.java | 21 +++++- .../android/service/TorEventHandler.java | 2 +- .../android/service/TorServiceConstants.java | 1 + .../android/service/util/ExternalIPFetcher.java | 6 +- .../torproject/android/service/vpn/VpnUtils.java | 74 +++++++++++++--------- 5 files changed, 69 insertions(+), 35 deletions(-) diff --git a/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java b/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java index afe8b008..f806e42a 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java +++ b/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java @@ -44,6 +44,7 @@ import com.jaredrummler.android.shell.CommandResult; import net.freehaven.tor.control.ConfigEntry; import net.freehaven.tor.control.TorControlConnection; +import org.apache.commons.io.IOUtils; import org.torproject.android.service.util.CustomShell; import org.torproject.android.service.util.CustomTorResourceInstaller; import org.torproject.android.service.util.DummyActivity; @@ -109,7 +110,7 @@ public class OrbotService extends Service implements TorServiceConstants, OrbotC private ArrayList<String> configBuffer = null; private ArrayList<String> resetBuffer = null; - private File fileControlPort; + private File fileControlPort, filePid; private boolean mConnectivity = true; @@ -456,6 +457,7 @@ public class OrbotService extends Service implements TorServiceConstants, OrbotC private void killAllDaemons() throws Exception { + if (conn != null) { logNotice("Using control port to shutdown Tor"); @@ -470,6 +472,18 @@ public class OrbotService extends Service implements TorServiceConstants, OrbotC conn = null; } + if (mLastProcessId != -1) + killProcess(mLastProcessId + "", "-9"); + + if (filePid != null && filePid.exists()) + { + List<String> lines = IOUtils.readLines(new FileReader(filePid)); + String torPid = lines.get(0); + killProcess(torPid,"-9"); + + } + + // if that fails, try again using native utils try { killProcess(fileTor, "-9"); // this is -HUP @@ -523,6 +537,7 @@ public class OrbotService extends Service implements TorServiceConstants, OrbotC fileTorRc = new File(appBinHome, TORRC_ASSET_KEY); fileControlPort = new File(getFilesDir(), TOR_CONTROL_PORT_FILE); + filePid = new File(getFilesDir(), TOR_PID_FILE); mHSBasePath = new File( getFilesDir().getAbsolutePath(), @@ -646,6 +661,8 @@ public class OrbotService extends Service implements TorServiceConstants, OrbotC extraLines.append("\n"); extraLines.append("ControlPortWriteToFile").append(' ').append(fileControlPort.getCanonicalPath()).append('\n'); + extraLines.append("PidFile").append(' ').append(filePid.getCanonicalPath()).append('\n'); + // extraLines.append("RunAsDaemon 1").append('\n'); // extraLines.append("AvoidDiskWrites 1").append('\n'); @@ -689,7 +706,7 @@ public class OrbotService extends Service implements TorServiceConstants, OrbotC extraLines.append("SocksListenAddress 0.0.0.0").append('\n'); - extraLines.append("HTTPTunnelPort ").append(checkPortOrAuto(HTTP_PROXY_PORT_DEFAULT)).append('\n'); + extraLines.append("HTTPTunnelPort ").append(httpPortPref).append('\n'); if(prefs.getBoolean(OrbotConstants.PREF_CONNECTION_PADDING, false)) { diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java b/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java index 466c4323..def94fcf 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java +++ b/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java @@ -215,7 +215,7 @@ public class TorEventHandler implements EventHandler, TorServiceConstants { if (node.ipAddress == null && (!node.isFetchingInfo) && Prefs.useDebugLogging()) { node.isFetchingInfo = true; - mService.exec(new ExternalIPFetcher(mService, node, TorService.mPortHTTP)); + mService.exec(new ExternalIPFetcher(mService, node, OrbotService.mPortHTTP)); } isFirstNode = false; diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java b/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java index 4962ac29..5776abe9 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java +++ b/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java @@ -11,6 +11,7 @@ public interface TorServiceConstants { String DIRECTORY_TOR_DATA = "data"; String TOR_CONTROL_PORT_FILE = "control.txt"; + String TOR_PID_FILE = "torpid"; //torrc (tor config file) String TORRC_ASSET_KEY = "torrc"; diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java b/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java index ae99e7de..080ed961 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java @@ -2,8 +2,8 @@ package org.torproject.android.service.util; import org.json.JSONArray; import org.json.JSONObject; +import org.torproject.android.service.OrbotService; import org.torproject.android.service.TorEventHandler; -import org.torproject.android.service.TorService; import java.io.BufferedReader; import java.io.InputStream; @@ -15,12 +15,12 @@ import java.net.URLConnection; public class ExternalIPFetcher implements Runnable { - private TorService mService; + private OrbotService mService; private TorEventHandler.Node mNode; private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addres..."; private int mLocalHttpProxyPort = 8118; - public ExternalIPFetcher (TorService service, TorEventHandler.Node node, int localProxyPort ) + public ExternalIPFetcher (OrbotService service, TorEventHandler.Node node, int localProxyPort ) { mService = service; mNode = node; diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java index 5a9901ff..acc15316 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java +++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java @@ -1,5 +1,6 @@ package org.torproject.android.service.vpn; +import android.app.ActivityManager; import android.content.Context; import android.content.SharedPreferences; @@ -7,7 +8,9 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.util.List; +import static android.content.Context.ACTIVITY_SERVICE; import static java.lang.Runtime.getRuntime; import static org.torproject.android.service.vpn.VpnConstants.SHELL_CMD_PS; import static org.torproject.android.service.vpn.VpnPrefs.PREF_TOR_SHARED_PREFS; @@ -20,25 +23,32 @@ public class VpnUtils { } public static int findProcessId(String command) throws IOException { - Process procPs = getRuntime().exec(SHELL_CMD_PS); - BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - if (!line.contains("PID") && line.contains(command)) { - String[] lineParts = line.split("\\s+"); - try { - return Integer.parseInt(lineParts[1]); //for most devices it is the second - } catch (NumberFormatException e) { - return Integer.parseInt(lineParts[0]); //but for samsungs it is the first - } finally { + String[] cmds = {"ps -ef","ps -A","toolbox ps","busybox ps"}; + + for (int i = 0; i < cmds.length;i++) { + Process procPs = getRuntime().exec(cmds[i]); + + BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream())); + + String line; + while ((line = reader.readLine()) != null) { + if (!line.contains("PID") && line.contains(command)) { + String[] lineParts = line.split("\\s+"); try { - procPs.destroy(); - } catch (Exception e) { + return Integer.parseInt(lineParts[1]); //for most devices it is the second + } catch (NumberFormatException e) { + return Integer.parseInt(lineParts[0]); //but for samsungs it is the first + } finally { + try { + procPs.destroy(); + } catch (Exception e) { + } } } } } + return -1; } @@ -46,18 +56,29 @@ public class VpnUtils { killProcess(fileProcBin, "-9"); // this is -KILL } - public static void killProcess(File fileProcBin, String signal) throws Exception { + public static int killProcess(File fileProcBin, String signal) throws Exception { + int procId = -1; int killAttempts = 0; - while ((procId = findProcessId(fileProcBin.getCanonicalPath())) != -1) { + while ((procId = findProcessId(fileProcBin.getName())) != -1) { killAttempts++; String pidString = String.valueOf(procId); - try { - getRuntime().exec("busybox killall " + signal + " " + fileProcBin.getName - ()); - } catch (IOException ioe) { + + String[] cmds = {"","busybox ","toolbox "}; + + for (int i = 0; i < cmds.length;i++) { + try { + getRuntime().exec(cmds[i] + "killall " + signal + " " + fileProcBin.getName + ()); + } catch (IOException ioe) { + } + try { + getRuntime().exec(cmds[i] + "killall " + signal + " " + fileProcBin.getCanonicalPath()); + } catch (IOException ioe) { + } } + killProcess(pidString, signal); try { @@ -69,25 +90,20 @@ public class VpnUtils { if (killAttempts > 4) throw new Exception("Cannot kill: " + fileProcBin.getAbsolutePath()); } + + return procId; } public static void killProcess(String pidString, String signal) throws Exception { + String[] cmds = {"","busybox ","toolbox "}; + for (int i = 0; i < cmds.length;i++) { try { getRuntime().exec("toolbox kill " + signal + " " + pidString); } catch (IOException ioe) { } - try { - getRuntime().exec("busybox kill " + signal + " " + pidString); - } catch (IOException ioe) { - } - try { - getRuntime().exec("kill " + signal + " " + pidString); - } catch (IOException ioe) { - } - - + } }