Orbot 0.0.2: major UI improvements w/ editable settings and more
svn:r21042
|
@ -3,6 +3,7 @@
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry kind="src" path="gen"/>
|
<classpathentry kind="src" path="gen"/>
|
||||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||||
<classpathentry kind="lib" path="jsocks.jar"/>
|
<classpathentry kind="lib" path="libs/jsocks.jar"/>
|
||||||
|
<classpathentry combineaccessrules="false" kind="src" path="/jtorctrl"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
10
BUILD
|
@ -91,6 +91,16 @@ We need to build our Java SOCKS library:
|
||||||
ant jar
|
ant jar
|
||||||
cp bin/jar/asocks.jar ../Orbot/libs
|
cp bin/jar/asocks.jar ../Orbot/libs
|
||||||
|
|
||||||
|
We need to get the TorControl library for Java (https://svn.torproject.org/svn/torctl/trunk/doc/howto.txt):
|
||||||
|
|
||||||
|
git clone git://git.torproject.org/git/jtorctl
|
||||||
|
cd jtorctl
|
||||||
|
mkdir bin
|
||||||
|
javac net/freehaven/tor/control/TorControlConnection.java -d bin
|
||||||
|
cd bin
|
||||||
|
jar cvf jtorctrl.jar *
|
||||||
|
cp jtorctrl.jar {Orbot Home}/libs
|
||||||
|
|
||||||
Finally, we'll make a proper Android package with ant and the Android App SDK:
|
Finally, we'll make a proper Android package with ant and the Android App SDK:
|
||||||
|
|
||||||
export APP_SDK=~/Documents/projects/android/android-sdk-linux_x86-1.5_r3/tools
|
export APP_SDK=~/Documents/projects/android/android-sdk-linux_x86-1.5_r3/tools
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
|
0.0.2 - 2009-11-27
|
||||||
|
- Major improvement to the user interface including relative layout for different screens
|
||||||
|
- New graphics resources
|
||||||
|
- Implemented Tor Control Port using official Java library
|
||||||
|
- Added 'clear' button to the log screen
|
||||||
|
- Added 'save' and editable textbox for the settings screen
|
||||||
|
- Moved screen navigation to a pop-up menu
|
||||||
|
|
||||||
Changes in version 0.0.1-alpha - 2009-10-21
|
Changes in version 0.0.1-alpha - 2009-10-21
|
||||||
- First code release
|
- First code release
|
||||||
- Major Features: Tor binary application is fully operational, UI: Start/Stop Tor, View Message Log, View Settings (torrc)
|
- Major Features: Tor binary application is fully operational, UI: Start/Stop Tor, View Message Log, View Settings (torrc)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,11 +52,11 @@ DataDirectory /data/data/org.torproject.android/data
|
||||||
|
|
||||||
## The port on which Tor will listen for local connections from Tor
|
## The port on which Tor will listen for local connections from Tor
|
||||||
## controller applications, as documented in control-spec.txt.
|
## controller applications, as documented in control-spec.txt.
|
||||||
#ControlPort 9051
|
ControlPort 9051
|
||||||
## If you enable the controlport, be sure to enable one of these
|
## If you enable the controlport, be sure to enable one of these
|
||||||
## authentication methods, to prevent attackers from accessing it.
|
## authentication methods, to prevent attackers from accessing it.
|
||||||
#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
|
#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
|
||||||
#CookieAuthentication 1
|
CookieAuthentication 1
|
||||||
|
|
||||||
############### This section is just for location-hidden services ###
|
############### This section is just for location-hidden services ###
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project name="Orbot" default="help">
|
<project name="Orbot">
|
||||||
|
|
||||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||||
It contain the path to the SDK. It should *NOT* be checked in in Version
|
It contain the path to the SDK. It should *NOT* be checked in in Version
|
||||||
|
|
|
@ -7,16 +7,8 @@
|
||||||
# "build.properties", and override values to adapt the script to your
|
# "build.properties", and override values to adapt the script to your
|
||||||
# project structure.
|
# project structure.
|
||||||
|
|
||||||
# apk configurations. This property allows creation of APK files with limited
|
|
||||||
# resources. For example, if your application contains many locales and
|
|
||||||
# you wish to release multiple smaller apks instead of a large one, you can
|
|
||||||
# define configuration to create apks with limited language sets.
|
|
||||||
# Format is a comma separated list of configuration names. For each
|
|
||||||
# configuration, a property will declare the resource configurations to
|
|
||||||
# include. Example:
|
|
||||||
# apk-configurations=european,northamerica
|
|
||||||
# apk-config-european=en,fr,it,de,es
|
|
||||||
# apk-config-northamerica=en,es
|
|
||||||
apk-configurations=
|
apk-configurations=
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-2
|
target=android-4
|
||||||
|
# Indicates whether an apk should be generated for each density.
|
||||||
|
split.density=false
|
||||||
|
|
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 16 KiB |
|
@ -16,13 +16,11 @@
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
<Button android:id="@+id/btnLogClose"
|
|
||||||
android:layout_width="fill_parent"
|
<Button android:id="@+id/btnLogClear"
|
||||||
android:layout_height="40px"
|
android:layout_height="40px"
|
||||||
android:text="Close Log"
|
android:text="Clear Log"
|
||||||
android:layout_margin="0sp"
|
android:layout_margin="0sp"
|
||||||
|
android:layout_width="fill_parent"/>
|
||||||
|
|
||||||
|
|
||||||
/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -1,63 +1,48 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<AbsoluteLayout
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/widget29"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
android:background="@drawable/bgdarkdroid">
|
||||||
android:background="#cccccc"
|
|
||||||
>
|
<ScrollView android:id="@+id/mainview"
|
||||||
<AbsoluteLayout
|
android:orientation="vertical"
|
||||||
android:id="@+id/topbox"
|
android:layout_width="fill_parent"
|
||||||
android:layout_width="275px"
|
android:layout_height="fill_parent">
|
||||||
android:layout_height="120px"
|
<TableLayout android:id="@+id/mainLayout"
|
||||||
android:layout_x="19px"
|
android:layout_gravity="center"
|
||||||
android:layout_y="23px"
|
android:layout_height="wrap_content"
|
||||||
>
|
android:layout_width="wrap_content">
|
||||||
<ImageView
|
<TableRow android:id="@+id/startRow">
|
||||||
|
<TableLayout
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content">
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
android:id="@+id/imgStatus"
|
android:id="@+id/imgStatus"
|
||||||
android:layout_x="40px"
|
|
||||||
android:layout_y="11px"
|
|
||||||
android:layout_width="64px"
|
|
||||||
android:layout_height="64px"
|
|
||||||
>
|
|
||||||
</ImageView>
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/lblStatus"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="TextView"
|
android:src="@drawable/toroff"/>
|
||||||
android:layout_x="111px"
|
</TableRow>
|
||||||
android:layout_y="39px"
|
<TableRow>
|
||||||
android:textColor="#333333"
|
<TextView android:id="@+id/lblStatus"
|
||||||
>
|
android:text=" \n "
|
||||||
</TextView>
|
android:paddingTop="15px"
|
||||||
</AbsoluteLayout>
|
android:layout_gravity="center_horizontal"
|
||||||
<Button
|
android:textStyle="bold"
|
||||||
android:id="@+id/btnStart"
|
android:textColor="#ffffff" />
|
||||||
android:layout_width="205px"
|
</TableRow>
|
||||||
android:layout_height="wrap_content"
|
</TableLayout>
|
||||||
android:text="Start Tor"
|
</TableRow>
|
||||||
android:layout_x="54px"
|
|
||||||
android:layout_y="133px"
|
</TableLayout>
|
||||||
>
|
</ScrollView>
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btnLog"
|
|
||||||
android:layout_width="206px"
|
</LinearLayout>
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="View Message Log"
|
|
||||||
android:layout_x="54px"
|
|
||||||
android:layout_y="221px"
|
|
||||||
>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btnSettings"
|
|
||||||
android:layout_width="206px"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="View Settings"
|
|
||||||
android:layout_x="53px"
|
|
||||||
android:layout_y="305px"
|
|
||||||
>
|
|
||||||
</Button>
|
|
||||||
</AbsoluteLayout>
|
|
||||||
|
|
||||||
|
|
|
@ -8,21 +8,21 @@
|
||||||
<ScrollView android:layout_height="380px"
|
<ScrollView android:layout_height="380px"
|
||||||
android:layout_width="fill_parent">
|
android:layout_width="fill_parent">
|
||||||
|
|
||||||
<TextView android:id="@+id/textSettings"
|
<EditText android:id="@+id/textSettings"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_weight="1.0"
|
android:layout_weight="1.0"
|
||||||
|
android:singleLine="false"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
<Button android:id="@+id/btnSettingsClose"
|
<Button android:id="@+id/btnSettingsSave"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="40px"
|
android:layout_height="40px"
|
||||||
android:text="Close Log"
|
android:text="Save Settings"
|
||||||
android:layout_margin="0sp"
|
android:layout_margin="0sp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -51,14 +51,21 @@ package org.torproject.android;
|
||||||
*
|
*
|
||||||
* Julian Robichaux -- http://www.nsftools.com
|
* Julian Robichaux -- http://www.nsftools.com
|
||||||
*/
|
*/
|
||||||
import java.io.*;
|
import java.io.BufferedInputStream;
|
||||||
import java.net.*;
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
import net.sourceforge.jsocks.socks.Socks4Proxy;
|
|
||||||
import net.sourceforge.jsocks.socks.Socks5Proxy;
|
import net.sourceforge.jsocks.socks.Socks5Proxy;
|
||||||
import net.sourceforge.jsocks.socks.SocksSocket;
|
import net.sourceforge.jsocks.socks.SocksSocket;
|
||||||
|
|
||||||
|
|
||||||
public class HttpProxy extends Thread
|
public class HttpProxy extends Thread
|
||||||
{
|
{
|
||||||
public static final int DEFAULT_PORT = 8888;
|
public static final int DEFAULT_PORT = 8888;
|
||||||
|
|
|
@ -54,11 +54,13 @@ public class TorBinaryInstaller implements TorConstants {
|
||||||
streamToFile(zip.getInputStream(zipen),TORRC_INSTALL_PATH);
|
streamToFile(zip.getInputStream(zipen),TORRC_INSTALL_PATH);
|
||||||
|
|
||||||
zip.close();
|
zip.close();
|
||||||
|
|
||||||
|
Log.i(LOG_TAG,"SUCCESS: unzipped tor binary from apk");
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException ioe)
|
catch (IOException ioe)
|
||||||
{
|
{
|
||||||
Log.i(LOG_TAG,"unable to unzip tor binary from apk",ioe);
|
Log.i(LOG_TAG,"FAIL: unable to unzip tor binary from apk",ioe);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@ public interface TorConstants {
|
||||||
|
|
||||||
//where to send the notices log
|
//where to send the notices log
|
||||||
public final static String TOR_LOG_PATH = TOR_HOME + "notices.log";
|
public final static String TOR_LOG_PATH = TOR_HOME + "notices.log";
|
||||||
|
|
||||||
|
//control port cookie path
|
||||||
|
public final static String TOR_CONTROL_AUTH_COOKIE = TOR_HOME + "data/control_auth_cookie";
|
||||||
|
|
||||||
//how to launch tor
|
//how to launch tor
|
||||||
public final static String TOR_COMMAND_LINE_ARGS = "-f " + TORRC_INSTALL_PATH;
|
public final static String TOR_COMMAND_LINE_ARGS = "-f " + TORRC_INSTALL_PATH;
|
||||||
|
@ -55,5 +58,16 @@ public interface TorConstants {
|
||||||
|
|
||||||
//what is says!
|
//what is says!
|
||||||
public final static String IP_LOCALHOST = "127.0.0.1";
|
public final static String IP_LOCALHOST = "127.0.0.1";
|
||||||
|
public final static int TOR_CONTROL_PORT = 9051;
|
||||||
|
public final static int UPDATE_TIMEOUT = 3000;
|
||||||
|
|
||||||
|
//status to communicate state
|
||||||
|
public final static int STATUS_OFF = 0;
|
||||||
|
public final static int STATUS_ON = 1;
|
||||||
|
public final static int STATUS_STARTING_UP = 2;
|
||||||
|
public final static int STATUS_SHUTTING_DOWN = 3;
|
||||||
|
|
||||||
|
//control port
|
||||||
|
public final static String TOR_CONTROL_PORT_MSG_BOOTSTRAP_DONE = "Bootstrapped 100%";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,18 +6,23 @@ package org.torproject.android;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
public class TorControlPanel extends Activity implements OnClickListener, TorConstants
|
public class TorControlPanel extends Activity implements OnClickListener, TorConstants
|
||||||
{
|
{
|
||||||
|
@ -27,13 +32,15 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
private Intent torService = null;
|
private Intent torService = null;
|
||||||
|
|
||||||
private boolean updateLog = false;
|
private boolean updateLog = false;
|
||||||
|
private boolean updateStatus = false;
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setTheme(android.R.style.Theme_Black);
|
||||||
|
|
||||||
|
|
||||||
showMain();
|
showMain();
|
||||||
|
|
||||||
|
@ -41,7 +48,50 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
super.onCreateOptionsMenu(menu);
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see android.app.Activity#onMenuItemSelected(int, android.view.MenuItem)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
||||||
|
|
||||||
|
super.onMenuItemSelected(featureId, item);
|
||||||
|
|
||||||
|
if (item.getItemId() == 1)
|
||||||
|
{
|
||||||
|
this.showMain();
|
||||||
|
}
|
||||||
|
else if (item.getItemId() == 2)
|
||||||
|
{
|
||||||
|
this.showSettings();
|
||||||
|
}
|
||||||
|
else if (item.getItemId() == 3)
|
||||||
|
{
|
||||||
|
this.showMessageLog();
|
||||||
|
}
|
||||||
|
else if (item.getItemId() == 4)
|
||||||
|
{
|
||||||
|
Toast.makeText(this, "Not yet implemented!", Toast.LENGTH_SHORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see android.app.Activity#onPause()
|
* @see android.app.Activity#onPause()
|
||||||
|
@ -63,7 +113,7 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
setUIState ();
|
checkStatus ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,7 +127,7 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
|
||||||
setUIState ();
|
checkStatus ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,17 +150,32 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
private void showMain ()
|
private void showMain ()
|
||||||
{
|
{
|
||||||
updateLog = false;
|
updateLog = false;
|
||||||
|
updateStatus = true;
|
||||||
|
|
||||||
setContentView(R.layout.layout_main);
|
setContentView(R.layout.layout_main);
|
||||||
|
|
||||||
((Button)findViewById(R.id.btnStart)).setOnClickListener(this);
|
findViewById(R.id.imgStatus).setOnClickListener(this);
|
||||||
|
|
||||||
((Button)findViewById(R.id.btnLog)).setOnClickListener(this);
|
|
||||||
|
Thread thread = new Thread ()
|
||||||
((Button)findViewById(R.id.btnSettings)).setOnClickListener(this);
|
{
|
||||||
|
public void run ()
|
||||||
|
{
|
||||||
setUIState ();
|
|
||||||
|
while (updateStatus)
|
||||||
|
{
|
||||||
|
handlerStatus.sendEmptyMessage(0);
|
||||||
|
try {
|
||||||
|
Thread.sleep(UPDATE_TIMEOUT);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -119,8 +184,9 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
private void showMessageLog ()
|
private void showMessageLog ()
|
||||||
{
|
{
|
||||||
setContentView(R.layout.layout_log);
|
setContentView(R.layout.layout_log);
|
||||||
((Button)findViewById(R.id.btnLogClose)).setOnClickListener(this);
|
((Button)findViewById(R.id.btnLogClear)).setOnClickListener(this);
|
||||||
|
|
||||||
|
updateStatus = false;
|
||||||
updateLog = true;
|
updateLog = true;
|
||||||
|
|
||||||
Thread thread = new Thread ()
|
Thread thread = new Thread ()
|
||||||
|
@ -130,13 +196,15 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
|
|
||||||
while (updateLog)
|
while (updateLog)
|
||||||
{
|
{
|
||||||
handler.sendEmptyMessage(0);
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(5000);
|
Thread.sleep(UPDATE_TIMEOUT);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handler.sendEmptyMessage(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -153,9 +221,12 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
|
|
||||||
TextView tvLog = (TextView)findViewById(R.id.messageLog);
|
TextView tvLog = (TextView)findViewById(R.id.messageLog);
|
||||||
|
|
||||||
String output = loadLogFile(TOR_LOG_PATH);
|
if (tvLog != null)
|
||||||
|
{
|
||||||
|
String output = loadTextFile(TOR_LOG_PATH);
|
||||||
|
|
||||||
tvLog.setText(output);
|
tvLog.setText(output);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +243,21 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle to reload Tor debug log every few seconds while viewing it
|
||||||
|
*/
|
||||||
|
private Handler handlerStatus = new Handler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
|
||||||
|
checkStatus();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the basic settings application to display torrc
|
* Load the basic settings application to display torrc
|
||||||
|
@ -179,14 +265,17 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
*/
|
*/
|
||||||
private void showSettings ()
|
private void showSettings ()
|
||||||
{
|
{
|
||||||
|
updateStatus = false;
|
||||||
|
updateLog = false;
|
||||||
|
|
||||||
setContentView(R.layout.layout_settings);
|
setContentView(R.layout.layout_settings);
|
||||||
|
|
||||||
TextView tvLog = (TextView)findViewById(R.id.textSettings);
|
|
||||||
((Button)findViewById(R.id.btnSettingsClose)).setOnClickListener(this);
|
|
||||||
|
|
||||||
String output = loadLogFile(TORRC_INSTALL_PATH);
|
|
||||||
|
|
||||||
tvLog.setText(output);
|
String output = loadTextFile(TORRC_INSTALL_PATH);
|
||||||
|
|
||||||
|
TextView tvSettings = (TextView)findViewById(R.id.textSettings);
|
||||||
|
((Button)findViewById(R.id.btnSettingsSave)).setOnClickListener(this);
|
||||||
|
tvSettings.setText(output);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,28 +283,42 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
/*
|
/*
|
||||||
* Set the state of the running/not running graphic and label
|
* Set the state of the running/not running graphic and label
|
||||||
*/
|
*/
|
||||||
public void setUIState ()
|
public void checkStatus ()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
TextView lblStatus = (TextView)findViewById(R.id.lblStatus);
|
TextView lblStatus = (TextView)findViewById(R.id.lblStatus);
|
||||||
ImageView imgStatus = (ImageView)findViewById(R.id.imgStatus);
|
ImageView imgStatus = (ImageView)findViewById(R.id.imgStatus);
|
||||||
|
|
||||||
Button btnStart = (Button)findViewById(R.id.btnStart);
|
if (imgStatus != null)
|
||||||
|
|
||||||
if (TorService.isRunning())
|
|
||||||
{
|
{
|
||||||
btnStart.setText("Stop Tor");
|
int torStatus = TorService.getStatus();
|
||||||
imgStatus.setImageResource(R.drawable.toron);
|
|
||||||
lblStatus.setText("Tor is running");
|
if (torStatus == STATUS_ON)
|
||||||
|
{
|
||||||
}
|
imgStatus.setImageResource(R.drawable.toron);
|
||||||
else
|
lblStatus.setText("Tor is running\n- touch to stop -");
|
||||||
{
|
updateStatus = false;
|
||||||
btnStart.setText("Start Tor");
|
}
|
||||||
imgStatus.setImageResource(R.drawable.toroff);
|
else if (torStatus == STATUS_STARTING_UP)
|
||||||
lblStatus.setText("Tor is not running");
|
{
|
||||||
|
imgStatus.setImageResource(R.drawable.torstarting);
|
||||||
|
lblStatus.setText("Tor is starting up\n(this might take a little bit)");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (torStatus == STATUS_SHUTTING_DOWN)
|
||||||
|
{
|
||||||
|
imgStatus.setImageResource(R.drawable.torstopping);
|
||||||
|
lblStatus.setText("Tor is shutting down\nplease wait...");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
imgStatus.setImageResource(R.drawable.toroff);
|
||||||
|
lblStatus.setText("Tor is not running\n- touch to start -");
|
||||||
|
updateStatus = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,59 +332,54 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
|
||||||
// the start button
|
// the start button
|
||||||
if (view.getId()==R.id.btnStart)
|
if (view.getId()==R.id.imgStatus)
|
||||||
{
|
{
|
||||||
//if Tor binary is not running, then start the service up
|
//if Tor binary is not running, then start the service up
|
||||||
if (!TorService.isRunning())
|
if (TorService.getStatus()==STATUS_OFF)
|
||||||
{
|
{
|
||||||
torService = new Intent(this, TorService.class);
|
torService = new Intent(this, TorService.class);
|
||||||
torService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
torService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
TorService.setActivity(this);
|
TorService.setActivity(this);
|
||||||
|
|
||||||
startService(torService);
|
startService(torService);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else if (TorService.getStatus()==STATUS_ON)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (torService == null)
|
|
||||||
torService = new Intent(this, TorService.class);
|
|
||||||
|
|
||||||
|
//stopService(torService);
|
||||||
|
|
||||||
TorService.setActivity(this);
|
TorService.stopTor ();
|
||||||
|
|
||||||
stopService(torService);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//update the UI
|
|
||||||
setUIState ();
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (view.getId()==R.id.btnLog)
|
|
||||||
{
|
|
||||||
showMessageLog();
|
|
||||||
|
|
||||||
|
showMain ();
|
||||||
}
|
}
|
||||||
else if (view.getId()==R.id.btnSettings)
|
else if (view.getId()==R.id.btnLogClear)
|
||||||
{
|
|
||||||
showSettings();
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (view.getId()==R.id.btnLogClose || view.getId()==R.id.btnSettingsClose)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
showMain();
|
saveTextFile(TOR_LOG_PATH,"");
|
||||||
|
}
|
||||||
|
else if (view.getId()==R.id.btnSettingsSave)
|
||||||
|
{
|
||||||
|
|
||||||
|
TextView tvSettings = (TextView)findViewById(R.id.textSettings);
|
||||||
|
String newSettings = tvSettings.getText().toString();
|
||||||
|
saveTextFile(TORRC_INSTALL_PATH, newSettings);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the log file text
|
* Load the log file text
|
||||||
*/
|
*/
|
||||||
public static String loadLogFile (String path)
|
public static String loadTextFile (String path)
|
||||||
{
|
{
|
||||||
String line = null;
|
String line = null;
|
||||||
|
|
||||||
|
@ -305,6 +403,34 @@ public class TorControlPanel extends Activity implements OnClickListener, TorCon
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the log file text
|
||||||
|
*/
|
||||||
|
public static boolean saveTextFile (String path, String contents)
|
||||||
|
{
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
FileWriter writer = new FileWriter( path, false );
|
||||||
|
writer.write( contents );
|
||||||
|
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Log.i(TAG, "error writing file: " + path, e);
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the last line of the log file for status display
|
* Get the last line of the log file for status display
|
||||||
|
|
|
@ -5,11 +5,20 @@ package org.torproject.android;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import net.freehaven.tor.control.EventHandler;
|
||||||
|
import net.freehaven.tor.control.NullEventHandler;
|
||||||
|
import net.freehaven.tor.control.TorControlConnection;
|
||||||
import net.sourceforge.jsocks.socks.Proxy;
|
import net.sourceforge.jsocks.socks.Proxy;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -28,22 +37,29 @@ public class TorService extends Service implements TorConstants
|
||||||
|
|
||||||
private static Process procTor = null;
|
private static Process procTor = null;
|
||||||
|
|
||||||
|
private static int currentStatus = STATUS_OFF;
|
||||||
|
|
||||||
|
private static TorControlConnection conn = null;
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isRunning ()
|
|
||||||
|
public static int getStatus ()
|
||||||
{
|
{
|
||||||
int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH);
|
try {
|
||||||
|
getTorStatus();
|
||||||
return (procId != -1);
|
} catch (IOException e) {
|
||||||
|
Log.i(TAG,"Unable to get tor status",e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentStatus;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -74,13 +90,18 @@ public class TorService extends Service implements TorConstants
|
||||||
|
|
||||||
private void startService ()
|
private void startService ()
|
||||||
{
|
{
|
||||||
Log.i(TAG,"Tor thread started");
|
Thread thread = new Thread ()
|
||||||
|
{
|
||||||
|
public void run ()
|
||||||
initTor();
|
{
|
||||||
|
|
||||||
|
Log.i(TAG,"Tor thread started");
|
||||||
setupWebProxy(true);
|
|
||||||
|
initTor();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -90,9 +111,25 @@ public class TorService extends Service implements TorConstants
|
||||||
public void onDestroy ()
|
public void onDestroy ()
|
||||||
{
|
{
|
||||||
|
|
||||||
killTorProcess ();
|
}
|
||||||
setupWebProxy(false);
|
|
||||||
|
public static void stopTor ()
|
||||||
|
{
|
||||||
|
currentStatus = STATUS_SHUTTING_DOWN;
|
||||||
|
|
||||||
|
Thread thread = new Thread ()
|
||||||
|
{
|
||||||
|
public void run ()
|
||||||
|
{
|
||||||
|
killTorProcess ();
|
||||||
|
|
||||||
|
setupWebProxy(false);
|
||||||
|
|
||||||
|
currentStatus = STATUS_OFF;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +137,7 @@ public class TorService extends Service implements TorConstants
|
||||||
ACTIVITY = activity;
|
ACTIVITY = activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupWebProxy (boolean enabled)
|
private static void setupWebProxy (boolean enabled)
|
||||||
{
|
{
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
|
@ -140,91 +177,142 @@ public class TorService extends Service implements TorConstants
|
||||||
|
|
||||||
if (webProxy != null)
|
if (webProxy != null)
|
||||||
{
|
{
|
||||||
showToast("Tor is disabled - browsing is not anonymous!");
|
//logNotice("Tor is disabled - browsing is not anonymous!");
|
||||||
webProxy.setDoSocks(false);
|
//webProxy.setDoSocks(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void killTorProcess ()
|
public static void reloadConfig ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (conn == null)
|
||||||
|
{
|
||||||
|
initControlConnection ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn != null)
|
||||||
|
{
|
||||||
|
conn.signal("RELOAD");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.i(TAG,"Unable to reload configuration",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shutdownTor ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
currentStatus = STATUS_SHUTTING_DOWN;
|
||||||
|
|
||||||
|
if (conn == null)
|
||||||
|
{
|
||||||
|
initControlConnection ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn != null)
|
||||||
|
{
|
||||||
|
conn.signal("SHUTDOWN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void killTorProcess ()
|
||||||
{
|
{
|
||||||
//doCommand(SHELL_CMD_KILLALL, CHMOD_EXE_VALUE, TOR_BINARY_INSTALL_PATH);
|
//doCommand(SHELL_CMD_KILLALL, CHMOD_EXE_VALUE, TOR_BINARY_INSTALL_PATH);
|
||||||
|
|
||||||
|
/*
|
||||||
if (procTor != null)
|
if (procTor != null)
|
||||||
{
|
{
|
||||||
Log.i(TAG,"shutting down Tor process...");
|
Log.i(TAG,"shutting down Tor process...");
|
||||||
|
|
||||||
procTor.destroy();
|
procTor.destroy();
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
procTor.waitFor();
|
procTor.waitFor();
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e2)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
e2.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
int exitStatus = procTor.exitValue();
|
int exitStatus = procTor.exitValue();
|
||||||
Log.i(TAG,"Tor exit: " + exitStatus);
|
Log.i(TAG,"Tor exit: " + exitStatus);
|
||||||
|
|
||||||
|
|
||||||
procTor = null;
|
procTor = null;
|
||||||
|
|
||||||
}
|
}*/
|
||||||
|
|
||||||
int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH);
|
int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH);
|
||||||
|
|
||||||
if (procId != -1)
|
if (procId != -1)
|
||||||
{
|
{
|
||||||
|
|
||||||
Log.i(TAG,"Found Tor PID=" + procId + " - killing now...");
|
Log.i(TAG,"Found Tor PID=" + procId + " - killing now...");
|
||||||
|
|
||||||
doCommand(SHELL_CMD_KILLALL, procId + "");
|
doCommand(SHELL_CMD_KILLALL, procId + "");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ACTIVITY != null)
|
conn = null;
|
||||||
((TorControlPanel)ACTIVITY).setUIState();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showToast (String msg)
|
private static void logNotice (String msg)
|
||||||
{
|
{
|
||||||
|
|
||||||
Toast toast = Toast.makeText(ACTIVITY, msg, Toast.LENGTH_LONG);
|
Log.i(TAG, msg);
|
||||||
toast.show();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkBinary ()
|
||||||
|
{
|
||||||
|
|
||||||
|
boolean binaryExists = new File(TOR_BINARY_INSTALL_PATH).exists();
|
||||||
|
|
||||||
|
if (!binaryExists)
|
||||||
|
{
|
||||||
|
killTorProcess ();
|
||||||
|
|
||||||
|
TorBinaryInstaller installer = new TorBinaryInstaller();
|
||||||
|
installer.start(true);
|
||||||
|
|
||||||
|
binaryExists = new File(TOR_BINARY_INSTALL_PATH).exists();
|
||||||
|
if (binaryExists)
|
||||||
|
{
|
||||||
|
logNotice("Tor binary installed!");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logNotice("Tor binary install FAILED!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG,"Setting permission on Tor binary");
|
||||||
|
doCommand(SHELL_CMD_CHMOD, CHMOD_EXE_VALUE + ' ' + TOR_BINARY_INSTALL_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
public void initTor ()
|
public void initTor ()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
currentStatus = STATUS_STARTING_UP;
|
||||||
boolean binaryExists = new File(TOR_BINARY_INSTALL_PATH).exists();
|
|
||||||
|
|
||||||
if (!binaryExists)
|
|
||||||
{
|
|
||||||
TorBinaryInstaller installer = new TorBinaryInstaller();
|
|
||||||
installer.start(false);
|
|
||||||
|
|
||||||
binaryExists = new File(TOR_BINARY_INSTALL_PATH).exists();
|
|
||||||
if (binaryExists)
|
|
||||||
{
|
|
||||||
showToast("Tor binary installed!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
showToast("Tor binary install FAILED!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(TAG,"Setting permission on Tor binary");
|
|
||||||
doCommand(SHELL_CMD_CHMOD, CHMOD_EXE_VALUE + ' ' + TOR_BINARY_INSTALL_PATH);
|
|
||||||
|
|
||||||
killTorProcess ();
|
killTorProcess ();
|
||||||
|
|
||||||
|
checkBinary ();
|
||||||
|
|
||||||
doCommand(SHELL_CMD_RM,TOR_LOG_PATH);
|
doCommand(SHELL_CMD_RM,TOR_LOG_PATH);
|
||||||
|
|
||||||
Log.i(TAG,"Starting tor process");
|
Log.i(TAG,"Starting tor process");
|
||||||
|
@ -232,11 +320,13 @@ public class TorService extends Service implements TorConstants
|
||||||
|
|
||||||
//Log.i(TAG,"Tor process id=" + procTor.);
|
//Log.i(TAG,"Tor process id=" + procTor.);
|
||||||
|
|
||||||
showToast("Tor is starting up...");
|
currentStatus = STATUS_STARTING_UP;
|
||||||
|
logNotice("Tor is starting up...");
|
||||||
|
|
||||||
((TorControlPanel)ACTIVITY).setUIState();
|
Thread.sleep(2000);
|
||||||
|
initControlConnection ();
|
||||||
} catch (Exception e) {
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
Log.w(TAG,"unable to start Tor Process",e);
|
Log.w(TAG,"unable to start Tor Process",e);
|
||||||
|
|
||||||
|
@ -311,7 +401,7 @@ public class TorService extends Service implements TorConstants
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Process doCommand(String command, String arg1)
|
public static Process doCommand(String command, String arg1)
|
||||||
{
|
{
|
||||||
|
|
||||||
Runtime r = Runtime.getRuntime();
|
Runtime r = Runtime.getRuntime();
|
||||||
|
@ -335,57 +425,161 @@ public class TorService extends Service implements TorConstants
|
||||||
return child;
|
return child;
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
public static String doCommand(String command, String arg0, String arg1, boolean logOutput) {
|
|
||||||
try {
|
|
||||||
// android.os.Exec is not included in android.jar so we need to use reflection.
|
|
||||||
Class execClass = Class.forName("android.os.Exec");
|
|
||||||
Method createSubprocess = execClass.getMethod("createSubprocess",
|
|
||||||
String.class, String.class, String.class, int[].class);
|
|
||||||
Method waitFor = execClass.getMethod("waitFor", int.class);
|
|
||||||
|
|
||||||
// Executes the command.
|
|
||||||
// NOTE: createSubprocess() is asynchronous.
|
|
||||||
int[] pid = new int[1];
|
|
||||||
FileDescriptor fd = (FileDescriptor)createSubprocess.invoke(
|
|
||||||
null, command, arg0, arg1, pid);
|
|
||||||
|
|
||||||
StringBuffer output = new StringBuffer();
|
|
||||||
|
|
||||||
if (logOutput)
|
|
||||||
{
|
|
||||||
// Reads stdout.
|
|
||||||
// NOTE: You can write to stdin of the command using new FileOutputStream(fd).
|
|
||||||
FileInputStream in = new FileInputStream(fd);
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
|
||||||
try {
|
|
||||||
String line;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
output.append(line);
|
|
||||||
output.append('\n');
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
// It seems IOException is thrown when it reaches EOF.
|
|
||||||
Log.e(TAG, "error reading output file", e);
|
|
||||||
|
|
||||||
}
|
public static String generateHashPassword ()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
PasswordDigest d = PasswordDigest.generateDigest();
|
||||||
|
byte[] s = d.getSecret(); // pass this to authenticate
|
||||||
|
String h = d.getHashedPassword(); // pass this to the Tor on startup.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void modifyConf () throws IOException
|
||||||
|
{
|
||||||
|
// Get one configuration variable.
|
||||||
|
List options = conn.getConf("contact");
|
||||||
|
// Get a set of configuration variables.
|
||||||
|
// List options = conn.getConf(Arrays.asList(new String[]{
|
||||||
|
// "contact", "orport", "socksport"}));
|
||||||
|
// Change a single configuration variable
|
||||||
|
conn.setConf("BandwidthRate", "1 MB");
|
||||||
|
// Change several configuration variables
|
||||||
|
conn.setConf(Arrays.asList(new String[]{
|
||||||
|
"HiddenServiceDir /home/tor/service1",
|
||||||
|
"HiddenServicePort 80",
|
||||||
|
}));
|
||||||
|
// Reset some variables to their defaults
|
||||||
|
conn.resetConf(Arrays.asList(new String[]{
|
||||||
|
"contact", "socksport"
|
||||||
|
}));
|
||||||
|
// Flush the configuration to disk.
|
||||||
|
conn.saveConf();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getTorStatus () throws IOException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
if (conn == null && (currentStatus == STATUS_STARTING_UP || currentStatus == STATUS_ON))
|
||||||
|
{
|
||||||
|
|
||||||
|
initControlConnection ();
|
||||||
|
|
||||||
// Waits for the command to finish.
|
|
||||||
waitFor.invoke(null, pid[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (conn != null)
|
||||||
|
{
|
||||||
|
// get a single value.
|
||||||
|
|
||||||
|
// get several values
|
||||||
|
|
||||||
|
if (currentStatus == STATUS_STARTING_UP)
|
||||||
|
{
|
||||||
|
//Map vals = conn.getInfo(Arrays.asList(new String[]{
|
||||||
|
// "status/bootstrap-phase", "status","version"}));
|
||||||
|
|
||||||
|
String bsPhase = conn.getInfo("status/bootstrap-phase");
|
||||||
// send output to the textbox
|
// Log.i(TAG, "bootstrap-phase: " + bsPhase);
|
||||||
return output.toString();
|
|
||||||
|
if (bsPhase.indexOf("PROGRESS=100")!=-1)
|
||||||
}
|
{
|
||||||
|
currentStatus = STATUS_ON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// String status = conn.getInfo("status/circuit-established");
|
||||||
|
// Log.i(TAG, "status/circuit-established=" + status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.i(TAG, "unable to execute command",e);
|
Log.i(TAG, "Unable to get Tor status from control port");
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
// 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.setEvents(Arrays.asList(new String[]{
|
||||||
|
// "DEBUG", "INFO", "NOTICE", "WARN", "ERR"}));
|
||||||
|
|
||||||
|
Log.i(TAG,"SUCCESS added control port event handler");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|