added tethering support
This commit is contained in:
parent
422ba4bbcd
commit
ddb4793b0a
|
@ -1,9 +1,8 @@
|
|||
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
||||
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - https://guardianproject.info */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
package org.torproject.android;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -47,35 +46,48 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
{
|
||||
|
||||
/* Useful UI bits */
|
||||
// so this is probably pretty obvious, here, but also an area
|
||||
// which we might see quite a bit of change+complexity was the main screen
|
||||
// UI gets new features
|
||||
private TextView lblStatus = null; //the main text display widget
|
||||
private ImageView imgStatus = null; //the main touchable image for activating Orbot
|
||||
private ProgressDialog progressDialog;
|
||||
private MenuItem mItemOnOff = null;
|
||||
private ProgressDialog progressDialog; //the spinning progress dialog that shows up now and then
|
||||
private MenuItem mItemOnOff = null; //the menu item which we toggle based on Orbot state
|
||||
|
||||
/* Some tracking bits */
|
||||
private int torStatus = STATUS_READY; //latest status reported from the tor service
|
||||
// this is a value we get passed back from the TorService
|
||||
|
||||
/* Tor Service interaction */
|
||||
/* The primary interface we will be calling on the service. */
|
||||
ITorService mService = null;
|
||||
private boolean autoStartOnBind = false;
|
||||
ITorService mService = null; //interface to remote TorService
|
||||
private boolean autoStartOnBind = false; //controls whether service starts when class binds to it
|
||||
|
||||
SharedPreferences prefs;
|
||||
SharedPreferences prefs; //what the user really wants!
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
/**
|
||||
* When the Orbot activity is created, we call startService
|
||||
* to ensure the Tor remote service is running. However, it may
|
||||
* already be running, and this should not create more than one instnace
|
||||
*/
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//if Tor binary is not running, then start the service up
|
||||
//might want to look at whether we need to call this every time
|
||||
//or whether binding to the service is enough
|
||||
startService(new Intent(INTENT_TOR_SERVICE));
|
||||
|
||||
|
||||
//something to play with on the UI branch
|
||||
setTheme(android.R.style.Theme_Black_NoTitleBar);
|
||||
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
//same here - layout_main has been cleaned up since 1.0.5.2 a bit (removed table as you recmnd)
|
||||
//but ther eis more to be done
|
||||
setContentView(R.layout.layout_main);
|
||||
|
||||
//obvious? -yep got everything so far
|
||||
lblStatus = (TextView)findViewById(R.id.lblStatus);
|
||||
lblStatus.setOnLongClickListener(this);
|
||||
imgStatus = (ImageView)findViewById(R.id.imgStatus);
|
||||
|
@ -201,14 +213,25 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is our attempt to REALLY exit Orbot, and stop the background service
|
||||
* However, Android doesn't like people "quitting" apps, and/or our code may not
|
||||
* be quite right b/c no matter what we do, it seems like the TorService still exists
|
||||
**/
|
||||
private void doExit ()
|
||||
{
|
||||
try {
|
||||
|
||||
//one of the confusing things about all of this code is the multiple
|
||||
//places where things like "stopTor" are called, both in the Activity and the Service
|
||||
//not something to tackle in your first iteration, but i thin we can talk about fixing
|
||||
//terminology but also making sure there are clear distinctions in control
|
||||
stopTor();
|
||||
|
||||
//perhaps this should be referenced as INTENT_TOR_SERVICE as in startService
|
||||
stopService(new Intent(ITorService.class.getName()));
|
||||
|
||||
//clears all notifications from the status bar
|
||||
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager.cancelAll();
|
||||
|
||||
|
@ -228,6 +251,7 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
/*
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event){
|
||||
|
||||
//yeah this should probably go away now :) - or not
|
||||
if(keyCode==KeyEvent.KEYCODE_BACK){
|
||||
|
||||
if(currentView != R.layout.layout_main){
|
||||
|
@ -256,6 +280,13 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
aDialog.dismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* i think we need to suport this onSave/Restore code more b/c i think
|
||||
* when someone rotates the screen, and the state is lost during setup
|
||||
* etc it causes problems. this might be the place to solve that in the wizard - hmm this prob coz android restarts the activity when the screen is rotated. this will prob be fixed(?) when
|
||||
we redesign the wizard into a view not just a dialogbox
|
||||
cool
|
||||
**/
|
||||
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||
// Save UI state changes to the savedInstanceState.
|
||||
// This bundle will be passed to onCreate if the process is
|
||||
|
@ -269,8 +300,16 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
// Restore UI state from the savedInstanceState.
|
||||
// This bundle has also been passed to onCreate.
|
||||
|
||||
//we do nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* confirm with the user that they want to open a browser to connect to https://check.torproject.org
|
||||
and then launch the URL.
|
||||
this may be where the TorCheck API code/UI is added, though always offering the web-based confirm
|
||||
should be an option, since users know it
|
||||
|
||||
**/
|
||||
private void doTorCheck ()
|
||||
{
|
||||
|
||||
|
@ -301,6 +340,14 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* this adds a port to the list of hidden service ports
|
||||
* we might want to add remove/disable port too
|
||||
* this is used by external apps that launch an intent
|
||||
* to request a hidden service on a specific port
|
||||
* currently, we haven't promoted this intent API or capability
|
||||
* that much, but we hope to
|
||||
**/
|
||||
private void enableHiddenServicePort (int hsPort)
|
||||
{
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
@ -332,10 +379,21 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
//this is where we make sure we have a handle to ITorService
|
||||
bindService();
|
||||
|
||||
//this is a hack which basically pings the ITorService to update our status for the UI
|
||||
// - the dialogbox/progressbar ?
|
||||
// right, this was for when the label displayed the status, and not the progress, so it may
|
||||
// not make as much sense now; there is a bunch of loose ends like this that should be
|
||||
// cleaned up with the transition to the progressdialog - ok
|
||||
updateStatus("");
|
||||
|
||||
//this checks if we were launched via an Intent call from another app or activity
|
||||
//- how does this matter? if Orbot has been launched via an Intent or not ?
|
||||
//we want to know if this is a launch by the user from the home screen, or via back, or some
|
||||
// standard interaction, or if it is another app launching Orbot for a programmatic/API request
|
||||
// this is how we can add more functionality into ORlib, for instance via Intent launching - hmm ok
|
||||
if (getIntent() == null)
|
||||
return;
|
||||
|
||||
|
@ -344,9 +402,11 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
if (action == null)
|
||||
return;
|
||||
|
||||
//this relates to the previously discussed hidden port capability
|
||||
if (action.equals("org.torproject.android.REQUEST_HS_PORT"))
|
||||
{
|
||||
|
||||
//tell the user an app is trying to open a hidden port and ask for permission
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
|
@ -379,7 +439,7 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
|
||||
|
||||
}
|
||||
else if (action.equals("org.torproject.android.START_TOR"))
|
||||
else if (action.equals("org.torproject.android.START_TOR")) //this is the intent used to start Tor from another app, again meant for ORlib functionality
|
||||
{
|
||||
autoStartOnBind = true;
|
||||
|
||||
|
@ -389,8 +449,8 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
//setTitle(getString(R.string.app_name) + ' ' + getString(R.string.app_version));
|
||||
//hmm not sure when this is ever reached honestly ;P
|
||||
//but it looks like a general UI reset
|
||||
|
||||
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager.cancelAll();
|
||||
|
@ -472,6 +532,9 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
//if we get a response from an activity we launched (like from line 527 where we launch the Settings/Prefs screen)
|
||||
//and the resultCode matches our arbitrary 1010 value, AND Tor is running
|
||||
//then update the preferences in an async background task
|
||||
if (requestCode == 1 && resultCode == 1010 && mService != null)
|
||||
{
|
||||
new ProcessSettingsAsyncTask().execute(mService);
|
||||
|
@ -480,6 +543,10 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
|
||||
AlertDialog aDialog = null;
|
||||
|
||||
//general alert dialog for mostly Tor warning messages
|
||||
//sometimes this can go haywire or crazy with too many error
|
||||
//messages from Tor, and the user cannot stop or exit Orbot
|
||||
//so need to ensure repeated error messages are not spamming this method
|
||||
private void showAlert(String title, String msg, boolean button)
|
||||
{
|
||||
try
|
||||
|
@ -511,15 +578,17 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
}
|
||||
/*
|
||||
* Set the state of the running/not running graphic and label
|
||||
* this all needs to be looked at w/ the shift to progressDialog
|
||||
*/
|
||||
public void updateStatus (String torServiceMsg)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
//if the serivce is bound, query it for the curren status value (int)
|
||||
if (mService != null)
|
||||
torStatus = mService.getStatus();
|
||||
|
||||
//now update the layout_main UI based on the status
|
||||
if (imgStatus != null)
|
||||
{
|
||||
|
||||
|
@ -605,16 +674,25 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
|
||||
}
|
||||
|
||||
// guess what? this start's Tor! actually no it just requests via the local ITorService to the remote TorService instance
|
||||
// to start Tor
|
||||
private void startTor () throws RemoteException
|
||||
{
|
||||
|
||||
// here we bind AGAIN - at some point i think we had to bind multiple times just in case
|
||||
// but i would love to clarify, clean this up
|
||||
bindService();
|
||||
|
||||
// this is a bit of a strange/old/borrowed code/design i used to change the service state
|
||||
// not sure it really makes sense when what we want to say is just "startTor"
|
||||
mService.setProfile(TorServiceConstants.PROFILE_ON); //this means turn on
|
||||
|
||||
//here we update the UI which is a bit sloppy and mixed up code wise
|
||||
//might be best to just call updateStatus() instead of directly manipulating UI in this method - yep makes sense
|
||||
imgStatus.setImageResource(R.drawable.torstarting);
|
||||
lblStatus.setText(getString(R.string.status_starting_up));
|
||||
|
||||
|
||||
//we send a message here to the progressDialog i believe, but we can clarify that shortly
|
||||
Message msg = mHandler.obtainMessage(TorServiceConstants.ENABLE_TOR_MSG);
|
||||
mHandler.sendMessage(msg);
|
||||
|
||||
|
@ -622,11 +700,15 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
|
||||
}
|
||||
|
||||
//now we stop Tor! amazing!
|
||||
private void stopTor () throws RemoteException
|
||||
{
|
||||
//if the service is bound, then turn it off, using the same "PROFILE_" technique
|
||||
if (mService != null)
|
||||
{
|
||||
mService.setProfile(TorServiceConstants.PROFILE_OFF);
|
||||
|
||||
//again this is related to the progress dialog or some other threaded UI object
|
||||
Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG);
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
@ -675,6 +757,10 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
/**
|
||||
* This implementation is used to receive callbacks from the remote
|
||||
* service.
|
||||
*
|
||||
* If we have this setup probably, we shouldn't have to poll or query status
|
||||
* to the service, as it should send it as it changes or when we bind/unbind to it
|
||||
* from this activity
|
||||
*/
|
||||
private ITorServiceCallback mCallback = new ITorServiceCallback.Stub() {
|
||||
/**
|
||||
|
@ -684,14 +770,17 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
* NOT be running in our main thread like most other things -- so,
|
||||
* to update the UI, we need to use a Handler to hop over there.
|
||||
*/
|
||||
|
||||
//receive a new string vaule end-user displayable message from the ITorService
|
||||
public void statusChanged(String value) {
|
||||
|
||||
//pass it off to the progressDialog
|
||||
Message msg = mHandler.obtainMessage(TorServiceConstants.STATUS_MSG);
|
||||
msg.getData().putString(HANDLER_TOR_MSG, value);
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override //this was when we displayed the log in the main Activity; can prob take this out now
|
||||
public void logMessage(String value) throws RemoteException {
|
||||
|
||||
Message msg = mHandler.obtainMessage(TorServiceConstants.LOG_MSG);
|
||||
|
@ -702,6 +791,8 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
};
|
||||
|
||||
|
||||
// this is what takes messages or values from the callback threads or other non-mainUI threads
|
||||
//and passes them back into the main UI thread for display to the user
|
||||
private Handler mHandler = new Handler() {
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
|
@ -741,6 +832,10 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
/**
|
||||
* Class for interacting with the main interface of the service.
|
||||
*/
|
||||
// this is the connection that gets called back when a successfull bind occurs
|
||||
// we should use this to activity monitor unbind so that we don't have to call
|
||||
// bindService() a million times
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
public void onServiceConnected(ComponentName className,
|
||||
IBinder service) {
|
||||
|
@ -756,6 +851,7 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
try {
|
||||
mService.registerCallback(mCallback);
|
||||
|
||||
//again with the update status?!? :P
|
||||
updateStatus("");
|
||||
|
||||
if (autoStartOnBind)
|
||||
|
@ -789,10 +885,15 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
}
|
||||
};
|
||||
|
||||
//should move this up with all the other class variables
|
||||
boolean mIsBound = false;
|
||||
|
||||
//this is where we bind!
|
||||
private void bindService ()
|
||||
{
|
||||
//since its auto create, we prob don't ever need to call startService
|
||||
//also we should again be consistent with using either iTorService.class.getName()
|
||||
//or the variable constant
|
||||
bindService(new Intent(ITorService.class.getName()),
|
||||
mConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
|
@ -800,6 +901,7 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
|
||||
}
|
||||
|
||||
//unbind removes the callback, and unbinds the service
|
||||
private void unbindService ()
|
||||
{
|
||||
if (mIsBound) {
|
||||
|
@ -815,6 +917,9 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
|||
}
|
||||
}
|
||||
|
||||
//maybe needs this?
|
||||
mService = null;
|
||||
|
||||
// Detach our existing connection.
|
||||
unbindService(mConnection);
|
||||
mIsBound = false;
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package org.torproject.android.boot;
|
||||
|
||||
import org.torproject.android.service.ITorService;
|
||||
import org.torproject.android.service.TorService;
|
||||
import org.torproject.android.service.TorServiceConstants;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
public class OnbootBroadcastReceiver extends BroadcastReceiver implements TorServiceConstants {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
Log.d(TAG, "received on boot notification");
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
boolean startOnBoot = prefs.getBoolean("pref_start_boot",true);
|
||||
|
||||
Log.d(TAG, "startOnBoot:" + startOnBoot);
|
||||
|
||||
if (startOnBoot)
|
||||
{
|
||||
Intent serviceIntent = new Intent(context,TorService.class);
|
||||
serviceIntent.setAction("onboot");
|
||||
context.startService(serviceIntent);
|
||||
}
|
||||
|
||||
//bindService(new Intent(ITorService.class.getName()),
|
||||
// mConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
||||
/* Copyright (c) 2009-2011, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
||||
/* See LICENSE for licensing information */
|
||||
package org.torproject.android.service;
|
||||
|
||||
|
@ -545,6 +545,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
|||
boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false);
|
||||
boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false);
|
||||
boolean transProxyPortFallback = prefs.getBoolean("pref_transparent_port_fallback", false);
|
||||
boolean transProxyTethering = prefs.getBoolean("pref_transparent_tethering", false);
|
||||
|
||||
TorService.logMessage ("Transparent Proxying: " + enableTransparentProxy);
|
||||
|
||||
|
@ -581,6 +582,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
|||
showAlert("Status", "Setting up app-based transparent proxying...");
|
||||
code = TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TorService.logMessage ("TorTransProxy resp code: " + code);
|
||||
|
@ -588,12 +590,23 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
|||
if (code == 0)
|
||||
{
|
||||
showAlert("Status", "Transparent proxying ENABLED");
|
||||
|
||||
|
||||
|
||||
if (transProxyTethering)
|
||||
{
|
||||
showAlert("Status", "TransProxy enabled for Tethering!");
|
||||
|
||||
TorTransProxy.enableTetheringRules(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
showAlert("Status", "WARNING: error starting transparent proxying!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
@ -313,14 +313,12 @@ public class TorTransProxy implements TorServiceConstants {
|
|||
return code;
|
||||
}
|
||||
|
||||
public static int enableWifiHotspotRules (Context context) throws Exception
|
||||
public static int enableTetheringRules (Context context) throws Exception
|
||||
{
|
||||
|
||||
boolean runRoot = true;
|
||||
boolean waitFor = true;
|
||||
|
||||
//redirectDNSResolvConf(); //not working yet
|
||||
|
||||
String ipTablesPath = new File(context.getDir("bin", 0),"iptables").getAbsolutePath();
|
||||
|
||||
StringBuilder script = new StringBuilder();
|
||||
|
@ -328,25 +326,24 @@ public class TorTransProxy implements TorServiceConstants {
|
|||
StringBuilder res = new StringBuilder();
|
||||
int code = -1;
|
||||
|
||||
String[] hwinterfaces = {"usb0","wl0.1"};
|
||||
|
||||
for (int i = 0; i < hwinterfaces.length; i++)
|
||||
{
|
||||
script.append(ipTablesPath);
|
||||
script.append(" -I FORWARD");
|
||||
script.append(" -m state --state ESTABLISHED,RELATED -j ACCEPT");
|
||||
script.append(" -t nat -A PREROUTING -i ");
|
||||
script.append(hwinterfaces[i]);
|
||||
script.append(" -p udp --dport 53 -j REDIRECT --to-ports ");
|
||||
script.append(TOR_DNS_PORT);
|
||||
script.append(" || exit\n");
|
||||
|
||||
script.append(ipTablesPath);
|
||||
script.append(" -I FORWARD");
|
||||
script.append(" -j ACCEPT");
|
||||
script.append(" || exit\n");
|
||||
|
||||
/*
|
||||
script.append(ipTablesPath);
|
||||
script.append(" -P FORWARD DROP");
|
||||
script.append(" || exit\n");
|
||||
*/
|
||||
|
||||
script.append(ipTablesPath);
|
||||
script.append(" -t nat -I POSTROUTING -j MASQUERADE");
|
||||
script.append(" -t nat -A PREROUTING -i ");
|
||||
script.append(hwinterfaces[i]);
|
||||
script.append(" -p tcp -j REDIRECT --to-ports ");
|
||||
script.append(TOR_TRANSPROXY_PORT);
|
||||
script.append(" || exit\n");
|
||||
}
|
||||
|
||||
String[] cmdAdd = {script.toString()};
|
||||
|
||||
|
@ -374,8 +371,6 @@ public class TorTransProxy implements TorServiceConstants {
|
|||
|
||||
purgeIptables(context);
|
||||
|
||||
enableWifiHotspotRules(context);
|
||||
|
||||
int torUid = context.getApplicationInfo().uid;
|
||||
|
||||
// Set up port redirection
|
||||
|
|
Loading…
Reference in New Issue