2011-06-02 22:21:50 +02:00
|
|
|
/* Copyright (c) 2009-2011, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
2010-02-08 21:39:42 +01:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
package org.torproject.android.service;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
2011-04-17 08:04:27 +02:00
|
|
|
import java.io.FileNotFoundException;
|
2010-02-08 21:39:42 +01:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.Socket;
|
2010-03-06 15:56:39 +01:00
|
|
|
import java.util.ArrayList;
|
2010-02-08 21:39:42 +01:00
|
|
|
import java.util.Arrays;
|
2010-03-06 15:56:39 +01:00
|
|
|
import java.util.Iterator;
|
2010-02-08 21:39:42 +01:00
|
|
|
import java.util.List;
|
2010-07-29 19:03:34 +02:00
|
|
|
import java.util.StringTokenizer;
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
import net.freehaven.tor.control.ConfigEntry;
|
|
|
|
import net.freehaven.tor.control.EventHandler;
|
|
|
|
import net.freehaven.tor.control.TorControlConnection;
|
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
import org.torproject.android.AppManager;
|
2010-02-08 21:39:42 +01:00
|
|
|
import org.torproject.android.Orbot;
|
2011-04-17 08:04:27 +02:00
|
|
|
import org.torproject.android.ProcessSettingsAsyncTask;
|
2010-02-08 21:39:42 +01:00
|
|
|
import org.torproject.android.R;
|
2010-07-29 19:03:34 +02:00
|
|
|
import org.torproject.android.TorConstants;
|
2011-04-17 08:04:27 +02:00
|
|
|
import org.torproject.android.Utils;
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
import android.app.AlertDialog;
|
2010-02-08 21:39:42 +01:00
|
|
|
import android.app.Notification;
|
|
|
|
import android.app.NotificationManager;
|
|
|
|
import android.app.PendingIntent;
|
|
|
|
import android.app.Service;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
2010-07-23 13:10:00 +02:00
|
|
|
import android.content.SharedPreferences;
|
2010-09-21 03:26:40 +02:00
|
|
|
import android.content.SharedPreferences.Editor;
|
2010-02-08 21:39:42 +01:00
|
|
|
import android.os.IBinder;
|
2011-04-17 08:04:27 +02:00
|
|
|
import android.os.Looper;
|
2010-02-08 21:39:42 +01:00
|
|
|
import android.os.RemoteCallbackList;
|
|
|
|
import android.os.RemoteException;
|
2010-07-23 13:10:00 +02:00
|
|
|
import android.preference.PreferenceManager;
|
2010-02-08 21:39:42 +01:00
|
|
|
import android.util.Log;
|
|
|
|
|
|
|
|
public class TorService extends Service implements TorServiceConstants, Runnable, EventHandler
|
|
|
|
{
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
public static boolean ENABLE_DEBUG_LOG = false;
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
private static int currentStatus = STATUS_OFF;
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
private TorControlConnection conn = null;
|
2010-09-21 03:26:40 +02:00
|
|
|
private Socket torConnSocket = null;
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
private static TorService _torInstance;
|
|
|
|
|
|
|
|
private static final int NOTIFY_ID = 1;
|
|
|
|
|
2010-07-20 00:34:15 +02:00
|
|
|
private static final int MAX_START_TRIES = 3;
|
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
private ArrayList<String> configBuffer = null;
|
2011-04-15 18:37:33 +02:00
|
|
|
private ArrayList<String> resetBuffer = null;
|
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
// private String appHome;
|
|
|
|
private File appBinHome;
|
|
|
|
private File appDataHome;
|
2011-04-15 18:37:33 +02:00
|
|
|
|
|
|
|
private String torBinaryPath;
|
|
|
|
private String privoxyPath;
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
/** Called when the activity is first created. */
|
|
|
|
public void onCreate() {
|
|
|
|
super.onCreate();
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
logMessage("serviced created");
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
public static void logMessage(String msg)
|
|
|
|
{
|
|
|
|
if (ENABLE_DEBUG_LOG)
|
|
|
|
Log.d(TAG,msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void logException(String msg, Exception e)
|
|
|
|
{
|
|
|
|
if (ENABLE_DEBUG_LOG)
|
|
|
|
Log.e(TAG,msg,e);
|
|
|
|
}
|
|
|
|
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
private boolean findExistingProc ()
|
|
|
|
{
|
2010-07-24 05:24:30 +02:00
|
|
|
int procId = TorServiceUtils.findProcessId(torBinaryPath);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
if (procId != -1)
|
|
|
|
{
|
2010-09-10 00:09:01 +02:00
|
|
|
logNotice("Found existing Tor process");
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackLogMessage ("found existing Tor process...");
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
try {
|
|
|
|
currentStatus = STATUS_CONNECTING;
|
|
|
|
|
|
|
|
initControlConnection();
|
|
|
|
|
|
|
|
currentStatus = STATUS_ON;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} catch (RuntimeException e) {
|
2010-09-09 22:39:52 +02:00
|
|
|
Log.d(TAG,"Unable to connect to existing Tor instance,",e);
|
2010-02-28 00:56:46 +01:00
|
|
|
currentStatus = STATUS_OFF;
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
} catch (Exception e) {
|
2010-09-09 22:39:52 +02:00
|
|
|
Log.d(TAG,"Unable to connect to existing Tor instance,",e);
|
2010-02-28 00:56:46 +01:00
|
|
|
currentStatus = STATUS_OFF;
|
2011-04-17 08:04:27 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see android.app.Service#onLowMemory()
|
|
|
|
*/
|
|
|
|
public void onLowMemory() {
|
|
|
|
super.onLowMemory();
|
|
|
|
|
2010-09-10 00:09:01 +02:00
|
|
|
logNotice( "Low Memory Warning!");
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see android.app.Service#onUnbind(android.content.Intent)
|
|
|
|
*/
|
|
|
|
public boolean onUnbind(Intent intent) {
|
|
|
|
|
2010-09-10 00:09:01 +02:00
|
|
|
// logNotice( "onUnbind Called: " + intent.getAction());
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
|
2010-07-20 00:34:15 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
return super.onUnbind(intent);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getTorStatus ()
|
|
|
|
{
|
|
|
|
|
|
|
|
return currentStatus;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
private void showToolbarNotification (String notifyMsg, int notifyId, int icon)
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
2010-09-09 22:39:52 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
|
|
|
|
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
CharSequence tickerText = notifyMsg;
|
2010-02-08 21:39:42 +01:00
|
|
|
long when = System.currentTimeMillis();
|
|
|
|
|
|
|
|
Notification notification = new Notification(icon, tickerText, when);
|
|
|
|
|
|
|
|
Context context = getApplicationContext();
|
2010-07-23 13:10:00 +02:00
|
|
|
CharSequence contentTitle = getString(R.string.app_name);
|
2010-02-08 21:39:42 +01:00
|
|
|
CharSequence contentText = notifyMsg;
|
|
|
|
|
|
|
|
Intent notificationIntent = new Intent(this, Orbot.class);
|
|
|
|
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
|
|
|
|
|
|
|
|
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
|
|
|
|
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
mNotificationManager.notify(notifyId, notification);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see android.app.Service#onRebind(android.content.Intent)
|
|
|
|
*/
|
|
|
|
public void onRebind(Intent intent) {
|
|
|
|
super.onRebind(intent);
|
|
|
|
|
2010-09-09 22:39:52 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see android.app.Service#onStart(android.content.Intent, int)
|
|
|
|
*/
|
|
|
|
public void onStart(Intent intent, int startId) {
|
|
|
|
super.onStart(intent, startId);
|
2010-09-17 23:32:21 +02:00
|
|
|
|
2010-09-23 21:47:25 +02:00
|
|
|
_torInstance = this;
|
|
|
|
|
|
|
|
Log.i(TAG, "service started: " + intent.getAction());
|
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
try {
|
|
|
|
checkTorBinaries ();
|
|
|
|
} catch (Exception e) {
|
2010-09-23 21:47:25 +02:00
|
|
|
|
|
|
|
logNotice("unable to find tor binaries: " + e.getMessage());
|
2011-05-03 07:56:40 +02:00
|
|
|
showToolbarNotification(e.getMessage(), NOTIFY_ID, R.drawable.tornotificationerr);
|
2010-09-23 21:47:25 +02:00
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
Log.e(TAG, "error checking tor binaries", e);
|
|
|
|
}
|
2010-09-23 21:47:25 +02:00
|
|
|
|
|
|
|
if (intent.getAction()!=null && intent.getAction().equals("onboot"))
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
|
|
|
|
boolean startOnBoot = prefs.getBoolean("pref_start_boot",true);
|
|
|
|
|
|
|
|
if (startOnBoot)
|
|
|
|
{
|
|
|
|
setTorProfile(PROFILE_ON);
|
|
|
|
}
|
|
|
|
}
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void run ()
|
|
|
|
{
|
2010-09-23 21:47:25 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
boolean isRunning = _torInstance.findExistingProc ();
|
|
|
|
|
|
|
|
if (!isRunning)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
initTor();
|
2011-04-17 08:04:27 +02:00
|
|
|
isRunning = true;
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-02-28 00:56:46 +01:00
|
|
|
currentStatus = STATUS_OFF;
|
2011-05-03 07:56:40 +02:00
|
|
|
this.showToolbarNotification(getString(R.string.status_disabled), NOTIFY_ID, R.drawable.tornotificationerr);
|
2010-09-09 22:39:52 +02:00
|
|
|
Log.d(TAG,"Unable to start Tor: " + e.getMessage(),e);
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void onDestroy ()
|
|
|
|
{
|
|
|
|
super.onDestroy();
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
Log.d(TAG,"onDestroy called");
|
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
// Unregister all callbacks.
|
|
|
|
mCallbacks.kill();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private void stopTor ()
|
|
|
|
{
|
2010-02-28 00:56:46 +01:00
|
|
|
currentStatus = STATUS_OFF;
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-07-28 06:43:58 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
killTorProcess ();
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
currentStatus = STATUS_OFF;
|
2010-09-23 21:47:25 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
showToolbarNotification (getString(R.string.status_disabled),NOTIFY_ID,R.drawable.tornotificationoff);
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage(getString(R.string.status_disabled));
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-07-28 06:43:58 +02:00
|
|
|
setupTransProxy(false);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-09-09 22:39:52 +02:00
|
|
|
Log.d(TAG, "An error occured stopping Tor",e);
|
2010-07-28 06:43:58 +02:00
|
|
|
logNotice("An error occured stopping Tor: " + e.getMessage());
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage("Something bad happened. Check the log");
|
2010-07-28 06:43:58 +02:00
|
|
|
|
|
|
|
}
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
/*
|
2010-02-08 21:39:42 +01:00
|
|
|
public void reloadConfig ()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (conn == null)
|
|
|
|
{
|
|
|
|
initControlConnection ();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conn != null)
|
|
|
|
{
|
|
|
|
conn.signal("RELOAD");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-09-09 22:39:52 +02:00
|
|
|
Log.d(TAG,"Unable to reload configuration",e);
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
2011-04-17 08:04:27 +02:00
|
|
|
}*/
|
|
|
|
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
private void getHiddenServiceHostname ()
|
|
|
|
{
|
|
|
|
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
|
|
|
|
boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
|
|
|
|
|
|
|
|
if (enableHiddenServices)
|
|
|
|
{
|
|
|
|
File file = new File(appDataHome, "hostname");
|
|
|
|
|
|
|
|
if (file.exists())
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
String onionHostname = Utils.readString(new FileInputStream(file));
|
2011-05-03 07:56:40 +02:00
|
|
|
showToolbarNotification("hidden service on: " + onionHostname, NOTIFY_ID, R.drawable.tornotification);
|
2011-04-17 08:04:27 +02:00
|
|
|
Editor pEdit = prefs.edit();
|
|
|
|
pEdit.putString("pref_hs_hostname",onionHostname);
|
|
|
|
pEdit.commit();
|
|
|
|
|
|
|
|
|
|
|
|
} catch (FileNotFoundException e) {
|
|
|
|
logException("unable to read onion hostname file",e);
|
2011-05-03 07:56:40 +02:00
|
|
|
showToolbarNotification("unable to read hidden service name", NOTIFY_ID, R.drawable.tornotificationerr);
|
2011-04-17 08:04:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-05-03 07:56:40 +02:00
|
|
|
showToolbarNotification("unable to read hidden service name", NOTIFY_ID, R.drawable.tornotificationerr);
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-07-28 06:43:58 +02:00
|
|
|
private void killTorProcess () throws Exception
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
2011-02-09 22:11:53 +01:00
|
|
|
//android.os.Debug.waitForDebugger();
|
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
StringBuilder log = new StringBuilder();
|
|
|
|
int procId = -1;
|
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
if (conn != null)
|
|
|
|
{
|
2010-09-21 03:26:40 +02:00
|
|
|
logNotice("Using control port to shutdown Tor");
|
|
|
|
|
2011-02-09 22:11:53 +01:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
try {
|
2010-07-23 13:10:00 +02:00
|
|
|
logNotice("sending SHUTDOWN signal to Tor process");
|
2010-09-23 21:47:25 +02:00
|
|
|
conn.shutdownTor("SHUTDOWN");
|
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
} catch (Exception e) {
|
2010-09-09 22:39:52 +02:00
|
|
|
Log.d(TAG,"error shutting down Tor via connection",e);
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
2010-09-21 03:26:40 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
conn = null;
|
|
|
|
}
|
2010-09-21 03:26:40 +02:00
|
|
|
|
2011-02-09 22:11:53 +01:00
|
|
|
while ((procId = TorServiceUtils.findProcessId(torBinaryPath)) != -1)
|
|
|
|
{
|
|
|
|
|
|
|
|
logNotice("Found Tor PID=" + procId + " - killing now...");
|
|
|
|
|
|
|
|
String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" };
|
|
|
|
TorServiceUtils.doShellCommand(cmd,log, false, false);
|
2011-04-15 18:37:33 +02:00
|
|
|
try { Thread.sleep(500); }
|
|
|
|
catch (Exception e){}
|
2011-02-09 22:11:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
while ((procId = TorServiceUtils.findProcessId(privoxyPath)) != -1)
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
|
|
|
|
2010-09-10 00:09:01 +02:00
|
|
|
logNotice("Found Privoxy PID=" + procId + " - killing now...");
|
2010-03-06 15:56:39 +01:00
|
|
|
String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" };
|
|
|
|
|
|
|
|
TorServiceUtils.doShellCommand(cmd,log, false, false);
|
2011-04-15 18:37:33 +02:00
|
|
|
try { Thread.sleep(500); }
|
|
|
|
catch (Exception e){}
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private void logNotice (String msg)
|
|
|
|
{
|
2010-09-10 00:09:01 +02:00
|
|
|
if (msg != null && msg.trim().length() > 0)
|
|
|
|
{
|
2011-04-17 08:04:27 +02:00
|
|
|
if (ENABLE_DEBUG_LOG)
|
2010-09-10 00:09:01 +02:00
|
|
|
Log.d(TAG, msg);
|
|
|
|
|
|
|
|
sendCallbackLogMessage(msg);
|
|
|
|
}
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
2010-09-23 21:47:25 +02:00
|
|
|
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2010-07-28 06:43:58 +02:00
|
|
|
private boolean checkTorBinaries () throws Exception
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
2011-04-15 18:37:33 +02:00
|
|
|
//check and install iptables
|
2011-07-25 16:51:34 +02:00
|
|
|
IptablesManager.assertBinaries(this, true);
|
2010-07-24 05:24:30 +02:00
|
|
|
|
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
appBinHome = getDir("bin",0);
|
|
|
|
appDataHome = getCacheDir();
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
// logNotice( "appHome=" + appHome);
|
|
|
|
|
|
|
|
File fileTor = new File(appBinHome, TOR_BINARY_ASSET_KEY);
|
|
|
|
File filePrivoxy = new File(appBinHome, PRIVOXY_ASSET_KEY);
|
|
|
|
|
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
logNotice( "checking Tor binaries");
|
2010-08-14 07:08:55 +02:00
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
if (!(fileTor.exists() && filePrivoxy.exists()))
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
|
|
|
killTorProcess ();
|
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
TorBinaryInstaller installer = new TorBinaryInstaller(this, appBinHome);
|
|
|
|
boolean success = installer.installFromRaw();
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
if (success)
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
2010-07-23 13:10:00 +02:00
|
|
|
logNotice(getString(R.string.status_install_success));
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
showToolbarNotification(getString(R.string.status_install_success), NOTIFY_ID, R.drawable.tornotification);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
|
|
|
|
torBinaryPath = fileTor.getAbsolutePath();
|
|
|
|
privoxyPath = filePrivoxy.getAbsolutePath();
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-07-23 13:10:00 +02:00
|
|
|
|
|
|
|
logNotice(getString(R.string.status_install_fail));
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage(getString(R.string.status_install_fail));
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-07-28 06:43:58 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
logNotice("Found Tor binary: " + torBinaryPath);
|
2010-08-14 07:08:55 +02:00
|
|
|
logNotice("Found Privoxy binary: " + privoxyPath);
|
2010-07-31 17:43:56 +02:00
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
|
|
|
|
torBinaryPath = fileTor.getAbsolutePath();
|
|
|
|
privoxyPath = filePrivoxy.getAbsolutePath();
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
2010-09-21 03:26:40 +02:00
|
|
|
|
2010-03-06 15:56:39 +01:00
|
|
|
StringBuilder log = new StringBuilder ();
|
|
|
|
|
2010-07-28 06:43:58 +02:00
|
|
|
logNotice("(re)Setting permission on Tor binary");
|
2010-07-24 05:24:30 +02:00
|
|
|
String[] cmd1 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + torBinaryPath};
|
2010-03-06 15:56:39 +01:00
|
|
|
TorServiceUtils.doShellCommand(cmd1, log, false, true);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-07-28 06:43:58 +02:00
|
|
|
logNotice("(re)Setting permission on Privoxy binary");
|
2010-07-24 05:24:30 +02:00
|
|
|
String[] cmd2 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + privoxyPath};
|
2010-03-06 15:56:39 +01:00
|
|
|
TorServiceUtils.doShellCommand(cmd2, log, false, true);
|
2010-09-21 03:26:40 +02:00
|
|
|
|
2010-07-31 17:43:56 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void initTor () throws Exception
|
|
|
|
{
|
2010-07-24 05:24:30 +02:00
|
|
|
|
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
currentStatus = STATUS_CONNECTING;
|
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
logNotice(getString(R.string.status_starting_up));
|
|
|
|
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage(getString(R.string.status_starting_up));
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
killTorProcess ();
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
try {
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
|
|
|
|
setupTransProxy(true);
|
2011-04-17 08:04:27 +02:00
|
|
|
runTorShellCmd();
|
|
|
|
runPrivoxyShellCmd();
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
logException("Unable to start Tor: " + e.getMessage(),e);
|
|
|
|
sendCallbackStatusMessage("Unable to start Tor: " + e.getMessage());
|
|
|
|
|
|
|
|
}
|
2010-05-08 06:21:45 +02:00
|
|
|
|
2010-03-06 15:56:39 +01:00
|
|
|
}
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
/*
|
|
|
|
* activate means whether to apply the users preferences
|
|
|
|
* or clear them out
|
|
|
|
*
|
|
|
|
* the idea is that if Tor is off then transproxy is off
|
|
|
|
*/
|
2011-04-17 08:04:27 +02:00
|
|
|
private boolean setupTransProxy (boolean activate) throws Exception
|
|
|
|
{
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
boolean hasRoot;
|
|
|
|
|
|
|
|
if (prefs.contains("has_root"))
|
|
|
|
{
|
|
|
|
hasRoot = prefs.getBoolean("has_root",false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hasRoot = TorServiceUtils.checkRootAccess();
|
|
|
|
Editor pEdit = prefs.edit();
|
|
|
|
pEdit.putBoolean("has_root",hasRoot);
|
|
|
|
pEdit.commit();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hasRoot)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (activate)
|
|
|
|
{
|
|
|
|
|
|
|
|
boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false);
|
|
|
|
boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false);
|
|
|
|
boolean transProxyPortFallback = prefs.getBoolean("pref_transparent_port_fallback", false);
|
2011-06-02 22:21:50 +02:00
|
|
|
boolean transProxyTethering = prefs.getBoolean("pref_transparent_tethering", false);
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
TorService.logMessage ("Transparent Proxying: " + enableTransparentProxy);
|
|
|
|
|
|
|
|
String portProxyList = prefs.getString("pref_port_list", "");
|
|
|
|
|
|
|
|
if (enableTransparentProxy)
|
|
|
|
{
|
2011-05-03 07:56:40 +02:00
|
|
|
//TODO: Find a nice place for the next (commented) line
|
|
|
|
//TorTransProxy.setDNSProxying();
|
|
|
|
|
|
|
|
int code = 0; // Default state is "okay"
|
|
|
|
|
|
|
|
if(transProxyPortFallback)
|
|
|
|
{
|
|
|
|
showAlert("Status", "Setting up port-based transparent proxying...");
|
|
|
|
StringTokenizer st = new StringTokenizer(portProxyList, ",");
|
|
|
|
int status = code;
|
|
|
|
while (st.hasMoreTokens())
|
|
|
|
{
|
|
|
|
status = TorTransProxy.setTransparentProxyingByPort(this, Integer.parseInt(st.nextToken()));
|
|
|
|
if(status != 0)
|
|
|
|
code = status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(transProxyAll)
|
|
|
|
{
|
|
|
|
showAlert("Status", "Setting up full transparent proxying...");
|
|
|
|
code = TorTransProxy.setTransparentProxyingAll(this);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
showAlert("Status", "Setting up app-based transparent proxying...");
|
|
|
|
code = TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this));
|
|
|
|
}
|
2011-06-02 22:21:50 +02:00
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
}
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
TorService.logMessage ("TorTransProxy resp code: " + code);
|
|
|
|
|
|
|
|
if (code == 0)
|
|
|
|
{
|
|
|
|
showAlert("Status", "Transparent proxying ENABLED");
|
2011-06-02 22:21:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (transProxyTethering)
|
|
|
|
{
|
|
|
|
showAlert("Status", "TransProxy enabled for Tethering!");
|
|
|
|
|
|
|
|
TorTransProxy.enableTetheringRules(this);
|
|
|
|
}
|
2011-04-17 08:04:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
showAlert("Status", "WARNING: error starting transparent proxying!");
|
|
|
|
}
|
2011-06-02 22:21:50 +02:00
|
|
|
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TorTransProxy.purgeIptables(this);
|
2011-05-03 08:41:34 +02:00
|
|
|
showAlert("Status", "Transparent proxying: DISABLED");
|
2011-04-17 08:04:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TorTransProxy.purgeIptables(this);
|
2011-05-03 08:41:34 +02:00
|
|
|
showAlert("Status", "Transparent proxying: DISABLED");
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-03-06 15:56:39 +01:00
|
|
|
private void runTorShellCmd() throws Exception
|
|
|
|
{
|
2010-09-09 22:39:52 +02:00
|
|
|
|
2010-03-06 15:56:39 +01:00
|
|
|
StringBuilder log = new StringBuilder();
|
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
String torrcPath = new File(appBinHome, TORRC_ASSET_KEY).getAbsolutePath();
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
String[] torCmd = {torBinaryPath + " DataDirectory " + appDataHome.getAbsolutePath() + " -f " + torrcPath + " || exit\n"};
|
2010-09-09 22:39:52 +02:00
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
boolean runAsRootFalse = false;
|
|
|
|
boolean waitForProcess = false;
|
|
|
|
|
|
|
|
int procId = -1;
|
2010-07-20 00:34:15 +02:00
|
|
|
int attempts = 0;
|
2010-09-21 03:26:40 +02:00
|
|
|
|
|
|
|
int torRetryWaitTimeMS = 5000;
|
2010-07-20 00:34:15 +02:00
|
|
|
|
|
|
|
while (procId == -1 && attempts < MAX_START_TRIES)
|
2010-03-06 15:56:39 +01:00
|
|
|
{
|
|
|
|
log = new StringBuilder();
|
2010-07-20 00:34:15 +02:00
|
|
|
|
|
|
|
logNotice(torCmd[0]);
|
2010-09-21 03:26:40 +02:00
|
|
|
sendCallbackStatusMessage(getString(R.string.status_starting_up));
|
|
|
|
|
|
|
|
TorServiceUtils.doShellCommand(torCmd, log, runAsRootFalse, waitForProcess);
|
|
|
|
|
|
|
|
Thread.sleep(torRetryWaitTimeMS);
|
2010-07-20 00:34:15 +02:00
|
|
|
|
2010-07-24 05:24:30 +02:00
|
|
|
procId = TorServiceUtils.findProcessId(torBinaryPath);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
logNotice("got tor proc id: " + procId);
|
|
|
|
|
2010-03-06 15:56:39 +01:00
|
|
|
if (procId == -1)
|
|
|
|
{
|
2010-09-21 03:26:40 +02:00
|
|
|
|
|
|
|
sendCallbackStatusMessage("Couldn't start Tor process.\nretrying..." + log.toString());
|
|
|
|
Thread.sleep(torRetryWaitTimeMS);
|
2010-07-20 00:34:15 +02:00
|
|
|
attempts++;
|
2010-03-06 15:56:39 +01:00
|
|
|
}
|
2010-07-20 00:34:15 +02:00
|
|
|
|
|
|
|
logNotice(log.toString());
|
2010-03-06 15:56:39 +01:00
|
|
|
}
|
|
|
|
|
2010-07-20 00:34:15 +02:00
|
|
|
if (procId == -1)
|
|
|
|
{
|
|
|
|
throw new Exception ("Unable to start Tor");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-03-06 15:56:39 +01:00
|
|
|
|
2010-07-20 00:34:15 +02:00
|
|
|
logNotice("Tor process id=" + procId);
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
showToolbarNotification(getString(R.string.status_starting_up), NOTIFY_ID, R.drawable.tornotification);
|
2010-07-20 00:34:15 +02:00
|
|
|
|
|
|
|
initControlConnection ();
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
applyPreferences();
|
2010-07-20 00:34:15 +02:00
|
|
|
}
|
2010-03-06 15:56:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private void runPrivoxyShellCmd () throws Exception
|
|
|
|
{
|
2010-07-28 06:43:58 +02:00
|
|
|
|
2010-09-10 00:09:01 +02:00
|
|
|
logNotice( "Starting privoxy process");
|
2010-07-28 06:43:58 +02:00
|
|
|
|
2010-07-24 05:24:30 +02:00
|
|
|
int privoxyProcId = TorServiceUtils.findProcessId(privoxyPath);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-07-20 00:34:15 +02:00
|
|
|
StringBuilder log = null;
|
2010-03-06 15:56:39 +01:00
|
|
|
|
2010-07-20 00:34:15 +02:00
|
|
|
int attempts = 0;
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
if (privoxyProcId == -1)
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
2010-07-20 00:34:15 +02:00
|
|
|
log = new StringBuilder();
|
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
String privoxyConfigPath = new File(appBinHome, PRIVOXYCONFIG_ASSET_KEY).getAbsolutePath();
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2010-03-06 15:56:39 +01:00
|
|
|
String[] cmds =
|
2010-07-28 06:43:58 +02:00
|
|
|
{ privoxyPath + " " + privoxyConfigPath + " &" };
|
2010-07-20 00:34:15 +02:00
|
|
|
|
2010-07-28 06:43:58 +02:00
|
|
|
logNotice (cmds[0]);
|
2010-07-20 00:34:15 +02:00
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
boolean runAsRoot = false;
|
|
|
|
boolean waitFor = false;
|
|
|
|
|
|
|
|
TorServiceUtils.doShellCommand(cmds, log, runAsRoot, waitFor);
|
2010-07-20 00:34:15 +02:00
|
|
|
|
|
|
|
//wait one second to make sure it has started up
|
2010-03-06 16:02:04 +01:00
|
|
|
Thread.sleep(1000);
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
while ((privoxyProcId = TorServiceUtils.findProcessId(privoxyPath)) == -1 && attempts < MAX_START_TRIES)
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
2011-05-03 07:56:40 +02:00
|
|
|
logNotice("Couldn't find Privoxy process... retrying...\n" + log);
|
2010-02-08 21:39:42 +01:00
|
|
|
Thread.sleep(3000);
|
2010-07-20 00:34:15 +02:00
|
|
|
attempts++;
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
2010-07-20 00:34:15 +02:00
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
|
2010-07-20 00:34:15 +02:00
|
|
|
logNotice(log.toString());
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackLogMessage("Privoxy is running on port: " + PORT_HTTP);
|
2010-03-06 16:02:04 +01:00
|
|
|
|
2010-07-20 00:34:15 +02:00
|
|
|
logNotice("Privoxy process id=" + privoxyProcId);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
/*
|
2010-02-08 21:39:42 +01:00
|
|
|
public String generateHashPassword ()
|
|
|
|
{
|
2010-07-23 13:10:00 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
PasswordDigest d = PasswordDigest.generateDigest();
|
|
|
|
byte[] s = d.getSecret(); // pass this to authenticate
|
|
|
|
String h = d.getHashedPassword(); // pass this to the Tor on startup.
|
2010-07-23 13:10:00 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
return null;
|
2010-07-23 13:10:00 +02:00
|
|
|
}*/
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
public void initControlConnection () throws Exception, RuntimeException
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2010-09-10 00:09:01 +02:00
|
|
|
logNotice( "Connecting to control port: " + TOR_CONTROL_PORT);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
String baseMessage = getString(R.string.tor_process_connecting);
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage(baseMessage);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
torConnSocket = new Socket(IP_LOCALHOST, TOR_CONTROL_PORT);
|
|
|
|
conn = TorControlConnection.getConnection(torConnSocket);
|
2011-04-15 18:37:33 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
// conn.authenticate(new byte[0]); // See section 3.2
|
|
|
|
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage(getString(R.string.tor_process_connecting_step2));
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-09-10 00:09:01 +02:00
|
|
|
logNotice( "SUCCESS connected to control port");
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2011-07-25 22:12:41 +02:00
|
|
|
String torAuthCookie = new File(appDataHome, TOR_CONTROL_COOKIE).getAbsolutePath();
|
2010-07-24 05:24:30 +02:00
|
|
|
|
|
|
|
File fileCookie = new File(torAuthCookie);
|
2010-07-29 19:03:34 +02:00
|
|
|
|
2011-04-15 18:37:33 +02:00
|
|
|
if (fileCookie.exists())
|
|
|
|
{
|
|
|
|
byte[] cookie = new byte[(int)fileCookie.length()];
|
|
|
|
new FileInputStream(new File(torAuthCookie)).read(cookie);
|
|
|
|
conn.authenticate(cookie);
|
|
|
|
|
|
|
|
logNotice( "SUCCESS authenticated to control port");
|
|
|
|
|
|
|
|
sendCallbackStatusMessage(getString(R.string.tor_process_connecting_step2) + getString(R.string.tor_process_connecting_step3));
|
|
|
|
|
|
|
|
addEventHandler();
|
|
|
|
|
|
|
|
}
|
2010-07-23 13:10:00 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
break; //don't need to retry
|
|
|
|
}
|
|
|
|
catch (Exception ce)
|
|
|
|
{
|
|
|
|
conn = null;
|
2010-09-09 22:39:52 +02:00
|
|
|
Log.d(TAG,"Attempt: Error connecting to control port: " + ce.getLocalizedMessage(),ce);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage(getString(R.string.tor_process_connecting_step4));
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
Thread.sleep(1000);
|
2011-04-15 18:37:33 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
private void getTorStatus () throws IOException
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
|
|
|
|
if (conn != null)
|
|
|
|
{
|
|
|
|
// get a single value.
|
|
|
|
|
|
|
|
// get several values
|
|
|
|
|
|
|
|
if (currentStatus == STATUS_CONNECTING)
|
|
|
|
{
|
|
|
|
//Map vals = conn.getInfo(Arrays.asList(new String[]{
|
|
|
|
// "status/bootstrap-phase", "status","version"}));
|
|
|
|
|
|
|
|
String bsPhase = conn.getInfo("status/bootstrap-phase");
|
2010-09-09 22:39:52 +02:00
|
|
|
Log.d(TAG, "bootstrap-phase: " + bsPhase);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// String status = conn.getInfo("status/circuit-established");
|
2010-09-09 22:39:52 +02:00
|
|
|
// Log.d(TAG, "status/circuit-established=" + status);
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-09-09 22:39:52 +02:00
|
|
|
Log.d(TAG, "Unable to get Tor status from control port");
|
2010-02-08 21:39:42 +01:00
|
|
|
currentStatus = STATUS_UNAVAILABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
// ...
|
2010-09-10 00:09:01 +02:00
|
|
|
logNotice( "adding control port event handler");
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
conn.setEventHandler(this);
|
|
|
|
|
|
|
|
conn.setEvents(Arrays.asList(new String[]{
|
2010-07-23 13:10:00 +02:00
|
|
|
"ORCONN", "CIRC", "NOTICE", "WARN", "ERR"}));
|
2010-02-08 21:39:42 +01:00
|
|
|
// conn.setEvents(Arrays.asList(new String[]{
|
|
|
|
// "DEBUG", "INFO", "NOTICE", "WARN", "ERR"}));
|
|
|
|
|
2010-09-10 00:09:01 +02:00
|
|
|
logNotice( "SUCCESS added control port event handler");
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the port number that the HTTP proxy is running on
|
|
|
|
*/
|
|
|
|
public int getHTTPPort() throws RemoteException {
|
|
|
|
return TorServiceConstants.PORT_HTTP;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the port number that the SOCKS proxy is running on
|
|
|
|
*/
|
|
|
|
public int getSOCKSPort() throws RemoteException {
|
|
|
|
return TorServiceConstants.PORT_SOCKS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public int getProfile() throws RemoteException {
|
|
|
|
//return mProfile;
|
|
|
|
return PROFILE_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setTorProfile(int profile) {
|
2010-09-23 21:47:25 +02:00
|
|
|
logNotice("Tor profile set to " + profile);
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
if (profile == PROFILE_ON)
|
|
|
|
{
|
|
|
|
currentStatus = STATUS_CONNECTING;
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage ("starting...");
|
2010-02-08 21:39:42 +01:00
|
|
|
|
2010-09-23 21:47:25 +02:00
|
|
|
Thread thread = new Thread(this);
|
|
|
|
thread.start();
|
2011-04-17 08:04:27 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
2011-04-17 08:04:27 +02:00
|
|
|
else if (profile == PROFILE_OFF)
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
2010-02-28 00:56:46 +01:00
|
|
|
currentStatus = STATUS_OFF;
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage ("shutting down...");
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
_torInstance.stopTor();
|
|
|
|
|
2010-09-23 21:47:25 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void message(String severity, String msg) {
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
|
2010-09-10 00:09:01 +02:00
|
|
|
logNotice( "[Tor Control Port] " + severity + ": " + msg);
|
2010-07-20 00:34:15 +02:00
|
|
|
|
|
|
|
if (msg.indexOf(TOR_CONTROL_PORT_MSG_BOOTSTRAP_DONE)!=-1)
|
|
|
|
{
|
|
|
|
currentStatus = STATUS_ON;
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
getHiddenServiceHostname ();
|
|
|
|
|
2010-07-20 00:34:15 +02:00
|
|
|
}
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
showToolbarNotification (getString(R.string.status_activated),NOTIFY_ID,R.drawable.tornotificationon);
|
|
|
|
|
2010-09-09 22:39:52 +02:00
|
|
|
sendCallbackStatusMessage (msg);
|
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
private void showAlert(String title, String msg)
|
|
|
|
{
|
2011-04-17 08:04:27 +02:00
|
|
|
/*
|
2010-07-23 13:10:00 +02:00
|
|
|
new AlertDialog.Builder(this)
|
|
|
|
.setTitle(title)
|
|
|
|
.setMessage(msg)
|
|
|
|
.setPositiveButton(android.R.string.ok, null)
|
|
|
|
.show();
|
2011-04-17 08:04:27 +02:00
|
|
|
*/
|
2011-05-03 07:56:40 +02:00
|
|
|
showToolbarNotification(msg, NOTIFY_ID, R.drawable.tornotification);
|
2010-07-23 13:10:00 +02:00
|
|
|
}
|
2011-04-17 08:04:27 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
public void newDescriptors(List<String> orList) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void orConnStatus(String status, String orName) {
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
if (ENABLE_DEBUG_LOG)
|
2010-09-10 00:09:01 +02:00
|
|
|
{
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("orConnStatus (");
|
|
|
|
sb.append((orName) );
|
|
|
|
sb.append("): ");
|
|
|
|
sb.append(status);
|
|
|
|
|
|
|
|
logNotice(sb.toString());
|
|
|
|
}
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void streamStatus(String status, String streamID, String target) {
|
2010-07-20 00:34:15 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
if (ENABLE_DEBUG_LOG)
|
2010-09-10 00:09:01 +02:00
|
|
|
{
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("StreamStatus (");
|
|
|
|
sb.append((streamID));
|
|
|
|
sb.append("): ");
|
|
|
|
sb.append(status);
|
|
|
|
|
|
|
|
logNotice(sb.toString());
|
|
|
|
}
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void unrecognized(String type, String msg) {
|
2010-07-20 00:34:15 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
if (ENABLE_DEBUG_LOG)
|
2010-09-10 00:09:01 +02:00
|
|
|
{
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("Message (");
|
|
|
|
sb.append(type);
|
|
|
|
sb.append("): ");
|
|
|
|
sb.append(msg);
|
|
|
|
|
|
|
|
logNotice(sb.toString());
|
|
|
|
}
|
2010-02-08 21:39:42 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public void bandwidthUsed(long read, long written) {
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
if (ENABLE_DEBUG_LOG)
|
|
|
|
{
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("Bandwidth used: ");
|
|
|
|
sb.append(read/1000);
|
|
|
|
sb.append("kb read / ");
|
|
|
|
sb.append(written/1000);
|
|
|
|
sb.append("kb written");
|
|
|
|
|
|
|
|
logNotice(sb.toString());
|
|
|
|
}
|
2010-07-20 00:34:15 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void circuitStatus(String status, String circID, String path) {
|
2010-07-20 00:34:15 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
if (ENABLE_DEBUG_LOG)
|
2010-09-10 00:09:01 +02:00
|
|
|
{
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("Circuit (");
|
|
|
|
sb.append((circID));
|
|
|
|
sb.append("): ");
|
|
|
|
sb.append(status);
|
|
|
|
sb.append("; ");
|
|
|
|
sb.append(path);
|
|
|
|
|
|
|
|
logNotice(sb.toString());
|
|
|
|
}
|
2010-07-20 00:34:15 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
public IBinder onBind(Intent intent) {
|
|
|
|
// Select the interface to return. If your service only implements
|
|
|
|
// a single interface, you can just return it here without checking
|
|
|
|
// the Intent.
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2010-09-23 21:47:25 +02:00
|
|
|
_torInstance = this;
|
2010-09-21 03:26:40 +02:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2010-09-23 21:47:25 +02:00
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
checkTorBinaries();
|
|
|
|
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-09-23 21:47:25 +02:00
|
|
|
logNotice("unable to find tor binaries: " + e.getMessage());
|
2011-05-03 07:56:40 +02:00
|
|
|
showToolbarNotification(e.getMessage(), NOTIFY_ID, R.drawable.tornotificationerr);
|
2010-09-23 21:47:25 +02:00
|
|
|
|
2010-09-21 03:26:40 +02:00
|
|
|
Log.d(TAG,"Unable to check for Tor binaries",e);
|
|
|
|
return null;
|
|
|
|
}
|
2010-07-24 05:24:30 +02:00
|
|
|
|
2010-09-23 21:47:25 +02:00
|
|
|
findExistingProc ();
|
|
|
|
|
2010-07-24 05:24:30 +02:00
|
|
|
if (ITorService.class.getName().equals(intent.getAction())) {
|
2010-02-08 21:39:42 +01:00
|
|
|
return mBinder;
|
|
|
|
}
|
2010-07-24 05:24:30 +02:00
|
|
|
|
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is a list of callbacks that have been registered with the
|
|
|
|
* service. Note that this is package scoped (instead of private) so
|
|
|
|
* that it can be accessed more efficiently from inner classes.
|
|
|
|
*/
|
|
|
|
final RemoteCallbackList<ITorServiceCallback> mCallbacks
|
|
|
|
= new RemoteCallbackList<ITorServiceCallback>();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The IRemoteInterface is defined through IDL
|
|
|
|
*/
|
|
|
|
private final ITorService.Stub mBinder = new ITorService.Stub() {
|
2010-07-23 13:10:00 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
public void registerCallback(ITorServiceCallback cb) {
|
2010-02-08 21:39:42 +01:00
|
|
|
if (cb != null) mCallbacks.register(cb);
|
|
|
|
}
|
|
|
|
public void unregisterCallback(ITorServiceCallback cb) {
|
|
|
|
if (cb != null) mCallbacks.unregister(cb);
|
|
|
|
}
|
|
|
|
public int getStatus () {
|
|
|
|
return getTorStatus();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setProfile (int profile)
|
|
|
|
{
|
|
|
|
setTorProfile(profile);
|
2010-03-01 07:15:35 +01:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
public void processSettings ()
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
applyPreferences();
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
logException ("error applying prefs",e);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
|
2010-08-04 12:16:38 +02:00
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
public String getConfiguration (String name)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (conn != null)
|
|
|
|
{
|
|
|
|
StringBuffer result = new StringBuffer();
|
|
|
|
|
|
|
|
List<ConfigEntry> listCe = conn.getConf(name);
|
|
|
|
|
|
|
|
Iterator<ConfigEntry> itCe = listCe.iterator();
|
|
|
|
ConfigEntry ce = null;
|
|
|
|
|
|
|
|
while (itCe.hasNext())
|
|
|
|
{
|
|
|
|
ce = itCe.next();
|
|
|
|
|
|
|
|
result.append(ce.key);
|
|
|
|
result.append(' ');
|
|
|
|
result.append(ce.value);
|
|
|
|
result.append('\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
return result.toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (IOException ioe)
|
|
|
|
{
|
|
|
|
Log.e(TAG, "Unable to update Tor configuration", ioe);
|
|
|
|
logNotice("Unable to update Tor configuration: " + ioe.getMessage());
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2011-04-17 08:04:27 +02:00
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
/**
|
|
|
|
* Set configuration
|
|
|
|
**/
|
|
|
|
public boolean updateConfiguration (String name, String value, boolean saveToDisk)
|
|
|
|
{
|
2010-07-29 19:03:34 +02:00
|
|
|
if (configBuffer == null)
|
|
|
|
configBuffer = new ArrayList<String>();
|
2011-04-15 18:37:33 +02:00
|
|
|
|
|
|
|
if (resetBuffer == null)
|
|
|
|
resetBuffer = new ArrayList<String>();
|
|
|
|
|
2010-08-14 07:08:55 +02:00
|
|
|
if (value == null || value.length() == 0)
|
|
|
|
{
|
2011-04-17 08:04:27 +02:00
|
|
|
resetBuffer.add(name);
|
2011-05-17 05:09:12 +02:00
|
|
|
|
2010-08-14 07:08:55 +02:00
|
|
|
}
|
|
|
|
else
|
2011-05-17 05:09:12 +02:00
|
|
|
{
|
2010-08-14 07:08:55 +02:00
|
|
|
configBuffer.add(name + ' ' + value);
|
2011-05-17 05:09:12 +02:00
|
|
|
}
|
2010-07-29 19:03:34 +02:00
|
|
|
|
2010-07-23 13:10:00 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean saveConfiguration ()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (conn != null)
|
|
|
|
{
|
2011-04-17 08:04:27 +02:00
|
|
|
|
2011-04-15 18:37:33 +02:00
|
|
|
if (resetBuffer != null && resetBuffer.size() > 0)
|
|
|
|
{
|
|
|
|
conn.resetConf(resetBuffer);
|
|
|
|
resetBuffer = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (configBuffer != null && configBuffer.size() > 0)
|
2010-07-29 19:03:34 +02:00
|
|
|
{
|
2011-04-15 18:37:33 +02:00
|
|
|
|
2010-07-29 19:03:34 +02:00
|
|
|
conn.setConf(configBuffer);
|
|
|
|
configBuffer = null;
|
|
|
|
}
|
2010-07-23 13:10:00 +02:00
|
|
|
|
|
|
|
// Flush the configuration to disk.
|
|
|
|
//this is doing bad things right now NF 22/07/10
|
|
|
|
//conn.saveConf();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ioe)
|
|
|
|
{
|
|
|
|
Log.e(TAG, "Unable to update Tor configuration", ioe);
|
|
|
|
logNotice("Unable to update Tor configuration: " + ioe.getMessage());
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
2010-02-08 21:39:42 +01:00
|
|
|
};
|
|
|
|
|
2010-03-06 15:56:39 +01:00
|
|
|
private ArrayList<String> callbackBuffer = new ArrayList<String>();
|
2010-09-23 21:47:25 +02:00
|
|
|
private boolean inCallbackStatus = false;
|
2011-04-17 08:04:27 +02:00
|
|
|
private boolean inCallback = false;
|
2010-03-06 15:56:39 +01:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
private synchronized void sendCallbackStatusMessage (String newStatus)
|
2010-02-08 21:39:42 +01:00
|
|
|
{
|
|
|
|
|
2010-09-23 21:47:25 +02:00
|
|
|
if (mCallbacks == null)
|
|
|
|
return;
|
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
// Broadcast to all clients the new value.
|
|
|
|
final int N = mCallbacks.beginBroadcast();
|
2010-03-06 15:56:39 +01:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
inCallback = true;
|
2010-09-23 21:47:25 +02:00
|
|
|
|
2010-03-06 15:56:39 +01:00
|
|
|
if (N > 0)
|
|
|
|
{
|
2010-09-23 21:47:25 +02:00
|
|
|
for (int i=0; i<N; i++) {
|
2010-03-06 15:56:39 +01:00
|
|
|
try {
|
2010-09-23 21:47:25 +02:00
|
|
|
mCallbacks.getBroadcastItem(i).statusChanged(newStatus);
|
2010-07-20 00:34:15 +02:00
|
|
|
|
|
|
|
|
2010-03-06 15:56:39 +01:00
|
|
|
} catch (RemoteException e) {
|
|
|
|
// The RemoteCallbackList will take care of removing
|
|
|
|
// the dead object for us.
|
|
|
|
}
|
|
|
|
}
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
2010-03-06 15:56:39 +01:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
mCallbacks.finishBroadcast();
|
2011-04-17 08:04:27 +02:00
|
|
|
inCallback = false;
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|
2010-07-23 13:10:00 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
private synchronized void sendCallbackLogMessage (String logMessage)
|
2010-09-09 22:39:52 +02:00
|
|
|
{
|
|
|
|
|
2010-09-23 21:47:25 +02:00
|
|
|
if (mCallbacks == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
callbackBuffer.add(logMessage);
|
2010-09-09 22:39:52 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
if (!inCallback)
|
|
|
|
{
|
|
|
|
|
|
|
|
inCallback = true;
|
|
|
|
// Broadcast to all clients the new value.
|
|
|
|
final int N = mCallbacks.beginBroadcast();
|
2010-09-09 22:39:52 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
if (N > 0)
|
|
|
|
{
|
|
|
|
|
|
|
|
Iterator<String> it = callbackBuffer.iterator();
|
|
|
|
String status = null;
|
|
|
|
|
|
|
|
while (it.hasNext())
|
|
|
|
{
|
|
|
|
status = it.next();
|
|
|
|
|
|
|
|
for (int i=0; i<N; i++) {
|
|
|
|
try {
|
|
|
|
mCallbacks.getBroadcastItem(i).logMessage(status);
|
|
|
|
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
// The RemoteCallbackList will take care of removing
|
|
|
|
// the dead object for us.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
callbackBuffer.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
mCallbacks.finishBroadcast();
|
|
|
|
inCallback = false;
|
|
|
|
}
|
|
|
|
|
2010-09-09 22:39:52 +02:00
|
|
|
}
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
private boolean applyPreferences () throws RemoteException
|
2010-07-29 19:03:34 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
ENABLE_DEBUG_LOG = prefs.getBoolean("pref_enable_logging",false);
|
|
|
|
Log.i(TAG,"debug logging:" + ENABLE_DEBUG_LOG);
|
|
|
|
|
2010-07-29 19:03:34 +02:00
|
|
|
boolean useBridges = prefs.getBoolean(TorConstants.PREF_BRIDGES_ENABLED, false);
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
//boolean autoUpdateBridges = prefs.getBoolean(TorConstants.PREF_BRIDGES_UPDATED, false);
|
2010-07-29 19:03:34 +02:00
|
|
|
|
|
|
|
boolean becomeRelay = prefs.getBoolean(TorConstants.PREF_OR, false);
|
|
|
|
|
|
|
|
boolean ReachableAddresses = prefs.getBoolean(TorConstants.PREF_REACHABLE_ADDRESSES,false);
|
|
|
|
|
2010-08-14 07:08:55 +02:00
|
|
|
boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
|
|
|
|
|
2011-05-17 04:02:36 +02:00
|
|
|
boolean enableStrictNodes = prefs.getBoolean("pref_strict_nodes", false);
|
2011-05-17 05:09:12 +02:00
|
|
|
String entranceNodes = prefs.getString("pref_entrance_nodes", null);
|
|
|
|
String exitNodes = prefs.getString("pref_exit_nodes", null);
|
|
|
|
String excludeNodes = prefs.getString("pref_exclude_nodes", null);
|
2011-05-16 05:50:10 +02:00
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
if (currentStatus == STATUS_ON)
|
|
|
|
{
|
|
|
|
//reset iptables rules in active mode
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
setupTransProxy(true);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
logException("unable to setup transproxy",e);
|
|
|
|
}
|
2011-05-16 05:50:10 +02:00
|
|
|
}
|
|
|
|
|
2011-05-17 05:09:12 +02:00
|
|
|
mBinder.updateConfiguration("EntryNodes", entranceNodes, false);
|
2011-05-17 04:02:36 +02:00
|
|
|
mBinder.updateConfiguration("ExitNodes", exitNodes, false);
|
|
|
|
mBinder.updateConfiguration("ExcludeNodes", excludeNodes, false);
|
2011-05-17 05:09:12 +02:00
|
|
|
mBinder.updateConfiguration("StrictNodes", enableStrictNodes ? "1" : "0", false);
|
2010-07-29 19:03:34 +02:00
|
|
|
|
|
|
|
if (useBridges)
|
|
|
|
{
|
2011-04-17 08:04:27 +02:00
|
|
|
String bridgeList = prefs.getString(TorConstants.PREF_BRIDGES_LIST,"");
|
|
|
|
|
2010-07-29 19:03:34 +02:00
|
|
|
if (bridgeList == null || bridgeList.length() == 0)
|
|
|
|
{
|
|
|
|
|
|
|
|
showAlert("Bridge Error","In order to use the bridge feature, you must enter at least one bridge IP address." +
|
|
|
|
"Send an email to bridges@torproject.org with the line \"get bridges\" by itself in the body of the mail from a gmail account.");
|
|
|
|
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
return false;
|
2010-07-29 19:03:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mBinder.updateConfiguration("UseBridges", "1", false);
|
|
|
|
|
|
|
|
String bridgeDelim = "\n";
|
|
|
|
|
|
|
|
if (bridgeList.indexOf(",") != -1)
|
|
|
|
{
|
|
|
|
bridgeDelim = ",";
|
|
|
|
}
|
|
|
|
|
|
|
|
StringTokenizer st = new StringTokenizer(bridgeList,bridgeDelim);
|
|
|
|
while (st.hasMoreTokens())
|
|
|
|
{
|
|
|
|
|
|
|
|
mBinder.updateConfiguration("bridge", st.nextToken(), false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mBinder.updateConfiguration("UpdateBridgesFromAuthority", "0", false);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mBinder.updateConfiguration("UseBridges", "0", false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (ReachableAddresses)
|
|
|
|
{
|
|
|
|
String ReachableAddressesPorts =
|
|
|
|
prefs.getString(TorConstants.PREF_REACHABLE_ADDRESSES_PORTS, "*:80,*:443");
|
|
|
|
|
|
|
|
mBinder.updateConfiguration("ReachableAddresses", ReachableAddressesPorts, false);
|
|
|
|
|
|
|
|
}
|
2010-08-14 07:08:55 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
mBinder.updateConfiguration("ReachableAddresses", "", false);
|
|
|
|
}
|
2010-07-29 19:03:34 +02:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
showAlert("Config Error","Your ReachableAddresses settings caused an exception!");
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
return false;
|
2010-07-29 19:03:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (becomeRelay && (!useBridges) && (!ReachableAddresses))
|
|
|
|
{
|
|
|
|
int ORPort = Integer.parseInt(prefs.getString(TorConstants.PREF_OR_PORT, "9001"));
|
|
|
|
String nickname = prefs.getString(TorConstants.PREF_OR_NICKNAME, "Orbot");
|
|
|
|
|
|
|
|
mBinder.updateConfiguration("ORPort", ORPort + "", false);
|
|
|
|
mBinder.updateConfiguration("Nickname", nickname, false);
|
|
|
|
mBinder.updateConfiguration("ExitPolicy", "reject *:*", false);
|
|
|
|
|
|
|
|
}
|
2010-08-14 07:08:55 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
mBinder.updateConfiguration("ORPort", "", false);
|
|
|
|
mBinder.updateConfiguration("Nickname", "", false);
|
|
|
|
mBinder.updateConfiguration("ExitPolicy", "", false);
|
|
|
|
}
|
2010-07-29 19:03:34 +02:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
showAlert("Uh-oh!","Your relay settings caused an exception!");
|
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
return false;
|
2010-07-29 19:03:34 +02:00
|
|
|
}
|
|
|
|
|
2010-08-14 07:08:55 +02:00
|
|
|
if (enableHiddenServices)
|
|
|
|
{
|
2011-07-25 22:12:41 +02:00
|
|
|
mBinder.updateConfiguration("HiddenServiceDir",appDataHome.getAbsolutePath(), false);
|
2010-08-14 07:08:55 +02:00
|
|
|
|
|
|
|
String hsPorts = prefs.getString("pref_hs_ports","");
|
|
|
|
|
|
|
|
StringTokenizer st = new StringTokenizer (hsPorts,",");
|
|
|
|
String hsPortConfig = null;
|
|
|
|
|
|
|
|
while (st.hasMoreTokens())
|
|
|
|
{
|
|
|
|
hsPortConfig = st.nextToken();
|
|
|
|
|
|
|
|
if (hsPortConfig.indexOf(":")==-1) //setup the port to localhost if not specifed
|
|
|
|
{
|
|
|
|
hsPortConfig = hsPortConfig + " 127.0.0.1:" + hsPortConfig;
|
|
|
|
}
|
|
|
|
|
|
|
|
mBinder.updateConfiguration("HiddenServicePort",hsPortConfig, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mBinder.updateConfiguration("HiddenServiceDir","", false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-07-29 19:03:34 +02:00
|
|
|
mBinder.saveConfiguration();
|
2011-04-17 08:04:27 +02:00
|
|
|
|
|
|
|
return true;
|
2010-07-29 19:03:34 +02:00
|
|
|
}
|
|
|
|
|
2011-05-03 07:56:40 +02:00
|
|
|
|
2011-04-17 08:04:27 +02:00
|
|
|
|
2010-02-08 21:39:42 +01:00
|
|
|
}
|