tor-android/src/org/torproject/android/TorService.java

391 lines
8.4 KiB
Java

/* Copyright (c) 2009, Nathan Freitas, The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
package org.torproject.android;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import net.sourceforge.jsocks.socks.Proxy;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class TorService extends Service implements TorConstants
{
private static TorControlPanel ACTIVITY = null;
private final static String TAG = "Tor";
private static HttpProxy webProxy = null;
private static Process procTor = null;
/** Called when the activity is first created. */
@Override
public void onCreate() {
super.onCreate();
}
public static boolean isRunning ()
{
int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH);
return (procId != -1);
}
/* (non-Javadoc)
* @see android.app.Service#onRebind(android.content.Intent)
*/
@Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
super.onRebind(intent);
Log.i(TAG,"on rebind");
}
/* (non-Javadoc)
* @see android.app.Service#onStart(android.content.Intent, int)
*/
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.i(TAG,"on start");
startService();
}
private void startService ()
{
Log.i(TAG,"Tor thread started");
initTor();
setupWebProxy(true);
}
public void onDestroy ()
{
killTorProcess ();
setupWebProxy(false);
}
public static void setActivity(TorControlPanel activity) {
ACTIVITY = activity;
}
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
{
webProxy.setDoSocks(true);
Log.i(TAG,"Web Proxy already running...");
}
}
else
{
Log.i(TAG,"Turning off Socks/Tor routing on Web Proxy");
if (webProxy != null)
{
showToast("Tor is disabled - browsing is not anonymous!");
webProxy.setDoSocks(false);
}
}
}
private 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 e)
{
e.printStackTrace();
}
int exitStatus = procTor.exitValue();
Log.i(TAG,"Tor exit: " + exitStatus);
procTor = null;
}
int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH);
if (procId != -1)
{
Log.i(TAG,"Found Tor PID=" + procId + " - killing now...");
doCommand(SHELL_CMD_KILLALL, procId + "");
}
if (ACTIVITY != null)
((TorControlPanel)ACTIVITY).setUIState();
}
private void showToast (String msg)
{
Toast toast = Toast.makeText(ACTIVITY, msg, Toast.LENGTH_LONG);
toast.show();
}
public void initTor ()
{
try {
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 ();
doCommand(SHELL_CMD_RM,TOR_LOG_PATH);
Log.i(TAG,"Starting tor process");
procTor = doCommand(TOR_BINARY_INSTALL_PATH, TOR_COMMAND_LINE_ARGS);
//Log.i(TAG,"Tor process id=" + procTor.);
showToast("Tor is starting up...");
((TorControlPanel)ACTIVITY).setUIState();
} catch (Exception e) {
Log.w(TAG,"unable to start Tor Process",e);
e.printStackTrace();
}
}
private static void logStream (InputStream is)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
try {
while ((line = reader.readLine()) != null)
{
Log.i(TAG, line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public static int findProcessId(String command)
{
int procId = -1;
Runtime r = Runtime.getRuntime();
Process procPs = null;
try {
procPs = r.exec(SHELL_CMD_PS);
BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream()));
String line = null;
while ((line = reader.readLine())!=null)
{
if (line.indexOf(command)!=-1)
{
StringTokenizer st = new StringTokenizer(line," ");
st.nextToken(); //proc owner
procId = Integer.parseInt(st.nextToken().trim());
break;
}
}
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
return procId;
}
public Process doCommand(String command, String arg1)
{
Runtime r = Runtime.getRuntime();
Process child = null;
try {
if(child != null) {
child.destroy();
child = null;
}
child = r.exec(command + ' ' + arg1);
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
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);
}
// Waits for the command to finish.
waitFor.invoke(null, pid[0]);
}
// send output to the textbox
return output.toString();
}
catch (Exception e)
{
Log.i(TAG, "unable to execute command",e);
e.printStackTrace();
return null;
}
}*/
}