From 9c4c3496f1c25b041980426d0e7c40e5c02df50a Mon Sep 17 00:00:00 2001 From: Nathan Freitas Date: Wed, 3 Sep 2014 22:45:31 -0400 Subject: [PATCH] fix for reconnecting to exiting Tor process after service restart --- src/org/torproject/android/Orbot.java | 13 + .../android/service/ITorService.aidl | 6 + .../android/service/TorService.java | 240 ++++++++++++------ 3 files changed, 185 insertions(+), 74 deletions(-) diff --git a/src/org/torproject/android/Orbot.java b/src/org/torproject/android/Orbot.java index 209896dd..5300deaf 100644 --- a/src/org/torproject/android/Orbot.java +++ b/src/org/torproject/android/Orbot.java @@ -590,6 +590,14 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic { try { startTor(); + + + Intent nResult = new Intent(); + + //nResult.putExtra("socks", ); //TODO respond with socks, transport, dns, etc + + setResult(RESULT_OK,nResult); + } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -631,6 +639,8 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic pEdit.putBoolean(TorConstants.PREF_BRIDGES_ENABLED,true); pEdit.commit(); + + setResult(RESULT_OK); } } } @@ -821,6 +831,9 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic torStatus = mService.getStatus(); + if (torStatus == 0) //make sure we don't have a tor process already running + mService.checkAndInit(); + handleIntents(); } catch (RemoteException e) { // TODO Auto-generated catch block diff --git a/src/org/torproject/android/service/ITorService.aidl b/src/org/torproject/android/service/ITorService.aidl index 07b08a0d..e1f28124 100644 --- a/src/org/torproject/android/service/ITorService.aidl +++ b/src/org/torproject/android/service/ITorService.aidl @@ -11,6 +11,12 @@ interface ITorService { **/ int getStatus(); + /** + * check for exiting Tor process + **/ + boolean checkAndInit (); + + /** * The profile value is the start/stop state for Tor **/ diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index 9d918834..1dd39f80 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -177,7 +177,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst try { - mLastProcessId = initControlConnection(3); + mLastProcessId = initControlConnection(3,true); if (mLastProcessId != -1 && conn != null) { @@ -570,7 +570,11 @@ public class TorService extends Service implements TorServiceConstants, TorConst @Override public void onCreate() { super.onCreate(); - + initialize(); + } + + private void initialize() + { try { initBinariesAndDirectories(); @@ -656,11 +660,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst String TORRC_CONTROLPORT_FILE_KEY = "ControlPortWriteToFile"; fileControlPort = new File(appBinHome,"control.txt"); extraLines.append(TORRC_CONTROLPORT_FILE_KEY).append(' ').append(fileControlPort.getCanonicalPath()).append('\n'); - - String transPort = prefs.getString("pref_transport", TorServiceConstants.TOR_TRANSPROXY_PORT_DEFAULT+""); - String dnsPort = prefs.getString("pref_dnsport", TorServiceConstants.TOR_DNS_PORT_DEFAULT+""); - if (mTransProxyTethering) { extraLines.append("TransListenAddress 0.0.0.0").append('\n'); @@ -676,8 +676,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst extraLines.append("TestSocks 0").append('\n'); extraLines.append("WarnUnsafeSocks 1").append('\n'); - extraLines.append("TransPort ").append(transPort).append('\n'); - extraLines.append("DNSPort ").append(dnsPort).append('\n'); + extraLines.append("TransPort ").append("auto").append('\n'); + extraLines.append("DNSPort ").append("auto").append('\n'); extraLines.append("VirtualAddrNetwork 10.192.0.0/10").append('\n'); extraLines.append("AutomapHostsOnResolve 1").append('\n'); @@ -741,7 +741,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst } - public void initTor () throws Exception + public void startTor () throws Exception { currentStatus = STATUS_CONNECTING; @@ -965,9 +965,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst return false; } - //now try to connect - mLastProcessId = initControlConnection (100); + mLastProcessId = initControlConnection (100,false); if (mLastProcessId == -1) { @@ -1052,7 +1051,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst } - private int initControlConnection (int maxTries) throws Exception, RuntimeException + private int initControlConnection (int maxTries, boolean isReconnect) throws Exception, RuntimeException { int i = 0; int controlPort = -1; @@ -1076,46 +1075,83 @@ public class TorService extends Service implements TorServiceConstants, TorConst conn = new TorControlConnection(torConnSocket); conn.launchThread(true);//is daemon - logNotice( "SUCCESS connected to Tor control port."); - - File fileCookie = new File(appCacheHome, TOR_CONTROL_COOKIE); - - if (fileCookie.exists()) - { - byte[] cookie = new byte[(int)fileCookie.length()]; - DataInputStream fis = new DataInputStream(new FileInputStream(fileCookie)); - fis.read(cookie); - fis.close(); - conn.authenticate(cookie); - - logNotice( "SUCCESS - authenticated to control port."); - - sendCallbackStatusMessage(getString(R.string.tor_process_starting) + ' ' + getString(R.string.tor_process_complete)); + break; + } + + } + catch (Exception ce) + { + conn = null; + logException( "Error connecting to Tor local control port: " + ce.getMessage(),ce); + + } + + + try { + logNotice("waiting..."); + Thread.sleep(1000); } + catch (Exception e){} + - addEventHandler(); - - String torProcId = conn.getInfo("process/pid"); - - //remove this for now until we can make a clean way to share logs from internal storage - /** - if (ENABLE_DEBUG_LOG) - { - File fileLog2 = new File(getFilesDir(),"orbot-tor-log.txt"); - fileLog2.setReadable(true); - conn.setConf("Log", "debug file " + fileLog2.getCanonicalPath()); - }*/ - - currentStatus = STATUS_CONNECTING; - - String confSocks = conn.getInfo("net/listeners/socks"); - StringTokenizer st = new StringTokenizer(confSocks," "); + + } + + if (conn != null) + { + logNotice( "SUCCESS connected to Tor control port."); + + File fileCookie = new File(appCacheHome, TOR_CONTROL_COOKIE); + + if (fileCookie.exists()) + { + byte[] cookie = new byte[(int)fileCookie.length()]; + DataInputStream fis = new DataInputStream(new FileInputStream(fileCookie)); + fis.read(cookie); + fis.close(); + conn.authenticate(cookie); + + logNotice( "SUCCESS - authenticated to control port."); + + sendCallbackStatusMessage(getString(R.string.tor_process_starting) + ' ' + getString(R.string.tor_process_complete)); + + addEventHandler(); + + String torProcId = conn.getInfo("process/pid"); + + //remove this for now until we can make a clean way to share logs from internal storage + /** + if (ENABLE_DEBUG_LOG) + { + File fileLog2 = new File(getFilesDir(),"orbot-tor-log.txt"); + fileLog2.setReadable(true); + conn.setConf("Log", "debug file " + fileLog2.getCanonicalPath()); + }*/ + + currentStatus = STATUS_CONNECTING; + + String confSocks = conn.getInfo("net/listeners/socks"); + StringTokenizer st = new StringTokenizer(confSocks," "); + + confSocks = st.nextToken().split(":")[1]; + confSocks = confSocks.substring(0,confSocks.length()-1); + mPortSOCKS = Integer.parseInt(confSocks); + + if (!isReconnect) //if we are reconnected then we don't need to reset the ports + { - confSocks = st.nextToken().split(":")[1]; - confSocks = confSocks.substring(0,confSocks.length()-1); - mPortSOCKS = Integer.parseInt(confSocks); - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); + String socksPortPref = prefs.getString(TorConstants.PREF_SOCKS, TorServiceConstants.PORT_SOCKS_DEFAULT); + if (socksPortPref.indexOf(':')!=-1) + socksPortPref = socksPortPref.split(":")[1]; + + String transPort = prefs.getString("pref_transport", TorServiceConstants.TOR_TRANSPROXY_PORT_DEFAULT+""); + if (transPort.indexOf(':')!=-1) + transPort = transPort.split(":")[1]; + + String dnsPort = prefs.getString("pref_dnsport", TorServiceConstants.TOR_DNS_PORT_DEFAULT+""); + if (dnsPort.indexOf(':')!=-1) + dnsPort = dnsPort.split(":")[1]; try { @@ -1126,7 +1162,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst ArrayList socksLines = new ArrayList(); socksLines.add("SOCKSPort " + mPortSOCKS); socksLines.add("SOCKSPort " + socksPortPref); - + conn.setConf(socksLines); mPortSOCKS = newSocksPort; @@ -1136,37 +1172,69 @@ public class TorService extends Service implements TorServiceConstants, TorConst } catch (Exception e) { - //sendCallbackLogMessage("ERROR adding SOCKS on port: " + socksPortPref); - sendCallbackLogMessage("Local SOCKS port: " + socksPortPref); + sendCallbackLogMessage("Error setting TransProxy port to: " + socksPortPref); + + + } + + try + { + int newPort = Integer.parseInt(transPort); + ServerSocket ss = new ServerSocket(newPort); + ss.close(); + + ArrayList confLines = new ArrayList(); + + confLines.add("TransPort " + transPort); + + conn.setConf(confLines); + + sendCallbackLogMessage("Local TransProxy port: " + transPort); + + } + catch (Exception e) + { + sendCallbackLogMessage("ERROR setting TransProxy port to: " + transPort); + + } - return Integer.parseInt(torProcId); - + try + { + int newPort = Integer.parseInt(dnsPort); + ServerSocket ss = new ServerSocket(newPort); + ss.close(); + + ArrayList confLines = new ArrayList(); + + confLines.add("DNSPort " + dnsPort); + + conn.setConf(confLines); + + sendCallbackLogMessage("Local DNSPort port: " + transPort); + + } + catch (Exception e) + { + sendCallbackLogMessage("ERROR setting DNSport to: " + dnsPort); + + + } } - else - { - logNotice ("Tor authentication cookie does not exist yet"); - conn = null; - - } - } + + return Integer.parseInt(torProcId); - } - catch (Exception ce) - { - conn = null; - logException( "Error connecting to Tor local control port: " + ce.getMessage(),ce); - + } + else + { + logNotice ("Tor authentication cookie does not exist yet"); + conn = null; + + } } - try { - logNotice("waiting..."); - Thread.sleep(1000); } - catch (Exception e){} - - } - + return -1; } @@ -1307,7 +1375,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst try { - initTor(); + startTor(); } catch (Exception e) @@ -1614,6 +1682,26 @@ public class TorService extends Service implements TorServiceConstants, TorConst return mBinder; } + public boolean checkAndInitImpl () + { + if (fileTor != null) + { + try { + if (TorServiceUtils.findProcessId(fileTor.getCanonicalPath()) != -1) + { + initialize(); + return true; + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + return false; + } + /** * The IRemoteInterface is defined through IDL */ @@ -1624,6 +1712,10 @@ public class TorService extends Service implements TorServiceConstants, TorConst } + public boolean checkAndInit () { + return checkAndInitImpl(); + } + public void setProfile (final int profileNew) {