diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 8bd45315..636ad29f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -8,7 +8,7 @@ + android:debuggable="false"> @@ -16,7 +16,10 @@ - + + + + diff --git a/CHANGELOG b/CHANGELOG index 2f45cc38..e9b3be25 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +0.0.2a - 2009-11-30 +- Update user interace layout and graphics +- Modified service launch, shutdown and handling +- Improved event handler on Tor Control port callbacks +- Added Help page + 0.0.2 - 2009-11-27 - Major improvement to the user interface including relative layout for different screens - New graphics resources diff --git a/assets/help.html b/assets/help.html new file mode 100644 index 00000000..1a1382b4 --- /dev/null +++ b/assets/help.html @@ -0,0 +1,48 @@ + + + + help.html + + + + + + + + + + +

ORbot

+ Onion Routing Robot - v0.0.2a / November 30, 2009
+
+

How to use ORbot

+ Simply touch the Orbot icon on the main screen and wait for it to fully connect to the Tor network. You can use the Menu -> Log option to view + more detailed information about the attempt to connect to the network. +

How to surf anonymously

+ Once you have Orbot running and connected to the Tor network, you can utilize the anonymous proxy service in multiple ways: + + You can always visit http://check.torproject.org to ensure that you are properly connected to the Tor network. +

Bridges and Other Settings

+ You can modify the TORRC settings file using the Menu -> Settings option. This is where you can copy and paste in Tor Bridge node addresses + if they are needed in your local area. +

Even More Information!

+ If you'd like to learn more about the Tor Project, please visit http://torproject.org. + + diff --git a/assets/torrc b/assets/torrc index f3085477..b1af5560 100644 --- a/assets/torrc +++ b/assets/torrc @@ -17,7 +17,7 @@ ## relay, and not make any local application connections yourself. SocksPort 9050 # what port to open for local application connections SocksListenAddress 127.0.0.1 # accept connections only from localhost -#SocksListenAddress 192.168.0.1:9100 # listen on this IP:port also +SocksListenAddress 127.0.0.1:1080 # listen on this IP:port also ## Entry policies to allow/deny SOCKS requests based on IP address. ## First entry that matches wins. If no SocksPolicy is set, we accept diff --git a/res/drawable/bgdarkdroid.jpg b/res/drawable/bgdarkdroid.jpg new file mode 100644 index 00000000..6c0570ad Binary files /dev/null and b/res/drawable/bgdarkdroid.jpg differ diff --git a/res/drawable/toroff.png b/res/drawable/toroff.png index 9e01731c..466eb615 100644 Binary files a/res/drawable/toroff.png and b/res/drawable/toroff.png differ diff --git a/res/drawable/toron.png b/res/drawable/toron.png index 6e3b1006..fee8023e 100644 Binary files a/res/drawable/toron.png and b/res/drawable/toron.png differ diff --git a/res/drawable/torstarting.png b/res/drawable/torstarting.png index 970bb8fc..f4d36cdd 100644 Binary files a/res/drawable/torstarting.png and b/res/drawable/torstarting.png differ diff --git a/res/drawable/torstopping.png b/res/drawable/torstopping.png index d82b3b51..0e8eeed5 100644 Binary files a/res/drawable/torstopping.png and b/res/drawable/torstopping.png differ diff --git a/res/layout/layout_log.xml b/res/layout/layout_log.xml index cb46b834..adadbdce 100644 --- a/res/layout/layout_log.xml +++ b/res/layout/layout_log.xml @@ -12,6 +12,7 @@ android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1.0" + android:textSize="11px" /> diff --git a/res/layout/layout_main.xml b/res/layout/layout_main.xml index fd482305..7fd25ece 100644 --- a/res/layout/layout_main.xml +++ b/res/layout/layout_main.xml @@ -32,7 +32,10 @@ android:src="@drawable/toroff"/> android:text=" \n " android:paddingTop="15px" android:layout_gravity="center_horizontal" + android:gravity="center_horizontal" android:textStyle="bold" + android:width="240px" + android:height="100px" android:textColor="#ffffff" /> diff --git a/res/layout/layout_settings.xml b/res/layout/layout_settings.xml index c4d194b3..ccaa3035 100644 --- a/res/layout/layout_settings.xml +++ b/res/layout/layout_settings.xml @@ -13,6 +13,7 @@ android:layout_width="fill_parent" android:layout_weight="1.0" android:singleLine="false" + android:textSize="11px" /> diff --git a/res/layout/layout_web.xml b/res/layout/layout_web.xml new file mode 100644 index 00000000..4773d1b3 --- /dev/null +++ b/res/layout/layout_web.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index a16b15e3..8c2303e9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,6 +1,6 @@ - Orbot - 0.0.1 + ORbot + 0.0.2a diff --git a/src/org/torproject/android/HttpProxy.java b/src/org/torproject/android/HttpProxy.java index f4c9f62c..1da7c719 100644 --- a/src/org/torproject/android/HttpProxy.java +++ b/src/org/torproject/android/HttpProxy.java @@ -75,9 +75,9 @@ public class HttpProxy extends Thread private String fwdServer = ""; private int fwdPort = 0; private int ptTimeout = ProxyThread.DEFAULT_TIMEOUT; - private int debugLevel = 0; + private int debugLevel = 1; private PrintStream debugOut = System.out; - + private boolean keepRunning = true; private boolean doSocks = false; private Socks5Proxy sProxy = null; @@ -220,6 +220,7 @@ public class HttpProxy extends Thread public void closeSocket () { try { + keepRunning = false; // close the open server socket server.close(); // send it a message to make it stop waiting immediately @@ -245,7 +246,7 @@ public class HttpProxy extends Thread // client connections server = new ServerSocket(thisPort); - while (true) + while (keepRunning) { Socket client = server.accept(); ProxyThread t = new ProxyThread(client, doSocks, sProxy); diff --git a/src/org/torproject/android/TorConstants.java b/src/org/torproject/android/TorConstants.java index 21261141..92b34efb 100644 --- a/src/org/torproject/android/TorConstants.java +++ b/src/org/torproject/android/TorConstants.java @@ -37,7 +37,7 @@ public interface TorConstants { //various console cmds public final static String SHELL_CMD_CHMOD = "/system/bin/chmod"; - public final static String SHELL_CMD_KILLALL = "/system/bin/kill"; + public final static String SHELL_CMD_KILL = "/system/bin/kill"; public final static String SHELL_CMD_RM = "/system/bin/rm"; public final static String SHELL_CMD_PS = "ps"; public final static String CHMOD_EXE_VALUE = "777"; @@ -61,6 +61,8 @@ public interface TorConstants { public final static int TOR_CONTROL_PORT = 9051; public final static int UPDATE_TIMEOUT = 3000; + public final static String DEFAULT_HOME_PAGE = "file:///android_asset/help.html";// "http://check.torproject.org"; + //status to communicate state public final static int STATUS_OFF = 0; public final static int STATUS_ON = 1; diff --git a/src/org/torproject/android/TorControlPanel.java b/src/org/torproject/android/TorControlPanel.java index 08cd4798..546cc00b 100644 --- a/src/org/torproject/android/TorControlPanel.java +++ b/src/org/torproject/android/TorControlPanel.java @@ -8,6 +8,10 @@ import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.util.List; + + +import net.freehaven.tor.control.EventHandler; import android.app.Activity; @@ -15,25 +19,42 @@ import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.util.Log; +import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; +import android.webkit.JsResult; +import android.webkit.WebChromeClient; +import android.webkit.WebSettings; +import android.webkit.WebView; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; -public class TorControlPanel extends Activity implements OnClickListener, TorConstants +public class TorControlPanel extends Activity implements OnClickListener, TorConstants, EventHandler { - private final static String LOG_TAG = "Tor"; + private final static String TAG = "Tor"; - private Intent torService = null; + private static Intent torService = null; private boolean updateLog = false; private boolean updateStatus = false; + private TextView lblStatus = null; + private ImageView imgStatus = null; + private String txtStatus = ""; + private int torStatus = STATUS_OFF; + + private Thread threadStatus = null; + + private WebView mWebView; + + private int currentView = 0; + /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { @@ -44,7 +65,7 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon showMain(); - + } @@ -54,12 +75,12 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon MenuItem mItem = menu.add(0, 1, Menu.NONE, "Home"); MenuItem mItem2 = menu.add(0, 2, Menu.NONE, "Settings"); MenuItem mItem3 = menu.add(0, 3, Menu.NONE, "Log"); - MenuItem mItem4 = menu.add(0, 4, Menu.NONE, "Browser"); + MenuItem mItem4 = menu.add(0, 4, Menu.NONE, "Help"); mItem.setIcon(R.drawable.ic_menu_home); mItem2.setIcon(R.drawable.ic_menu_register); mItem3.setIcon(R.drawable.ic_menu_reports); - mItem4.setIcon(R.drawable.ic_menu_goto); + mItem4.setIcon(R.drawable.ic_menu_about); return true; } @@ -86,12 +107,28 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon } else if (item.getItemId() == 4) { - Toast.makeText(this, "Not yet implemented!", Toast.LENGTH_SHORT); + this.showWeb(DEFAULT_HOME_PAGE); } return true; } + public boolean onKeyDown(int keyCode, KeyEvent event){ + if(keyCode==KeyEvent.KEYCODE_BACK){ + if(currentView != R.layout.layout_main){ + + showMain (); + + return true; + } + else{ + return super.onKeyDown(keyCode, event); + } + } + + return super.onKeyDown(keyCode, event); + + } /* (non-Javadoc) * @see android.app.Activity#onPause() @@ -100,6 +137,8 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon protected void onPause() { // TODO Auto-generated method stub super.onPause(); + + TorService.setStatus(torStatus); } @@ -113,7 +152,9 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon // TODO Auto-generated method stub super.onResume(); - checkStatus (); + torStatus = TorService.getStatus(); + + updateStatus (); } @@ -127,7 +168,10 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon // TODO Auto-generated method stub super.onStart(); - checkStatus (); + torStatus = TorService.getStatus(); + + + updateStatus (); } @@ -140,6 +184,8 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon protected void onStop() { // TODO Auto-generated method stub super.onStop(); + + TorService.setStatus(torStatus); } @@ -152,38 +198,47 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon updateLog = false; updateStatus = true; - setContentView(R.layout.layout_main); + currentView = R.layout.layout_main; + setContentView(currentView); findViewById(R.id.imgStatus).setOnClickListener(this); - - - Thread thread = new Thread () - { - public void run () - { - - while (updateStatus) - { - handlerStatus.sendEmptyMessage(0); - try { - Thread.sleep(UPDATE_TIMEOUT); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - }; - - thread.start(); + + lblStatus = (TextView)findViewById(R.id.lblStatus); + imgStatus = (ImageView)findViewById(R.id.imgStatus); + + updateStatus(); } + private void showWeb (String url) + { + + + currentView =R.layout.layout_web; + setContentView(currentView); + + mWebView = (WebView) findViewById(R.id.webview); + + WebSettings webSettings = mWebView.getSettings(); + webSettings.setSavePassword(false); + webSettings.setSaveFormData(false); + webSettings.setJavaScriptEnabled(true); + + + mWebView.setWebChromeClient(new MyWebChromeClient()); + + mWebView.loadUrl(url); + + + } + + /* * Show the message log UI */ private void showMessageLog () { - setContentView(R.layout.layout_log); + currentView = R.layout.layout_log; + setContentView(currentView); ((Button)findViewById(R.id.btnLogClear)).setOnClickListener(this); updateStatus = false; @@ -252,8 +307,9 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon @Override public void handleMessage(Message msg) { - checkStatus(); - + updateStatus(); + + // Toast.makeText(this,txtStatus, Toast.LENGTH_SHORT).show(); } }; @@ -268,7 +324,8 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon updateStatus = false; updateLog = false; - setContentView(R.layout.layout_settings); + currentView = R.layout.layout_settings; + setContentView(currentView); String output = loadTextFile(TORRC_INSTALL_PATH); @@ -283,40 +340,36 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon /* * Set the state of the running/not running graphic and label */ - public void checkStatus () + public void updateStatus () { - - TextView lblStatus = (TextView)findViewById(R.id.lblStatus); - ImageView imgStatus = (ImageView)findViewById(R.id.imgStatus); - if (imgStatus != null) { - int torStatus = TorService.getStatus(); if (torStatus == STATUS_ON) { imgStatus.setImageResource(R.drawable.toron); - lblStatus.setText("Tor is running\n- touch to stop -"); + lblStatus.setText("ORbot is running\n- touch the bot to stop -"); updateStatus = false; } else if (torStatus == STATUS_STARTING_UP) { imgStatus.setImageResource(R.drawable.torstarting); - lblStatus.setText("Tor is starting up\n(this might take a little bit)"); - + + lblStatus.setText("ORbot reports:\n\"" + txtStatus + "\""); + } else if (torStatus == STATUS_SHUTTING_DOWN) { imgStatus.setImageResource(R.drawable.torstopping); - lblStatus.setText("Tor is shutting down\nplease wait..."); + lblStatus.setText("ORbot is shutting down\nplease wait..."); } else { imgStatus.setImageResource(R.drawable.toroff); - lblStatus.setText("Tor is not running\n- touch to start -"); + lblStatus.setText("ORbot is not running\n- touch the bot to start -"); updateStatus = false; } } @@ -337,26 +390,27 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon //if Tor binary is not running, then start the service up if (TorService.getStatus()==STATUS_OFF) { - torService = new Intent(this, TorService.class); - torService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - TorService.setActivity(this); + torStatus = STATUS_STARTING_UP; + txtStatus = "Connecting to Tor..."; + updateStatus(); - startService(torService); + startTorService (); } - else if (TorService.getStatus()==STATUS_ON) + else { + torStatus = STATUS_SHUTTING_DOWN; + updateStatus(); - //stopService(torService); + stopService(torService); - TorService.stopTor (); + torStatus = STATUS_OFF; + updateStatus(); } - - showMain (); } else if (view.getId()==R.id.btnLogClear) { @@ -375,6 +429,20 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon } + private void startTorService () + { + if (torService == null) + { + torService = new Intent(this, TorService.class); + //torService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + TorService.setActivity(this); + } + + startService(torService); + + + + } /* * Load the log file text @@ -431,33 +499,89 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon } - - /* - * Get the last line of the log file for status display - */ - public static String getLastLine (String path) - { - String line = null; - - String lastLine = null; - - try { - BufferedReader reader = new BufferedReader((new FileReader(new File(path)))); - while ((line = reader.readLine()) != null) - { - lastLine = line; - } - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return lastLine; - - } + @Override + public void bandwidthUsed(long read, long written) { + Log.i(TAG,"BW Used: read=" + read + " written=" + written); + + } + + + @Override + public void circuitStatus(String status, String circID, String path) { + Log.i(TAG,"CircuitStatus=" + status + ": " + circID); + + } + + + @Override + public void message(String severity, String msg) { + + // Log.println(priority, tag, msg)("["+severity+"] "+msg); + //Toast.makeText(, text, duration) + // Toast.makeText(ACTIVITY, severity + ": " + msg, Toast.LENGTH_SHORT); + Log.i(TAG, "[Tor Control Port] " + severity + ": " + msg); + + if (msg.indexOf(TOR_CONTROL_PORT_MSG_BOOTSTRAP_DONE)!=-1) + { + torStatus = STATUS_ON; + + + + //setupWebProxy(true); + + } + + + txtStatus = msg; + handlerStatus.sendEmptyMessage(0); + + + } + + + @Override + public void newDescriptors(List orList) { + // TODO Auto-generated method stub + + } + + + @Override + public void orConnStatus(String status, String orName) { + + Log.i(TAG,"OrConnStatus=" + status + ": " + orName); + + } + + + @Override + public void streamStatus(String status, String streamID, String target) { + Log.i(TAG,"StreamStatus=" + status + ": " + streamID); + + } + + + @Override + public void unrecognized(String type, String msg) { + Log.i(TAG,"unrecognized log=" + type + ": " + msg); + + } - + /** + * Provides a hook for calling "alert" from javascript. Useful for + * debugging your javascript. + */ + final class MyWebChromeClient extends WebChromeClient { + @Override + public boolean onJsAlert(WebView view, String url, String message, JsResult result) { + Log.d(TAG, message); + result.confirm(); + return true; + } + + + } } \ No newline at end of file diff --git a/src/org/torproject/android/TorService.java b/src/org/torproject/android/TorService.java index 69850275..bb1cca97 100644 --- a/src/org/torproject/android/TorService.java +++ b/src/org/torproject/android/TorService.java @@ -10,11 +10,14 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.ConnectException; import java.net.Socket; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.StringTokenizer; +import java.util.Timer; +import java.util.TimerTask; import net.freehaven.tor.control.EventHandler; import net.freehaven.tor.control.NullEventHandler; @@ -31,35 +34,118 @@ public class TorService extends Service implements TorConstants private static TorControlPanel ACTIVITY = null; - private final static String TAG = "Tor"; + private final static String TAG = "TorService"; private static HttpProxy webProxy = null; - private static Process procTor = null; - private static int currentStatus = STATUS_OFF; - private static TorControlConnection conn = null; + private TorControlConnection conn = null; + + private Timer timer = new Timer (); + private final static int UPDATE_INTERVAL = 60000; /** Called when the activity is first created. */ @Override public void onCreate() { super.onCreate(); + Log.i(TAG,"TorService: onCreate"); + + timer.scheduleAtFixedRate( + new TimerTask() { + public void run() { + + //do nothing + // Log.i(TAG,"TorService: task is running"); + } + }, + 0, + UPDATE_INTERVAL); + + + int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH); + + if (procId != -1) + { + Log.i(TAG,"Found existing Tor process"); + + try { + currentStatus = STATUS_STARTING_UP; + + initControlConnection(); + + getTorStatus(); + + if (webProxy != null) + { + if (webProxy.isRunning()) + { + //do nothing + Log.i(TAG, "Web Proxy is already running"); + } + else + { + //do nothing + Log.i(TAG, "killing Web Proxy"); + webProxy.closeSocket(); + setupWebProxy(true); + } + } + else //do something + { + setupWebProxy(true); + } + + currentStatus = STATUS_ON; + + } catch (RuntimeException e) { + Log.i(TAG,"Unable to connect to existing Tor instance,",e); + currentStatus = STATUS_OFF; + this.stopTor(); + + } catch (Exception e) { + Log.i(TAG,"Unable to connect to existing Tor instance,",e); + currentStatus = STATUS_OFF; + this.stopTor(); + + } + } + } - public static int getStatus () + /* (non-Javadoc) + * @see android.app.Service#onLowMemory() + */ + @Override + public void onLowMemory() { + // TODO Auto-generated method stub + super.onLowMemory(); + } + + + /* (non-Javadoc) + * @see android.app.Service#onUnbind(android.content.Intent) + */ + @Override + public boolean onUnbind(Intent intent) { + // TODO Auto-generated method stub + return super.onUnbind(intent); + } + + + public static int getStatus () { - try { - getTorStatus(); - } catch (IOException e) { - Log.i(TAG,"Unable to get tor status",e); - } return currentStatus; } + + public static void setStatus (int newStatus) + { + currentStatus = newStatus; + } /* (non-Javadoc) @@ -82,54 +168,35 @@ public class TorService extends Service implements TorConstants // TODO Auto-generated method stub super.onStart(intent, startId); - Log.i(TAG,"on start"); - - startService(); + Log.i(TAG,"onStart called"); + + initTor(); + + setupWebProxy (true); } - - private void startService () - { - Thread thread = new Thread () - { - public void run () - { - - Log.i(TAG,"Tor thread started"); - - initTor(); - } - }; - - thread.start(); - - - } - - - + public void onDestroy () { + super.onDestroy(); + Log.i(TAG,"onDestroy called"); + + if (timer != null) timer.cancel(); + + stopTor(); } - public static void stopTor () + private void stopTor () { currentStatus = STATUS_SHUTTING_DOWN; - Thread thread = new Thread () - { - public void run () - { - killTorProcess (); + setupWebProxy(false); + + killTorProcess (); - setupWebProxy(false); - - currentStatus = STATUS_OFF; - } - }; + currentStatus = STATUS_OFF; - thread.start(); } @@ -137,55 +204,62 @@ public class TorService extends Service implements TorConstants ACTIVITY = activity; } - private static void setupWebProxy (boolean enabled) + private void setupWebProxy (boolean enabled) { if (enabled) { - if (webProxy == null) - { - Log.i(TAG,"Setting up Web Proxy on port 8888"); - //httpd s - webProxy = new HttpProxy(PORT_HTTP); - webProxy.setDoSocks(true); - webProxy.start(); - - //socks - try - { - Proxy.setDefaultProxy(IP_LOCALHOST,PORT_SOCKS); - - } - catch (Exception e) - { - Log.w(TAG,e.getMessage()); - } - - //Settings.System.putString(getContentResolver(), Settings.System.HTTP_PROXY, proxySetting);//enable proxy - // Settings.Secure.putString(getContentResolver(), Settings.Secure.HTTP_PROXY, proxySetting);//enable proxy - } - else + if (webProxy != null) { + webProxy.closeSocket(); + webProxy = null; - webProxy.setDoSocks(true); - Log.i(TAG,"Web Proxy already running..."); } + + Log.i(TAG,"Starting up Web Proxy on port: " + PORT_HTTP); + //httpd s + webProxy = new HttpProxy(PORT_HTTP); + webProxy.setDoSocks(true); + webProxy.start(); + + //socks + try + { + + Proxy.setDefaultProxy(IP_LOCALHOST,PORT_SOCKS); + + + } + catch (Exception e) + { + Log.w(TAG,e.getMessage()); + } + + Log.i(TAG,"Web Proxy enabled..."); + + + //Settings.System.putString(getContentResolver(), Settings.System.HTTP_PROXY, proxySetting);//enable proxy + // Settings.Secure.putString(getContentResolver(), Settings.Secure.HTTP_PROXY, proxySetting);//enable proxy + } else { - Log.i(TAG,"Turning off Socks/Tor routing on Web Proxy"); + //Log.i(TAG,"Turning off Socks/Tor routing on Web Proxy"); if (webProxy != null) { //logNotice("Tor is disabled - browsing is not anonymous!"); //webProxy.setDoSocks(false); + webProxy.closeSocket(); + webProxy = null; + Log.i(TAG,"WebProxy ServerSocket closed"); } } } - public static void reloadConfig () + public void reloadConfig () { try { @@ -205,65 +279,39 @@ public class TorService extends Service implements TorConstants } } - private void shutdownTor () + private void killTorProcess () { - try - { - currentStatus = STATUS_SHUTTING_DOWN; - - if (conn == null) - { - initControlConnection (); - } - if (conn != null) - { - conn.signal("SHUTDOWN"); - } - } - catch (Exception e) + if (conn != null) { + try { + Log.i(TAG,"sending SHUTDOWN signal"); + conn.signal("SHUTDOWN"); + } catch (IOException e) { + // TODO Auto-generated catch block + Log.i(TAG,"error shutting down Tor via connection",e); + } + conn = null; } - } - private static void killTorProcess () - { - //doCommand(SHELL_CMD_KILLALL, CHMOD_EXE_VALUE, TOR_BINARY_INSTALL_PATH); - /* - if (procTor != null) - { - Log.i(TAG,"shutting down Tor process..."); - procTor.destroy(); - - - try { - procTor.waitFor(); - } - catch(Exception e2) - { - e2.printStackTrace(); - } - - int exitStatus = procTor.exitValue(); - Log.i(TAG,"Tor exit: " + exitStatus); + try { + Thread.sleep(500); + } catch (InterruptedException e) { - - procTor = null; - - }*/ - + } + int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH); - if (procId != -1) + while (procId != -1) { Log.i(TAG,"Found Tor PID=" + procId + " - killing now..."); - doCommand(SHELL_CMD_KILLALL, procId + ""); + doCommand(SHELL_CMD_KILL, procId + ""); + procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH); } - conn = null; } @@ -316,14 +364,22 @@ public class TorService extends Service implements TorConstants doCommand(SHELL_CMD_RM,TOR_LOG_PATH); Log.i(TAG,"Starting tor process"); - procTor = doCommand(TOR_BINARY_INSTALL_PATH, TOR_COMMAND_LINE_ARGS); + doCommand(TOR_BINARY_INSTALL_PATH, TOR_COMMAND_LINE_ARGS); - //Log.i(TAG,"Tor process id=" + procTor.); + int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH); + + if (procId == -1) + { + doCommand(TOR_BINARY_INSTALL_PATH, TOR_COMMAND_LINE_ARGS); + procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH); + } + + Log.i(TAG,"Tor process id=" + procId); currentStatus = STATUS_STARTING_UP; logNotice("Tor is starting up..."); - Thread.sleep(2000); + Thread.sleep(500); initControlConnection (); } catch (Exception e) { @@ -419,7 +475,7 @@ public class TorService extends Service implements TorConstants } catch (Exception e) { - Log.e(TAG, "error: " + e.getMessage(), e); + Log.e(TAG, "error: " + e.getMessage()); } return child; @@ -436,27 +492,38 @@ public class TorService extends Service implements TorConstants return null; } - public static synchronized void initControlConnection () throws Exception, RuntimeException + public void initControlConnection () throws Exception, RuntimeException { - if (conn == null) - { - Log.i(TAG,"Connecting to control port: " + TOR_CONTROL_PORT); - Socket s = new Socket(IP_LOCALHOST, TOR_CONTROL_PORT); - conn = TorControlConnection.getConnection(s); - // conn.authenticate(new byte[0]); // See section 3.2 - - Log.i(TAG,"SUCCESS connected to control port"); - - // - File fileCookie = new File(TOR_CONTROL_AUTH_COOKIE); - byte[] cookie = new byte[(int)fileCookie.length()]; - new FileInputStream(new File(TOR_CONTROL_AUTH_COOKIE)).read(cookie); - conn.authenticate(cookie); - - Log.i(TAG,"SUCCESS authenticated to control port"); - - addEventHandler(); - } + for (int i = 0; i < 50; i++) + { + try + { + Log.i(TAG,"Connecting to control port: " + TOR_CONTROL_PORT); + Socket s = new Socket(IP_LOCALHOST, TOR_CONTROL_PORT); + conn = TorControlConnection.getConnection(s); + // conn.authenticate(new byte[0]); // See section 3.2 + + Log.i(TAG,"SUCCESS connected to control port"); + + // + File fileCookie = new File(TOR_CONTROL_AUTH_COOKIE); + byte[] cookie = new byte[(int)fileCookie.length()]; + new FileInputStream(new File(TOR_CONTROL_AUTH_COOKIE)).read(cookie); + conn.authenticate(cookie); + + Log.i(TAG,"SUCCESS authenticated to control port"); + + addEventHandler(); + + break; //don't need to retry + } + catch (ConnectException ce) + { + Log.i(TAG,"Attempt " + i + ": Error connecting to control port; retrying..."); + Thread.sleep(1000); + } + } + } @@ -484,17 +551,12 @@ public class TorService extends Service implements TorConstants } - private static void getTorStatus () throws IOException + private void getTorStatus () throws IOException { try { - if (conn == null && (currentStatus == STATUS_STARTING_UP || currentStatus == STATUS_ON)) - { - - initControlConnection (); - - } + if (conn != null) @@ -522,6 +584,10 @@ public class TorService extends Service implements TorConstants // Log.i(TAG, "status/circuit-established=" + status); } } + else + { + currentStatus = STATUS_OFF; + } } catch (Exception e) { @@ -530,56 +596,22 @@ public class TorService extends Service implements TorConstants } - /* - * The recognized signal names are: - "RELOAD" -- Reload configuration information - "SHUTDOWN" -- Start a clean shutdown of the Tor process - "DUMP" -- Write current statistics to the logs - "DEBUG" -- Switch the logs to debugging verbosity - "HALT" -- Stop the Tor process immediately. - - */ - public void sendSignal () throws IOException - { - - conn.signal("RELOAD"); - - } - public static void addEventHandler () throws IOException + public void addEventHandler () throws IOException { // We extend NullEventHandler so that we don't need to provide empty // implementations for all the events we don't care about. // ... Log.i(TAG,"adding control port event handler"); - - EventHandler eh = new NullEventHandler() - { - public void message(String severity, String msg) { - - // Log.println(priority, tag, msg)("["+severity+"] "+msg); - //Toast.makeText(, text, duration) - // Toast.makeText(ACTIVITY, severity + ": " + msg, Toast.LENGTH_SHORT); - Log.i(TAG, "[Tor Control Port] " + severity + ": " + msg); - - if (msg.indexOf(TOR_CONTROL_PORT_MSG_BOOTSTRAP_DONE)!=-1) - { - currentStatus = STATUS_ON; - setupWebProxy(true); - - } - - } - }; - - conn.setEventHandler(eh); - conn.setEvents(Arrays.asList(new String[]{ - "ORCONN", "CIRC", "INFO", "NOTICE", "ERR"})); + conn.setEventHandler(ACTIVITY); + + conn.setEvents(Arrays.asList(new String[]{ + "ORCONN", "CIRC", "NOTICE", "ERR"})); // conn.setEvents(Arrays.asList(new String[]{ // "DEBUG", "INFO", "NOTICE", "WARN", "ERR"})); - Log.i(TAG,"SUCCESS added control port event handler"); + Log.i(TAG,"SUCCESS added control port event handler"); } } \ No newline at end of file