Merge branch 'master' of git://git.torproject.org/n8fr8/orbot

Conflicts:
	AUTHORS
	AndroidManifest.xml
This commit is contained in:
Sathyanarayanan Gunasekaran 2011-07-25 21:57:58 -04:00
commit 34ce45398f
51 changed files with 1742 additions and 770 deletions

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.torproject.android" android:versionName="0.2.2.25-orbot-alpha-1.0.5.2" android:versionCode="14">
package="org.torproject.android" android:versionName="0.2.3.1-orbot-alpha-1.0.5.3" android:versionCode="16">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
<application android:theme="@style/DefaultTheme" android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
<activity android:name=".Orbot"
android:theme="@android:style/Theme.NoTitleBar">
@ -28,8 +28,12 @@
<action android:name="org.torproject.android.START_TOR" />
</intent-filter>
</activity>
<activity android:name=".SettingsPreferences" android:label="@string/app_name"/>
<activity android:name=".LotsaText"/>
<activity android:name=".Permissions"/>
<activity android:name=".TipsAndTricks"/>
<activity android:name=".ConfigureTransProxy"/>
<activity android:name=".SettingsPreferences" android:label="@string/app_name"/>
<activity android:name=".AppManager" android:label="@string/app_name"/>
<activity android:name=".WizardActivity" android:label="@string/app_name"/>

8
BUILD
View File

@ -124,7 +124,13 @@ Finally, we'll make a proper Android package with ant and the Android App SDK:
export APP_SDK=~/Documents/projects/android/android-sdk-linux_x86-1.5_r3/tools
cd ../Orbot/
cp $DROID_ROOT/external/privoxy/privoxy-3.0.12-stable/privoxy assets/privoxy
cp $DROID_ROOT/external/tor/tor/src/or/tor assets/tor
Now you need to split and copy the tor binary into res/raw. We split it into < 1M chunks
because some Android devices don't like resources larger than 1M.
split --bytes=1m $DROID_ROOT/external/tor/tor/src/or/tor res/raw/tor
Now build the Android app
$APP_SDK/android update project --name Orbot --target 3 --path .
ant release

View File

@ -1,5 +1,14 @@
NOTE: Specific #s below correspond to Trac tickets logged and maintained at https://trac.torproject.org/projects/tor/
1.0.5.3
- added auto-tor of wireless and usb tethering
- integrated new setup wizard
- moved large tor binary into split multiple 1M segments to fix for devices with 1M resource limit
1.0.5.1/.2
- small updates to layout of main screen to fit smaller screens
- fixed preference setting of EntryNode torrc value
1.0.5
- added exit node and "StrictExitNode" preference
- fixed tor binary installation issue related to max resource size and compression

90
WALKTHROUGH Normal file
View File

@ -0,0 +1,90 @@
.
└── org
└── torproject
└── android
├── AppManager.java
//this is what helps us track the app-by-app torification
//and gets the app name, icon, etc for display - we have some problems here
//in normalizing the icon on the list label
//some of this code came originally from DroidWall project (yay open source)
├── boot
│ └── OnbootBroadcastReceiver.java
//i think this is a dup now and should be removed
├── HiddenServiceManager.java
//empty! but at some point i thought it would be good to aggregate HS functions here
├── OnBootReceiver.java
//this is the class registered in AndroidManifest.xml to handle Onboot events
//to start Orbot/Tor when the device boots if the user has elected to do so - what kind of permissions does this require?
// <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
// BTW, this shows up as a fairly unintrusive type perm request now in Android / in older versions (1.6 and earlier)
// it was reported "as read / monitor phone state" and paranoid Tor-types didn't like the idea of it
// in 1.6+ it has a much better UX in terms of having a more granular permisions around boot since it is a very
// common request - ah , that's awesome, i think i remember seeing sth of this sorts when i was going through the guardianproject mailing list. iirc this is something ioerror wanted
├── Orbot.java
//our wonderful main activity!
├── ProcessSettingsAsyncTask.java
//this was just added in 1.0.5.x, but it was meant to help stop the UI blocking while processing settings and prefs
//it uses the AsyncTask feature of Android, which seems to work pretty well
//for this type of non-time critical function you just want to happen in the background at some point soon-ish
├── SettingsPreferences.java
// Settings activity that loads the res/xml/preferences.xml resource up
// has some custom event handlng, onActivityResult callback result code's as well
// basically meant to tell Orbot activity if critical settings have been modified and whether
// those new settings should be applied (like iptables/transproxy changes)
├── TorConstants.java
// globals! well, constants! but yeah, just a place to put values we use a lot
├── TorifiedApp.java
// object to store a single app's metadata for display in UI and for transproxy process
├── Utils.java
// random methods that can be useful, a.k.a. another place to put stuff
├── WizardActivity.java
// our original attempt at wizard activity that didn't get far
└── WizardHelper.java
// the helper class that manages the dialog based wizard
├── service //okay the Service subpackage!
│ ├── Api.java
//this is more code taken from DroidWall, that needs to be cleaned up and paired down to just what we need it for
//this is related to 1.0.5.x changes with how we bundle and install our C binaries (tor, privoxy and iptables)
│ ├── ITorService.aidl
// the android remote interface definition file;
// this is the remote interface which the Orbot activity gets a reference to
// and that in the TorService is instantiated as the "binder"
│ ├── ITorServiceCallback.aidl
// this is the callback interface that the Orbot activity instantiates, and passes
// to the ITorService; reverse of ITorService in a sense
│ ├── TorBinaryInstaller.java
// this handles installation of binaries; uses Api.java; // tied into Wizard as well
│ ├── TorServiceConstants.java
// reusable constants for just the Service package
│ ├── TorService.java
// the main might powerful service class; Orbot and TorService are the front and backends of this whole app
// should run as a remote service, but the manifest doesn't seem to indicate that at the moment
│ ├── TorServiceUtils.java
//utility methods for the service; specificaly check for root and tools for finding processID of background binaries
│ └── TorTransProxy.java
// all the code for iptables transproxying management

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

BIN
res/drawable/proxymob.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
res/drawable/warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -5,12 +5,13 @@
android:layout_height="fill_parent"
android:stretchColumns="1">
<TableRow>
<ImageView android:id="@+id/itemicon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="3dip"></ImageView>
<ImageView android:id="@+id/itemicon" android:layout_width="50dip" android:layout_height="50dip" android:padding="3dip"></ImageView>
<TextView android:layout_height="wrap_content" android:id="@+id/itemtext" android:text="uid:packages" android:textSize="18sp" android:padding="3dip"></TextView>
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/itemcheck" ></CheckBox>
</TableRow>
</TableLayout>

View File

@ -33,11 +33,17 @@
android:layout_toLeftOf="@+id/radioModeImage"
android:textColor="#cccccc" />
</RelativeLayout>
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
>
<ImageView
android:id="@+id/imgStatus"
android:layout_margin="5dip"
android:layout_width="320dip"
android:layout_margin="15dip"
android:layout_width="fill_parent"
android:layout_height="320dip"
android:src="@drawable/toroff"
android:layout_gravity="center_horizontal"
@ -45,14 +51,14 @@
<TextView android:id="@+id/lblStatus"
android:text="@string/press_to_start"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="30dip"
android:layout_width="fill_parent"
android:layout_height="60dip"
android:textColor="#ffffff"
android:layout_below="@id/imgStatus"
/>
</RelativeLayout>
</LinearLayout>

View File

@ -0,0 +1,55 @@
<?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">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/relativeLayout1"
android:layout_gravity="center_horizontal"
android:background="#000000">
<TextView android:textSize="10pt"
android:textColor="#FFFFFF"
android:layout_alignParentTop="true"
android:layout_height="wrap_content"
android:id="@+id/WizardTextTitle"
android:layout_width="wrap_content"
android:fadingEdge="vertical"
android:text="TITLE"
android:singleLine="true"
android:padding="20px" android:layout_centerInParent="true">
</TextView>
</RelativeLayout>
<TableLayout android:id="@+id/TableLayout01" android:stretchColumns="*" android:layout_height="fill_parent" android:layout_width="wrap_content">
<TableRow android:layout_margin="10dip" android:id="@+id/TableRow01" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent">
<ScrollView android:id="@+id/helpscrollview"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_span="3"
>
<LinearLayout android:background="#575757" android:layout_width="wrap_content" android:id="@+id/linearLayout1" android:layout_height="wrap_content" android:orientation="vertical">
<TextView android:layout_width="wrap_content" android:textColor="#ffffff" android:layout_height="wrap_content" android:textSize="8pt" android:id="@+id/WizardTextBody1" android:text="this is sample text this is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample text" android:padding="20dip"></TextView>
<Button android:layout_width="wrap_content" android:visibility="gone" android:layout_height="wrap_content" android:gravity="center" android:text="Grant Permission" android:id="@+id/grantPermissions" android:layout_gravity="center"></Button>
<TextView android:layout_width="wrap_content" android:visibility="gone" android:textColor="#ffffff" android:layout_height="wrap_content" android:textSize="8pt" android:id="@+id/WizardTextBody2" android:text="this is sample text this is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample text" android:padding="20dip"></TextView>
<CheckBox android:id="@+id/checkBox" android:layout_gravity="center" android:text="@string/wizard_permissions_consent" android:layout_height="wrap_content" android:layout_width="wrap_content" android:gravity="center" android:visibility="visible"></CheckBox>
</LinearLayout>
</ScrollView>
</TableRow>
<TableRow android:background="#000000" android:layout_marginTop="10dip" android:paddingTop="10dip" android:id="@+id/TableRow01" android:textColor="#00ff00" android:layout_width="fill_parent" android:layout_height="30px">
<Button android:text="Back" android:id="@+id/btnWizard1" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
<Button android:text="Next" android:id="@+id/btnWizard2" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
</TableRow>
</TableLayout>
</LinearLayout>

View File

@ -1,29 +1,69 @@
<?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="wrap_content">
android:layout_height="fill_parent">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/relativeLayout1"
android:layout_gravity="center_horizontal"
android:background="#000000">
<TextView android:textSize="10pt"
android:textColor="#FFFFFF"
android:layout_alignParentTop="true"
android:layout_height="wrap_content"
android:id="@+id/WizardTextTitle"
android:layout_width="wrap_content"
android:fadingEdge="vertical"
android:text="TITLE"
android:singleLine="true"
android:padding="20px" android:layout_centerInParent="true">
</TextView>
</RelativeLayout>
<TableLayout android:id="@+id/TableLayout01" android:stretchColumns="*" android:layout_height="fill_parent" android:layout_width="wrap_content">
<TableRow android:layout_margin="10dip" android:id="@+id/TableRow01" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent">
<ScrollView android:id="@+id/helpscrollview"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_height="fill_parent"
android:layout_span="3">
<LinearLayout
android:background="#575757"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="3px">
<TextView android:text="@string/wizard_configure_msg" android:textColor="#ffffff" android:id="@+id/WizardRootTextView01" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
<CheckBox android:layout_marginTop="20px" android:text="@string/wizard_configure_all" android:id="@+id/WizardRootCheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox>
<TextView android:text=" or " android:textColor="#ffffff" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
<Button android:text="@string/wizard_configure_select_apps" android:id="@+id/WizardRootButton01" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<TextView android:text="@string/wizard_transproxy_msg" android:layout_width="wrap_content" android:textColor="#ffffff" android:layout_height="wrap_content" android:textSize="8pt" android:id="@+id/WizardTextBody1" android:padding="20dip"></TextView>
<RadioGroup android:id="@+id/radioGroup" android:layout_height="wrap_content" android:layout_width="wrap_content" android:paddingLeft="15dip">
<RadioButton android:text="@string/wizard_configure_all" android:id="@+id/radio0" android:layout_height="wrap_content" android:layout_width="wrap_content"></RadioButton>
<TextView android:layout_height="wrap_content"
android:text="@string/wizard_transproxy_hint"
android:layout_width="wrap_content"
android:textSize="15sp"
android:paddingBottom="10dip" android:paddingRight="20dip">
</TextView>
<RadioButton android:text="@string/wizard_configure_select_apps" android:id="@+id/radio1" android:layout_height="wrap_content" android:layout_width="wrap_content"></RadioButton>
<RadioButton android:text="@string/wizard_transproxy_none" android:id="@+id/radio2" android:layout_height="wrap_content" android:layout_width="wrap_content"></RadioButton>
</RadioGroup>
</LinearLayout>
</ScrollView>
</ScrollView>
</TableRow>
<TableRow android:background="#000000" android:layout_marginTop="10dip" android:paddingTop="10dip" android:id="@+id/TableRow01" android:textColor="#00ff00" android:layout_width="fill_parent" android:layout_height="30px">
<Button android:text="Back" android:id="@+id/btnWizard1" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
<Button android:text="Next" android:id="@+id/btnWizard2" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
</TableRow>
</TableLayout>
</LinearLayout>

View File

@ -1,29 +1,63 @@
<?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="wrap_content">
android:layout_height="fill_parent">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/relativeLayout1"
android:layout_gravity="center_horizontal"
android:background="#000000">
<TextView android:textSize="10pt"
android:textColor="#FFFFFF"
android:layout_alignParentTop="true"
android:layout_height="wrap_content"
android:id="@+id/WizardTextTitle"
android:layout_width="wrap_content"
android:fadingEdge="vertical"
android:text="TITLE"
android:singleLine="true"
android:padding="20px" android:layout_centerInParent="true">
</TextView>
</RelativeLayout>
<TableLayout android:id="@+id/TableLayout01" android:stretchColumns="*" android:layout_height="fill_parent" android:layout_width="wrap_content">
<TableRow android:layout_margin="10dip" android:id="@+id/TableRow01" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent">
<ScrollView android:id="@+id/helpscrollview"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_height="fill_parent"
android:layout_span="3">
<LinearLayout
android:background="#575757"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="3px">
android:paddingRight="20dip"
>
<TextView android:text="@string/wizard_tips_msg" android:layout_gravity="left" android:textColor="#ffffff" android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
<TextView android:text="@string/wizard_tips_msg" android:layout_width="wrap_content" android:textColor="#ffffff" android:layout_height="wrap_content" android:textSize="8pt" android:id="@+id/WizardTextBody1" android:padding="20dip"></TextView>
<Button android:text="@string/wizard_tips_gibberbot" android:layout_gravity="left" android:drawableLeft="@drawable/ic_launcher_gibberbot" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonInstallGibberbot" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<Button android:text="@string/wizard_tips_otrchat" android:layout_gravity="left" android:drawableLeft="@drawable/ic_launcher_gibberbot" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonInstallOtrchat" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<Button android:text="@string/wizard_tips_firefox" android:layout_gravity="left" android:drawableLeft="@drawable/icon_firefox" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonInstallFirefox" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<Button android:text="@string/wizard_tips_orweb" android:drawableLeft="@drawable/icon_orweb" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonInstallOrweb" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<Button android:text="@string/wizard_tips_proxy" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonProxyHelp" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<Button android:text="@string/wizard_tips_proxymob" android:layout_marginTop="10px" android:drawableLeft="@drawable/proxymob" android:id="@+id/WizardRootButtonInstallProxyMob" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
</ScrollView>
</TableRow>
<TableRow android:background="#000000" android:layout_marginTop="10dip" android:paddingTop="10dip" android:id="@+id/TableRow01" android:textColor="#00ff00" android:layout_width="fill_parent" android:layout_height="30px">
<Button android:text="Back" android:id="@+id/btnWizard1" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
<Button android:text="Next" android:id="@+id/btnWizard2" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
</TableRow>
</TableLayout>
</LinearLayout>

View File

@ -0,0 +1,68 @@
<?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"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/relativeLayout1"
android:layout_gravity="center_horizontal"
android:background="#000000"
>
<ImageView
android:src="@drawable/warning"
android:id="@+id/orbot_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:paddingLeft="20px" android:layout_marginLeft="10dip" android:layout_marginTop="8dip">
</ImageView>
<TextView
android:textColor="#FFFFFF"
android:textSize="10pt"
android:layout_toRightOf="@id/orbot_image"
android:layout_alignParentTop="true"
android:gravity="center_vertical"
android:layout_height="wrap_content"
android:id="@+id/WizardTextTitle"
android:layout_width="wrap_content"
android:fadingEdge="vertical"
android:text="TITLE"
android:singleLine="true"
android:layout_centerInParent="true"
android:paddingLeft="5px"
android:padding="20px"
>
</TextView>
</RelativeLayout>
<TableLayout android:id="@+id/TableLayout01" android:stretchColumns="*" android:layout_height="fill_parent" android:layout_width="wrap_content" >
<TableRow android:id="@+id/TableRow01" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_margin="10dip">
<ScrollView android:id="@+id/helpscrollview"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_span="3">
<TextView android:background="#575757" android:text="this is sample text this is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample text" android:textColor="#ffffff" android:id="@+id/WizardTextBody" android:textSize="8pt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="20dip"></TextView>
</ScrollView>
</TableRow>
<TableRow android:background="#000000" android:id="@+id/TableRow01" android:textColor="#00ff00" android:layout_width="fill_parent" android:layout_height="30px" android:layout_marginTop="10dip" android:paddingTop="10dip">
<Button android:text="Back" android:id="@+id/btnWizard1" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
<Button android:text="Next" android:id="@+id/btnWizard2" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
</TableRow>
</TableLayout>
</LinearLayout>

Binary file not shown.

BIN
res/raw/toraa Normal file

Binary file not shown.

BIN
res/raw/torab Normal file

Binary file not shown.

BIN
res/raw/torac Normal file

Binary file not shown.

BIN
res/raw/torad Normal file

Binary file not shown.

View File

@ -7,5 +7,8 @@ RelayBandwidthRate 20 KBytes
RelayBandwidthBurst 20 KBytes
UseBridges 0
AutomapHostsOnResolve 1
TransListenAddress 0.0.0.0
TransPort 9040
DNSListenAddress 0.0.0.0
DNSPort 5400

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">اوربوت (Orbot)</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">اوربات</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Орбот</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>
<string name="secure_default_web_url">https://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">1.0.5</string>
<string name="internal_web_url">http://orbot/</string>
<string name="default_web_url">http://check.torproject.org</string>
@ -130,5 +129,42 @@
<string name="pref_general_group">General</string>
<string name="pref_start_boot_title">Start Orbot on Boot</string>
<string name="pref_start_boot_summary">Automatically start Orbot and connect Tor when your Android device boots</string>
<!-- New Wizard Strings -->
<!-- Title Screen -->
<string name="wizard_title_msg">Orbot brings Tor to Android \n\nTor helps you defend against a form of network surveillance that threatens privacy, confidential business activity and relationships, and state security known as traffic analysis</string>
<!-- Warning screen -->
<string name="wizard_warning_title">Warning</string>
<string name="wizard_warning_msg">Simply installing Orbot will not automatically anonymize your mobile traffic.\n\nPlease follow the following steps to get started</string>
<!-- Permissions screen -->
<string name="wizard_permissions_title">Permissions</string>
<string name="wizard_permissions_root_msg1">Orbot has detected that you have root permissions enabled. To enable \'Transparent Proxying\', please grant superuser privileges to Orbot</string>
<string name="wizard_permissions_root_msg2">If you choose to continue without providing superuser privileges, make sure to use apps made to work with orbot</string>
<string name="wizard_permissions_msg">Orbot has detected that you do not have root permissions.\nTransparent Proxying is not possible without superuser privileges.\nMake sure to use apps that have been configured to work with Orbot</string>
<!-- TipsAndTricks screen -->
<string name="wizard_tips_title">Orbot configured Apps</string>
<string name="wizard_tips_gibberbot">Gibberbot - Secure instant messaging client for Android</string>
<string name="wizard_tips_firefox">Firefox - Android browser - To be used along with ProxyMob Add-on </string>
<string name="wizard_tips_proxymob">ProxyMob - Simple Firefox Add-on for setting HTTP, SOCKS and SSL proxy settings</string>
<string name="gibberbot_apk_url">https://market.android.com/details?id=info.guardianproject.otr.app.im</string>
<string name="firefox_apk_url">https://market.android.com/details?id=org.mozilla.firefox</string>
<string name="proxymob_url">https://addons.mozilla.org/mobile/downloads/latest/251558/type:attachment/addon-251558-latest.xpi?src=addon-detail</string>
<!-- Transparent Proxy screen -->
<string name="wizard_transproxy_title">Transparent Proxy</string>
<string name="wizard_transproxy_msg">Transparent Proxying allows you to redirect client requests without any special configuration or knowledge at the client.</string>
<string name="wizard_transproxy_hint">(Check this box if you have no idea what we are talking about)</string>
<string name="wizard_transproxy_none">None</string>
<string name="pref_transparent_tethering_title">Tor Tethering</string>
<string name="pref_transparent_tethering_summary">Enable Tor Transparent Proxying for Wifi and USB Tethered Devices</string>
<string name="pref_select_apps">Select Apps</string>
<string name="pref_select_apps_summary">Choose Apps to Route Through Tor</string>
<string name="pref_node_configuration">Node Configuration</string>
<string name="pref_node_configuration_summary">These are advanced settings that can reduce your anonymity</string>
<string name="pref_entrance_node">Entrance Nodes</string>
<string name="pref_entrance_node_summary">Fingerprints, nicks, countries and addresses for the first hop</string>
<string name="pref_entrance_node_dialog">Enter Entrance Nodes</string>
</resources>

9
res/values/theme.xml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="custom_theme_color">#333</color>
<style name="DefaultTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/bgtitanium</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>

View File

@ -35,18 +35,27 @@ android:title="@string/pref_transparent_all_title"/>
<Preference
android:defaultValue=""
android:key="pref_transparent_app_list"
android:title="Select Apps"
android:summary="Choose Apps to Route Through Tor"
android:title="@string/pref_select_apps"
android:summary="@string/pref_select_apps_summary"
android:enabled="true"/>
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_transparent_tethering"
android:summary="@string/pref_transparent_tethering_summary"
android:enabled="true"
android:title="@string/pref_transparent_tethering_title"/>
</PreferenceCategory>
<PreferenceCategory android:title="Node Configuration" android:summary="These are advanced settings that can reduce your anonymity">
<PreferenceCategory android:title="@string/pref_node_configuration"
android:summary="@string/pref_node_configuration_summary">
<EditTextPreference android:key="pref_entrance_nodes"
android:title="Entrance Nodes"
android:summary="Fingerprints, nicks, countries and addresses for the first hop"
android:dialogTitle="Enter Entrance Nodes"
android:title="@string/pref_entrance_node"
android:summary="@string/pref_entrance_node_summary"
android:dialogTitle="@string/pref_entrance_node_dialog"
/>
<EditTextPreference android:key="pref_exit_nodes"
android:title="Exit Nodes"
@ -70,11 +79,6 @@ android:summary="Use *only* these specified nodes"/>
android:title="Use Bridges" android:key="pref_bridges_enabled"
android:summary="Enable alternate entrance nodes into the Tor Network"></CheckBoxPreference>
<!-- 5/8/2010 NF: Arma says this doesn't actually work, so commenting out for now
<CheckBoxPreference android:defaultValue="false"
android:title="Update from Authority" android:key="pref_bridges_update"
android:summary="Modify bridge list automatically"></CheckBoxPreference>
-->
<EditTextPreference android:key="pref_bridges_list"
android:title="Bridges"

View File

@ -0,0 +1,183 @@
package org.torproject.android;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Toast;
public class ConfigureTransProxy extends Activity implements TorConstants {
private Context context;
private int flag = 0;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
context = this;
}
@Override
protected void onStart() {
super.onStart();
setContentView(R.layout.layout_wizard_root);
stepSix();
}
@Override
protected void onResume() {
super.onResume();
}
private void stepSix(){
String title = context.getString(R.string.wizard_transproxy_title);
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
txtTitle.setText(title);
Button back = ((Button)findViewById(R.id.btnWizard1));
Button next = ((Button)findViewById(R.id.btnWizard2));
next.setEnabled(false);
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new Intent(getBaseContext(), Permissions.class), 1);
}
});
next.setOnClickListener(new View.OnClickListener() {
//Dirty flag variable - improve logic
@Override
public void onClick(View v) {
if( flag == 1 )
context.startActivity(new Intent(context, AppManager.class));
else
showWizardFinal();
}
});
RadioGroup mRadioGroup = (RadioGroup)findViewById(R.id.radioGroup);
mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener (){
@Override
public void onCheckedChanged(RadioGroup group, int checkedId){
Button next = ((Button)findViewById(R.id.btnWizard2));
next.setEnabled(true);
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showWizardFinal();
}
});
RadioButton rb0 = (RadioButton)findViewById(R.id.radio0);
RadioButton rb1 = (RadioButton)findViewById(R.id.radio1);
RadioButton rb2 = (RadioButton)findViewById(R.id.radio2);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
Editor pEdit = prefs.edit();
pEdit.putBoolean(PREF_TRANSPARENT, rb0.isChecked());
pEdit.putBoolean(PREF_TRANSPARENT_ALL, rb0.isChecked());
pEdit.commit();
if(rb0.isChecked())
{
pEdit.putString("radiobutton","rb0");
pEdit.commit();
}
else if(rb1.isChecked())
{
flag = 1;
pEdit.putBoolean(PREF_TRANSPARENT, true);
pEdit.putBoolean(PREF_TRANSPARENT_ALL, false);
pEdit.putString("radiobutton","rb1");
pEdit.commit();
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
context.startActivity(new Intent(context, AppManager.class));
}
});
}
else if(rb2.isChecked())
{
pEdit.putString("radiobutton", "rb2");
pEdit.commit();
}
}
});
}
private void showWizardFinal ()
{
String title = null;
String msg = null;
title = context.getString(R.string.wizard_final);
msg = context.getString(R.string.wizard_final_msg);
DialogInterface.OnClickListener ocListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
context.startActivity(new Intent(context, Orbot.class));
}
};
new AlertDialog.Builder(context)
.setIcon(R.drawable.icon)
.setTitle(title)
.setPositiveButton(R.string.button_close, ocListener)
.setMessage(msg)
.show();
}
}

View File

@ -0,0 +1,133 @@
package org.torproject.android;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class LotsaText extends Activity implements TorConstants{
private Context context;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
context = this;
}
@Override
protected void onStart() {
super.onStart();
setContentView(R.layout.scrollingtext_buttons_view);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean wizardScreen1 = prefs.getBoolean("wizardscreen1",true);
if(wizardScreen1)
stepOne();
else
stepTwo();
}
@Override
protected void onResume() {
super.onResume();
}
private void stepOne() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
Editor pEdit = prefs.edit();
pEdit.putBoolean("wizardscreen1",true);
pEdit.commit();
String title = context.getString(R.string.wizard_title);
String msg = context.getString(R.string.wizard_title_msg);
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
txtTitle.setText(title);
TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
txtBody.setText(msg);
Button btn1 = ((Button)findViewById(R.id.btnWizard1));
Button btn2 = ((Button)findViewById(R.id.btnWizard2));
ImageView img = (ImageView) findViewById(R.id.orbot_image);
btn1.setVisibility(Button.INVISIBLE);
img.setImageResource(R.drawable.tor);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stepTwo();
}
});
}
private void stepTwo() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
Editor pEdit = prefs.edit();
pEdit.putBoolean("wizardscreen1",false);
pEdit.commit();
setContentView(R.layout.scrollingtext_buttons_view);
String title = context.getString(R.string.wizard_warning_title);
String msg = context.getString(R.string.wizard_warning_msg);
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
txtTitle.setText(title);
TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
txtBody.setText(msg);
Button btn1 = ((Button)findViewById(R.id.btnWizard1));
Button btn2 = ((Button)findViewById(R.id.btnWizard2));
ImageView img = (ImageView) findViewById(R.id.orbot_image);
btn1.setVisibility(Button.VISIBLE);
img.setImageResource(R.drawable.warning);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stepOne();
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new Intent(getBaseContext(), Permissions.class), 1);
}
});
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,229 @@
package org.torproject.android;
import org.torproject.android.service.TorService;
import org.torproject.android.service.TorServiceUtils;
import org.torproject.android.service.TorTransProxy;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.Toast;
public class Permissions extends Activity implements TorConstants {
private Context context;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
context = this;
}
@Override
protected void onStart() {
super.onStart();
setContentView(R.layout.layout_wizard_permissions);
stepThree();
}
@Override
protected void onResume() {
super.onResume();
}
private void stepThree(){
boolean hasRoot = TorServiceUtils.checkRootAccess();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
Editor pEdit = prefs.edit();
pEdit.putBoolean("has_root",hasRoot);
pEdit.commit();
if (hasRoot)
{
stepFourRoot();
}
else
{
stepFour();
}
}
private void stepFourRoot(){
String title = context.getString(R.string.wizard_permissions_title);
String msg1 = context.getString(R.string.wizard_permissions_root_msg1);
String msg2 = context.getString(R.string.wizard_permissions_root_msg2);
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
txtTitle.setText(title);
TextView txtBody1 = ((TextView)findViewById(R.id.WizardTextBody1));
txtBody1.setText(msg1);
TextView txtBody2 = ((TextView)findViewById(R.id.WizardTextBody2));
txtBody2.setText(msg2);
txtBody2.setVisibility(TextView.VISIBLE);
Button grantPermissions = ((Button)findViewById(R.id.grantPermissions));
grantPermissions.setVisibility(Button.VISIBLE);
Button back = ((Button)findViewById(R.id.btnWizard1));
Button next = ((Button)findViewById(R.id.btnWizard2));
next.setEnabled(false);
CheckBox consent = (CheckBox)findViewById(R.id.checkBox);
consent.setVisibility(CheckBox.VISIBLE);
consent.setOnCheckedChangeListener(new OnCheckedChangeListener (){
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
Editor pEdit = prefs.edit();
pEdit.putBoolean(PREF_TRANSPARENT, !isChecked);
pEdit.putBoolean(PREF_TRANSPARENT_ALL, !isChecked);
pEdit.commit();
Button next = ((Button)findViewById(R.id.btnWizard2));
if(isChecked)
next.setEnabled(true);
else
next.setEnabled(false);
}
});
grantPermissions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Check and Install iptables - TorTransProxy.testOwnerModule(this)
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean hasRoot = prefs.getBoolean("has_root",false);
if (hasRoot)
{
try {
int resp = TorTransProxy.testOwnerModule(context);
if (resp < 0)
{
hasRoot = false;
Toast.makeText(context, "ERROR: IPTables OWNER module not available", Toast.LENGTH_LONG).show();
Log.i(TorService.TAG,"ERROR: IPTables OWNER module not available");
stepFour();
}
} catch (Exception e) {
hasRoot = false;
Log.d(TorService.TAG,"ERROR: IPTables OWNER module not available",e);
}
}
startActivityForResult(new Intent(getBaseContext(), ConfigureTransProxy.class), 1);
}
});
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new Intent(getBaseContext(), LotsaText.class), 1);
}
});
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new Intent(getBaseContext(), TipsAndTricks.class), 1);
}
});
}
private void stepFour(){
Toast.makeText(context, "NON ROOT FUNC", Toast.LENGTH_SHORT).show();
String title = context.getString(R.string.wizard_permissions_title);
String msg = context.getString(R.string.wizard_permissions_msg);
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
txtTitle.setText(title);
TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody1));
txtBody.setText(msg);
Button btn1 = ((Button)findViewById(R.id.btnWizard1));
Button btn2 = ((Button)findViewById(R.id.btnWizard2));
btn2.setEnabled(true);
TextView txtBody2 = ((TextView)findViewById(R.id.WizardTextBody2));
txtBody2.setVisibility(TextView.GONE);
Button grantPermissions = ((Button)findViewById(R.id.grantPermissions));
grantPermissions.setVisibility(Button.GONE);
CheckBox consent = (CheckBox)findViewById(R.id.checkBox);
consent.setVisibility(CheckBox.GONE);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new Intent(getBaseContext(), LotsaText.class), 1);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new Intent(getBaseContext(), TipsAndTricks.class), 1);
}
});
}
}

View File

@ -28,6 +28,9 @@ public class SettingsPreferences
private boolean hasRoot = false;
private final static int HIDDEN_SERVICE_PREF_IDX = 6;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
@ -77,12 +80,11 @@ public class SettingsPreferences
}
int hiddenGroupIdx = 6;
prefHiddenServices = ((CheckBoxPreference)((PreferenceCategory)this.getPreferenceScreen().getPreference(hiddenGroupIdx)).getPreference(0));
prefHiddenServices = ((CheckBoxPreference)((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(0));
prefHiddenServices.setOnPreferenceClickListener(this);
((PreferenceCategory)this.getPreferenceScreen().getPreference(hiddenGroupIdx)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
((PreferenceCategory)this.getPreferenceScreen().getPreference(hiddenGroupIdx)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
};
@ -113,8 +115,8 @@ public class SettingsPreferences
else if (preference == prefHiddenServices)
{
((PreferenceCategory)this.getPreferenceScreen().getPreference(5)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
((PreferenceCategory)this.getPreferenceScreen().getPreference(5)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
}
else

View File

@ -0,0 +1,139 @@
package org.torproject.android;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class TipsAndTricks extends Activity implements TorConstants {
private Context context;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
context = this;
}
@Override
protected void onStart() {
super.onStart();
setContentView(R.layout.layout_wizard_tips);
stepFive();
}
@Override
protected void onResume() {
super.onResume();
}
void stepFive(){
String title = context.getString(R.string.wizard_tips_title);
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
txtTitle.setText(title);
Button btn1 = (Button)findViewById(R.id.WizardRootButtonInstallGibberbot);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String url = context.getString(R.string.gibberbot_apk_url);
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
});
Button btn2 = (Button)findViewById(R.id.WizardRootButtonInstallFirefox);
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String url = context.getString(R.string.firefox_apk_url);
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
});
Button btn3 = (Button)findViewById(R.id.WizardRootButtonInstallProxyMob);
btn3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String url = context.getString(R.string.proxymob_url);
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
});
Button back = ((Button)findViewById(R.id.btnWizard1));
Button next = ((Button)findViewById(R.id.btnWizard2));
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new Intent(getBaseContext(), Permissions.class), 1);
}
});
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showWizardFinal();
}
});
}
private void showWizardFinal ()
{
String title = null;
String msg = null;
title = context.getString(R.string.wizard_final);
msg = context.getString(R.string.wizard_final_msg);
DialogInterface.OnClickListener ocListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
context.startActivity(new Intent(context, Orbot.class));
}
};
new AlertDialog.Builder(context)
.setIcon(R.drawable.icon)
.setTitle(title)
.setPositiveButton(R.string.button_close, ocListener)
.setMessage(msg)
.show();
}
}

View File

@ -1,71 +0,0 @@
package org.torproject.android;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
public class WizardActivity extends Activity implements OnClickListener
{
protected void onCreate(Bundle savedInstanceState)
{
this.setContentView(R.layout.layout_help);
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
showStep1();
}
public void showStep1()
{
showDialog("Test","","foo","bar",this);
}
private void showDialog (String title, String msg, String button1, String button2, OnClickListener ocListener)
{
new AlertDialog.Builder(this)
.setInverseBackgroundForced(true)
.setTitle(title)
.setMessage(msg)
.setNeutralButton(button1, ocListener)
.setNegativeButton(button2, ocListener)
.show();
}
@Override
public void onClick(DialogInterface arg0, int arg1) {
}
}

View File

@ -215,7 +215,7 @@ public class WizardHelper implements TorConstants {
LayoutInflater li = LayoutInflater.from(context);
View view = li.inflate(R.layout.layout_wizard_tips, null);
Button btn1 = (Button)view.findViewById(R.id.WizardRootButtonInstallOtrchat);
Button btn1 = (Button)view.findViewById(R.id.WizardRootButtonInstallGibberbot);
btn1.setOnClickListener(new OnClickListener() {
@ -228,7 +228,7 @@ public class WizardHelper implements TorConstants {
}
});
Button btn2 = (Button)view.findViewById(R.id.WizardRootButtonInstallOrweb);
Button btn2 = (Button)view.findViewById(R.id.WizardRootButtonInstallFirefox);
btn2.setOnClickListener(new OnClickListener() {
@ -241,7 +241,7 @@ public class WizardHelper implements TorConstants {
}
});
Button btn3 = (Button)view.findViewById(R.id.WizardRootButtonProxyHelp);
Button btn3 = (Button)view.findViewById(R.id.WizardRootButtonInstallProxyMob);
btn3.setOnClickListener(new OnClickListener() {
@ -277,7 +277,7 @@ public class WizardHelper implements TorConstants {
public void showWizardRootConfigureTorification()
{
/*
LayoutInflater li = LayoutInflater.from(context);
View view = li.inflate(R.layout.layout_wizard_root, null);
@ -347,7 +347,7 @@ public class WizardHelper implements TorConstants {
}
});
*/
}

View File

@ -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);
}
}

View File

@ -55,7 +55,7 @@ import android.widget.Toast;
* Contains shared programming interfaces.
* All iptables "communication" is handled by this class.
*/
public final class Api {
public final class IptablesManager {
/** application version string */
public static final String VERSION = "1.5.1-dev";
/** special application UID used to indicate "any application" */
@ -861,8 +861,8 @@ public final class Api {
return;
}
/* notify */
final Intent message = new Intent(Api.STATUS_CHANGED_MSG);
message.putExtra(Api.STATUS_EXTRA, enabled);
final Intent message = new Intent(IptablesManager.STATUS_CHANGED_MSG);
message.putExtra(IptablesManager.STATUS_EXTRA, enabled);
ctx.sendBroadcast(message);
}
/**

View File

@ -20,160 +20,88 @@ import android.util.Log;
public class TorBinaryInstaller implements TorServiceConstants {
String installPath;
String apkPath;
File installFolder;
Context context;
public TorBinaryInstaller (Context context, String installPath, String apkPath)
public TorBinaryInstaller (Context context, File installFolder)
{
this.installPath = installPath;
this.apkPath = apkPath;
this.installFolder = installFolder;
this.context = context;
}
/*
* Start the binary installation if the file doesn't exist or is forced
*/
public void start (boolean force)
{
boolean torBinaryExists = new File(installPath + TOR_BINARY_ASSET_KEY).exists();
Log.d(TAG,"Tor binary exists=" + torBinaryExists);
boolean privoxyBinaryExists = new File(installPath + PRIVOXY_ASSET_KEY).exists();
Log.d(TAG,"Privoxy binary exists=" + privoxyBinaryExists);
if (!(torBinaryExists && privoxyBinaryExists) || force)
installFromRaw ();
}
//
/*
* Extract the Tor binary from the APK file using ZIP
*/
private void installFromRaw ()
public boolean installFromRaw ()
{
boolean result = false;
InputStream is = context.getResources().openRawResource(R.raw.tor);
streamToFile(is,installPath + TOR_BINARY_ASSET_KEY);
is = context.getResources().openRawResource(R.raw.torrc);
streamToFile(is,installPath + TORRC_ASSET_KEY);
is = context.getResources().openRawResource(R.raw.privoxy);
streamToFile(is,installPath + PRIVOXY_ASSET_KEY);
is = context.getResources().openRawResource(R.raw.privoxy_config);
streamToFile(is,installPath + PRIVOXYCONFIG_ASSET_KEY);
Log.d(TAG,"SUCCESS: installed tor, privoxy binaries from raw");
}
/*
* Extract the Tor binary from the APK file using ZIP
*/
private void installFromZip ()
{
try
{
InputStream is;
ZipFile zip = new ZipFile(apkPath);
is = context.getResources().openRawResource(R.raw.toraa);
streamToFile(is,installFolder, TOR_BINARY_ASSET_KEY, false);
is = context.getResources().openRawResource(R.raw.torab);
streamToFile(is,installFolder, TOR_BINARY_ASSET_KEY, true);
is = context.getResources().openRawResource(R.raw.torac);
streamToFile(is,installFolder, TOR_BINARY_ASSET_KEY, true);
is = context.getResources().openRawResource(R.raw.torad);
streamToFile(is,installFolder, TOR_BINARY_ASSET_KEY, true);
is = context.getResources().openRawResource(R.raw.torrc);
streamToFile(is,installFolder, TORRC_ASSET_KEY, false);
ZipEntry zipen = zip.getEntry(ASSETS_BASE + TOR_BINARY_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + TOR_BINARY_ASSET_KEY);
zipen = zip.getEntry(ASSETS_BASE + TORRC_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + TORRC_ASSET_KEY);
zipen = zip.getEntry(ASSETS_BASE + PRIVOXY_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + PRIVOXY_ASSET_KEY);
zipen = zip.getEntry(ASSETS_BASE + PRIVOXYCONFIG_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + PRIVOXYCONFIG_ASSET_KEY);
zipen = zip.getEntry(ASSETS_BASE + PRIVOXYCONFIG_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + PRIVOXYCONFIG_ASSET_KEY);
zip.close();
Log.d(TAG,"SUCCESS: unzipped tor, privoxy, iptables binaries from apk");
is = context.getResources().openRawResource(R.raw.privoxy);
streamToFile(is,installFolder, PRIVOXY_ASSET_KEY, false);
is = context.getResources().openRawResource(R.raw.privoxy_config);
streamToFile(is,installFolder, PRIVOXYCONFIG_ASSET_KEY, false);
}
catch (IOException ioe)
{
Log.d(TAG,"FAIL: unable to unzip binaries from apk",ioe);
Log.e(TAG, "unable to install tor binaries from raw", ioe);
return false;
}
return true;
}
/*
* Write the inputstream contents to the file
*/
private static void streamToFile(InputStream stm, String targetFilename)
private static boolean streamToFile(InputStream stm, File folder, String targetFilename, boolean append) throws IOException
{
FileOutputStream stmOut = null;
byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE];
int bytecount;
File outFile = new File(targetFilename);
File outFile = new File(folder, targetFilename);
FileOutputStream stmOut = new FileOutputStream(outFile, append);
while ((bytecount = stm.read(buffer)) > 0)
{
stmOut.write(buffer, 0, bytecount);
}
stmOut.close();
try {
outFile.createNewFile();
stmOut = new FileOutputStream(outFile);
}
catch (java.io.IOException e)
{
Log.d(TAG,"Error opening output file " + targetFilename,e);
return;
}
try
{
while ((bytecount = stm.read(buffer)) > 0)
{
stmOut.write(buffer, 0, bytecount);
}
stmOut.close();
}
catch (java.io.IOException e)
{
Log.d(TAG,"Error writing output file '" + targetFilename + "': " + e.toString());
return;
}
return true;
}

View File

@ -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;
@ -60,16 +60,13 @@ public class TorService extends Service implements TorServiceConstants, Runnable
private ArrayList<String> resetBuffer = null;
private String appHome;
private String appBinHome;
private String appDataHome;
// private String appHome;
private File appBinHome;
private File appDataHome;
private String torBinaryPath;
private String privoxyPath;
private boolean hasRoot = false;
/** Called when the activity is first created. */
public void onCreate() {
super.onCreate();
@ -416,43 +413,37 @@ public class TorService extends Service implements TorServiceConstants, Runnable
private boolean checkTorBinaries () throws Exception
{
//android.os.Debug.waitForDebugger();
//check and install iptables
Api.assertBinaries(this, true);
IptablesManager.assertBinaries(this, true);
File fileInstall = getDir("",0);
String subBinPath = "bin/";
appHome = fileInstall.getAbsolutePath();
appBinHome = appHome + subBinPath;
appDataHome = getCacheDir().getAbsolutePath() + '/';
logNotice( "appHome=" + appHome);
appBinHome = getDir("bin",0);
appDataHome = getCacheDir();
// logNotice( "appHome=" + appHome);
File fileTor = new File(appBinHome, TOR_BINARY_ASSET_KEY);
File filePrivoxy = new File(appBinHome, PRIVOXY_ASSET_KEY);
torBinaryPath = appBinHome + TOR_BINARY_ASSET_KEY;
privoxyPath = appBinHome + PRIVOXY_ASSET_KEY;
logNotice( "checking Tor binaries");
boolean torBinaryExists = new File(torBinaryPath).exists();
boolean privoxyBinaryExists = new File(privoxyPath).exists();
if (!(torBinaryExists && privoxyBinaryExists))
if (!(fileTor.exists() && filePrivoxy.exists()))
{
killTorProcess ();
TorBinaryInstaller installer = new TorBinaryInstaller(this, appBinHome, appBinHome);
installer.start(true);
TorBinaryInstaller installer = new TorBinaryInstaller(this, appBinHome);
boolean success = installer.installFromRaw();
torBinaryExists = new File(torBinaryPath).exists();
privoxyBinaryExists = new File(privoxyPath).exists();
if (torBinaryExists && privoxyBinaryExists)
if (success)
{
logNotice(getString(R.string.status_install_success));
showToolbarNotification(getString(R.string.status_install_success), NOTIFY_ID, R.drawable.tornotification);
torBinaryPath = fileTor.getAbsolutePath();
privoxyPath = filePrivoxy.getAbsolutePath();
}
else
{
@ -470,6 +461,9 @@ public class TorService extends Service implements TorServiceConstants, Runnable
logNotice("Found Tor binary: " + torBinaryPath);
logNotice("Found Privoxy binary: " + privoxyPath);
torBinaryPath = fileTor.getAbsolutePath();
privoxyPath = filePrivoxy.getAbsolutePath();
}
StringBuilder log = new StringBuilder ();
@ -545,6 +539,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 +576,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,11 +584,22 @@ 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;
@ -618,9 +625,9 @@ public class TorService extends Service implements TorServiceConstants, Runnable
StringBuilder log = new StringBuilder();
String torrcPath = appBinHome + TORRC_ASSET_KEY;
String torrcPath = new File(appBinHome, TORRC_ASSET_KEY).getAbsolutePath();
String[] torCmd = {torBinaryPath + " DataDirectory " + appDataHome + " -f " + torrcPath + " || exit\n"};
String[] torCmd = {torBinaryPath + " DataDirectory " + appDataHome.getAbsolutePath() + " -f " + torrcPath + " || exit\n"};
boolean runAsRootFalse = false;
boolean waitForProcess = false;
@ -688,7 +695,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
{
log = new StringBuilder();
String privoxyConfigPath = appBinHome + PRIVOXYCONFIG_ASSET_KEY;
String privoxyConfigPath = new File(appBinHome, PRIVOXYCONFIG_ASSET_KEY).getAbsolutePath();
String[] cmds =
{ privoxyPath + " " + privoxyConfigPath + " &" };
@ -753,7 +760,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
logNotice( "SUCCESS connected to control port");
String torAuthCookie = appDataHome + TOR_CONTROL_COOKIE;
String torAuthCookie = new File(appDataHome, TOR_CONTROL_COOKIE).getAbsolutePath();
File fileCookie = new File(torAuthCookie);
@ -1137,18 +1144,12 @@ public class TorService extends Service implements TorServiceConstants, Runnable
if (value == null || value.length() == 0)
{
resetBuffer.add(name);
/*
if (conn != null)
{
try {
conn.resetConf(Arrays.asList(new String[]{name}));
} catch (IOException e) {
Log.w(TAG, "Unable to reset conf",e);
}
}*/
}
else
{
configBuffer.add(name + ' ' + value);
}
return false;
}
@ -1290,13 +1291,10 @@ public class TorService extends Service implements TorServiceConstants, Runnable
boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
boolean enableStrictNodes = prefs.getBoolean("pref_strict_nodes", false);
String entranceNodes = prefs.getString("pref_entrance_nodes", "");
String exitNodes = prefs.getString("pref_exit_nodes", "");
String excludeNodes = prefs.getString("pref_exclude_nodes", "");
String entranceNodes = prefs.getString("pref_entrance_nodes", null);
String exitNodes = prefs.getString("pref_exit_nodes", null);
String excludeNodes = prefs.getString("pref_exclude_nodes", null);
//boolean enableTransparentProxy = prefs.getBoolean(TorConstants.PREF_TRANSPARENT, false);
if (currentStatus == STATUS_ON)
{
//reset iptables rules in active mode
@ -1311,10 +1309,10 @@ public class TorService extends Service implements TorServiceConstants, Runnable
}
}
mBinder.updateConfiguration("EntranceNodes", entranceNodes, false);
mBinder.updateConfiguration("EntryNodes", entranceNodes, false);
mBinder.updateConfiguration("ExitNodes", exitNodes, false);
mBinder.updateConfiguration("ExcludeNodes", excludeNodes, false);
mBinder.updateConfiguration("StrictExitNodes", enableStrictNodes ? "1" : "0", false);
mBinder.updateConfiguration("StrictNodes", enableStrictNodes ? "1" : "0", false);
if (useBridges)
{
@ -1407,7 +1405,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
if (enableHiddenServices)
{
mBinder.updateConfiguration("HiddenServiceDir",appDataHome, false);
mBinder.updateConfiguration("HiddenServiceDir",appDataHome.getAbsolutePath(), false);
String hsPorts = prefs.getString("pref_hs_ports","");

View File

@ -17,7 +17,9 @@ public class TorServiceUtils implements TorServiceConstants {
* Check if we have root access
* @return boolean true if we have root
*/
public static boolean checkRootAccess() {
/*
public static boolean checkRootAccess() {
StringBuilder log = new StringBuilder();
@ -45,7 +47,40 @@ public class TorServiceUtils implements TorServiceConstants {
TorService.logMessage("Could not acquire root permissions");
return false;
}
*/
public static boolean checkRootAccess(){
StringBuilder log = new StringBuilder();
try {
// Check if Superuser.apk exists
File file = new File("/system/app/Superuser.apk");
//Check for 'su' binary
String[] cmd = {"which su"};
int exitCode = TorServiceUtils.doShellCommand(cmd, log, false, true);
if (file.exists() && exitCode == 0) {
TorService.logMessage("Can acquire root permissions");
return true;
}
} catch (IOException e) {
//this means that there is no root to be had (normally) so we won't log anything
TorService.logException("Error checking for root access",e);
}
catch (Exception e) {
TorService.logException("Error checking for root access",e);
//this means that there is no root to be had (normally)
}
TorService.logMessage("Could not acquire root permissions");
return false;
}
public static int findProcessId(String command)

View File

@ -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;
script.append(ipTablesPath);
script.append(" -I FORWARD");
script.append(" -m state --state ESTABLISHED,RELATED -j ACCEPT");
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(" || exit\n");
String[] hwinterfaces = {"usb0","wl0.1"};
for (int i = 0; i < hwinterfaces.length; i++)
{
script.append(ipTablesPath);
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(" -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