modified control port usage, updated startup UI screen, implemented all-app torification and more
svn:r22677
This commit is contained in:
parent
7d7a33b983
commit
183a58f39f
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.torproject.android"
|
package="org.torproject.android"
|
||||||
android:versionName="0.2.2.13-orbot-alpha-0.0.8" android:versionCode="2">
|
android:versionName="0.2.2.13-orbot-alpha-0.0.8" android:versionCode="8">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
|
|
|
@ -10,5 +10,5 @@
|
||||||
# Indicates whether an apk should be generated for each density.
|
# Indicates whether an apk should be generated for each density.
|
||||||
split.density=false
|
split.density=false
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-8
|
target=android-3
|
||||||
apk-configurations=
|
apk-configurations=
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 35 KiB |
Binary file not shown.
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 59 KiB |
|
@ -4,11 +4,15 @@
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
>
|
>
|
||||||
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/itemcheck"></CheckBox>
|
|
||||||
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/itemicon" android:layout_width="48px" android:layout_height="48px"></ImageView>
|
<ImageView android:id="@+id/itemicon" android:layout_width="48px" android:layout_height="48px"></ImageView>
|
||||||
|
|
||||||
<TextView android:layout_height="wrap_content" android:id="@+id/itemtext" android:text="uid:packages" android:layout_width="wrap_content"
|
<TextView android:layout_height="wrap_content" android:id="@+id/itemtext" android:text="uid:packages"
|
||||||
android:textSize="18sp"></TextView>
|
android:layout_width="220px" android:textSize="18sp"></TextView>
|
||||||
|
|
||||||
|
<CheckBox android:layout_width="48px" android:layout_height="48px" android:id="@+id/itemcheck"></CheckBox>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -1,17 +1,52 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="@drawable/bgtitanium">
|
||||||
|
|
||||||
|
<RelativeLayout android:id="@+id/layoutHeaderMain"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:background="#A0909090">
|
||||||
|
<ImageView android:id="@+id/radioModeImage"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="0px"
|
||||||
|
android:layout_marginRight="3px"
|
||||||
|
android:gravity="right"
|
||||||
|
android:layout_toRightOf="@+id/radioModeLabel"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:src="@drawable/tor25"
|
||||||
|
/>
|
||||||
|
<TextView android:id="@+id/radioModeText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/powered_by"
|
||||||
|
android:layout_marginTop="9px"
|
||||||
|
android:layout_marginRight="0px"
|
||||||
|
android:gravity="right"
|
||||||
|
android:layout_toLeftOf="@+id/radioModeImage"
|
||||||
|
android:textColor="#333333" />
|
||||||
|
</RelativeLayout>
|
||||||
<ScrollView android:orientation="vertical"
|
<ScrollView android:orientation="vertical"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_width="fill_parent" android:id="@+id/logScrollView"
|
android:layout_width="fill_parent" android:id="@+id/logScrollView"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<TextView android:id="@+id/messageLog"
|
<TextView android:id="@+id/messageLog"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_x="2px"
|
android:layout_x="2px"
|
||||||
android:layout_y="2px"
|
android:layout_y="2px"
|
||||||
android:textSize="12px"
|
android:textSize="12px"
|
||||||
|
android:background="#A0222222"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<string name="status_shutting_down">Orbot is shutting down</string>
|
<string name="status_shutting_down">Orbot is shutting down</string>
|
||||||
|
|
||||||
<string name="tor_process_connecting">Starting Tor...</string>
|
<string name="tor_process_connecting">Starting Tor...</string>
|
||||||
<string name="tor_process_connecting_step2">authenticating control connection...</string>
|
<string name="tor_process_connecting_step2">Setting up control...</string>
|
||||||
<string name="tor_process_connecting_step3">complete.</string>
|
<string name="tor_process_connecting_step3">complete.</string>
|
||||||
<string name="tor_process_connecting_step4">waiting.</string>
|
<string name="tor_process_connecting_step4">waiting.</string>
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<string name="help_text_1">Orbot requires different configuration depending on the Android operating system version it is used on.
|
<string name="help_text_1">Orbot requires different configuration depending on the Android operating system version it is used on.
|
||||||
Please visit https://www.torproject.org/docs/android.html for the latest information.</string>
|
Please visit https://www.torproject.org/docs/android.html for the latest information.</string>
|
||||||
|
|
||||||
<string name="help_text_2">For non-rooted Android 1.x devices (G1, MyTouch3G, Hero): Please use the "ProxySurf" browser available in the Android Market, and set
|
<string name="help_text_2">For non-rooted Android 1.x devices: Please use the "ProxySurf" browser available in the Android Market, and set
|
||||||
the HTTP Proxy to 127.0.0.1 and port 8118, for HTTP traffic only (HTTP/S will not work).</string>
|
the HTTP Proxy to 127.0.0.1 and port 8118, for HTTP traffic only (HTTP/S will not work).</string>
|
||||||
|
|
||||||
<string name="help_text_3">For Instant Messaging, try "Beem" in the market, and set the SOCKS5 proxy to 127.0.0.1 / port 9050.</string>
|
<string name="help_text_3">For Instant Messaging, try "Beem" in the market, and set the SOCKS5 proxy to 127.0.0.1 / port 9050.</string>
|
||||||
|
@ -52,4 +52,16 @@ and all DNS requests. This includes the built-in Browser, Gmail, YouTube and Map
|
||||||
<string name="menu_exit">Exit</string>
|
<string name="menu_exit">Exit</string>
|
||||||
<string name="powered_by">powered by the Tor Project</string>
|
<string name="powered_by">powered by the Tor Project</string>
|
||||||
<string name="press_to_start">- press to start -</string>
|
<string name="press_to_start">- press to start -</string>
|
||||||
|
|
||||||
|
<string name="pref_trans_proxy_group">Transparent Proxying (Requires Root)</string>
|
||||||
|
<string name="pref_trans_proxy_title">Transparent Proxying</string>
|
||||||
|
<string name="pref_trans_proxy_summary">Automatic Torifying of Apps</string>
|
||||||
|
|
||||||
|
<string name="pref_transparent_all_title">Tor Everything</string>
|
||||||
|
<string name="pref_transparent_all_summary">Send traffic for all apps through Tor</string>
|
||||||
|
|
||||||
|
<string name="status_install_success">Tor binaries successfully installed!</string>
|
||||||
|
<string name="status_install_fail">The Tor binary files were unable to be installed. Please check the log and notify tor-assistants@torproject.org</string>
|
||||||
|
|
||||||
|
<string name="title_error">Application Error</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<PreferenceCategory android:title="Transparent Proxying (Requires Root)">
|
<PreferenceCategory android:title="@string/pref_trans_proxy_group">
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="pref_transparent"
|
android:key="pref_transparent"
|
||||||
android:title="Transparent Proxying"
|
android:title="@string/pref_trans_proxy_title"
|
||||||
android:summary="Auto-Tor Proxying"
|
android:summary="@string/pref_trans_proxy_summary"
|
||||||
android:enabled="true"/>
|
android:enabled="true"/>
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="pref_transparent_all"
|
android:key="pref_transparent_all"
|
||||||
android:title="Auto-Proxy All Apps"
|
android:summary="@string/pref_transparent_all_summary"
|
||||||
android:summary="Route All Traffic Through Tor"
|
android:enabled="true"
|
||||||
android:enabled="true"/>
|
android:title="@string/pref_transparent_all_title"/>
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:defaultValue=""
|
android:defaultValue=""
|
||||||
|
|
|
@ -3,15 +3,11 @@
|
||||||
|
|
||||||
package org.torproject.android;
|
package org.torproject.android;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.torproject.android.service.ITorService;
|
import org.torproject.android.service.ITorService;
|
||||||
import org.torproject.android.service.ITorServiceCallback;
|
import org.torproject.android.service.ITorServiceCallback;
|
||||||
import org.torproject.android.service.TorServiceUtils;
|
|
||||||
import org.torproject.android.service.TorTransProxy;
|
import org.torproject.android.service.TorTransProxy;
|
||||||
import org.torproject.android.service.TorServiceConstants;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
@ -36,28 +32,21 @@ import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.ArrayAdapter;
|
import android.view.animation.Animation;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ListAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
|
||||||
|
|
||||||
public class Orbot extends Activity implements OnClickListener, TorConstants, OnCheckedChangeListener
|
public class Orbot extends Activity implements OnClickListener, TorConstants
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Useful UI bits */
|
/* Useful UI bits */
|
||||||
private TextView txtMessageLog = null; //the full screen log view of Tor control messages
|
private TextView txtMessageLog = null; //the full screen log view of Tor control messages
|
||||||
private TextView lblStatus = null; //the main text display widget
|
private TextView lblStatus = null; //the main text display widget
|
||||||
private ImageView imgStatus = null; //the main touchable image for activating Orbot
|
private ImageView imgStatus = null; //the main touchable image for activating Orbot
|
||||||
private ProgressDialog progressDialog;
|
// private ProgressDialog progressDialog;
|
||||||
private ListView listApps;
|
|
||||||
private boolean showingSettings = false;
|
|
||||||
private MenuItem mItemOnOff = null;
|
private MenuItem mItemOnOff = null;
|
||||||
|
|
||||||
/* Some tracking bits */
|
/* Some tracking bits */
|
||||||
|
@ -96,7 +85,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
mItem.setIcon(R.drawable.ic_menu_register);
|
mItem.setIcon(R.drawable.ic_menu_register);
|
||||||
|
|
||||||
mItem = menu.add(0, 7, Menu.NONE, getString(R.string.menu_verify));
|
mItem = menu.add(0, 7, Menu.NONE, getString(R.string.menu_verify));
|
||||||
mItem.setIcon(R.drawable.ic_menu_goto);
|
mItem.setIcon(R.drawable.ic_menu_check);
|
||||||
|
|
||||||
mItem = menu.add(0,6, Menu.NONE, getString(R.string.menu_log));
|
mItem = menu.add(0,6, Menu.NONE, getString(R.string.menu_log));
|
||||||
mItem.setIcon(R.drawable.ic_menu_reports);
|
mItem.setIcon(R.drawable.ic_menu_reports);
|
||||||
|
@ -163,10 +152,6 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
{
|
{
|
||||||
showHelp();
|
showHelp();
|
||||||
}
|
}
|
||||||
else if (item.getItemId() == 5)
|
|
||||||
{
|
|
||||||
showApps();
|
|
||||||
}
|
|
||||||
else if (item.getItemId() == 7)
|
else if (item.getItemId() == 7)
|
||||||
{
|
{
|
||||||
//launch check.torproject.org
|
//launch check.torproject.org
|
||||||
|
@ -257,22 +242,22 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
|
|
||||||
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
mNotificationManager.cancelAll();
|
mNotificationManager.cancelAll();
|
||||||
|
|
||||||
updateStatus (""); //update the status, which checks the service status
|
|
||||||
|
|
||||||
if (showingSettings)
|
if (mService != null)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
showingSettings = false;
|
processSettings();
|
||||||
processSettings();
|
} catch (RemoteException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -285,8 +270,10 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
startService(new Intent(INTENT_TOR_SERVICE));
|
startService(new Intent(INTENT_TOR_SERVICE));
|
||||||
bindService ();
|
bindService ();
|
||||||
|
|
||||||
updateStatus ("");
|
//updateStatus ("");
|
||||||
|
|
||||||
|
hasRoot = TorTransProxy.hasRootAccess();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -298,8 +285,6 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
|
||||||
TorServiceUtils.saveAppSettings(this);
|
|
||||||
|
|
||||||
unbindService();
|
unbindService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,23 +297,6 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
{
|
{
|
||||||
bindService(); //connect the UI activity to the remote service
|
bindService(); //connect the UI activity to the remote service
|
||||||
|
|
||||||
if (currentView == R.layout.layout_apps)
|
|
||||||
{
|
|
||||||
if (hasRoot)
|
|
||||||
{
|
|
||||||
|
|
||||||
TorServiceUtils.saveAppSettings(this);
|
|
||||||
|
|
||||||
if (enableTransparentProxy)
|
|
||||||
{
|
|
||||||
TorTransProxy.purgeNatIptables();
|
|
||||||
TorTransProxy.setDNSProxying();
|
|
||||||
TorTransProxy.setTransparentProxying(this, TorServiceUtils.getApps(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentView = R.layout.layout_main;
|
currentView = R.layout.layout_main;
|
||||||
setContentView(currentView);
|
setContentView(currentView);
|
||||||
|
@ -352,61 +320,6 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadApps ()
|
|
||||||
{
|
|
||||||
final TorifiedApp[] apps = TorServiceUtils.getApps(this);
|
|
||||||
|
|
||||||
Arrays.sort(apps, new Comparator<TorifiedApp>() {
|
|
||||||
public int compare(TorifiedApp o1, TorifiedApp o2) {
|
|
||||||
if (o1.isTorified() == o2.isTorified()) return o1.getName().compareTo(o2.getName());
|
|
||||||
if (o1.isTorified()) return -1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final LayoutInflater inflater = getLayoutInflater();
|
|
||||||
|
|
||||||
final ListAdapter adapter = new ArrayAdapter<TorifiedApp>(this,R.layout.layout_apps_item,R.id.itemtext,apps) {
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
ListEntry entry;
|
|
||||||
if (convertView == null) {
|
|
||||||
// Inflate a new view
|
|
||||||
convertView = inflater.inflate(R.layout.layout_apps_item, parent, false);
|
|
||||||
entry = new ListEntry();
|
|
||||||
entry.box = (CheckBox) convertView.findViewById(R.id.itemcheck);
|
|
||||||
entry.text = (TextView) convertView.findViewById(R.id.itemtext);
|
|
||||||
convertView.setTag(entry);
|
|
||||||
entry.box.setOnCheckedChangeListener(Orbot.this);
|
|
||||||
} else {
|
|
||||||
// Convert an existing view
|
|
||||||
entry = (ListEntry) convertView.getTag();
|
|
||||||
}
|
|
||||||
final TorifiedApp app = apps[position];
|
|
||||||
|
|
||||||
|
|
||||||
entry.text.setText(app.getName());
|
|
||||||
final CheckBox box = entry.box;
|
|
||||||
box.setTag(app);
|
|
||||||
box.setChecked(app.isTorified());
|
|
||||||
return convertView;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.listApps.setAdapter(adapter);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called an application is check/unchecked
|
|
||||||
*/
|
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
||||||
final TorifiedApp app = (TorifiedApp) buttonView.getTag();
|
|
||||||
if (app != null) {
|
|
||||||
app.setTorified(isChecked);
|
|
||||||
}
|
|
||||||
|
|
||||||
TorServiceUtils.saveAppSettings(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ListEntry {
|
private static class ListEntry {
|
||||||
private CheckBox box;
|
private CheckBox box;
|
||||||
|
@ -424,7 +337,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
versionName.setText(R.string.app_version);
|
versionName.setText(R.string.app_version);
|
||||||
|
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
.setTitle(getString(R.string.menu_info))
|
.setTitle(getString(R.string.button_about))
|
||||||
.setView(view)
|
.setView(view)
|
||||||
.setNeutralButton(getString(R.string.button_help), new DialogInterface.OnClickListener() {
|
.setNeutralButton(getString(R.string.button_help), new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int whichButton) {
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
@ -451,6 +364,25 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
StringBuilder msg = new StringBuilder();
|
StringBuilder msg = new StringBuilder();
|
||||||
msg.append(getString(R.string.help_text_1));
|
msg.append(getString(R.string.help_text_1));
|
||||||
msg.append("\n\n");
|
msg.append("\n\n");
|
||||||
|
|
||||||
|
if (hasRoot)
|
||||||
|
{
|
||||||
|
msg.append("Your device is ROOTED. Please enable the 'Transparent Proxying' setting to select which apps to send through Tor.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
msg.append("Your device is NOT rooted.\n");
|
||||||
|
|
||||||
|
msg.append(getString(R.string.help_text_5));
|
||||||
|
|
||||||
|
msg.append("\n\n");
|
||||||
|
|
||||||
|
msg.append(getString(R.string.not_anonymous_yet));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
msg.append(getString(R.string.help_text_2));
|
msg.append(getString(R.string.help_text_2));
|
||||||
msg.append("\n\n");
|
msg.append("\n\n");
|
||||||
msg.append(getString(R.string.help_text_3));
|
msg.append(getString(R.string.help_text_3));
|
||||||
|
@ -459,6 +391,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
msg.append("\n\n");
|
msg.append("\n\n");
|
||||||
msg.append(getString(R.string.help_text_5));
|
msg.append(getString(R.string.help_text_5));
|
||||||
msg.append("\n\n");
|
msg.append("\n\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
|
@ -478,16 +411,14 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showApps ()
|
private void showHelpWizard ()
|
||||||
{
|
{
|
||||||
currentView = R.layout.layout_apps;
|
|
||||||
setContentView(currentView);
|
|
||||||
|
|
||||||
listApps = (ListView)findViewById(R.id.applistview);
|
|
||||||
|
|
||||||
loadApps();
|
//sshowAlert("Configure",getString(R.string.not_anonymous_yet));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show the message log UI
|
* Show the message log UI
|
||||||
*/
|
*/
|
||||||
|
@ -510,7 +441,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
private void showSettings ()
|
private void showSettings ()
|
||||||
{
|
{
|
||||||
|
|
||||||
showingSettings = true;
|
|
||||||
startActivity(new Intent(this, SettingsPreferences.class));
|
startActivity(new Intent(this, SettingsPreferences.class));
|
||||||
|
|
||||||
|
|
||||||
|
@ -520,7 +451,8 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
* Read in the Preferences and write then to the .torrc file
|
* Read in the Preferences and write then to the .torrc file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void processSettings ()
|
/*
|
||||||
|
private void processSettingsOld ()
|
||||||
{
|
{
|
||||||
StringBuffer torrcText = new StringBuffer();
|
StringBuffer torrcText = new StringBuffer();
|
||||||
|
|
||||||
|
@ -566,6 +498,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
torrcText.append("UseBridges 1");
|
torrcText.append("UseBridges 1");
|
||||||
torrcText.append('\n');
|
torrcText.append('\n');
|
||||||
|
|
||||||
|
@ -645,6 +578,111 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
|
|
||||||
Utils.saveTextFile(TorServiceConstants.TORRC_INSTALL_PATH, torrcText.toString());
|
Utils.saveTextFile(TorServiceConstants.TORRC_INSTALL_PATH, torrcText.toString());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
private void processSettings () throws RemoteException
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
|
boolean useBridges = prefs.getBoolean(PREF_BRIDGES_ENABLED, false);
|
||||||
|
|
||||||
|
boolean autoUpdateBridges = prefs.getBoolean(PREF_BRIDGES_UPDATED, false);
|
||||||
|
|
||||||
|
boolean becomeRelay = prefs.getBoolean(PREF_OR, false);
|
||||||
|
|
||||||
|
boolean ReachableAddresses = prefs.getBoolean(PREF_REACHABLE_ADDRESSES,false);
|
||||||
|
|
||||||
|
boolean enableTransparentProxy = prefs.getBoolean(PREF_TRANSPARENT, false);
|
||||||
|
|
||||||
|
|
||||||
|
String bridgeList = prefs.getString(PREF_BRIDGES_LIST,"");
|
||||||
|
|
||||||
|
if (useBridges)
|
||||||
|
{
|
||||||
|
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.");
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mService.updateConfiguration("UseBridges", "1", false);
|
||||||
|
|
||||||
|
if (autoUpdateBridges)
|
||||||
|
{
|
||||||
|
mService.updateConfiguration("UpdateBridgesFromAuthority", "1", false);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mService.updateConfiguration("UpdateBridgesFromAuthority", "0", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
String bridgeDelim = "\n";
|
||||||
|
|
||||||
|
if (bridgeList.indexOf(",") != -1)
|
||||||
|
{
|
||||||
|
bridgeDelim = ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringTokenizer st = new StringTokenizer(bridgeList,bridgeDelim);
|
||||||
|
while (st.hasMoreTokens())
|
||||||
|
{
|
||||||
|
|
||||||
|
mService.updateConfiguration("bridge", st.nextToken(), false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mService.updateConfiguration("UseBridges", "0", false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (ReachableAddresses)
|
||||||
|
{
|
||||||
|
String ReachableAddressesPorts =
|
||||||
|
prefs.getString(PREF_REACHABLE_ADDRESSES_PORTS, "*:80,*:443");
|
||||||
|
|
||||||
|
mService.updateConfiguration("ReachableAddresses", ReachableAddressesPorts, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
showAlert("Config Error","Your ReachableAddresses settings caused an exception!");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (becomeRelay && (!useBridges) && (!ReachableAddresses))
|
||||||
|
{
|
||||||
|
int ORPort = Integer.parseInt(prefs.getString(PREF_OR_PORT, "9001"));
|
||||||
|
String nickname = prefs.getString(PREF_OR_NICKNAME, "Orbot");
|
||||||
|
|
||||||
|
mService.updateConfiguration("ORPort", ORPort + "", false);
|
||||||
|
mService.updateConfiguration("Nickname", nickname, false);
|
||||||
|
mService.updateConfiguration("ExitPolicy", "reject *:*", false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
showAlert("Uh-oh!","Your relay settings caused an exception!");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mService.saveConfiguration();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void showAlert(String title, String msg)
|
private void showAlert(String title, String msg)
|
||||||
{
|
{
|
||||||
|
@ -679,9 +717,14 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
if (torStatus == STATUS_ON)
|
if (torStatus == STATUS_ON)
|
||||||
{
|
{
|
||||||
imgStatus.setImageResource(R.drawable.toron);
|
imgStatus.setImageResource(R.drawable.toron);
|
||||||
|
imgStatus.clearAnimation();
|
||||||
|
|
||||||
lblStatus.setText(getString(R.string.status_activated));
|
lblStatus.setText(getString(R.string.status_activated));
|
||||||
|
|
||||||
|
showHelpWizard ();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
if (progressDialog != null)
|
if (progressDialog != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -689,23 +732,28 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
progressDialog.hide();
|
progressDialog.hide();
|
||||||
progressDialog = null;
|
progressDialog = null;
|
||||||
|
|
||||||
if (!enableTransparentProxy)
|
|
||||||
{
|
}*/
|
||||||
showAlert("Configure",getString(R.string.not_anonymous_yet));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (torServiceMsg != null && torServiceMsg.length()>0)
|
|
||||||
// Toast.makeText(this, torServiceMsg, Toast.LENGTH_LONG).show();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (torStatus == STATUS_CONNECTING)
|
else if (torStatus == STATUS_CONNECTING)
|
||||||
{
|
{
|
||||||
|
|
||||||
imgStatus.setImageResource(R.drawable.torstarting);
|
imgStatus.setImageResource(R.drawable.torstarting);
|
||||||
lblStatus.setText(getString(R.string.status_starting_up));
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (imgStatus.getAnimation()==null)
|
||||||
|
{
|
||||||
|
|
||||||
|
imgStatus.setAnimation(AnimationUtils.loadAnimation(this, R.anim.starting));
|
||||||
|
imgStatus.getAnimation().setRepeatMode(Animation.INFINITE);
|
||||||
|
|
||||||
|
imgStatus.getAnimation().setRepeatCount(Animation.INFINITE);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
if (progressDialog == null)
|
if (progressDialog == null)
|
||||||
{
|
{
|
||||||
progressDialog = new ProgressDialog(this);
|
progressDialog = new ProgressDialog(this);
|
||||||
|
@ -719,14 +767,18 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
}
|
}
|
||||||
|
|
||||||
progressDialog.setMessage(torServiceMsg);
|
progressDialog.setMessage(torServiceMsg);
|
||||||
|
*/
|
||||||
|
|
||||||
|
lblStatus.setText(torServiceMsg);
|
||||||
|
|
||||||
|
|
||||||
int idx = torServiceMsg.indexOf("%");
|
int idx = torServiceMsg.indexOf("%");
|
||||||
|
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
{
|
{
|
||||||
String pComp = torServiceMsg.substring(idx-2,idx).trim();
|
String pComp = torServiceMsg.substring(idx-2,idx).trim();
|
||||||
int ipComp = Integer.parseInt(pComp);
|
int ipComp = Integer.parseInt(pComp);
|
||||||
progressDialog.setProgress(ipComp);
|
// progressDialog.setProgress(ipComp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,21 +786,16 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
else if (torStatus == STATUS_OFF)
|
else if (torStatus == STATUS_OFF)
|
||||||
{
|
{
|
||||||
imgStatus.setImageResource(R.drawable.torstopping);
|
imgStatus.setImageResource(R.drawable.torstopping);
|
||||||
|
imgStatus.clearAnimation();
|
||||||
|
|
||||||
lblStatus.setText(getString(R.string.status_shutting_down));
|
lblStatus.setText(getString(R.string.status_shutting_down));
|
||||||
|
|
||||||
//if (torServiceMsg != null && torServiceMsg.length()>0)
|
|
||||||
//Toast.makeText(this, torServiceMsg, Toast.LENGTH_LONG).show();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
//if (torServiceMsg != null && torServiceMsg.length()>0)
|
|
||||||
//Toast.makeText(this, torServiceMsg, Toast.LENGTH_LONG).show();
|
|
||||||
|
|
||||||
|
/*
|
||||||
if (progressDialog != null)
|
if (progressDialog != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -756,7 +803,8 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
progressDialog.hide();
|
progressDialog.hide();
|
||||||
progressDialog = null;
|
progressDialog = null;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
imgStatus.clearAnimation();
|
||||||
|
|
||||||
imgStatus.setImageResource(R.drawable.toroff);
|
imgStatus.setImageResource(R.drawable.toroff);
|
||||||
lblStatus.setText(getString(R.string.status_disabled));
|
lblStatus.setText(getString(R.string.status_disabled));
|
||||||
|
@ -837,31 +885,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doTorSetup (boolean enabled)
|
|
||||||
{
|
|
||||||
if (enabled)
|
|
||||||
{
|
|
||||||
processSettings();
|
|
||||||
|
|
||||||
|
|
||||||
if (hasRoot && enableTransparentProxy)
|
|
||||||
{
|
|
||||||
|
|
||||||
TorTransProxy.setDNSProxying();
|
|
||||||
TorTransProxy.setTransparentProxying(this,TorServiceUtils.getApps(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hasRoot && enableTransparentProxy)
|
|
||||||
{
|
|
||||||
TorTransProxy.purgeNatIptables();
|
|
||||||
//TorRoot.setDNSProxying(false);
|
|
||||||
//TorRoot.setTransparentProxying(this,false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation is used to receive callbacks from the remote
|
* This implementation is used to receive callbacks from the remote
|
||||||
* service.
|
* service.
|
||||||
|
@ -876,21 +900,30 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
*/
|
*/
|
||||||
public void statusChanged(String value) {
|
public void statusChanged(String value) {
|
||||||
|
|
||||||
Message msg = mHandler.obtainMessage(BUMP_MSG);
|
Message msg = mHandler.obtainMessage(STATUS_MSG);
|
||||||
msg.getData().putString(HANDLER_TOR_MSG, value);
|
msg.getData().putString(HANDLER_TOR_MSG, value);
|
||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logMessage(String value) throws RemoteException {
|
||||||
|
|
||||||
|
Message msg = mHandler.obtainMessage(LOG_MSG);
|
||||||
|
msg.getData().putString(HANDLER_TOR_MSG, value);
|
||||||
|
mHandler.sendMessage(msg);
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final int BUMP_MSG = 1;
|
private static final int STATUS_MSG = 1;
|
||||||
|
|
||||||
private static final int ENABLE_TOR_MSG = 2;
|
private static final int ENABLE_TOR_MSG = 2;
|
||||||
private static final int DISABLE_TOR_MSG = 3;
|
private static final int DISABLE_TOR_MSG = 3;
|
||||||
|
private static final int LOG_MSG = 4;
|
||||||
|
|
||||||
private Handler mHandler = new Handler() {
|
private Handler mHandler = new Handler() {
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case BUMP_MSG:
|
case STATUS_MSG:
|
||||||
|
|
||||||
String torServiceMsg = (String)msg.getData().getString(HANDLER_TOR_MSG);
|
String torServiceMsg = (String)msg.getData().getString(HANDLER_TOR_MSG);
|
||||||
|
|
||||||
|
@ -899,16 +932,24 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
|
|
||||||
|
|
||||||
if (torServiceMsg.length() > 0 && torServiceMsg.charAt(0)!='>')
|
if (torServiceMsg.length() > 0 && torServiceMsg.charAt(0)!='>')
|
||||||
updateStatus(torServiceMsg);
|
updateStatus(torServiceMsg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case LOG_MSG:
|
||||||
|
|
||||||
|
String torLogMsg = (String)msg.getData().getString(HANDLER_TOR_MSG);
|
||||||
|
|
||||||
|
logBuffer.append(torLogMsg);
|
||||||
|
logBuffer.append('\n');
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ENABLE_TOR_MSG:
|
case ENABLE_TOR_MSG:
|
||||||
|
|
||||||
doTorSetup(true);
|
|
||||||
break;
|
break;
|
||||||
case DISABLE_TOR_MSG:
|
case DISABLE_TOR_MSG:
|
||||||
|
|
||||||
doTorSetup(false);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -958,7 +999,6 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
|
|
||||||
boolean mIsBound = false;
|
boolean mIsBound = false;
|
||||||
boolean hasRoot = false;
|
boolean hasRoot = false;
|
||||||
boolean enableTransparentProxy = false;
|
|
||||||
|
|
||||||
private void bindService ()
|
private void bindService ()
|
||||||
{
|
{
|
||||||
|
@ -967,8 +1007,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants, On
|
||||||
|
|
||||||
mIsBound = true;
|
mIsBound = true;
|
||||||
|
|
||||||
hasRoot = TorTransProxy.hasRootAccess();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,25 @@ public class SettingsPreferences
|
||||||
private CheckBoxPreference prefcBTransProxyAll = null;
|
private CheckBoxPreference prefcBTransProxyAll = null;
|
||||||
private Preference prefTransProxyApps = null;
|
private Preference prefTransProxyApps = null;
|
||||||
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
private boolean hasRoot = false;
|
||||||
|
|
||||||
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
addPreferencesFromResource(R.xml.preferences);
|
||||||
|
|
||||||
|
hasRoot = TorServiceUtils.hasRoot();
|
||||||
|
|
||||||
if (!TorServiceUtils.hasRoot())
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
if (!hasRoot)
|
||||||
{
|
{
|
||||||
getPreferenceScreen().getPreference(0).setEnabled(false);
|
getPreferenceScreen().getPreference(0).setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ package org.torproject.android;
|
||||||
public interface TorConstants {
|
public interface TorConstants {
|
||||||
|
|
||||||
public final static String TAG = "Orbot";
|
public final static String TAG = "Orbot";
|
||||||
|
|
||||||
|
|
||||||
|
public final static String PREFS_KEY = "OrbotPrefs";
|
||||||
|
public final static String PREFS_KEY_TORIFIED = "PrefTord";
|
||||||
|
|
||||||
public final static int FILE_WRITE_BUFFER_SIZE = 2048;
|
public final static int FILE_WRITE_BUFFER_SIZE = 2048;
|
||||||
|
|
||||||
|
@ -23,10 +27,12 @@ public interface TorConstants {
|
||||||
|
|
||||||
public final static String NEWLINE = "\n";
|
public final static String NEWLINE = "\n";
|
||||||
|
|
||||||
|
/*
|
||||||
public final static String TORRC_DEFAULT =
|
public final static String TORRC_DEFAULT =
|
||||||
"SocksPort 9050\nSocksListenAddress 127.0.0.1\nSafeSocks 1\nDNSPort 5400\nLog debug syslog\nDataDirectory /data/data/org.torproject.android/cache\n"
|
"SocksPort 9050\nSocksListenAddress 127.0.0.1\nSafeSocks 1\nDNSPort 5400\nLog debug syslog\nDataDirectory /data/data/org.torproject.android/cache\n"
|
||||||
+ "ControlPort 9051\nCookieAuthentication 1\nRelayBandwidthRate 20 KBytes\nRelayBandwidthBurst 20 KBytes\nAutomapHostsOnResolve 1\nTransPort 9040\n";
|
+ "ControlPort 9051\nCookieAuthentication 1\nRelayBandwidthRate 20 KBytes\nRelayBandwidthBurst 20 KBytes\nAutomapHostsOnResolve 1\nTransPort 9040\n";
|
||||||
|
*/
|
||||||
|
|
||||||
public final static String INTENT_TOR_SERVICE = "org.torproject.android.service.TOR_SERVICE";
|
public final static String INTENT_TOR_SERVICE = "org.torproject.android.service.TOR_SERVICE";
|
||||||
|
|
||||||
public final static String HANDLER_TOR_MSG = "torServiceMsg";
|
public final static String HANDLER_TOR_MSG = "torServiceMsg";
|
||||||
|
|
|
@ -6,19 +6,40 @@ import org.torproject.android.service.ITorServiceCallback;
|
||||||
* an interface for calling on to a remote service
|
* an interface for calling on to a remote service
|
||||||
*/
|
*/
|
||||||
interface ITorService {
|
interface ITorService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Often you want to allow a service to call back to its clients.
|
* This allows Tor service to send messages back to the GUI
|
||||||
* This shows how to do so, by registering a callback interface with
|
|
||||||
* the service.
|
|
||||||
*/
|
*/
|
||||||
void registerCallback(ITorServiceCallback cb);
|
void registerCallback(ITorServiceCallback cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a previously registered callback interface.
|
* Remove registered callback interface.
|
||||||
*/
|
*/
|
||||||
void unregisterCallback(ITorServiceCallback cb);
|
void unregisterCallback(ITorServiceCallback cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a simple int status value for the state of Tor
|
||||||
|
**/
|
||||||
int getStatus();
|
int getStatus();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The profile value is the start/stop state for Tor
|
||||||
|
**/
|
||||||
void setProfile(int profile);
|
void setProfile(int profile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set configuration
|
||||||
|
**/
|
||||||
|
boolean updateConfiguration (String name, String value, boolean saveToDisk);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set configuration
|
||||||
|
**/
|
||||||
|
boolean saveConfiguration ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current configuration value from torrc
|
||||||
|
*/
|
||||||
|
String getConfiguration (String name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,13 @@ package org.torproject.android.service;
|
||||||
*/
|
*/
|
||||||
oneway interface ITorServiceCallback {
|
oneway interface ITorServiceCallback {
|
||||||
/**
|
/**
|
||||||
* Called when the service has a new value for you.
|
* Called when the service has a something to display to the user
|
||||||
*/
|
*/
|
||||||
void statusChanged(String value);
|
void statusChanged(String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the service has something to add to the log
|
||||||
|
*/
|
||||||
|
void logMessage(String value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,25 +15,28 @@ import net.freehaven.tor.control.ConfigEntry;
|
||||||
import net.freehaven.tor.control.EventHandler;
|
import net.freehaven.tor.control.EventHandler;
|
||||||
import net.freehaven.tor.control.TorControlConnection;
|
import net.freehaven.tor.control.TorControlConnection;
|
||||||
|
|
||||||
|
import org.torproject.android.AppManager;
|
||||||
import org.torproject.android.Orbot;
|
import org.torproject.android.Orbot;
|
||||||
import org.torproject.android.R;
|
import org.torproject.android.R;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteCallbackList;
|
import android.os.RemoteCallbackList;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class TorService extends Service implements TorServiceConstants, Runnable, EventHandler
|
public class TorService extends Service implements TorServiceConstants, Runnable, EventHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static int currentStatus = STATUS_READY;
|
private static int currentStatus = STATUS_READY;
|
||||||
|
|
||||||
private TorControlConnection conn = null;
|
private TorControlConnection conn = null;
|
||||||
|
@ -44,7 +47,10 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
private static final int MAX_START_TRIES = 3;
|
private static final int MAX_START_TRIES = 3;
|
||||||
|
|
||||||
|
private ArrayList<String> configBuffer = null;
|
||||||
|
|
||||||
|
private boolean hasRoot = false;
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
@ -57,6 +63,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
_torInstance = this;
|
_torInstance = this;
|
||||||
|
|
||||||
|
hasRoot = TorServiceUtils.hasRoot();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,19 +137,19 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void showToolbarNotification (String title, String notifyMsg, int icon)
|
private void showToolbarNotification (String notifyMsg, int icon)
|
||||||
{
|
{
|
||||||
|
|
||||||
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
|
||||||
CharSequence tickerText = title;
|
CharSequence tickerText = notifyMsg;
|
||||||
long when = System.currentTimeMillis();
|
long when = System.currentTimeMillis();
|
||||||
|
|
||||||
Notification notification = new Notification(icon, tickerText, when);
|
Notification notification = new Notification(icon, tickerText, when);
|
||||||
|
|
||||||
Context context = getApplicationContext();
|
Context context = getApplicationContext();
|
||||||
CharSequence contentTitle = title;
|
CharSequence contentTitle = getString(R.string.app_name);
|
||||||
CharSequence contentText = notifyMsg;
|
CharSequence contentText = notifyMsg;
|
||||||
|
|
||||||
Intent notificationIntent = new Intent(this, Orbot.class);
|
Intent notificationIntent = new Intent(this, Orbot.class);
|
||||||
|
@ -189,7 +196,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
currentStatus = STATUS_OFF;
|
currentStatus = STATUS_OFF;
|
||||||
this.showToolbarNotification("Orbot", "Unable to start Tor", R.drawable.tornotification);
|
this.showToolbarNotification(getString(R.string.status_disabled), R.drawable.tornotification);
|
||||||
Log.i(TAG,"Unable to start Tor: " + e.getMessage(),e);
|
Log.i(TAG,"Unable to start Tor: " + e.getMessage(),e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,9 +227,11 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
currentStatus = STATUS_READY;
|
currentStatus = STATUS_READY;
|
||||||
|
|
||||||
showToolbarNotification ("Orbot","Tor is disabled",R.drawable.tornotificationoff);
|
|
||||||
sendCallbackMessage("Tor is disabled");
|
showToolbarNotification (getString(R.string.status_disabled),R.drawable.tornotificationoff);
|
||||||
|
sendCallbackMessage(getString(R.string.status_disabled));
|
||||||
|
|
||||||
|
setupTransProxy(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -254,7 +263,8 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
if (conn != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Log.i(TAG,"sending SHUTDOWN signal");
|
logNotice("sending SHUTDOWN signal to Tor process");
|
||||||
|
// conn.shutdownTor(arg0)
|
||||||
conn.signal("SHUTDOWN");
|
conn.signal("SHUTDOWN");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.i(TAG,"error shutting down Tor via connection",e);
|
Log.i(TAG,"error shutting down Tor via connection",e);
|
||||||
|
@ -269,7 +279,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
while (procId != -1)
|
while (procId != -1)
|
||||||
{
|
{
|
||||||
|
|
||||||
Log.i(TAG,"Found Tor PID=" + procId + " - killing now...");
|
logNotice("Found Tor PID=" + procId + " - killing now...");
|
||||||
|
|
||||||
String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" };
|
String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" };
|
||||||
TorServiceUtils.doShellCommand(cmd,log, false, false);
|
TorServiceUtils.doShellCommand(cmd,log, false, false);
|
||||||
|
@ -290,22 +300,6 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
procId = TorServiceUtils.findProcessId(TorServiceConstants.PRIVOXY_INSTALL_PATH);
|
procId = TorServiceUtils.findProcessId(TorServiceConstants.PRIVOXY_INSTALL_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
//removing this for now
|
|
||||||
if (_webProxy != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//shutdown web proxy
|
|
||||||
_webProxy.stop();
|
|
||||||
_webProxy = null;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.i(TAG,"error stopping web proxy",e);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logNotice (String msg)
|
private void logNotice (String msg)
|
||||||
|
@ -335,17 +329,17 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
if (torBinaryExists && privoxyBinaryExists)
|
if (torBinaryExists && privoxyBinaryExists)
|
||||||
{
|
{
|
||||||
logNotice("Tor, Privoxy, IPtables binaries installed!");
|
logNotice(getString(R.string.status_install_success));
|
||||||
|
|
||||||
this.showToolbarNotification("Orbot Installed!", "Tor was successfully extracted and installed", R.drawable.tornotification);
|
showToolbarNotification(getString(R.string.status_install_success), R.drawable.tornotification);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logNotice("Binary install FAILED!");
|
|
||||||
|
logNotice(getString(R.string.status_install_fail));
|
||||||
this.showToolbarNotification("Orbot FAIL!", "The binaries were unable to be installed", R.drawable.tornotification);
|
|
||||||
|
|
||||||
|
showAlert(getString(R.string.title_error),getString(R.string.status_install_fail));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -354,11 +348,11 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
StringBuilder log = new StringBuilder ();
|
StringBuilder log = new StringBuilder ();
|
||||||
|
|
||||||
Log.i(TAG,"Setting permission on Tor binary");
|
logNotice("Setting permission on Tor binary");
|
||||||
String[] cmd1 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + TOR_BINARY_INSTALL_PATH};
|
String[] cmd1 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + TOR_BINARY_INSTALL_PATH};
|
||||||
TorServiceUtils.doShellCommand(cmd1, log, false, true);
|
TorServiceUtils.doShellCommand(cmd1, log, false, true);
|
||||||
|
|
||||||
Log.i(TAG,"Setting permission on Privoxy binary");
|
logNotice("Setting permission on Privoxy binary");
|
||||||
String[] cmd2 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + PRIVOXY_INSTALL_PATH};
|
String[] cmd2 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + PRIVOXY_INSTALL_PATH};
|
||||||
TorServiceUtils.doShellCommand(cmd2, log, false, true);
|
TorServiceUtils.doShellCommand(cmd2, log, false, true);
|
||||||
|
|
||||||
|
@ -367,17 +361,19 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
public void initTor () throws Exception
|
public void initTor () throws Exception
|
||||||
{
|
{
|
||||||
|
// android.os.Debug.waitForDebugger();
|
||||||
|
|
||||||
currentStatus = STATUS_CONNECTING;
|
currentStatus = STATUS_CONNECTING;
|
||||||
|
|
||||||
logNotice("Tor is starting up...");
|
logNotice(getString(R.string.status_starting_up));
|
||||||
this.sendCallbackMessage("starting...");
|
|
||||||
|
sendCallbackMessage(getString(R.string.status_starting_up));
|
||||||
|
|
||||||
killTorProcess ();
|
killTorProcess ();
|
||||||
|
|
||||||
checkTorBinaries ();
|
checkTorBinaries ();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
new Thread()
|
new Thread()
|
||||||
{
|
{
|
||||||
|
@ -401,6 +397,8 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
runTorShellCmd();
|
runTorShellCmd();
|
||||||
|
|
||||||
|
setupTransProxy(true);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.i(TAG,"Unable to start Tor: " + e.getMessage(),e);
|
Log.i(TAG,"Unable to start Tor: " + e.getMessage(),e);
|
||||||
|
@ -440,7 +438,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
{
|
{
|
||||||
sendCallbackMessage("Couldn't start Tor process...\n" + log.toString());
|
sendCallbackMessage("Couldn't start Tor process...\n" + log.toString());
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
sendCallbackMessage("Trying to start Tor again...\n" + log.toString());
|
sendCallbackMessage(getString(R.string.status_starting_up));
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
attempts++;
|
attempts++;
|
||||||
}
|
}
|
||||||
|
@ -457,7 +455,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
logNotice("Tor process id=" + procId);
|
logNotice("Tor process id=" + procId);
|
||||||
|
|
||||||
showToolbarNotification("Orbot starting...", "Tor is running", R.drawable.tornotification);
|
showToolbarNotification(getString(R.string.status_starting_up), R.drawable.tornotification);
|
||||||
|
|
||||||
initControlConnection ();
|
initControlConnection ();
|
||||||
}
|
}
|
||||||
|
@ -489,7 +487,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
if (privoxyProcId == -1)
|
if (privoxyProcId == -1)
|
||||||
{
|
{
|
||||||
this.sendCallbackMessage("Couldn't start Privoxy process... retrying...\n" + log);
|
logNotice("Couldn't start Privoxy process... retrying...\n" + log);
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
attempts++;
|
attempts++;
|
||||||
}
|
}
|
||||||
|
@ -506,18 +504,16 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
public String generateHashPassword ()
|
public String generateHashPassword ()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
PasswordDigest d = PasswordDigest.generateDigest();
|
PasswordDigest d = PasswordDigest.generateDigest();
|
||||||
byte[] s = d.getSecret(); // pass this to authenticate
|
byte[] s = d.getSecret(); // pass this to authenticate
|
||||||
String h = d.getHashedPassword(); // pass this to the Tor on startup.
|
String h = d.getHashedPassword(); // pass this to the Tor on startup.
|
||||||
*/
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public void initControlConnection () throws Exception, RuntimeException
|
public void initControlConnection () throws Exception, RuntimeException
|
||||||
{
|
{
|
||||||
|
@ -534,7 +530,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
conn = TorControlConnection.getConnection(s);
|
conn = TorControlConnection.getConnection(s);
|
||||||
// conn.authenticate(new byte[0]); // See section 3.2
|
// conn.authenticate(new byte[0]); // See section 3.2
|
||||||
|
|
||||||
sendCallbackMessage(baseMessage + ' ' + getString(R.string.tor_process_connecting_step2));
|
sendCallbackMessage(getString(R.string.tor_process_connecting_step2));
|
||||||
|
|
||||||
Log.i(TAG,"SUCCESS connected to control port");
|
Log.i(TAG,"SUCCESS connected to control port");
|
||||||
|
|
||||||
|
@ -542,13 +538,20 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
byte[] cookie = new byte[(int)fileCookie.length()];
|
byte[] cookie = new byte[(int)fileCookie.length()];
|
||||||
new FileInputStream(new File(TOR_CONTROL_AUTH_COOKIE)).read(cookie);
|
new FileInputStream(new File(TOR_CONTROL_AUTH_COOKIE)).read(cookie);
|
||||||
conn.authenticate(cookie);
|
conn.authenticate(cookie);
|
||||||
|
|
||||||
Log.i(TAG,"SUCCESS authenticated to control port");
|
Log.i(TAG,"SUCCESS authenticated to control port");
|
||||||
|
|
||||||
sendCallbackMessage(baseMessage + ' ' + getString(R.string.tor_process_connecting_step3));
|
sendCallbackMessage(getString(R.string.tor_process_connecting_step2) + getString(R.string.tor_process_connecting_step3));
|
||||||
|
|
||||||
addEventHandler();
|
addEventHandler();
|
||||||
|
|
||||||
|
if (configBuffer != null)
|
||||||
|
{
|
||||||
|
conn.setConf(configBuffer);
|
||||||
|
//conn.saveConf();
|
||||||
|
configBuffer = null;
|
||||||
|
}
|
||||||
|
|
||||||
break; //don't need to retry
|
break; //don't need to retry
|
||||||
}
|
}
|
||||||
catch (Exception ce)
|
catch (Exception ce)
|
||||||
|
@ -568,29 +571,6 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void modifyConf () throws IOException
|
|
||||||
{
|
|
||||||
// Get one configuration variable.
|
|
||||||
List<ConfigEntry> options = conn.getConf("contact");
|
|
||||||
options.size();
|
|
||||||
// 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 void getTorStatus () throws IOException
|
private void getTorStatus () throws IOException
|
||||||
|
@ -640,7 +620,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
conn.setEventHandler(this);
|
conn.setEventHandler(this);
|
||||||
|
|
||||||
conn.setEvents(Arrays.asList(new String[]{
|
conn.setEvents(Arrays.asList(new String[]{
|
||||||
"ORCONN", "CIRC", "NOTICE", "ERR"}));
|
"ORCONN", "CIRC", "NOTICE", "WARN", "ERR"}));
|
||||||
// conn.setEvents(Arrays.asList(new String[]{
|
// conn.setEvents(Arrays.asList(new String[]{
|
||||||
// "DEBUG", "INFO", "NOTICE", "WARN", "ERR"}));
|
// "DEBUG", "INFO", "NOTICE", "WARN", "ERR"}));
|
||||||
|
|
||||||
|
@ -701,7 +681,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
if (msg.indexOf(TOR_CONTROL_PORT_MSG_BOOTSTRAP_DONE)!=-1)
|
if (msg.indexOf(TOR_CONTROL_PORT_MSG_BOOTSTRAP_DONE)!=-1)
|
||||||
{
|
{
|
||||||
currentStatus = STATUS_ON;
|
currentStatus = STATUS_ON;
|
||||||
showToolbarNotification ("Orbot","Tor is enabled",R.drawable.tornotification);
|
showToolbarNotification (getString(R.string.status_activated),R.drawable.tornotification);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,6 +689,15 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showAlert(String title, String msg)
|
||||||
|
{
|
||||||
|
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setTitle(title)
|
||||||
|
.setMessage(msg)
|
||||||
|
.setPositiveButton(android.R.string.ok, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
public void newDescriptors(List<String> orList) {
|
public void newDescriptors(List<String> orList) {
|
||||||
|
|
||||||
|
@ -783,6 +772,8 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Intent launchContext = null;
|
||||||
|
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
// Select the interface to return. If your service only implements
|
// Select the interface to return. If your service only implements
|
||||||
// a single interface, you can just return it here without checking
|
// a single interface, you can just return it here without checking
|
||||||
|
@ -807,6 +798,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
* The IRemoteInterface is defined through IDL
|
* The IRemoteInterface is defined through IDL
|
||||||
*/
|
*/
|
||||||
private final ITorService.Stub mBinder = new ITorService.Stub() {
|
private final ITorService.Stub mBinder = new ITorService.Stub() {
|
||||||
|
|
||||||
public void registerCallback(ITorServiceCallback cb) {
|
public void registerCallback(ITorServiceCallback cb) {
|
||||||
if (cb != null) mCallbacks.register(cb);
|
if (cb != null) mCallbacks.register(cb);
|
||||||
}
|
}
|
||||||
|
@ -820,10 +812,103 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
public void setProfile (int profile)
|
public void setProfile (int profile)
|
||||||
{
|
{
|
||||||
setTorProfile(profile);
|
setTorProfile(profile);
|
||||||
sendCallbackMessage("");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set configuration
|
||||||
|
**/
|
||||||
|
public boolean updateConfiguration (String name, String value, boolean saveToDisk)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (conn != null)
|
||||||
|
{
|
||||||
|
conn.setConf(name, value);
|
||||||
|
|
||||||
|
if (saveToDisk)
|
||||||
|
{
|
||||||
|
// Flush the configuration to disk.
|
||||||
|
//conn.saveConf(); //NF 22/07/10 this is crashing right now
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (configBuffer == null)
|
||||||
|
configBuffer = new ArrayList<String>();
|
||||||
|
|
||||||
|
configBuffer.add(name + ' ' + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException ioe)
|
||||||
|
{
|
||||||
|
Log.e(TAG, "Unable to update Tor configuration", ioe);
|
||||||
|
logNotice("Unable to update Tor configuration: " + ioe.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean saveConfiguration ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (conn != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private ArrayList<String> callbackBuffer = new ArrayList<String>();
|
private ArrayList<String> callbackBuffer = new ArrayList<String>();
|
||||||
|
@ -864,4 +949,40 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
mCallbacks.finishBroadcast();
|
mCallbacks.finishBroadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupTransProxy (boolean enabled)
|
||||||
|
{
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
|
boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false);
|
||||||
|
boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false);
|
||||||
|
|
||||||
|
logNotice ("Transparent Proxying: " + enableTransparentProxy);
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (hasRoot && enableTransparentProxy)
|
||||||
|
{
|
||||||
|
|
||||||
|
TorTransProxy.setDNSProxying();
|
||||||
|
TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this),transProxyAll);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TorTransProxy.purgeNatIptables();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (hasRoot)
|
||||||
|
{
|
||||||
|
TorTransProxy.purgeNatIptables();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,12 @@ public interface TorServiceConstants {
|
||||||
|
|
||||||
public final static String TAG = "TOR_SERVICE";
|
public final static String TAG = "TOR_SERVICE";
|
||||||
|
|
||||||
|
public final static String TOR_APP_USERNAME = "org.torproject.android";
|
||||||
|
|
||||||
//home directory of Android application
|
//home directory of Android application
|
||||||
public final static String TOR_HOME = "/data/data/org.torproject.android/";
|
public final static String TOR_HOME = "/data/data/" + TOR_APP_USERNAME + "/";
|
||||||
|
|
||||||
public final static String TOR_HOME_DATA_DIR = TOR_HOME + "cache/";
|
public final static String TOR_HOME_DATA_DIR = TOR_HOME + "data/";
|
||||||
|
|
||||||
//name of the tor C binary
|
//name of the tor C binary
|
||||||
public final static String TOR_BINARY_ASSET_KEY = "tor";
|
public final static String TOR_BINARY_ASSET_KEY = "tor";
|
||||||
|
|
|
@ -21,94 +21,10 @@ import android.util.Log;
|
||||||
|
|
||||||
public class TorServiceUtils implements TorServiceConstants {
|
public class TorServiceUtils implements TorServiceConstants {
|
||||||
|
|
||||||
private static TorifiedApp[] apps = null;
|
|
||||||
|
|
||||||
private final static String PREFS_KEY = "OrbotPrefs";
|
private final static String PREFS_KEY = "OrbotPrefs";
|
||||||
private final static String PREFS_KEY_TORIFIED = "PrefTord";
|
private final static String PREFS_KEY_TORIFIED = "PrefTord";
|
||||||
|
|
||||||
public static void saveAppSettings (Context context)
|
|
||||||
{
|
|
||||||
if (apps == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
final SharedPreferences prefs = context.getSharedPreferences(PREFS_KEY, 0);
|
|
||||||
|
|
||||||
StringBuilder tordApps = new StringBuilder();
|
|
||||||
|
|
||||||
for (int i = 0; i < apps.length; i++)
|
|
||||||
{
|
|
||||||
if (apps[i].isTorified())
|
|
||||||
{
|
|
||||||
tordApps.append(apps[i].getUsername());
|
|
||||||
tordApps.append("|");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Editor edit = prefs.edit();
|
|
||||||
edit.putString(PREFS_KEY_TORIFIED, tordApps.toString());
|
|
||||||
edit.commit();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TorifiedApp[] getApps (Context context)
|
|
||||||
{
|
|
||||||
if (apps != null)
|
|
||||||
return apps;
|
|
||||||
|
|
||||||
final SharedPreferences prefs = context.getSharedPreferences(PREFS_KEY, 0);
|
|
||||||
|
|
||||||
String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, "");
|
|
||||||
String[] tordApps;
|
|
||||||
|
|
||||||
StringTokenizer st = new StringTokenizer(tordAppString,"|");
|
|
||||||
tordApps = new String[st.countTokens()];
|
|
||||||
int tordIdx = 0;
|
|
||||||
while (st.hasMoreTokens())
|
|
||||||
{
|
|
||||||
tordApps[tordIdx++] = st.nextToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
Arrays.sort(tordApps);
|
|
||||||
|
|
||||||
//else load the apps up
|
|
||||||
PackageManager pMgr = context.getPackageManager();
|
|
||||||
|
|
||||||
List<ApplicationInfo> lAppInfo = pMgr.getInstalledApplications(0);
|
|
||||||
|
|
||||||
Iterator<ApplicationInfo> itAppInfo = lAppInfo.iterator();
|
|
||||||
|
|
||||||
apps = new TorifiedApp[lAppInfo.size()];
|
|
||||||
|
|
||||||
ApplicationInfo aInfo = null;
|
|
||||||
|
|
||||||
int appIdx = 0;
|
|
||||||
|
|
||||||
while (itAppInfo.hasNext())
|
|
||||||
{
|
|
||||||
aInfo = itAppInfo.next();
|
|
||||||
|
|
||||||
apps[appIdx] = new TorifiedApp();
|
|
||||||
|
|
||||||
apps[appIdx].setEnabled(aInfo.enabled);
|
|
||||||
apps[appIdx].setUid(aInfo.uid);
|
|
||||||
apps[appIdx].setUsername(pMgr.getNameForUid(apps[appIdx].getUid()));
|
|
||||||
apps[appIdx].setProcname(aInfo.processName);
|
|
||||||
apps[appIdx].setName(pMgr.getApplicationLabel(aInfo).toString());
|
|
||||||
|
|
||||||
// check if this application is allowed
|
|
||||||
if (Arrays.binarySearch(tordApps, apps[appIdx].getUsername()) >= 0) {
|
|
||||||
apps[appIdx].setTorified(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
apps[appIdx].setTorified(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
appIdx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return apps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int findProcessId(String command)
|
public static int findProcessId(String command)
|
||||||
{
|
{
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class TorTransProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean setTransparentProxying(Context context, TorifiedApp[] apps) {
|
public static boolean setTransparentProxyingByApp(Context context, TorifiedApp[] apps, boolean forceAll) {
|
||||||
|
|
||||||
String command = null;
|
String command = null;
|
||||||
|
|
||||||
|
@ -101,14 +101,24 @@ public class TorTransProxy {
|
||||||
|
|
||||||
final StringBuilder script = new StringBuilder();
|
final StringBuilder script = new StringBuilder();
|
||||||
|
|
||||||
|
StringBuilder res = new StringBuilder();
|
||||||
|
int code = -1;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int code;
|
|
||||||
|
|
||||||
for (int i = 0; i < apps.length; i++)
|
for (int i = 0; i < apps.length; i++)
|
||||||
{
|
{
|
||||||
|
if (forceAll || apps[i].isTorified())
|
||||||
if (apps[i].isTorified())
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (apps[i].getUsername().equals(TorServiceConstants.TOR_APP_USERNAME))
|
||||||
|
{
|
||||||
|
Log.i(TAG,"detected Orbot app - will not transproxy");
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Log.i(TAG,"enabling transproxy for app: " + apps[i].getUsername() + "(" + apps[i].getUid() + ")");
|
Log.i(TAG,"enabling transproxy for app: " + apps[i].getUsername() + "(" + apps[i].getUid() + ")");
|
||||||
|
|
||||||
//TCP
|
//TCP
|
||||||
|
@ -129,17 +139,16 @@ public class TorTransProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder res = new StringBuilder();
|
|
||||||
|
|
||||||
String[] cmd = {script.toString()};
|
String[] cmd = {script.toString()};
|
||||||
|
|
||||||
code = TorServiceUtils.doShellCommand(cmd, res, true, true);
|
code = TorServiceUtils.doShellCommand(cmd, res, true, true);
|
||||||
|
|
||||||
String msg = res.toString();
|
String msg = res.toString();
|
||||||
Log.e(TAG, msg);
|
Log.e(TAG, msg);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(TAG, "error refreshing iptables: " + e);
|
Log.w(TAG, "error refreshing iptables: err=" + code + "; resp=" + res.toString(), e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue